Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 14 additions & 1 deletion Angular2Spa.xproj
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,22 @@
<BaseIntermediateOutputPath Condition="'$(BaseIntermediateOutputPath)'=='' ">.\obj</BaseIntermediateOutputPath>
<OutputPath Condition="'$(OutputPath)'=='' ">.\bin\</OutputPath>
<TargetFrameworkVersion>v4.5.2</TargetFrameworkVersion>
</PropertyGroup>
</PropertyGroup>
<PropertyGroup>
<SchemaVersion>2.0</SchemaVersion>
</PropertyGroup>
<ItemGroup>
<DnxInvisibleFolder Include=".awcache\" />
<DnxInvisibleFolder Include=".git\" />
<DnxInvisibleFolder Include=".vscode\" />
<DnxInvisibleFolder Include=".vs\" />
<DnxInvisibleFolder Include="docs\" />
</ItemGroup>
<ItemGroup>
<DnxInvisibleContent Include="CHANGELOG.md" />
<DnxInvisibleContent Include="Dockerfile" />
<DnxInvisibleContent Include="LICENSE.md" />
<DnxInvisibleContent Include="README.md" />
</ItemGroup>
<Import Project="$(VSToolsPath)\DotNet.Web\Microsoft.DotNet.Web.targets" Condition="'$(VSToolsPath)' != ''" />
</Project>
10 changes: 7 additions & 3 deletions Client/app/app.routes.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,14 @@
import { Route } from '@angular/router';
import { Route } from '@angular/router';

// Container (aka: "pages") imports
import {
HomeComponent,
RestTestComponent,
BootstrapComponent,
LoginComponent,
ExamplesComponent
ExamplesComponent,
ChatComponent,
NotFoundComponent
} from 'app-containers';

