Skip to content

Commit

Permalink
More sexy demo
Browse files Browse the repository at this point in the history
  • Loading branch information
jods4 committed Mar 13, 2017
1 parent b1f01d4 commit 5a6aac4
Show file tree
Hide file tree
Showing 19 changed files with 14,302 additions and 10,324 deletions.
7 changes: 2 additions & 5 deletions App/app.html
Original file line number Diff line number Diff line change
@@ -1,7 +1,4 @@
<template>
<h2>Server Clock</h2>
<div>
<button click.trigger="fetchTime()">Fetch time</button>
${time}
</div>
<h1>Aurelia SSR demo</h1>
<router-view></router-view>
</template>
21 changes: 12 additions & 9 deletions App/app.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,16 @@
export class AppViewModel {
time = "n/a";
import { PLATFORM } from "aurelia-framework";
import { Router, RouterConfiguration } from "aurelia-router";

activate() {
return this.fetchTime();
}
export class AppViewModel {
router: Router;

fetchTime() {
return fetch("/api/Time")
.then<any>(response => response.json())
.then(obj => this.time = obj.time);
configureRouter(config: RouterConfiguration, router: Router) {
this.router = router;
config.options.pushState = true;
config.map([
{ route: '', name: 'home', moduleId: PLATFORM.moduleName('pages/home.html') },
{ route: 'all', name: 'master', moduleId: PLATFORM.moduleName('pages/master') },
{ route: 'item/:id', name: 'details', moduleId: PLATFORM.moduleName('pages/details') },
]);
}
}
6 changes: 5 additions & 1 deletion App/main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,10 @@ import {Aurelia, PLATFORM} from "aurelia-framework";
export function configure(aurelia: Aurelia) {
aurelia.use.standardConfiguration()
.developmentLogging();
aurelia.start()

// This is a hack so that we can delay Aurelia startup until user clicks on "Start Aurelia" button,
// to better demonstrate the effect of server-side rendering
Promise.resolve(window['clientStart'])
.then(_ => aurelia.start())
.then(() => aurelia.setRoot(PLATFORM.moduleName("app")));
}
19 changes: 19 additions & 0 deletions App/pages/details.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
<template>
<h2>Details for ${item.firstName} ${item.lastName}</h2>
<p>When you're done, <a route-href="route: master">go back to the list</a>!</p>
<form with.bind="item">
<div>
<label class="form-label">Id:</label>
<!-- Wanted to use <input> but it breaks in JSDOM for now, confusion between fake and real Object -->
<span textcontent.one-time="id"></span>
</div>
<div>
<label>First name:</label>
<span textcontent.one-time="firstName"></span>
</div>
<div>
<label>Last name:</label>
<span textcontent.one-time="lastName"></span>
</div>
</form>
</template>
9 changes: 9 additions & 0 deletions App/pages/details.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
export class DetailsViewModel {
item: any;

activate({ id }: any) {
return fetch("/api/duck/" + id)
.then<any>(response => response.json())
.then(duck => this.item = duck);
}
}
6 changes: 6 additions & 0 deletions App/pages/home.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
<template>
<h2>Home</h2>
<p>This is the home page of this application.</p>
<p>It's all static text so it's really boring.</p>
<p>You should try another page, such as <a route-href="route: master">the master list</a>.</p>
</template>
18 changes: 18 additions & 0 deletions App/pages/master.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
<template>
<h2>Master List</h2>
<p>Here's what the server has in store for us.</p>
<p>You can click any line to see the details!</p>
<p>Or <a route-href="route: home">go back to the boring home</a>
<table>
<thead>
<tr>
<th>Name</th>
</tr>
</thead>
<tbody>
<tr repeat.for="duck of list" click.delegate="go(duck.id)">
<td>${duck.firstName}</td>
</tr>
</tbody>
</table>
</template>
19 changes: 19 additions & 0 deletions App/pages/master.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import { autoinject } from 'aurelia-framework';
import { Router } from 'aurelia-router';

@autoinject
export class MasterViewModel {
list: any[];

constructor(private router: Router) { }

activate() {
return fetch("/api/duck")
.then<any[]>(response => response.json())
.then(list => this.list = list);
}

go(id: number) {
this.router.navigateToRoute("details", { id });
}
}
22 changes: 22 additions & 0 deletions Controllers/DuckController.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
using Microsoft.AspNetCore.Mvc;

namespace AureliaDemo.Controllers
{
[Route("/api/duck")]
public class DuckController {

private static object[] data = new[] {
new { Id = 1, FirstName = "Scrooge", LastName = "McDuck" },
new { Id = 2, FirstName = "Huey", LastName = "Duck" },
new { Id = 3, FirstName = "Dewey", LastName = "Duck" },
new { Id = 4, FirstName = "Louie", LastName = "Duck" },
new { Id = 5, FirstName = "Webbigail", LastName = "Vanderquack" },
};

[HttpGet]
public object Index() => data;

[HttpGet("{id}")]
public object Index(int id) => data[id - 1];
}
}
12 changes: 0 additions & 12 deletions Controllers/TimeController.cs

This file was deleted.

3 changes: 1 addition & 2 deletions Startup.cs
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,7 @@ public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerF
app.UseStaticFiles();

app.UseMvc(routes =>
{
routes.MapRoute("api", "api/{controller}/{action=Index}");
{
routes.MapSpaFallbackRoute("spa-fallback", new { controller = "Home", action = "Index" });
});
}
Expand Down
18 changes: 17 additions & 1 deletion Views/Home/Index.cshtml
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,24 @@
<!doctype html>
<html>
<head>
<link rel="stylesheet" href="/app.css">
<script defer src="/dist/app.js" asp-append-version="true"></script>
</head>
<body aurelia-app="main" asp-prerender-module="render">
<body aurelia-app="main">
<!-- Hacky "Rendered server-side" header for illustration purposes -->
<div class="server-side">
<span>What you see was rendered server-side!</span>
<script>
window.clientStart = new Promise(resolve => window.clientResolve = resolve);
</script>
<button onclick="window.clientResolve()">Start Aurelia</button>
</div>

<!-- Normally you'd put asp-prerender-module on the same tag as your aurelia-app,
but this is a hack so that I can implement the "Rendered server-side" header.
Setting the timeout is not required but the default of 30s is far too long.
If something went wrong (e.g. unknown route) I prefer to get a crash after 2s. -->
<div asp-prerender-module="render" asp-prerender-timeout="5000">
</div>
</body>
</html>
7 changes: 5 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,18 @@
"devDependencies": {
"aspnet-webpack": "^1.0.28",
"aurelia-webpack-plugin": "^2.0.0-rc.1",
"ts-loader": "^2.0.1",
"typescript": "^2.2.1",
"webpack": "^2.2.1",
"webpack-hot-middleware": "^2.17.1"
"webpack-hot-middleware": "^2.17.1",
"css-loader": "^0.27.3",
"style-loader": "^0.13.2",
"ts-loader": "^2.0.1"
},
"dependencies": {
"aspnet-prerendering": "^2.0.3",
"aurelia-bootstrapper": "^2.1.1",
"jsdom": "^9.11.0",
"tslib": "^1.6.0",
"whatwg-fetch": "^2.0.3"
}
}
2 changes: 2 additions & 0 deletions render.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ const jsdom = require("jsdom");

module.exports = prerendering.createServerRenderer(params =>
new Promise((resolve, reject) => {
let virtualConsole = jsdom.createVirtualConsole().sendTo(console);
jsdom.env({
html: "<html><body aurelia-app=main></body></html>",
scripts: ["/dist/app.js"],
Expand All @@ -11,6 +12,7 @@ module.exports = prerendering.createServerRenderer(params =>
FetchExternalResources: ["script"],
ProcessExternalResources: ["script"]
},
virtualConsole,
created: (err, window) => {
// HACK: "polyfill" missing stuff in JSDOM...
window.SVGElement = class SVGElement extends window.Element {};
Expand Down
3 changes: 2 additions & 1 deletion tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
"lib": [ "es6", "dom" ],
"importHelpers": true,

"experimentalDecorators": true
"experimentalDecorators": true,
"emitDecoratorMetadata": true
}
}
1 change: 1 addition & 0 deletions webpack.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ module.exports = {
rules: [
{ test: /\.html$/i, loaders: "html-loader" },
{ test: /\.ts$/i, loaders: "ts-loader" },
{ test: /\.css$/i, loaders: "css-loader"},
]
},

Expand Down
81 changes: 81 additions & 0 deletions wwwroot/app.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
@import url('https://fonts.googleapis.com/css?family=Bungee');

html {
font-family: "Segoe UI", Arial, sans-serif;
}

body {
margin: 0 8px;
}

h1, h2 {
font-family: "Bungee";
color: #6E4D9B;
margin: 0;
}

h2, a {
color: #E82887;
}

p {
color: #444;
margin: 0;
}

table {
margin-top: 12px;
width: 100%;
border-spacing: 0;
}

th, td {
color: #333;
text-align: left;
border-bottom: 1px solid #666;
padding: 4px;
}

td {
border-bottom-color: #ccc;
}

tbody tr:hover {
background: #FFDEEE;
cursor: pointer;
}

form {
margin-top: 12px;
}

label {
display: inline-block;
width: 150px;
font-weight: 600;
}

label + span {
display: inline-block;
width: 150px;
border-bottom: solid 1px #ccc;
}

.server-side {
margin: 0 -8px;
padding: 8px;
background: repeating-linear-gradient(45deg, #fff 0, #fff 15px, #FFDEEE 15px, #FFDEEE 30px);
border-bottom: solid 1px #E82887;
font-weight: bold;
}

.server-side button {
margin-left: 16px;
background: #6E4D9B;
font-weight: bold;
color: #fff;
text-shadow: rgba(0, 0, 0, 0.25) -1px -1px;
padding: 4px 16px;
border: 1px solid #533281;
border-radius: 4px;
}
Loading

0 comments on commit 5a6aac4

Please sign in to comment.