add package Microsoft.Owin.StaticFiles.

added www folder to project, with bootstrap css/js files.
added the main single page app files to the project, pulled from codepen.io test/demo pages.
set properties to copy always for the main app files, bootstrap stuff is copy if newer.
added filesystem options to the StartOwin method.
This commit is contained in:
chris.watts90@outlook.com 2017-01-29 15:24:23 +00:00
parent 283ce5ceec
commit 430f91ce18
22 changed files with 15204 additions and 5 deletions

View File

@ -3,4 +3,12 @@
<startup> <startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5.2" /> <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5.2" />
</startup> </startup>
<runtime>
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
<dependentAssembly>
<assemblyIdentity name="Microsoft.Owin" publicKeyToken="31bf3856ad364e35" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-3.0.1.0" newVersion="3.0.1.0" />
</dependentAssembly>
</assemblyBinding>
</runtime>
</configuration> </configuration>

View File

@ -11,7 +11,9 @@ using System.Text;
using System.Threading; using System.Threading;
using System.Threading.Tasks; using System.Threading.Tasks;
using System.Web.Http; using System.Web.Http;
using Microsoft.Owin.FileSystems;
using Microsoft.Owin.Hosting; using Microsoft.Owin.Hosting;
using Microsoft.Owin.StaticFiles;
using Owin; using Owin;
namespace WindowsDataCenter namespace WindowsDataCenter
@ -81,6 +83,21 @@ namespace WindowsDataCenter
); );
appBuilder.UseWebApi(config); appBuilder.UseWebApi(config);
var fileSystem = new PhysicalFileSystem(@"./www");
var options = new FileServerOptions
{
EnableDefaultFiles = true,
FileSystem = fileSystem
};
options.StaticFileOptions.FileSystem = fileSystem;
options.StaticFileOptions.ServeUnknownFileTypes = true;
options.DefaultFilesOptions.DefaultFileNames = new[]
{
"index.html"
};
appBuilder.UseFileServer(options);
} }
} }
@ -104,6 +121,28 @@ namespace WindowsDataCenter
} }
} }
public class RouteController : ApiController
{
public IHttpActionResult Get()
{
List<RouteObject> routeList = new List<RouteObject>();
var routes = GlobalConfiguration.Configuration.Routes;
foreach (var route in routes)
{
var obj = new RouteObject();
obj.RouteUrl = route.RouteTemplate;
routeList.Add(obj);
}
return Json(routeList);
}
class RouteObject
{
public string RouteUrl { get; set; }
}
}
public class UsersController : ApiController public class UsersController : ApiController
{ {
public IHttpActionResult GetUsers() public IHttpActionResult GetUsers()

View File

@ -33,8 +33,12 @@
<WarningLevel>4</WarningLevel> <WarningLevel>4</WarningLevel>
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>
<Reference Include="Microsoft.Owin, Version=2.0.2.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL"> <Reference Include="Microsoft.Owin, Version=3.0.1.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<HintPath>..\packages\Microsoft.Owin.2.0.2\lib\net45\Microsoft.Owin.dll</HintPath> <HintPath>..\packages\Microsoft.Owin.3.0.1\lib\net45\Microsoft.Owin.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="Microsoft.Owin.FileSystems, Version=3.0.1.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<HintPath>..\packages\Microsoft.Owin.FileSystems.3.0.1\lib\net45\Microsoft.Owin.FileSystems.dll</HintPath>
<Private>True</Private> <Private>True</Private>
</Reference> </Reference>
<Reference Include="Microsoft.Owin.Host.HttpListener, Version=2.0.2.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL"> <Reference Include="Microsoft.Owin.Host.HttpListener, Version=2.0.2.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
@ -45,6 +49,10 @@
<HintPath>..\packages\Microsoft.Owin.Hosting.2.0.2\lib\net45\Microsoft.Owin.Hosting.dll</HintPath> <HintPath>..\packages\Microsoft.Owin.Hosting.2.0.2\lib\net45\Microsoft.Owin.Hosting.dll</HintPath>
<Private>True</Private> <Private>True</Private>
</Reference> </Reference>
<Reference Include="Microsoft.Owin.StaticFiles, Version=3.0.1.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<HintPath>..\packages\Microsoft.Owin.StaticFiles.3.0.1\lib\net45\Microsoft.Owin.StaticFiles.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="Newtonsoft.Json, Version=6.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL"> <Reference Include="Newtonsoft.Json, Version=6.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL">
<HintPath>..\packages\Newtonsoft.Json.6.0.4\lib\net45\Newtonsoft.Json.dll</HintPath> <HintPath>..\packages\Newtonsoft.Json.6.0.4\lib\net45\Newtonsoft.Json.dll</HintPath>
<Private>True</Private> <Private>True</Private>
@ -59,6 +67,7 @@
<HintPath>..\packages\Microsoft.AspNet.WebApi.Client.5.2.3\lib\net45\System.Net.Http.Formatting.dll</HintPath> <HintPath>..\packages\Microsoft.AspNet.WebApi.Client.5.2.3\lib\net45\System.Net.Http.Formatting.dll</HintPath>
<Private>True</Private> <Private>True</Private>
</Reference> </Reference>
<Reference Include="System.Web" />
<Reference Include="System.Web.Http, Version=5.2.3.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL"> <Reference Include="System.Web.Http, Version=5.2.3.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<HintPath>..\packages\Microsoft.AspNet.WebApi.Core.5.2.3\lib\net45\System.Web.Http.dll</HintPath> <HintPath>..\packages\Microsoft.AspNet.WebApi.Core.5.2.3\lib\net45\System.Web.Http.dll</HintPath>
<Private>True</Private> <Private>True</Private>
@ -67,6 +76,10 @@
<HintPath>..\packages\Microsoft.AspNet.WebApi.Owin.5.2.3\lib\net45\System.Web.Http.Owin.dll</HintPath> <HintPath>..\packages\Microsoft.AspNet.WebApi.Owin.5.2.3\lib\net45\System.Web.Http.Owin.dll</HintPath>
<Private>True</Private> <Private>True</Private>
</Reference> </Reference>
<Reference Include="System.Web.Http.WebHost, Version=5.2.3.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<HintPath>..\packages\Microsoft.AspNet.WebApi.WebHost.5.2.3\lib\net45\System.Web.Http.WebHost.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="System.Xml.Linq" /> <Reference Include="System.Xml.Linq" />
<Reference Include="System.Data.DataSetExtensions" /> <Reference Include="System.Data.DataSetExtensions" />
<Reference Include="Microsoft.CSharp" /> <Reference Include="Microsoft.CSharp" />
@ -90,6 +103,59 @@
<ItemGroup> <ItemGroup>
<None Include="App.config" /> <None Include="App.config" />
<None Include="packages.config" /> <None Include="packages.config" />
<None Include="www\css\bootstrap-grid.css.map">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Include="www\css\bootstrap-grid.min.css.map">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Include="www\css\bootstrap-reboot.css.map">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Include="www\css\bootstrap-reboot.min.css.map">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Include="www\css\bootstrap.css.map">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Include="www\css\bootstrap.min.css.map">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
</ItemGroup>
<ItemGroup>
<Content Include="www\css\bootstrap-grid.css">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="www\css\bootstrap-grid.min.css">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="www\css\bootstrap-reboot.css">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="www\css\bootstrap-reboot.min.css">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="www\css\bootstrap.css">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="www\css\bootstrap.min.css">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="www\index.html">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Content>
<Content Include="www\js\bootstrap.js">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="www\js\bootstrap.min.js">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="www\spa.css">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Content>
<Content Include="www\spa.js">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Content>
</ItemGroup> </ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" /> <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<!-- To modify your build process, add your task inside one of the targets below and uncomment it. <!-- To modify your build process, add your task inside one of the targets below and uncomment it.

View File

@ -4,9 +4,12 @@
<package id="Microsoft.AspNet.WebApi.Core" version="5.2.3" targetFramework="net452" /> <package id="Microsoft.AspNet.WebApi.Core" version="5.2.3" targetFramework="net452" />
<package id="Microsoft.AspNet.WebApi.Owin" version="5.2.3" targetFramework="net452" /> <package id="Microsoft.AspNet.WebApi.Owin" version="5.2.3" targetFramework="net452" />
<package id="Microsoft.AspNet.WebApi.OwinSelfHost" version="5.2.3" targetFramework="net452" /> <package id="Microsoft.AspNet.WebApi.OwinSelfHost" version="5.2.3" targetFramework="net452" />
<package id="Microsoft.Owin" version="2.0.2" targetFramework="net452" /> <package id="Microsoft.AspNet.WebApi.WebHost" version="5.2.3" targetFramework="net452" />
<package id="Microsoft.Owin" version="3.0.1" targetFramework="net452" />
<package id="Microsoft.Owin.FileSystems" version="3.0.1" targetFramework="net452" />
<package id="Microsoft.Owin.Host.HttpListener" version="2.0.2" targetFramework="net452" /> <package id="Microsoft.Owin.Host.HttpListener" version="2.0.2" targetFramework="net452" />
<package id="Microsoft.Owin.Hosting" version="2.0.2" targetFramework="net452" /> <package id="Microsoft.Owin.Hosting" version="2.0.2" targetFramework="net452" />
<package id="Microsoft.Owin.StaticFiles" version="3.0.1" targetFramework="net452" />
<package id="Newtonsoft.Json" version="6.0.4" targetFramework="net452" /> <package id="Newtonsoft.Json" version="6.0.4" targetFramework="net452" />
<package id="Owin" version="1.0" targetFramework="net452" /> <package id="Owin" version="1.0" targetFramework="net452" />
</packages> </packages>

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1,459 @@
/*! normalize.css v5.0.0 | MIT License | github.com/necolas/normalize.css */
html {
font-family: sans-serif;
line-height: 1.15;
-ms-text-size-adjust: 100%;
-webkit-text-size-adjust: 100%;
}
body {
margin: 0;
}
article,
aside,
footer,
header,
nav,
section {
display: block;
}
h1 {
font-size: 2em;
margin: 0.67em 0;
}
figcaption,
figure,
main {
display: block;
}
figure {
margin: 1em 40px;
}
hr {
-webkit-box-sizing: content-box;
box-sizing: content-box;
height: 0;
overflow: visible;
}
pre {
font-family: monospace, monospace;
font-size: 1em;
}
a {
background-color: transparent;
-webkit-text-decoration-skip: objects;
}
a:active,
a:hover {
outline-width: 0;
}
abbr[title] {
border-bottom: none;
text-decoration: underline;
text-decoration: underline dotted;
}
b,
strong {
font-weight: inherit;
}
b,
strong {
font-weight: bolder;
}
code,
kbd,
samp {
font-family: monospace, monospace;
font-size: 1em;
}
dfn {
font-style: italic;
}
mark {
background-color: #ff0;
color: #000;
}
small {
font-size: 80%;
}
sub,
sup {
font-size: 75%;
line-height: 0;
position: relative;
vertical-align: baseline;
}
sub {
bottom: -0.25em;
}
sup {
top: -0.5em;
}
audio,
video {
display: inline-block;
}
audio:not([controls]) {
display: none;
height: 0;
}
img {
border-style: none;
}
svg:not(:root) {
overflow: hidden;
}
button,
input,
optgroup,
select,
textarea {
font-family: sans-serif;
font-size: 100%;
line-height: 1.15;
margin: 0;
}
button,
input {
overflow: visible;
}
button,
select {
text-transform: none;
}
button,
html [type="button"],
[type="reset"],
[type="submit"] {
-webkit-appearance: button;
}
button::-moz-focus-inner,
[type="button"]::-moz-focus-inner,
[type="reset"]::-moz-focus-inner,
[type="submit"]::-moz-focus-inner {
border-style: none;
padding: 0;
}
button:-moz-focusring,
[type="button"]:-moz-focusring,
[type="reset"]:-moz-focusring,
[type="submit"]:-moz-focusring {
outline: 1px dotted ButtonText;
}
fieldset {
border: 1px solid #c0c0c0;
margin: 0 2px;
padding: 0.35em 0.625em 0.75em;
}
legend {
-webkit-box-sizing: border-box;
box-sizing: border-box;
color: inherit;
display: table;
max-width: 100%;
padding: 0;
white-space: normal;
}
progress {
display: inline-block;
vertical-align: baseline;
}
textarea {
overflow: auto;
}
[type="checkbox"],
[type="radio"] {
-webkit-box-sizing: border-box;
box-sizing: border-box;
padding: 0;
}
[type="number"]::-webkit-inner-spin-button,
[type="number"]::-webkit-outer-spin-button {
height: auto;
}
[type="search"] {
-webkit-appearance: textfield;
outline-offset: -2px;
}
[type="search"]::-webkit-search-cancel-button,
[type="search"]::-webkit-search-decoration {
-webkit-appearance: none;
}
::-webkit-file-upload-button {
-webkit-appearance: button;
font: inherit;
}
details,
menu {
display: block;
}
summary {
display: list-item;
}
canvas {
display: inline-block;
}
template {
display: none;
}
[hidden] {
display: none;
}
html {
-webkit-box-sizing: border-box;
box-sizing: border-box;
}
*,
*::before,
*::after {
-webkit-box-sizing: inherit;
box-sizing: inherit;
}
@-ms-viewport {
width: device-width;
}
html {
-ms-overflow-style: scrollbar;
-webkit-tap-highlight-color: transparent;
}
body {
font-family: -apple-system, system-ui, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
font-size: 1rem;
font-weight: normal;
line-height: 1.5;
color: #292b2c;
background-color: #fff;
}
[tabindex="-1"]:focus {
outline: none !important;
}
h1, h2, h3, h4, h5, h6 {
margin-top: 0;
margin-bottom: .5rem;
}
p {
margin-top: 0;
margin-bottom: 1rem;
}
abbr[title],
abbr[data-original-title] {
cursor: help;
}
address {
margin-bottom: 1rem;
font-style: normal;
line-height: inherit;
}
ol,
ul,
dl {
margin-top: 0;
margin-bottom: 1rem;
}
ol ol,
ul ul,
ol ul,
ul ol {
margin-bottom: 0;
}
dt {
font-weight: bold;
}
dd {
margin-bottom: .5rem;
margin-left: 0;
}
blockquote {
margin: 0 0 1rem;
}
a {
color: #0275d8;
text-decoration: none;
}
a:focus, a:hover {
color: #014c8c;
text-decoration: underline;
}
a:not([href]):not([tabindex]) {
color: inherit;
text-decoration: none;
}
a:not([href]):not([tabindex]):focus, a:not([href]):not([tabindex]):hover {
color: inherit;
text-decoration: none;
}
a:not([href]):not([tabindex]):focus {
outline: 0;
}
pre {
margin-top: 0;
margin-bottom: 1rem;
overflow: auto;
}
figure {
margin: 0 0 1rem;
}
img {
vertical-align: middle;
}
[role="button"] {
cursor: pointer;
}
a,
area,
button,
[role="button"],
input,
label,
select,
summary,
textarea {
-ms-touch-action: manipulation;
touch-action: manipulation;
}
table {
border-collapse: collapse;
background-color: transparent;
}
caption {
padding-top: 0.75rem;
padding-bottom: 0.75rem;
color: #636c72;
text-align: left;
caption-side: bottom;
}
th {
text-align: left;
}
label {
display: inline-block;
margin-bottom: .5rem;
}
button:focus {
outline: 1px dotted;
outline: 5px auto -webkit-focus-ring-color;
}
input,
button,
select,
textarea {
line-height: inherit;
}
input[type="radio"]:disabled,
input[type="checkbox"]:disabled {
cursor: not-allowed;
}
input[type="date"],
input[type="time"],
input[type="datetime-local"],
input[type="month"] {
-webkit-appearance: listbox;
}
textarea {
resize: vertical;
}
fieldset {
min-width: 0;
padding: 0;
margin: 0;
border: 0;
}
legend {
display: block;
width: 100%;
padding: 0;
margin-bottom: .5rem;
font-size: 1.5rem;
line-height: inherit;
}
input[type="search"] {
-webkit-appearance: none;
}
output {
display: inline-block;
}
[hidden] {
display: none !important;
}
/*# sourceMappingURL=bootstrap-reboot.css.map */

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1 @@
/*! normalize.css v5.0.0 | MIT License | github.com/necolas/normalize.css */html{font-family:sans-serif;line-height:1.15;-ms-text-size-adjust:100%;-webkit-text-size-adjust:100%}body{margin:0}article,aside,footer,header,nav,section{display:block}h1{font-size:2em;margin:.67em 0}figcaption,figure,main{display:block}figure{margin:1em 40px}hr{-webkit-box-sizing:content-box;box-sizing:content-box;height:0;overflow:visible}pre{font-family:monospace,monospace;font-size:1em}a{background-color:transparent;-webkit-text-decoration-skip:objects}a:active,a:hover{outline-width:0}abbr[title]{border-bottom:none;text-decoration:underline;text-decoration:underline dotted}b,strong{font-weight:inherit}b,strong{font-weight:bolder}code,kbd,samp{font-family:monospace,monospace;font-size:1em}dfn{font-style:italic}mark{background-color:#ff0;color:#000}small{font-size:80%}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}sub{bottom:-.25em}sup{top:-.5em}audio,video{display:inline-block}audio:not([controls]){display:none;height:0}img{border-style:none}svg:not(:root){overflow:hidden}button,input,optgroup,select,textarea{font-family:sans-serif;font-size:100%;line-height:1.15;margin:0}button,input{overflow:visible}button,select{text-transform:none}[type=reset],[type=submit],button,html [type=button]{-webkit-appearance:button}[type=button]::-moz-focus-inner,[type=reset]::-moz-focus-inner,[type=submit]::-moz-focus-inner,button::-moz-focus-inner{border-style:none;padding:0}[type=button]:-moz-focusring,[type=reset]:-moz-focusring,[type=submit]:-moz-focusring,button:-moz-focusring{outline:1px dotted ButtonText}fieldset{border:1px solid silver;margin:0 2px;padding:.35em .625em .75em}legend{-webkit-box-sizing:border-box;box-sizing:border-box;color:inherit;display:table;max-width:100%;padding:0;white-space:normal}progress{display:inline-block;vertical-align:baseline}textarea{overflow:auto}[type=checkbox],[type=radio]{-webkit-box-sizing:border-box;box-sizing:border-box;padding:0}[type=number]::-webkit-inner-spin-button,[type=number]::-webkit-outer-spin-button{height:auto}[type=search]{-webkit-appearance:textfield;outline-offset:-2px}[type=search]::-webkit-search-cancel-button,[type=search]::-webkit-search-decoration{-webkit-appearance:none}::-webkit-file-upload-button{-webkit-appearance:button;font:inherit}details,menu{display:block}summary{display:list-item}canvas{display:inline-block}template{display:none}[hidden]{display:none}html{-webkit-box-sizing:border-box;box-sizing:border-box}*,::after,::before{-webkit-box-sizing:inherit;box-sizing:inherit}@-ms-viewport{width:device-width}html{-ms-overflow-style:scrollbar;-webkit-tap-highlight-color:transparent}body{font-family:-apple-system,system-ui,BlinkMacSystemFont,"Segoe UI",Roboto,"Helvetica Neue",Arial,sans-serif;font-size:1rem;font-weight:400;line-height:1.5;color:#292b2c;background-color:#fff}[tabindex="-1"]:focus{outline:0!important}h1,h2,h3,h4,h5,h6{margin-top:0;margin-bottom:.5rem}p{margin-top:0;margin-bottom:1rem}abbr[data-original-title],abbr[title]{cursor:help}address{margin-bottom:1rem;font-style:normal;line-height:inherit}dl,ol,ul{margin-top:0;margin-bottom:1rem}ol ol,ol ul,ul ol,ul ul{margin-bottom:0}dt{font-weight:700}dd{margin-bottom:.5rem;margin-left:0}blockquote{margin:0 0 1rem}a{color:#0275d8;text-decoration:none}a:focus,a:hover{color:#014c8c;text-decoration:underline}a:not([href]):not([tabindex]){color:inherit;text-decoration:none}a:not([href]):not([tabindex]):focus,a:not([href]):not([tabindex]):hover{color:inherit;text-decoration:none}a:not([href]):not([tabindex]):focus{outline:0}pre{margin-top:0;margin-bottom:1rem;overflow:auto}figure{margin:0 0 1rem}img{vertical-align:middle}[role=button]{cursor:pointer}[role=button],a,area,button,input,label,select,summary,textarea{-ms-touch-action:manipulation;touch-action:manipulation}table{border-collapse:collapse;background-color:transparent}caption{padding-top:.75rem;padding-bottom:.75rem;color:#636c72;text-align:left;caption-side:bottom}th{text-align:left}label{display:inline-block;margin-bottom:.5rem}button:focus{outline:1px dotted;outline:5px auto -webkit-focus-ring-color}button,input,select,textarea{line-height:inherit}input[type=checkbox]:disabled,input[type=radio]:disabled{cursor:not-allowed}input[type=date],input[type=time],input[type=datetime-local],input[type=month]{-webkit-appearance:listbox}textarea{resize:vertical}fieldset{min-width:0;padding:0;margin:0;border:0}legend{display:block;width:100%;padding:0;margin-bottom:.5rem;font-size:1.5rem;line-height:inherit}input[type=search]{-webkit-appearance:none}output{display:inline-block}[hidden]{display:none!important}/*# sourceMappingURL=bootstrap-reboot.min.css.map */

View File

@ -0,0 +1 @@
{"version":3,"sources":["../../scss/_normalize.scss","bootstrap-reboot.css","../../scss/_reboot.scss","../../scss/_variables.scss","../../scss/mixins/_hover.scss"],"names":[],"mappings":"4EAYA,KACE,YAAA,WACA,YAAA,KACA,qBAAA,KACA,yBAAA,KAUF,KACE,OAAA,EAOF,QAAA,MAAA,OAAA,OAAA,IAAA,QAME,QAAA,MAQF,GACE,UAAA,IACA,OAAA,MAAA,EAWF,WAAA,OAAA,KAGE,QAAA,MAOF,OACE,OAAA,IAAA,KAQF,GACE,mBAAA,YAAA,WAAA,YACA,OAAA,EACA,SAAA,QAQF,IACE,YAAA,UAAA,UACA,UAAA,IAWF,EACE,iBAAA,YACA,6BAAA,QAQF,SAAA,QAEE,cAAA,EAQF,YACE,cAAA,KACA,gBAAA,UACA,gBAAA,UAAA,OAOF,EAAA,OAEE,YAAA,QAOF,EAAA,OAEE,YAAA,OAQF,KAAA,IAAA,KAGE,YAAA,UAAA,UACA,UAAA,IAOF,IACE,WAAA,OAOF,KACE,iBAAA,KACA,MAAA,KAOF,MACE,UAAA,IAQF,IAAA,IAEE,UAAA,IACA,YAAA,EACA,SAAA,SACA,eAAA,SAGF,IACE,OAAA,OAGF,IACE,IAAA,MAUF,MAAA,MAEE,QAAA,aAOF,sBACE,QAAA,KACA,OAAA,EAOF,IACE,aAAA,KAOF,eACE,SAAA,OAWF,OAAA,MAAA,SAAA,OAAA,SAKE,YAAA,WACA,UAAA,KACA,YAAA,KACA,OAAA,EAQF,OAAA,MAEE,SAAA,QAQF,OAAA,OAEE,eAAA,KASF,aAAA,cAAA,OAAA,mBAIE,mBAAA,OAOF,gCAAA,+BAAA,gCAAA,yBAIE,aAAA,KACA,QAAA,EAOF,6BAAA,4BAAA,6BAAA,sBAIE,QAAA,IAAA,OAAA,WAOF,SACE,OAAA,IAAA,MAAA,OACA,OAAA,EAAA,IACA,QAAA,MAAA,OAAA,MAUF,OACE,mBAAA,WAAA,WAAA,WACA,MAAA,QACA,QAAA,MACA,UAAA,KACA,QAAA,EACA,YAAA,OAQF,SACE,QAAA,aACA,eAAA,SAOF,SACE,SAAA,KCrKF,gBAAA,aD+KE,mBAAA,WAAA,WAAA,WACA,QAAA,EC1KF,yCAAA,yCDmLE,OAAA,KC9KF,cDuLE,mBAAA,UACA,eAAA,KCnLF,4CAAA,yCD4LE,mBAAA,KAQF,6BACE,mBAAA,OACA,KAAA,QAWF,QAAA,KAEE,QAAA,MAOF,QACE,QAAA,UAUF,OACE,QAAA,aAOF,SACE,QAAA,KCnNF,SD8NE,QAAA,KEtbF,KACE,mBAAA,WAAA,WAAA,WAGF,EAAA,QAAA,SAGE,mBAAA,QAAA,WAAA,QAoBA,cAAgB,MAAA,aAQlB,KAYE,mBAAA,UAGA,4BAAA,YAGF,KACE,YAAA,cAAA,UAAA,mBAAA,WAAA,OC2K4H,iBD3K5H,MAAA,WACA,UAAA,KACA,YAAA,IACA,YAAA,IAEA,MAAA,QAEA,iBAAA,KD2LF,sBClLE,QAAA,YAYF,GAAI,GAAI,GAAI,GAAI,GAAI,GAClB,WAAA,EACA,cAAA,MAOF,EACE,WAAA,EACA,cAAA,KAIF,0BAAA,YAGE,OAAA,KAGF,QACE,cAAA,KACA,WAAA,OACA,YAAA,QAGF,GAAA,GAAA,GAGE,WAAA,EACA,cAAA,KAGF,MAAA,MAAA,MAAA,MAIE,cAAA,EAGF,GACE,YAAA,IAGF,GACE,cAAA,MACA,YAAA,EAGF,WACE,OAAA,EAAA,EAAA,KAQF,EACE,MAAA,QACA,gBAAA,KEhJE,QAAA,QFmJA,MAAA,QACA,gBAAA,UAUJ,8BACE,MAAA,QACA,gBAAA,KEhKE,oCAAA,oCFmKA,MAAA,QACA,gBAAA,KANJ,oCAUI,QAAA,EASJ,IAEE,WAAA,EAEA,cAAA,KAEA,SAAA,KAQF,OAGE,OAAA,EAAA,EAAA,KAQF,IAGE,eAAA,ODsIF,cCzHE,OAAA,QAcF,cAAA,EAAA,KAAA,OAAA,MAAA,MAAA,OAAA,QAAA,SASE,iBAAA,aAAA,aAAA,aAQF,MAEE,gBAAA,SAEA,iBAAA,YAGF,QACE,YAAA,OACA,eAAA,OACA,MAAA,QACA,WAAA,KACA,aAAA,OAGF,GAEE,WAAA,KAQF,MAEE,QAAA,aACA,cAAA,MAOF,aACE,QAAA,IAAA,OACA,QAAA,IAAA,KAAA,yBAGF,OAAA,MAAA,OAAA,SAME,YAAA,QAGF,8BAAA,2BAMI,OAAA,YAKJ,iBAAA,iBAAA,2BAAA,kBASE,mBAAA,QAGF,SAEE,OAAA,SAGF,SAME,UAAA,EAEA,QAAA,EACA,OAAA,EACA,OAAA,EAGF,OAEE,QAAA,MACA,MAAA,KACA,QAAA,EACA,cAAA,MACA,UAAA,OACA,YAAA,QAGF,mBAKE,mBAAA,KAIF,OACE,QAAA,aDsEF,SC9DE,QAAA"}

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1,102 @@
<html>
<head>
<title>Flexi Time Tracker</title>
<script src="https://code.jquery.com/jquery-3.1.0.min.js"
integrity="sha256-cCueBR6CsyA4/9szpPfrX3s49M9vUU5BgtiJj06wt/s="
crossorigin="anonymous"></script>
<script src="http://learn.knockoutjs.com/Scripts/Lib/knockout-3.0.0.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/sammy.js/0.7.6/sammy.js" type="text/javascript"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.2.2/Chart.bundle.js"></script>
<link href="css/bootstrap.min.css" rel="stylesheet" type="text/css"/>
<link href="spa.css" rel="stylesheet" type="text/css"/>
<script src="spa.js" type="text/javascript"></script>
</head>
<body>
<nav class="navbar navbar-default">
<div class="container-fluid">
<!-- Brand and toggle get grouped for better mobile display -->
<div class="navbar-header">
<button type="button" class="navbar-toggle collapsed"
data-toggle="collapse" data-target="#bs-example-navbar-collapse-1" aria-expanded="false">
<span class="sr-only">Toggle navigation</span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
</button>
<a class="navbar-brand" href="#">FlexiTime DataViewer</a>
</div>
<!-- Collect the nav links, forms, and other content for toggling data-bind="foreach: menuOptions"-->
<div class="collapse navbar-collapse" id="bs-example-navbar-collapse-1">
<ul class="nav navbar-nav" data-bind="foreach: menuOptions">
<li data-bind="text: $data,
css: { selected: $data == $root.chosenMenuItemId(),active: $data == $root.chosenMenuItemId() },
click: $root.goToMenuOption">
<!-- "css: {active: $data == $root.chosenMenuItemId()}, click: $root.goToMenuOption()">
<a data-bind="text:$data"></a>-->
</li>
</ul>
</div>
</div>
</nav>
<div class="usersPage container" data-bind="with: userList">
<div class="col-md-10 col-md-offset-1">
<button class="btn btn-default" data-bind="click: $root.addNewUserClick"><span class="glyphicon glyphicon-plus"></span> Add New User</button>
<div class="usersGrid">
<table class="users table table-striped">
<thead>
<tr>
<th>ID</th>
<th>UserId</th>
<th class="col-md-1">firstName</th>
<th class="col-md-1">lastName</th>
</tr>
</thead>
<tbody data-bind="foreach: Users">
<tr>
<td class="valign" data-bind="text: Id"></td>
<td class="valign" data-bind="text: Id"></td>
<td class="valign" data-bind="text: LastName"></td>
<td class="valign" data-bind="text: FirstName"></td>
<td class="fit"><button data-bind="click: $root.goToUserDetails" class="btn btn-default">Details</button></td>
<td class="fit"><button data-bind="click: $root.goToTimeLogs" class="btn btn-default">View Logs</button></td>
</tr>
</tbody>
</table>
<label>Total User Count: <span data-bind="text: UserCount"></span></label>
</div>
</div>
</div>
<div class="chosenUserDetails container" data-bind="with: chosenUserDetails">
<div class=" col-md-10 col-md-offset-1">
<button pageDestination="Users" data-bind="click: $root.returnButtonClick" id="returnButton" class="btn btn-default">
<span class="glyphicon glyphicon-chevron-left"></span>Users
</button>
<h1 data-bind="text: FirstName"></h1>
<form action="#edituser" method="post">
<input type="hidden" name="id" data-bind="value: Id">
<div class="form-group">
<label for="firstName">First Name</label>
<input for="firstName" type="text" class="form-control" id="firstNameEdit" placeholder="Your First Name" data-bind="value: FirstName">
</div>
<div class="form-group">
<label for="LastName">Last Name</label>
<input for="FirstName" type="text" class="form-control" id="lastNameEdit" placeholder="Your Last Name" data-bind="value: LastName">
</div>
<div class="form-group">
<label for="HoursPerWeek">Hours Per Week</label>
<input for="HoursPerWeek" type="text" class="form-control" id="hoursPerWeekEdit" placeholder="Contracted Hours per Week" data-bind="value: HoursPerWeek">
</div>
<div data-bind="with: $root.unassignedCardData">
<!-- ko foreach: data -->
<input type="checkbox" data-bind="name: Id, value: CardUId, checked: IsSelected"> <span data-bind="text: CardUId"></span><br />
<!-- /ko -->
</div>
<button type="submit" class="btn btn-primary">Submit</button>
</form>
</div>
</div>
</body>
</html>

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1,127 @@
table.scroll {
width: 650px; /* Optional */
/* border-collapse: collapse; */
border-spacing: 0;
table-layout:auto;
border: 2px solid black;
word-wrap: break-word;
}
/*table.scroll tbody,
table.scroll thead { display: block }*/
table.scroll thead tr th {
/*width: 100px;
width: 90px;*/
height: 30px;
line-height: 30px;
border-bottom: 1px solid black;
/*text-align: left;*/
}
table.scroll tbody {
border-top: 1px solid black;
height: 300px;
overflow-y: auto;
overflow-x: hidden;
}
table.scroll tbody { border-top: 2px solid black; }
table.scroll tbody td, thead th {
/*width: 20%; Optional
width: 100px;*/
border-right: 1px solid black;
}
table.scroll tbody td {
text-align: center;
}
table.scroll tbody td:last-child, thead th:last-child {
border-right: none;
}
#contentContainer{
}
#nav {
padding-top: 10px;
float: left;
height: 800px;
}
#navBar{
width: 200px;
padding: 20px;
float:left;
}
#content {
margin-left: 250px;
width: 700px;
padding: 10px;
}
#collapser{
float: right;
background: black;
width: 10px;
height: 100%;
}
/* Dropdown Button */
.hoverdropbtn {
/*background-color: #4CAF50;
color: white;*/
padding: 14px;
border: none;
cursor: pointer;
}
.hoverdropdown:hover {
background-color: #4CAF50;
}
/* The container <div> - needed to position the dropdown content */
.hoverdropdown {
position: relative;
display: inline-block;
}
/* Dropdown Content (Hidden by Default) */
.hoverdropdown-content {
display: none;
position: absolute;
background-color: #f9f9f9;
min-width: 200px;
z-index: 999;
box-shadow: 0px 8px 16px 0px rgba(0,0,0,0.2);
}
/* Links inside the dropdown */
.hoverdropdown-content a {
color: black;
padding: 12px 16px;
text-decoration: none;
display: block;
}
/* Change color of dropdown links on hover */
.hoverdropdown-content a:hover {background-color: #f1f1f1}
/* Show the dropdown menu on hover */
.hoverdropdown:hover .hoverdropdown-content {
display: block;
}
/* Change the background color of the dropdown button when the dropdown content is shown */
.hoverdropdown:hover .hoverdropbtn {
background-color: #4CAF50;
}
.table td.fit,
.table th.fit {
white-space: nowrap;
width: 1%;
}
.table > tbody > tr > td.valign {
vertical-align: middle;
}

View File

@ -0,0 +1,172 @@
(function ($) {
'use strict';
$.fn.clickToggle = function (func1, func2) {
var funcs = [func1, func2];
this.data('toggleclicked', 0);
this.click(function () {
var data = $(this).data();
var tc = data.toggleclicked;
$.proxy(funcs[tc], this)();
data.toggleclicked = (tc + 1) % 2;
});
return this;
};
}(jQuery));
function DataVM() {
'use strict';
var self = this;
self.endpointUrl = 'http://localhost:8800/api';
self.menuOptions = ['Users', 'Data', 'Other'];
self.chosenMenuItemId = ko.observable();
self.userList = ko.observable();
self.chosenUserDetails = ko.observable();
self.chosenMenuData = ko.observable();
self.userTimeLogData = ko.observable();
self.unassignedCardData = ko.observable();
self.goToMenuOption = function (menu) { location.hash = menu; console.log(menu); };
self.goToUserDetails = function (user) { location.hash = 'userData/' + user.Id; };
self.goToTimeLogs = function (user) { console.log("getTimeLogs"); location.hash = 'timeLogs/' + user.Id; };
//$.each(self.unassignedCardData().data, function(k,v){ if(v.IsSelected == true){console.log(v.CardUId);}})
//this function looks for a custom attribute called "pagedestination".
//if this is used as a clickhandler, the pagedestination attribute should name the page you want.
self.returnButtonClick = function (data, event) {
var target;
if (event.target) target = event.target;
else if (event.srcElement) target = event.srcElement;
var destination = "";
for (var i = 0; i < target.attributes.length; i++) {
if (target.attributes[i].nodeName === "pagedestination") {
destination = target.attributes[i].value;
break;
}
}
console.log(destination);
self.goToMenuOption(destination); //redirect to whereever the button is telling us to go..
};
self.addNewUserClick = function (data, event) {
self.goToMenuOption("newUser");
};
self.getUserData = function () {
console.log("beginGetUserData");
$.getJSON(self.endpointUrl + '/users?callback=?', function (res) {
console.log("getting user data");
console.log(res);
self.userList(res);
}).fail(function () {
console.log("error - getusers");
});
};
self.getUserDetails = function (userId) {
console.log("beginGetUserDetailsData");
var url = self.endpointUrl + '/users/' + userId;
console.log(url);
$.getJSON(url + '?callback=?', function (res) {
console.log("got user data");
//console.log(res);
self.chosenUserDetails(res);
//console.log(self.chosenUserDetails());
}).fail(function () {
console.log("error - getuserdetails");
});
};
self.handleEditedUser = function (user) {
console.log("Post Edited User: " + user.Id);
var url = self.endpointUrl + '/users/edit';
console.log("posting..");
$.post(url, user, function () {
console.log("finished posting..");
}, 'json')
.done(function () {
self.goToMenuOption("Users");
self.chosenUserDetails(null);
})
.fail(function () {
console.log("error - post edited user");
console.log(self.chosenUserDetails().Id);
self.goToUserData(self.chosenUserDetails().Id);
});
};
self.getTimeLogData = function (userId) {
console.log("begin get TimeLog Data");
var url = self.endpointUrl + '/timelogs?userId=' + userId;
console.log(url);
$.getJSON(url + '&callback=?', function (res) {
console.log("got user timelog data");
//console.log(res);
self.userTimeLogData(res);
//console.log(self.chosenUserDetails());
}).fail(function () {
console.log("error - getuserdetails");
});
};
self.getUnassignedCardData = function () {
console.log("begin get unassigned cards");
var url = self.endpointUrl + '/unassignedCards';
console.log(url);
$.getJSON(url + '?callback=?', function (res) {
console.log("got unassigned card data");
//console.log(res);
self.unassignedCardData(res);
//console.log(self.chosenUserDetails());
}).fail(function () {
console.log("error - getuserdetails");
});
};
Sammy(function () {
this.get('#Users', function () {
console.log(this.params.menuOption);
self.chosenMenuItemId(this.params.menuOption);
self.chosenUserDetails(null);
self.userList(null);
self.userTimeLogData(null);
self.getUserData();
//$.get("http://localhost:3000", { menu: this.params.menu }, self.chosenMenuData);
});
this.get('#userData/:userId', function () {
console.log("userData userId: " + this.params.userId);
console.log("getting details for user: " + this.params.userId);
self.chosenMenuItemId('Data');
self.userList(null);
self.getUserDetails(this.params.userId);
self.userTimeLogData(null);
//$.get("http://localhost:3000", { menu: this.params.menu }, self.chosenMenuData);
});
this.get('#timeLogs/:userId', function () {
console.log("get user time logs, userID: " + this.params.userId);
self.chosenMenuItemId('TimeLogs');
self.userList(null);
self.chosenUserDetails(null);
self.getTimeLogData(this.params.userId);
});
this.get('#newUser', function () {
console.log("creating new user");
self.chosenMenuItemId('newUser');
self.userList(null);
self.userTimeLogData(null);
self.chosenUserDetails(
{
"Id": -1,
"UserId": -1,
"FirstName": null,
"LastName": null,
"HoursPerWeek": null
});
self.getUnassignedCardData();
});
this.post('#edituser', function (context) {
console.log(self.chosenUserDetails());
self.handleEditedUser(self.chosenUserDetails());
return true;
});
this.get('', function () { this.app.runRoute('get', '#Users') });
}).run();
}
DataVM.prototype.dispose = function () {
'use strict';
//window.clearInterval(self.locationTimerHandle);
//window.clearInterval(self.weatherTimerHandle);
//self.chart.destroy();
};
ko.applyBindings(new DataVM());

View File

@ -3,4 +3,12 @@
<startup> <startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5.2" /> <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5.2" />
</startup> </startup>
<runtime>
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
<dependentAssembly>
<assemblyIdentity name="Microsoft.Owin" publicKeyToken="31bf3856ad364e35" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-3.0.1.0" newVersion="3.0.1.0" />
</dependentAssembly>
</assemblyBinding>
</runtime>
</configuration> </configuration>