export const ROUTES: Route[] = [
Expand All @@ -19,6 +21,8 @@ export const ROUTES: Route[] = [
{ path: 'rest-test', component: RestTestComponent, data: { title: 'WebAPI Examples'} },
{ path: 'login', component: LoginComponent, data: { title: 'Login'} },
{ path: 'examples', component: ExamplesComponent, data: { title: 'Platform Examples'} },
{ path: 'chat', component: ChatComponent, data: { title: 'Chat' } },
{ path: 'not-found', component: NotFoundComponent, data: { title: '404 - Not Found' } },

{ // ** LAZY-LOADING EXAMPLE **
// Notice we don't reference the file anywhere else, imports, declarations, anywhere
Expand All @@ -34,5 +38,5 @@ export const ROUTES: Route[] = [
// loadChildren: '../containers/+faq/faq.module#FAQModule' },

// All else fails - go home
{ path: '**', redirectTo: 'home' }
{ path: '**', redirectTo: 'not-found' }
];
3 changes: 1 addition & 2 deletions Client/app/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,5 +20,4 @@ export * from './state/app.reducer';
export * from './state/app-state';
export * from './state/hmr';

export * from './shared-module/base.shared.module';

export * from './shared-module/base.shared.module';
1 change: 1 addition & 0 deletions Client/app/platform-modules/app.browser.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ export function getResponse() {
// Other providers you want to add that you don't want shared in "Common" but are browser only
]
})

export class AppBrowserModule {

constructor(public cache: CacheService) {
Expand Down
7 changes: 5 additions & 2 deletions Client/app/platform-modules/app.common.module.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@

/*
* _Common_ NgModule to share between our "BASE" App.Browser & App.Server module platforms
*
Expand Down Expand Up @@ -27,7 +26,9 @@ import {
RestTestComponent,
BootstrapComponent,
LoginComponent,
ExamplesComponent
ExamplesComponent,
ChatComponent,
NotFoundComponent
} from 'app-containers';

// Provider (aka: "shared" | "services") imports
Expand Down Expand Up @@ -79,6 +80,8 @@ const COMPONENTS = [
LoginComponent,
BootstrapComponent,
ExamplesComponent,
ChatComponent,
NotFoundComponent,

// Directives
RxContextDirective
Expand Down
1 change: 1 addition & 0 deletions Client/app/platform-modules/app.server.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ export function getResponse() {
// Other providers you want to add that you don't want shared in "Common" but are browser only
]
})

export class AppServerModule {

constructor(public cache: CacheService) { }
Expand Down
10 changes: 10 additions & 0 deletions Client/components/navmenu/navmenu.component.html
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,16 @@
<i class="fa fa-chrome" aria-hidden="true"></i> RestAPI Demo
</a>
</li>
<li [routerLinkActive]="['link-active']">
<a [routerLink]="['/chat']">
<i class="fa fa-comments-o" aria-hidden="true"></i> SignalR Chat
</a>
</li>
<li [routerLinkActive]="['link-active']">
<a [routerLink]="['/video-chat']">
<i class="fa fa-video-camera" aria-hidden="true"></i> WebRTC Video Chat
</a>
</li>
<li [routerLinkActive]="['link-active']">
<a [routerLink]="['/faq']">
<i class="fa fa-question-circle" aria-hidden="true"></i> FAQ
Expand Down
1 change: 1 addition & 0 deletions Client/containers/chat/chat.component.html
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
SignalR Chat example will go here
21 changes: 21 additions & 0 deletions Client/containers/chat/chat.component.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import { Component, OnInit, Inject } from '@angular/core';


@Component({
selector: 'app-chat',
templateUrl: './chat.component.html'
})
export class ChatComponent implements OnInit
{
// Use "constructor"s only for dependency injection
constructor (@Inject('isBrowser') private isBrowser: boolean) {
// Example of how to Inject the isBrowser/isNode we injected in our app.browser & app.server NgModules
}

// Here you want to handle anything with @Input()'s @Output()'s
// Data retrieval / etc - this is when the Component is "ready" and wired up
ngOnInit ()
{
console.log('Are we inside the Browser ? ' + this.isBrowser);
}
}
2 changes: 2 additions & 0 deletions Client/containers/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,3 +17,5 @@ export * from './home/home.component';
export * from './bootstrap/bootstrap.component';
export * from './login/login.component';
export * from './platform-examples/examples.component';
export * from './not-found/not-found.component';
export * from './chat/chat.component';
3 changes: 3 additions & 0 deletions Client/containers/not-found/not-found.component.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
:host(.span12) {
color: red;
}
13 changes: 13 additions & 0 deletions Client/containers/not-found/not-found.component.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
<div class="row">
<div class="span12">
<div class="hero-unit center">
<h1>Page Not Found <small><font face="Tahoma" color="red">Error 404</font></small></h1>
<br />
<p>The page you requested could not be found, either contact your webmaster or try again. Use your browsers <b>Back</b> button to navigate to the page you have prevously come from</p>
<p><b>Or you could just press this neat little button:</b></p>
<a [routerLink]="['/home']" class="btn btn-large btn-info"><i class="icon-home icon-white"></i> Take Me Home</a>
</div>
<br />
<!-- By ConnerT HTML & CSS Enthusiast -->
</div>
</div>
22 changes: 22 additions & 0 deletions Client/containers/not-found/not-found.component.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import { Component, OnInit, Inject } from '@angular/core';


@Component({
selector: 'app-notFound',
templateUrl: './not-found.component.html',
styleUrls: ['./not-found.component.css']
})
export class NotFoundComponent implements OnInit
{
// Use "constructor"s only for dependency injection
constructor (@Inject('isBrowser') private isBrowser: boolean) {
// Example of how to Inject the isBrowser/isNode we injected in our app.browser & app.server NgModules
}

// Here you want to handle anything with @Input()'s @Output()'s
// Data retrieval / etc - this is when the Component is "ready" and wired up
ngOnInit ()
{
console.log('Are we inside the Browser ? ' + this.isBrowser);
}
}
65 changes: 65 additions & 0 deletions Hubs/ChatHub.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
using Microsoft.AspNetCore.SignalR;
using Microsoft.AspNetCore.SignalR.Hubs;
using Microsoft.Extensions.Logging;
using System.Threading.Tasks;

namespace Angular2Spa.Hubs
{
[HubName("chat")]
public class ChatHub : Hub
{
private readonly ILogger<ChatHub> _logger;
public static readonly string testGroupName = "test_group";

public ChatHub(ILogger<ChatHub> logger)
{
_logger = logger;
}

public override Task OnConnected()
{
_logger.LogWarning(
Context.ConnectionId + " - Connected"
);
return base.OnConnected();
}


//rejoin groups if client disconnects and then reconnects
public override Task OnReconnected()
{
_logger.LogWarning(
Context.ConnectionId + " ReConnected"
);
return base.OnReconnected();
}

public override Task OnDisconnected(bool stopCalled)
{
_logger.LogWarning(
Context.ConnectionId + " DisConnected"
);

return base.OnDisconnected(stopCalled);
}

public Task JoinGroup(string groupName)
{
return Groups.Add(Context.ConnectionId, groupName);
}

public Task LeaveGroup(string groupName)
{
return Groups.Remove(Context.ConnectionId, groupName);
}

public void Send(string message)
{
Clients.All.messageReceived(Context.ConnectionId.ToString(), message );

_logger.LogWarning(
Context.ConnectionId + " - " + message
);
}
}
}
5 changes: 0 additions & 5 deletions Program.cs
Original file line number Diff line number Diff line change
@@ -1,8 +1,4 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Configuration;

Expand All @@ -12,7 +8,6 @@ public class Program
{
public static void Main(string[] args)
{

var config = new ConfigurationBuilder()
.AddCommandLine(args)
.AddEnvironmentVariables(prefix: "ASPNETCORE_")
Expand Down
16 changes: 12 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
# ASP.NET Core & Angular 2+ Universal starter

<p align="center">
<img src="https://github.com/markpieszak/aspnetcore-angular2-starter/blob/master/architecture.png" alt="ASP.NET Core Angular 2+ Starter" title="ASP.NET Core Angular2 Starter">
<img src="./docs/architecture.png" alt="ASP.NET Core Angular 2+ Starter" title="ASP.NET Core Angular 2+ Starter">
</p>

### What is this repo?
Expand Down Expand Up @@ -98,7 +98,7 @@ to: `ASPNETCORE_ENVIRONMENT=Production`, then run `webpack` manually. Then you c

- [ ] (On-hold) Example of NgRx (redux) transfering App State from server to client - track [#29](https://github.com/MarkPieszak/aspnetcore-angular2-universal/issues/29)
- [ ] (On-hold) AoT (Ahead-of-time compilation) production builds - track [#10](https://github.com/MarkPieszak/aspnetcore-angular2-universal/issues/10)
- [ ] SignalR (Websockets) example - track [#39](https://github.com/MarkPieszak/aspnetcore-angular2-universal/issues/39)
- [x] ~~SignalR (Websockets) example - track [#39](https://github.com/MarkPieszak/aspnetcore-angular2-universal/issues/39)~~
- [x] ~~Automatically update Browser Title on Route change [#32](https://github.com/MarkPieszak/aspnetcore-angular2-universal/issues/32)~~
- [x] ~~Update components real unit & e2e tests - track [#45](https://github.com/MarkPieszak/aspnetcore-angular2-universal/issues/45)~~
- [x] ~~Storage Service (localStorage) showcasing Dependency Injection per-platform - [#35](https://github.com/MarkPieszak/aspnetcore-angular2-universal/issues/35)~~
Expand Down Expand Up @@ -252,6 +252,14 @@ Nothing's ever perfect, but please let me know by creating an issue (make sure t
----

# FAQ

**How to add a route in the app**

1. Create a folder in `Client\Containers\`
2. Create a component in the folder
3. Add the container in the `Client\Containers\index.ts` (this is the "barrels" file for all containers)
4. Add the container in the `\Client\app\platform-modules\app.common.module.ts`
5. Add the container in the `\Client\app\app.routes.ts`

### How can I disable Universal / SSR (Server-side rendering)?

Expand Down Expand Up @@ -299,13 +307,13 @@ In a Component you want to use jQuery, make sure to import it near the top like

**Always make sure to wrap anything jQuery oriented in Universal's `isBrowser` conditional!**


----

# Special Thanks

Many thanks go out to Steve Sanderson ([@SteveSandersonMS](https://github.com/SteveSandersonMS)) from Microsoft and his amazing work on JavaScriptServices and integrating the world of Node with ASP.NET Core.


----

# License
Expand Down
29 changes: 27 additions & 2 deletions Server/Controllers/TestController.cs
Original file line number Diff line number Diff line change
@@ -1,14 +1,35 @@
using Microsoft.AspNetCore.Mvc;
using Angular2Spa.Hubs;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.SignalR.Infrastructure;
using Microsoft.Extensions.Logging;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.SignalR;
using System.IO;

namespace Angular2Spa.Server.Controllers
{
[Route("api/[controller]")]
public class TestController : Controller
{
/*
private IHubContext _hub;
private ILogger<TestController> _logger;
private string uploadDirectory;

public TestController(ILogger<TestController> logger, IHostingEnvironment environment, IConnectionManager connectionManager) //, IHostingEnvironment environment
{
_hub = connectionManager.GetHubContext<ChatHub>();
_logger = logger;
IHostingEnvironment _environment = environment;
var location = System.Reflection.Assembly.GetEntryAssembly().Location;
uploadDirectory = _environment.WebRootPath + $@"/{"uploads"}";
Directory.CreateDirectory(uploadDirectory); //Should be in startup
}
*/

private static string[] Names = new[]
{
"Mark Pieszak", "Angular mcAngular", "Redux-man", "Nintendo"
Expand All @@ -18,6 +39,10 @@ public class TestController : Controller
public IEnumerable<SampleData> Users()
{
var random = new Random();

//Calling a hub function
//_hub.Clients.All.Send("REST Working");

return Enumerable.Range(1, 5).Select(index => new SampleData
{
ID = random.Next(0, 2000),
Expand Down
Loading