ignore resharper settings file.
centralise content on html pages. replaced single quote with double. added full racesession form to create competition race separate Monitor.cshtml js into own file. remove js manual redirection as solved server side redirect (Context.AsRedirect) add methods to create and stop race session in IDbProvider interface. implement file upload for pilot pictures. Will upload picture, save into /images/ folder, update pilot profile to take new image, delete the old one, and refresh the edit screen.
This commit is contained in:
parent
c98384bfcd
commit
3d3a552664
1
.gitignore
vendored
1
.gitignore
vendored
@ -4,3 +4,4 @@
|
|||||||
**/packages/**
|
**/packages/**
|
||||||
**/.vs/**
|
**/.vs/**
|
||||||
**dotsettings
|
**dotsettings
|
||||||
|
**.DotSettings.user
|
||||||
|
|||||||
@ -15,7 +15,7 @@ namespace RaceLapTimer.ApiControllers
|
|||||||
|
|
||||||
private dynamic GetRootMonitorData(dynamic args)
|
private dynamic GetRootMonitorData(dynamic args)
|
||||||
{
|
{
|
||||||
return Response.AsJson(new { data=_provider.GetRaceSessions(true)});
|
return Response.AsJson(new { data = _provider.GetRaceSessions(true)});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,21 +1,66 @@
|
|||||||
using System.Web.Http;
|
using System;
|
||||||
|
using System.IO;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Web.Http;
|
||||||
using Interfaces;
|
using Interfaces;
|
||||||
using Nancy;
|
using Nancy;
|
||||||
|
using Nancy.Extensions;
|
||||||
using Nancy.ModelBinding;
|
using Nancy.ModelBinding;
|
||||||
|
using Nancy.Responses;
|
||||||
|
|
||||||
namespace RaceLapTimer.ApiControllers
|
namespace RaceLapTimer.ApiControllers
|
||||||
{
|
{
|
||||||
public class PilotApiModule:NancyModule
|
public class PilotApiModule:NancyModule
|
||||||
{
|
{
|
||||||
private readonly IDbProvider _provider;
|
private readonly IDbProvider _provider;
|
||||||
public PilotApiModule(IDbProvider provider) : base("/api/pilot")
|
private readonly IRootPathProvider _rootPathProvider;
|
||||||
|
|
||||||
|
public PilotApiModule(IDbProvider provider, IRootPathProvider pathProvider) : base("/api/pilot")
|
||||||
{
|
{
|
||||||
_provider = provider;
|
_provider = provider;
|
||||||
|
_rootPathProvider = pathProvider;
|
||||||
|
|
||||||
Get["/{id}"] = args => GetPilot(args);
|
Get["/{id}"] = args => GetPilot(args);
|
||||||
Post["/edit"] = args => EditCreatePilot(args);
|
Post["/edit"] = args => EditCreatePilot(args);
|
||||||
Post["/create"] = args => EditCreatePilot(args);
|
Post["/create"] = args => EditCreatePilot(args);
|
||||||
Get["/delete/{id}"] = args => DeletePilot(args);
|
Get["/delete/{id}"] = args => DeletePilot(args);
|
||||||
|
Post["/upload/{id}"] = args => UploadPicture(args);
|
||||||
|
}
|
||||||
|
|
||||||
|
private dynamic UploadPicture(dynamic args)
|
||||||
|
{
|
||||||
|
var pilotId = args.Id;
|
||||||
|
var pilot = (Pilot)_provider.GetPilot(pilotId);
|
||||||
|
var oldImagePath = pilot.ImageUrl;
|
||||||
|
|
||||||
|
var uploadDirectory = Path.Combine(_rootPathProvider.GetRootPath(), "images");
|
||||||
|
|
||||||
|
if (!Directory.Exists(uploadDirectory))
|
||||||
|
{
|
||||||
|
Directory.CreateDirectory(uploadDirectory);
|
||||||
|
}
|
||||||
|
|
||||||
|
var file = Request.Files.First();
|
||||||
|
|
||||||
|
var newFileName = Guid.NewGuid();
|
||||||
|
var generatedFileName = string.Format("{0}{1}",newFileName,Path.GetExtension(file.Name)); //0000-0000.....ext
|
||||||
|
|
||||||
|
var filename = Path.Combine(uploadDirectory, generatedFileName);
|
||||||
|
|
||||||
|
using (FileStream fileStream = new FileStream(filename, FileMode.Create))
|
||||||
|
{
|
||||||
|
file.Value.CopyTo(fileStream);
|
||||||
|
fileStream.Flush();
|
||||||
|
fileStream.Close();
|
||||||
|
}
|
||||||
|
|
||||||
|
pilot.ImageUrl = "/images/" + generatedFileName;
|
||||||
|
_provider.UpdatePilot(pilot);
|
||||||
|
|
||||||
|
File.Delete(Path.Combine(uploadDirectory, oldImagePath));
|
||||||
|
|
||||||
|
string returnurl = "/pilot/edit/" + pilotId;
|
||||||
|
return Context.GetRedirect(returnurl);
|
||||||
}
|
}
|
||||||
|
|
||||||
private dynamic DeletePilot(dynamic args)
|
private dynamic DeletePilot(dynamic args)
|
||||||
@ -34,9 +79,7 @@ namespace RaceLapTimer.ApiControllers
|
|||||||
{
|
{
|
||||||
var pilotObject = this.Bind<Pilot>();
|
var pilotObject = this.Bind<Pilot>();
|
||||||
var resp = _provider.CreatePilot(pilotObject);
|
var resp = _provider.CreatePilot(pilotObject);
|
||||||
if(resp)
|
return Context.GetRedirect("/pilots");
|
||||||
return new {url = "/pilots"};
|
|
||||||
return "error";
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,12 +1,13 @@
|
|||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using Interfaces;
|
using Interfaces;
|
||||||
using Nancy;
|
using Nancy;
|
||||||
|
using Nancy.Extensions;
|
||||||
using Nancy.ModelBinding;
|
using Nancy.ModelBinding;
|
||||||
using Nancy.Responses;
|
using Nancy.Responses;
|
||||||
|
|
||||||
namespace RaceLapTimer.ApiControllers
|
namespace RaceLapTimer.ApiControllers
|
||||||
{
|
{
|
||||||
public class RaceSessionApiModule:NancyModule
|
public class RaceSessionApiModule : NancyModule
|
||||||
{
|
{
|
||||||
private readonly IDbProvider _provider;
|
private readonly IDbProvider _provider;
|
||||||
public RaceSessionApiModule(IDbProvider provider) : base("/api/racesession")
|
public RaceSessionApiModule(IDbProvider provider) : base("/api/racesession")
|
||||||
@ -20,19 +21,20 @@ namespace RaceLapTimer.ApiControllers
|
|||||||
private dynamic GetHistoricRaceSessions()
|
private dynamic GetHistoricRaceSessions()
|
||||||
{
|
{
|
||||||
var sessions = _provider.GetRaceSessions(false);
|
var sessions = _provider.GetRaceSessions(false);
|
||||||
return Response.AsJson(new {data= sessions});
|
return Response.AsJson(new { data = sessions });
|
||||||
}
|
}
|
||||||
|
|
||||||
private dynamic GetRaceSessions()
|
private dynamic GetRaceSessions()
|
||||||
{
|
{
|
||||||
var sessions = _provider.GetRaceSessions(true);
|
var sessions = _provider.GetRaceSessions(true);
|
||||||
return Response.AsJson(new {data= sessions});
|
return Response.AsJson(new { data = sessions });
|
||||||
}
|
}
|
||||||
|
|
||||||
private dynamic CreateRaceSession(dynamic args)
|
private dynamic CreateRaceSession(dynamic args)
|
||||||
{
|
{
|
||||||
var postObject = this.Bind<RaceSession>();
|
var session = this.Bind<RaceSession>();
|
||||||
return new {url="/racedirector"};
|
var res = _provider.CreateRaceSession(session);
|
||||||
|
return Context.GetRedirect("/racedirector");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1,18 +1,25 @@
|
|||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using Interfaces;
|
using Interfaces;
|
||||||
|
using RaceLapTimer.ApiControllers;
|
||||||
|
|
||||||
namespace RaceLapTimer.ApiControllers
|
namespace RaceLapTimer
|
||||||
{
|
{
|
||||||
public interface IDbProvider
|
public interface IDbProvider
|
||||||
{
|
{
|
||||||
List<RaceSession> GetRaceSessions(bool getActive);
|
List<RaceSession> GetRaceSessions(bool getActive);
|
||||||
|
|
||||||
|
bool CreateRaceSession(RaceSession session);
|
||||||
|
|
||||||
|
bool StopRaceSession(RaceSession session);
|
||||||
|
|
||||||
List<Pilot> GetPilotsList();
|
List<Pilot> GetPilotsList();
|
||||||
|
|
||||||
Pilot GetPilot(int pilotId);
|
Pilot GetPilot(int pilotId);
|
||||||
|
|
||||||
bool CreatePilot(Pilot pilot);
|
bool CreatePilot(Pilot pilot);
|
||||||
|
|
||||||
|
bool UpdatePilot(Pilot pilot);
|
||||||
|
|
||||||
int GetLastScannedId();
|
int GetLastScannedId();
|
||||||
|
|
||||||
void StoreTransponderLog(SatelliteLog log);
|
void StoreTransponderLog(SatelliteLog log);
|
||||||
|
|||||||
@ -18,7 +18,7 @@ namespace RaceLapTimer.Modules
|
|||||||
|
|
||||||
private dynamic EditPilot(dynamic args)
|
private dynamic EditPilot(dynamic args)
|
||||||
{
|
{
|
||||||
return View["EditPilot.cshtml"];
|
return View["EditPilot.cshtml", new {Id=args.id}];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -155,6 +155,13 @@
|
|||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<None Include="App.config" />
|
<None Include="App.config" />
|
||||||
<None Include="packages.config" />
|
<None Include="packages.config" />
|
||||||
|
<None Include="www\fonts\glyphicons-halflings-regular.eot" />
|
||||||
|
<None Include="www\fonts\glyphicons-halflings-regular.ttf" />
|
||||||
|
<None Include="www\fonts\glyphicons-halflings-regular.woff" />
|
||||||
|
<None Include="www\fonts\glyphicons-halflings-regular.woff2" />
|
||||||
|
<None Include="www\Views\EditPilot.cshtml">
|
||||||
|
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||||
|
</None>
|
||||||
<None Include="www\Views\History.cshtml" />
|
<None Include="www\Views\History.cshtml" />
|
||||||
<None Include="www\Views\index.cshtml">
|
<None Include="www\Views\index.cshtml">
|
||||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||||
@ -178,10 +185,7 @@
|
|||||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||||
</None>
|
</None>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup />
|
||||||
<Folder Include="www\css\" />
|
|
||||||
<Folder Include="www\fonts\" />
|
|
||||||
</ItemGroup>
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ProjectReference Include="..\Helpers.Encrytion\Helpers.Encryption.csproj">
|
<ProjectReference Include="..\Helpers.Encrytion\Helpers.Encryption.csproj">
|
||||||
<Project>{bc7dea8b-5029-459a-aa54-ea81eb390f87}</Project>
|
<Project>{bc7dea8b-5029-459a-aa54-ea81eb390f87}</Project>
|
||||||
@ -199,9 +203,32 @@
|
|||||||
<Content Include="Plugins\placeholder.txt">
|
<Content Include="Plugins\placeholder.txt">
|
||||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||||
</Content>
|
</Content>
|
||||||
|
<Content Include="www\css\bootstrap-theme.css" />
|
||||||
|
<Content Include="www\css\bootstrap-theme.min.css" />
|
||||||
|
<Content Include="www\css\bootstrap.css" />
|
||||||
|
<Content Include="www\css\bootstrap.min.css" />
|
||||||
|
<Content Include="www\css\stickyfooter.css">
|
||||||
|
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||||
|
</Content>
|
||||||
|
<Content Include="www\fonts\glyphicons-halflings-regular.svg" />
|
||||||
<Content Include="www\images\pilotPic.png">
|
<Content Include="www\images\pilotPic.png">
|
||||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||||
</Content>
|
</Content>
|
||||||
|
<Content Include="www\js\bootstrap.js" />
|
||||||
|
<Content Include="www\js\bootstrap.min.js" />
|
||||||
|
<Content Include="www\js\monitor.js">
|
||||||
|
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||||
|
</Content>
|
||||||
|
<Content Include="www\js\editPilot.js">
|
||||||
|
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||||
|
</Content>
|
||||||
|
<Content Include="www\js\npm.js" />
|
||||||
|
<Content Include="www\js\RaceSessionObject.js">
|
||||||
|
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||||
|
</Content>
|
||||||
|
<Content Include="www\js\PilotObject.js">
|
||||||
|
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||||
|
</Content>
|
||||||
<Content Include="www\js\pilots.js">
|
<Content Include="www\js\pilots.js">
|
||||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||||
</Content>
|
</Content>
|
||||||
|
|||||||
@ -2,12 +2,14 @@
|
|||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using Interfaces;
|
using Interfaces;
|
||||||
|
using RaceLapTimer.ApiControllers;
|
||||||
|
|
||||||
namespace RaceLapTimer.ApiControllers
|
namespace RaceLapTimer
|
||||||
{
|
{
|
||||||
public class TestProvider : IDbProvider
|
public class TestProvider : IDbProvider
|
||||||
{
|
{
|
||||||
readonly List<Pilot> _pilots;
|
private readonly List<Pilot> _pilots;
|
||||||
|
private readonly List<RaceSession> _sessions;
|
||||||
|
|
||||||
public TestProvider()
|
public TestProvider()
|
||||||
{
|
{
|
||||||
@ -21,7 +23,7 @@ namespace RaceLapTimer.ApiControllers
|
|||||||
TeamName = "PilotTeam 1",
|
TeamName = "PilotTeam 1",
|
||||||
ThingyName = "Kart1",
|
ThingyName = "Kart1",
|
||||||
TransponderToken = 222,
|
TransponderToken = 222,
|
||||||
ImageUrl = "images/pilotPic.png"
|
ImageUrl = "/images/pilotPic.png"
|
||||||
},
|
},
|
||||||
new Pilot
|
new Pilot
|
||||||
{
|
{
|
||||||
@ -33,11 +35,8 @@ namespace RaceLapTimer.ApiControllers
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
#endregion
|
#endregion
|
||||||
}
|
#region RaceSessions
|
||||||
|
_sessions = new List<RaceSession>
|
||||||
public List<RaceSession> GetRaceSessions(bool getActive)
|
|
||||||
{
|
|
||||||
return new List<RaceSession>
|
|
||||||
{
|
{
|
||||||
#region Session 1
|
#region Session 1
|
||||||
new RaceSession
|
new RaceSession
|
||||||
@ -72,7 +71,7 @@ namespace RaceLapTimer.ApiControllers
|
|||||||
#region Session 3
|
#region Session 3
|
||||||
new RaceSession
|
new RaceSession
|
||||||
{
|
{
|
||||||
Active = getActive,
|
Active = false,
|
||||||
CreatedAt = DateTime.UtcNow,
|
CreatedAt = DateTime.UtcNow,
|
||||||
HotSeatEnabled = false,
|
HotSeatEnabled = false,
|
||||||
Id = 3,
|
Id = 3,
|
||||||
@ -87,7 +86,7 @@ namespace RaceLapTimer.ApiControllers
|
|||||||
#region Session 3
|
#region Session 3
|
||||||
new RaceSession
|
new RaceSession
|
||||||
{
|
{
|
||||||
Active = getActive,
|
Active = false,
|
||||||
CreatedAt = DateTime.UtcNow,
|
CreatedAt = DateTime.UtcNow,
|
||||||
HotSeatEnabled = false,
|
HotSeatEnabled = false,
|
||||||
Id = 4,
|
Id = 4,
|
||||||
@ -100,6 +99,34 @@ namespace RaceLapTimer.ApiControllers
|
|||||||
}
|
}
|
||||||
#endregion
|
#endregion
|
||||||
};
|
};
|
||||||
|
#endregion
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<RaceSession> GetRaceSessions(bool getActive)
|
||||||
|
{
|
||||||
|
return getActive ? _sessions.Where(x => x.Active == getActive).ToList() : _sessions;
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool CreateRaceSession(RaceSession session)
|
||||||
|
{
|
||||||
|
_sessions.Add(session);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool StopRaceSession(RaceSession session)
|
||||||
|
{
|
||||||
|
var selectedSession = _sessions.FirstOrDefault(x => x.CreatedAt == session.CreatedAt
|
||||||
|
&& x.Title == session.Title
|
||||||
|
&& x.MaxLaps == session.MaxLaps
|
||||||
|
&& x.Mode == session.Mode
|
||||||
|
&& x.IdleTimeSeconds == session.IdleTimeSeconds);
|
||||||
|
if (selectedSession == null)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
selectedSession.Active = false;
|
||||||
|
selectedSession.UpdatedAt = DateTime.UtcNow;
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<Pilot> GetPilotsList()
|
public List<Pilot> GetPilotsList()
|
||||||
@ -121,6 +148,21 @@ namespace RaceLapTimer.ApiControllers
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public bool UpdatePilot(Pilot pilot)
|
||||||
|
{
|
||||||
|
if (_pilots.All(x => x.Id != pilot.Id))
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
var p = _pilots.First(x => x.Id == pilot.Id);
|
||||||
|
p.ImageUrl = pilot.ImageUrl;
|
||||||
|
p.TransponderToken = pilot.TransponderToken;
|
||||||
|
p.Name = pilot.Name;
|
||||||
|
p.TeamName = pilot.TeamName;
|
||||||
|
p.ThingyName = pilot.ThingyName;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
public bool DeletePilot(int id)
|
public bool DeletePilot(int id)
|
||||||
{
|
{
|
||||||
return _pilots.Remove(_pilots.FirstOrDefault(x => x.Id == id));
|
return _pilots.Remove(_pilots.FirstOrDefault(x => x.Id == id));
|
||||||
|
|||||||
47
RaceLapTimer/RaceLapTimer/www/Views/EditPilot.cshtml
Normal file
47
RaceLapTimer/RaceLapTimer/www/Views/EditPilot.cshtml
Normal file
@ -0,0 +1,47 @@
|
|||||||
|
@inherits Nancy.ViewEngines.Razor.NancyRazorViewBase<dynamic>
|
||||||
|
@{
|
||||||
|
Layout = "razor-layout.cshtml";
|
||||||
|
ViewBag.Title = "Pilot Editor";
|
||||||
|
ViewBag.EditPilotEndpoint = "/api/pilot/edit";
|
||||||
|
ViewBag.UploadImageUrl = "/api/pilot/upload/" + Model.Id;
|
||||||
|
}
|
||||||
|
|
||||||
|
<h3>@ViewBag.Title</h3>
|
||||||
|
|
||||||
|
<form class="form-horizontal" id="editPilot" action="@ViewBag.EditPilotEndpoint" method="post"
|
||||||
|
onsubmit="return jsonPostForm('editPilot', '@ViewBag.EditPilotEndpoint')">
|
||||||
|
@Html.AntiForgeryToken()
|
||||||
|
<input type="hidden" name="Id" value="@Model.Id" id="pilotId"/>
|
||||||
|
<div class="form-group">
|
||||||
|
<label for="pilotName">Name</label>
|
||||||
|
<input placeholder="Jon Doe" class="form-control" required="required" type="text" name="Name" id="pilotName" data-bind="value: $root.pilot().name()">
|
||||||
|
</div>
|
||||||
|
<div class="form-group">
|
||||||
|
<label for="pilotTransponderToken">Transponder Token</label>
|
||||||
|
<input placeholder="XXXXXX" class="form-control" required="required" type="number" name="TransponderToken" id="pilotTransponderToken" data-bind="value: $root.pilot().transponderToken()">
|
||||||
|
</div>
|
||||||
|
<div class="form-group">
|
||||||
|
<label for="pilotKartName">Kart</label>
|
||||||
|
<input placeholder="Kart Attack" class="form-control" required="required" type="text" name="ThingyName" id="pilotKartName" data-bind="value: $root.pilot().thingyName()">
|
||||||
|
</div>
|
||||||
|
<div class="form-group">
|
||||||
|
<label for="pilotTeamName">Team</label>
|
||||||
|
<input placeholder="" class="form-control" type="text" name="TeamName" id="pilotTeamName" data-bind="value: $root.pilot().teamName()">
|
||||||
|
</div>
|
||||||
|
<div class="form-group">
|
||||||
|
<label for="pilotImage">Image</label>
|
||||||
|
<img data-bind="attr:{ src: pilot().imageUrl() }" alt="pilotImage" height="50" width="50"/>
|
||||||
|
</div>
|
||||||
|
<button class="btn btn-primary" type="submit">Create</button>
|
||||||
|
<div></div>
|
||||||
|
</form>
|
||||||
|
<form class="form-inline" id="uploadImage" action="@ViewBag.UploadImageUrl" method="post" enctype="multipart/form-data">
|
||||||
|
<div class="form-group">
|
||||||
|
<label for="pilotImage">Image</label>
|
||||||
|
<input type="file" accept="image/*" id="pilotImage" Name="pic" />
|
||||||
|
</div>
|
||||||
|
<button class="btn btn-primary">upload</button>
|
||||||
|
</form>
|
||||||
|
<script src="/js/PilotObject.js" type="text/javascript"></script>
|
||||||
|
<script src="/js/editPilot.js" type="text/javascript"></script>
|
||||||
|
<script src="/js/supportingPages.js" type="text/javascript"></script>
|
||||||
@ -21,33 +21,4 @@
|
|||||||
</tr>
|
</tr>
|
||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
<script type="text/javascript">
|
<script type="text/javascript" src="/js/monitor.js"></script>
|
||||||
function ViewModel() {
|
|
||||||
'use strict';
|
|
||||||
var self = this;
|
|
||||||
self.raceSessions = ko.observable();
|
|
||||||
|
|
||||||
$.get("/api/monitor", {}, self.raceSessions);
|
|
||||||
self.tmrHandle = setTimeout(function () {
|
|
||||||
self.getData();
|
|
||||||
}, 2000);
|
|
||||||
|
|
||||||
self.getData = function () {
|
|
||||||
$.get("/api/monitor", {}, self.raceSessions)
|
|
||||||
.done(function () {
|
|
||||||
console.log("done");
|
|
||||||
})
|
|
||||||
.always(function() {
|
|
||||||
self.tmrHandle = setTimeout(self.getData, 2000);
|
|
||||||
})
|
|
||||||
;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
ViewModel.prototype.dispose = function () {
|
|
||||||
'use strict';
|
|
||||||
window.clearInterval(self.tmrHandle);
|
|
||||||
console.log("disposed of timer");
|
|
||||||
};
|
|
||||||
ko.applyBindings(new ViewModel());
|
|
||||||
</script>
|
|
||||||
@ -5,7 +5,7 @@
|
|||||||
ViewBag.CreateUserEndpoint = "/api/pilot/create";
|
ViewBag.CreateUserEndpoint = "/api/pilot/create";
|
||||||
}
|
}
|
||||||
<h3>@ViewBag.Title</h3>
|
<h3>@ViewBag.Title</h3>
|
||||||
<button class="pull-right btn btn-default">Create</button>
|
|
||||||
<form class="form-inline" id="createPilot" action="@ViewBag.CreateUserEndpoint" method="post"
|
<form class="form-inline" id="createPilot" action="@ViewBag.CreateUserEndpoint" method="post"
|
||||||
onsubmit="return jsonPostForm('createPilot', '@ViewBag.CreateUserEndpoint')">
|
onsubmit="return jsonPostForm('createPilot', '@ViewBag.CreateUserEndpoint')">
|
||||||
@Html.AntiForgeryToken()
|
@Html.AntiForgeryToken()
|
||||||
|
|||||||
@ -17,14 +17,38 @@
|
|||||||
|
|
||||||
<form id="createStandardRace" action="@ViewBag.CreateRaceApiEndpoint" method="POST" class="form-group"
|
<form id="createStandardRace" action="@ViewBag.CreateRaceApiEndpoint" method="POST" class="form-group"
|
||||||
onsubmit="return jsonPostForm('createStandardRace', '@ViewBag.CreateRaceApiEndpoint')">
|
onsubmit="return jsonPostForm('createStandardRace', '@ViewBag.CreateRaceApiEndpoint')">
|
||||||
|
<input type="hidden" name="Active" value="true"/>
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<label for="Title">Race Title</label>
|
<label for="Title">Race Title</label>
|
||||||
<input name="Title" id="Title" type="text" class="form-control" placeholder="Awesome Race" autocomplete="off"/>
|
<input name="Title" id="Title" type="text" class="form-control" placeholder="Awesome Race" autocomplete="off"/>
|
||||||
</div>
|
</div>
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<label for="IdleTimeSeconds">Idle Time (s)</label>
|
<label for="idleTimeSeconds">Idle Time (s)</label>
|
||||||
<input name="IdleTimeSeconds" id="IdleTimeSeconds" type="number" class="form-control" placeholder="0" autocomplete="off"/>
|
<input name="IdleTimeSeconds" id="idleTimeSeconds" type="number" class="form-control" placeholder="0" autocomplete="off"/>
|
||||||
</div>
|
</div>
|
||||||
<button type="submit">Submit</button>
|
<div>
|
||||||
|
<label for="competitionMode">Competition Mode</label>
|
||||||
|
<input id="competitionMode" type="checkbox" name="mode" data-bind="checked:raceSession().mode" autocomplete="off"/>
|
||||||
|
</div>
|
||||||
|
<div class="form-group" data-bind="visible:raceSession().mode">
|
||||||
|
<label for="maxLaps">Max Laps</label>
|
||||||
|
<input name="MaxLaps" id="maxLaps" type="number" class="form-control" placeholder="0" autocomplete="off" />
|
||||||
|
</div>
|
||||||
|
<div class="form-group" data-bind="visible:raceSession().mode">
|
||||||
|
<label for="satelliteCount">Satellite Count</label>
|
||||||
|
<input name="SatelliteCount" id="satelliteCount" type="number" class="form-control" placeholder="0" autocomplete="off" />
|
||||||
|
</div>
|
||||||
|
<div class="form-group" data-bind="visible:raceSession().mode">
|
||||||
|
<label for="timePenaltyPerSatellite">Time Penalty Per Satellite</label>
|
||||||
|
<input name="TimePenaltyPerSatellite" id="timePenaltyPerSatellite" type="number" class="form-control" placeholder="0" autocomplete="off" />
|
||||||
|
</div>
|
||||||
|
<div class="form-group" data-bind="visible:raceSession().mode">
|
||||||
|
<label for="hotSeatEnabled">Hot Seat Enabled</label>
|
||||||
|
<input name="HotSeatEnabled" id="hotSeatEnabled" type="checkbox" autocomplete="off" data-bind="attr:{checked:raceSession().hotSeatEnabled()}" />
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<button type="submit" class="btn btn-default">Submit</button>
|
||||||
</form>
|
</form>
|
||||||
|
<script type="text/javascript" src="js/RaceSessionObject.js"></script>
|
||||||
|
<script type="text/javascript" src="js/raceDirector.js"></script>
|
||||||
<script type="text/javascript" src="js/supportingPages.js"></script>
|
<script type="text/javascript" src="js/supportingPages.js"></script>
|
||||||
@ -6,12 +6,8 @@
|
|||||||
@*<link rel="stylesheet" href="~/Content/css/bootstrap.css" />
|
@*<link rel="stylesheet" href="~/Content/css/bootstrap.css" />
|
||||||
<script src="~/Content/js/bootstrap.js"></script>
|
<script src="~/Content/js/bootstrap.js"></script>
|
||||||
<link rel="stylesheet" href="~/Content/css/site.css"/>*@
|
<link rel="stylesheet" href="~/Content/css/site.css"/>*@
|
||||||
@*<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.3.7/fonts/glyphicons-halflings-regular.eot" />
|
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.3.7/css/bootstrap.min.css" />
|
||||||
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.3.7/fonts/glyphicons-halflings-regular.svg" />
|
<link rel="stylesheet" href="/css/stickyfooter.css" />
|
||||||
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.3.7/fonts/glyphicons-halflings-regular.ttf" />
|
|
||||||
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.3.7/fonts/glyphicons-halflings-regular.woff" />
|
|
||||||
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.3.7/fonts/glyphicons-halflings-regular.woff2" />*@
|
|
||||||
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.3.7/css/bootstrap.min.css"/>
|
|
||||||
|
|
||||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.2.1/jquery.min.js" type="text/javascript"></script>
|
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.2.1/jquery.min.js" type="text/javascript"></script>
|
||||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.3.7/js/bootstrap.min.js" type="text/javascript"></script>
|
<script src="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.3.7/js/bootstrap.min.js" type="text/javascript"></script>
|
||||||
@ -20,39 +16,39 @@
|
|||||||
<title>Razor Localization Demo</title>
|
<title>Razor Localization Demo</title>
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<div data-rails-cable-ip='192.168.42.1' id='host_data'></div>
|
<div data-rails-cable-ip="192.168.42.1" id="host_data"></div>
|
||||||
<navbar class='navbar-default navbar-fixed-top'>
|
<navbar class="navbar-default navbar-fixed-top" id="top">
|
||||||
<div class='container-fluid'>
|
<div class="container-fluid">
|
||||||
<div class='navbar-header'>
|
<div class="navbar-header">
|
||||||
<button aria-controls='navbar' aria-expanded='false' class='navbar-toggle collapsed' data-target='#navbar' data-toggle='collapse' type='button'>
|
<button aria-controls="navbar" aria-expanded="false" class="navbar-toggle collapsed" data-target="#navbar" data-toggle="collapse" type="button">
|
||||||
<span class='sr-only'>Toggle navigation</span>
|
<span class="sr-only">Toggle navigation</span>
|
||||||
<span class='icon-bar'></span>
|
<span class="icon-bar"></span>
|
||||||
<span class='icon-bar'></span>
|
<span class="icon-bar"></span>
|
||||||
<span class='icon-bar'></span>
|
<span class="icon-bar"></span>
|
||||||
</button>
|
</button>
|
||||||
<a class='navbar-brand' href='/'>
|
<a class="navbar-brand" href="/">
|
||||||
EasyRaceLapTimer
|
EasyRaceLapTimer
|
||||||
</a>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
<div class='collapse navbar-collapse' id='navbar'>
|
<div class="collapse navbar-collapse" id="navbar">
|
||||||
<ul class='nav navbar-nav navbar-right'>
|
<ul class="nav navbar-nav navbar-right">
|
||||||
<li>
|
<li>
|
||||||
<a href="/racedirector">Race Director</a>
|
<a href="/racedirector">Race Director</a>
|
||||||
</li>
|
</li>
|
||||||
<li class='dropdown'>
|
<li class="dropdown">
|
||||||
<a aria-expanded='false' aria-haspopup='true' class='dropdown-toggle' data-toggle='dropdown' href='#' role='button'>
|
<a aria-expanded="false" aria-haspopup="true" class="dropdown-toggle" data-toggle="dropdown" href="#" role="button">
|
||||||
Configuration
|
Configuration
|
||||||
<span class='caret'></span>
|
<span class="caret"></span>
|
||||||
</a>
|
</a>
|
||||||
<ul class='dropdown-menu'>
|
<ul class="dropdown-menu">
|
||||||
<li>
|
<li>
|
||||||
<a href="/system">System</a>
|
<a href="#">System</a>
|
||||||
</li>
|
</li>
|
||||||
<li>
|
<li>
|
||||||
<a href="/system/pilot">Pilots</a>
|
<a href="/pilots">Pilots</a>
|
||||||
</li>
|
</li>
|
||||||
<li>
|
<li>
|
||||||
<a href="/system/soundfile">Soundeffects</a>
|
<a href="#">Soundeffects</a>
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
</li>
|
</li>
|
||||||
@ -65,10 +61,16 @@
|
|||||||
<li>
|
<li>
|
||||||
<a href="/history">History</a>
|
<a href="/history">History</a>
|
||||||
</li>
|
</li>
|
||||||
|
@if (Html.IsAuthenticated)
|
||||||
|
{
|
||||||
|
<li>
|
||||||
|
<a href="/logout">Logout</a>
|
||||||
|
</li>
|
||||||
|
}
|
||||||
<li>
|
<li>
|
||||||
<a href="#">
|
<a href="#">
|
||||||
Version
|
Version
|
||||||
0.5.1
|
0.0.1
|
||||||
</a>
|
</a>
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
@ -76,32 +78,33 @@
|
|||||||
<!-- /.nav-collapse -->
|
<!-- /.nav-collapse -->
|
||||||
</div>
|
</div>
|
||||||
</navbar>
|
</navbar>
|
||||||
<div class='container-fluid'>
|
<div class="container-fluid">
|
||||||
<div class='row' style="margin-top: 55px;">
|
<div class="row" style="margin-top: 55px;">
|
||||||
<div class='col-xs-12 center'>
|
<div class="col-md-8 center-block" style="float: none;">
|
||||||
|
<div class="center-block">
|
||||||
@RenderBody()
|
@RenderBody()
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<footer>
|
</div>
|
||||||
<div class='row'>
|
</div>
|
||||||
<div class='col-lg-12'>
|
<footer class="footer">
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-lg-12">
|
||||||
|
<ul class="list-unstyled">
|
||||||
|
<li class="pull-right">
|
||||||
|
<a class="backtotop" href="#top">Back to top</a>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
<p>
|
<p>
|
||||||
Made & Sponsored by
|
Made & Sponsored by
|
||||||
<a href='http://www.airbirds.de' rel='nofollow'>AirBirds</a>.
|
<a href="http://www.airbirds.de" rel="nofollow">AirBirds</a>.
|
||||||
</p>
|
</p>
|
||||||
<p>
|
<p>
|
||||||
Code released under the
|
Code released under the
|
||||||
<a href='http://www.gnu.org/licenses/gpl-3.0.de.html'>GPL V3</a>.
|
<a href="http://www.gnu.org/licenses/gpl-3.0.de.html">GPL V3</a>.
|
||||||
</p>
|
</p>
|
||||||
<ul class='list-unstyled'>
|
|
||||||
<li class='pull-right'>
|
|
||||||
<a class='backtotop' href='#top'>Back to top</a>
|
|
||||||
</li>
|
|
||||||
</ul>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</footer>
|
</footer>
|
||||||
|
|
||||||
</div>
|
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
9
RaceLapTimer/RaceLapTimer/www/js/PilotObject.js
Normal file
9
RaceLapTimer/RaceLapTimer/www/js/PilotObject.js
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
function Pilot(data) {
|
||||||
|
var self = this;
|
||||||
|
self.id = ko.observable(data.id);
|
||||||
|
self.imageUrl = ko.observable(data.imageUrl);
|
||||||
|
self.name = ko.observable(data.name);
|
||||||
|
self.transponderToken = ko.observable(data.transponderToken);
|
||||||
|
self.thingyName = ko.observable(data.thingyName);
|
||||||
|
self.teamName = ko.observable(data.teamName);
|
||||||
|
}
|
||||||
15
RaceLapTimer/RaceLapTimer/www/js/RaceSessionObject.js
Normal file
15
RaceLapTimer/RaceLapTimer/www/js/RaceSessionObject.js
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
function RaceSession(data) {
|
||||||
|
var self = this;
|
||||||
|
self.id = ko.observable(data.id);
|
||||||
|
self.createdDate = ko.observable(data.createdDate);
|
||||||
|
self.updatedAt = ko.observable(data.updatedAt);
|
||||||
|
self.title = ko.observable(data.title);
|
||||||
|
self.active = ko.observable(data.active);
|
||||||
|
self.mode = ko.observable(data.mode);
|
||||||
|
self.maxLaps = ko.observable(data.maxLaps);
|
||||||
|
self.deletedAt = ko.observable(data.deletedAt);
|
||||||
|
self.satelliteCount = ko.observable(data.satelliteCount);
|
||||||
|
self.timePenaltyPerSatellite = ko.observable(data.timePenaltyPerSatellite);
|
||||||
|
self.hotSeatEnabled = ko.observable(data.hotSeatEnabled);
|
||||||
|
self.idleTimeSeconds = ko.observable(data.idleTimeSeconds);
|
||||||
|
}
|
||||||
23
RaceLapTimer/RaceLapTimer/www/js/editPilot.js
Normal file
23
RaceLapTimer/RaceLapTimer/www/js/editPilot.js
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
function ViewModel() {
|
||||||
|
"use strict";
|
||||||
|
var self = this;
|
||||||
|
self.pilot = ko.observable(new Pilot({id:-1,name:"",transponderToken:-1, imageUrl:"",thingyName:"",teamName:""}));
|
||||||
|
self.editForm = $("#editPilot");
|
||||||
|
self.pilotId = $("[name='Id']", self.editForm).val();
|
||||||
|
$.get("/api/pilot/" + self.pilotId, {}
|
||||||
|
, function(data) {
|
||||||
|
self.pilot(new Pilot(data));
|
||||||
|
})
|
||||||
|
.done(function(a) {
|
||||||
|
console.log(self.pilot());
|
||||||
|
});
|
||||||
|
|
||||||
|
//self.getData = function () {
|
||||||
|
// $.get("/api/pilots", {}, self.pilotsList);
|
||||||
|
//};
|
||||||
|
};
|
||||||
|
|
||||||
|
ViewModel.prototype.dispose = function () {
|
||||||
|
"use strict";
|
||||||
|
};
|
||||||
|
ko.applyBindings(new ViewModel());
|
||||||
@ -1,22 +1,23 @@
|
|||||||
function ViewModel() {
|
function ViewModel() {
|
||||||
"use strict";
|
"use strict";
|
||||||
var self = this;
|
var self = this;
|
||||||
self.raceSessions = ko.observable();
|
self.raceSession = ko.observable(new RaceSession({id:-1, createdDate:"", updatedAt:"", title:"", active:false, mode:0, maxLaps:0, deletedAt:"", satelliteCount:0,timePenaltyPerSatellite:0, hotSeatEnabled:true, idleTimeSeconds:50}));
|
||||||
|
//self.raceSessions = ko.observable();
|
||||||
|
|
||||||
$.get("/api/monitor", {}, self.raceSessions);
|
//$.get("/api/monitor", {}, self.raceSession);
|
||||||
self.tmrHandle = setTimeout(function () {
|
//self.tmrHandle = setTimeout(function () {
|
||||||
self.getData();
|
// self.getData();
|
||||||
}, 2000);
|
//}, 2000);
|
||||||
|
|
||||||
self.getData = function () {
|
//self.getData = function () {
|
||||||
$.get("/api/monitor", {}, self.raceSessions)
|
// $.get("/api/monitor", {}, self.raceSession)
|
||||||
.done(function () {
|
// .done(function () {
|
||||||
console.log("done");
|
// console.log("done");
|
||||||
})
|
// })
|
||||||
.always(function () {
|
// .always(function () {
|
||||||
self.tmrHandle = setTimeout(self.getData, 2000);
|
// //self.tmrHandle = setTimeout(self.getData, 2000);
|
||||||
});
|
// });
|
||||||
};
|
//};
|
||||||
};
|
};
|
||||||
|
|
||||||
ViewModel.prototype.dispose = function () {
|
ViewModel.prototype.dispose = function () {
|
||||||
|
|||||||
@ -7,8 +7,6 @@
|
|||||||
data: formData,
|
data: formData,
|
||||||
dataType: "json",
|
dataType: "json",
|
||||||
contentType: "application/json"
|
contentType: "application/json"
|
||||||
}).done(function(a) {
|
|
||||||
window.location.replace(a.url);
|
|
||||||
});
|
});
|
||||||
return false;
|
return false;
|
||||||
};
|
};
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user