restart front-end proj

This commit is contained in:
Collin Barrett 2018-01-18 16:46:37 -06:00
parent b0fc5fa8f2
commit 9faf0895a9
19 changed files with 3558 additions and 196 deletions

View file

@ -1,6 +1,6 @@
Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio 15
VisualStudioVersion = 15.0.27004.2005
VisualStudioVersion = 15.0.27130.2024
MinimumVisualStudioVersion = 10.0.40219.1
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "FilterLists.Api", "src\FilterLists.Api\FilterLists.Api.csproj", "{57E4CE18-41F3-48F6-B142-12947FFBA86C}"
EndProject
@ -8,7 +8,7 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "FilterLists.Data", "src\Fil
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "FilterLists.Services", "src\FilterLists.Services\FilterLists.Services.csproj", "{9F296ECF-97C9-47E6-A794-5AD900ECFE6C}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "FilterLists.Web", "src\FilterLists.Web\FilterLists.Web.csproj", "{D2D9EB4D-A7DA-4F50-BFCF-4C380444B5E5}"
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "FilterLists.Web", "src\FilterLists.Web\FilterLists.Web.csproj", "{6B3E6765-5B8B-4A23-AD12-7E2BC5F4D2E6}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
@ -28,10 +28,10 @@ Global
{9F296ECF-97C9-47E6-A794-5AD900ECFE6C}.Debug|Any CPU.Build.0 = Debug|Any CPU
{9F296ECF-97C9-47E6-A794-5AD900ECFE6C}.Release|Any CPU.ActiveCfg = Release|Any CPU
{9F296ECF-97C9-47E6-A794-5AD900ECFE6C}.Release|Any CPU.Build.0 = Release|Any CPU
{D2D9EB4D-A7DA-4F50-BFCF-4C380444B5E5}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{D2D9EB4D-A7DA-4F50-BFCF-4C380444B5E5}.Debug|Any CPU.Build.0 = Debug|Any CPU
{D2D9EB4D-A7DA-4F50-BFCF-4C380444B5E5}.Release|Any CPU.ActiveCfg = Release|Any CPU
{D2D9EB4D-A7DA-4F50-BFCF-4C380444B5E5}.Release|Any CPU.Build.0 = Release|Any CPU
{6B3E6765-5B8B-4A23-AD12-7E2BC5F4D2E6}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{6B3E6765-5B8B-4A23-AD12-7E2BC5F4D2E6}.Debug|Any CPU.Build.0 = Debug|Any CPU
{6B3E6765-5B8B-4A23-AD12-7E2BC5F4D2E6}.Release|Any CPU.ActiveCfg = Release|Any CPU
{6B3E6765-5B8B-4A23-AD12-7E2BC5F4D2E6}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE

View file

@ -1,9 +0,0 @@
// https://github.com/aspnet/Docs/blob/master/aspnetcore/performance/caching/memory/sample/WebCache/CacheKeys.cs
namespace FilterLists.Web
{
public static class CacheKeys
{
public static readonly string Entry = "_Entry";
}
}

View file

@ -8,6 +8,8 @@ import * as RoutesModule from "./routes";
let routes = RoutesModule.routes;
function renderApp() {
// This code starts up the React app when it runs in a browser. It sets up the routing
// configuration and injects the app into a DOM element.
const baseUrl = document.getElementsByTagName("base")[0].getAttribute("href")!;
ReactDOM.render(
<AppContainer>
@ -19,6 +21,7 @@ function renderApp() {
renderApp();
// Allow Hot Module Replacement
if (module.hot) {
module.hot.accept("./routes",
() => {

View file

@ -0,0 +1,65 @@
import * as React from "react";
import { RouteComponentProps } from "react-router";
import "isomorphic-fetch";
interface FetchDataExampleState {
forecasts: WeatherForecast[];
loading: boolean;
}
export class FetchData extends React.Component<RouteComponentProps<{}>, FetchDataExampleState> {
constructor() {
super();
this.state = { forecasts: [], loading: true };
fetch("api/SampleData/WeatherForecasts")
.then(response => response.json() as Promise<WeatherForecast[]>)
.then(data => {
this.setState({ forecasts: data, loading: false });
});
}
render() {
const contents = this.state.loading
? <p>
<em>Loading...</em>
</p>
: FetchData.renderForecastsTable(this.state.forecasts);
return <div>
<h1>Weather forecast</h1>
<p>This component demonstrates fetching data from the server.</p>
{ contents }
</div>;
}
private static renderForecastsTable(forecasts: WeatherForecast[]) {
return <table className="table">
<thead>
<tr>
<th>Date</th>
<th>Temp. (C)</th>
<th>Temp. (F)</th>
<th>Summary</th>
</tr>
</thead>
<tbody>
{forecasts.map(forecast =>
<tr key={ forecast.dateFormatted }>
<td>{ forecast.dateFormatted }</td>
<td>{ forecast.temperatureC }</td>
<td>{ forecast.temperatureF }</td>
<td>{ forecast.summary }</td>
</tr>
)}
</tbody>
</table>;
}
}
interface WeatherForecast {
dateFormatted: string;
temperatureC: number;
temperatureF: number;
summary: string;
}

View file

@ -1,65 +0,0 @@
import * as React from "react";
import { RouteComponentProps } from "react-router";
import "isomorphic-fetch";
import MuiThemeProvider from "material-ui/styles/MuiThemeProvider";
import {
Table,
TableHead,
TableBody,
TableRow,
TableCell,
} from "material-ui";
interface IFilterListsState {
filterLists: IFilterList[];
loading: boolean;
}
interface IFilterList {
id: number;
name: string;
description: string;
}
export class Home extends React.Component<RouteComponentProps<{}>, IFilterListsState> {
constructor(props: any) {
super(props);
this.state = { filterLists: [], loading: true };
fetch("https://api.filterlists.com/v1/lists")
.then(response => response.json() as Promise<IFilterList[]>)
.then(data => {
this.setState({ filterLists: data, loading: false });
});
}
render() {
const contents = this.state.loading
? <p>
<em>Loading...</em>
</p>
: Home.renderFilterListsTable(this.state.filterLists);
return <div>
<MuiThemeProvider>
{contents}
</MuiThemeProvider>
</div>;
}
private static renderFilterListsTable(filterLists: IFilterList[]) {
return <Table>
<TableHead>
<TableRow>
<TableCell>List</TableCell>
</TableRow>
</TableHead>
<TableBody>
{filterLists.map(filterList =>
<TableRow key={filterList.id}>
<TableCell><h2>{filterList.name}</h2>{filterList.description}</TableCell>
</TableRow>
)}
</TableBody>
</Table>;
}
}

View file

@ -32,9 +32,8 @@
}
.main-nav .navbar {
-ms-border-radius: 0;
border-radius: 0;
border-width: 0;
border-radius: 0px;
border-width: 0px;
height: 100%;
}
@ -42,7 +41,7 @@
.main-nav .navbar-collapse {
border-top: 1px solid #444;
padding: 0;
padding: 0px;
}
.main-nav .navbar ul { float: none; }
@ -54,7 +53,6 @@
}
.main-nav .navbar li a {
-ms-border-radius: 4px;
border-radius: 4px;
padding: 10px 16px;
}

View file

@ -1,8 +1,8 @@
import * as React from "react";
import { Route } from "react-router-dom";
import { Layout } from "./components/Layout";
import { Home } from "./components/Home";
import { FetchData } from "./components/FetchData";
export const routes = <Layout>
<Route exact path="/" component={ Home }/>
<Route exact path="/" component={ FetchData }/>
</Layout>;

View file

@ -1,27 +1,13 @@
using System;
using System.Diagnostics;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Caching.Memory;
namespace FilterLists.Web.Controllers
{
[ResponseCache(CacheProfileName = "Long-Lived")]
public class HomeController : Controller
{
private readonly IMemoryCache memoryCache;
public HomeController(IMemoryCache memoryCache)
{
this.memoryCache = memoryCache;
}
public IActionResult Index()
{
return memoryCache.GetOrCreate(CacheKeys.Entry, entry =>
{
entry.AbsoluteExpirationRelativeToNow = TimeSpan.FromSeconds(86400);
return View();
});
return View();
}
public IActionResult Error()

View file

@ -0,0 +1,37 @@
using System;
using System.Collections.Generic;
using System.Linq;
using Microsoft.AspNetCore.Mvc;
namespace FilterLists.Web.Controllers
{
[Route("api/[controller]")]
public class SampleDataController : Controller
{
private static readonly string[] Summaries =
{
"Freezing", "Bracing", "Chilly", "Cool", "Mild", "Warm", "Balmy", "Hot", "Sweltering", "Scorching"
};
[HttpGet("[action]")]
public IEnumerable<WeatherForecast> WeatherForecasts()
{
var rng = new Random();
return Enumerable.Range(1, 5).Select(index => new WeatherForecast
{
DateFormatted = DateTime.Now.AddDays(index).ToString("d"),
TemperatureC = rng.Next(-20, 55),
Summary = Summaries[rng.Next(Summaries.Length)]
});
}
public class WeatherForecast
{
public string DateFormatted { get; set; }
public int TemperatureC { get; set; }
public string Summary { get; set; }
public int TemperatureF => 32 + (int) (TemperatureC / 0.5556);
}
}
}

View file

@ -1,27 +0,0 @@
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.DependencyInjection;
namespace FilterLists.Web.DependencyInjection.Extensions
{
public static class ConfigureServicesCollection
{
public static void AddFilterListsWeb(this IServiceCollection services)
{
services.AddMvcCustom();
services.AddResponseCaching();
services.AddMemoryCache();
}
private static void AddMvcCustom(this IServiceCollection services)
{
services.AddMvc(options =>
{
options.CacheProfiles.Add("Long-Lived",
new CacheProfile
{
Duration = 86400
});
});
}
}
}

View file

@ -8,14 +8,16 @@
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.ApplicationInsights.AspNetCore" Version="2.1.1" />
<PackageReference Include="Microsoft.AspNetCore.All" Version="2.0.5" />
<PackageReference Include="Microsoft.DotNet.Analyzers.Compatibility" Version="0.1.2-alpha" />
<PackageReference Include="Microsoft.Extensions.Caching.Memory" Version="2.0.0" />
</ItemGroup>
<ItemGroup>
<DotNetCliToolReference Include="Microsoft.VisualStudio.Web.CodeGeneration.Tools" Version="2.0.0" />
<DotNetCliToolReference Include="Microsoft.VisualStudio.Web.CodeGeneration.Tools" Version="2.0.2" />
</ItemGroup>
<ItemGroup>
<!-- Files not to publish (note that the 'dist' subfolders are re-added below) -->
<Content Remove="ClientApp\**" />
</ItemGroup>
<Target Name="DebugRunWebpack" BeforeTargets="Build" Condition=" '$(Configuration)' == 'Debug' And !Exists('wwwroot\dist') ">
@ -40,7 +42,7 @@
<!-- Include the newly-built files in the publish output -->
<ItemGroup>
<DistFiles Include="wwwroot\dist\**" />
<DistFiles Include="wwwroot\dist\**; ClientApp\dist\**" />
<ResolvedFileToPublish Include="@(DistFiles->'%(FullPath)')" Exclude="@(ResolvedFileToPublish)">
<RelativePath>%(DistFiles.Identity)</RelativePath>
<CopyToPublishDirectory>PreserveNewest</CopyToPublishDirectory>
@ -48,4 +50,4 @@
</ItemGroup>
</Target>
</Project>
</Project>

View file

@ -13,7 +13,6 @@ public static void Main(string[] args)
public static IWebHost BuildWebHost(string[] args)
{
return WebHost.CreateDefaultBuilder(args)
.UseUrls("http://localhost:5001;")
.UseStartup<Startup>()
.Build();
}

View file

@ -1,12 +1,27 @@
{
"iisSettings": {
"windowsAuthentication": false,
"anonymousAuthentication": true,
"iisExpress": {
"applicationUrl": "http://localhost:63086/",
"sslPort": 0
}
},
"profiles": {
"IIS Express": {
"commandName": "IISExpress",
"launchBrowser": true,
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
}
},
"FilterLists.Web": {
"commandName": "Project",
"launchBrowser": true,
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
},
"applicationUrl": "http://localhost:5001/"
"applicationUrl": "http://localhost:63087/"
}
}
}

View file

@ -1,4 +1,3 @@
using FilterLists.Web.DependencyInjection.Extensions;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.SpaServices.Webpack;
@ -16,11 +15,13 @@ public Startup(IConfiguration configuration)
public IConfiguration Configuration { get; }
// This method gets called by the runtime. Use this method to add services to the container.
public void ConfigureServices(IServiceCollection services)
{
services.AddFilterListsWeb();
services.AddMvc();
}
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
if (env.IsDevelopment())
@ -33,9 +34,12 @@ public void Configure(IApplicationBuilder app, IHostingEnvironment env)
});
}
else
{
app.UseExceptionHandler("/Home/Error");
app.UseResponseCaching();
}
app.UseStaticFiles();
app.UseMvc(routes =>
{
routes.MapRoute(

View file

@ -1,23 +0,0 @@
/*
WARNING - This file will be checked into source control. Do not change this file.
Use this as an example file only.
Use {env.EnvironmentName}.json as your configuration file as it will not be checked into source control.
{env.EnvironmentName} values : development, staging, production
*/
{
"Logging": {
"IncludeScopes": false,
"LogLevel": {
"Default": "Debug",
"System": "Information",
"Microsoft": "Information"
}
},
"ApplicationInsights": {
"InstrumentationKey": "InstrumentationKeyValue"
},
"FilterListsApi": {
"Url": "https://api.filterlists.com/",
"Version": 1
}
}

3379
src/FilterLists.Web/npm-shrinkwrap.json generated Normal file

File diff suppressed because it is too large Load diff

View file

@ -3,36 +3,32 @@
"private": true,
"version": "0.0.0",
"devDependencies": {
"@types/history": "^4.6.2",
"@types/material-ui": "^0.18.5",
"@types/react": "^16.0.27",
"@types/react-dom": "^16.0.3",
"@types/react-hot-loader": "^3.0.5",
"@types/react-router": "^4.0.19",
"@types/react-router-dom": "^4.2.3",
"@types/webpack-env": "^1.13.2",
"@types/history": "4.6.0",
"@types/react": "15.0.35",
"@types/react-dom": "15.5.1",
"@types/react-hot-loader": "3.0.3",
"@types/react-router": "4.0.12",
"@types/react-router-dom": "4.0.5",
"@types/webpack-env": "1.13.0",
"aspnet-webpack": "^2.0.1",
"aspnet-webpack-react": "^3.0.0",
"awesome-typescript-loader": "^3.4.1",
"bootstrap": "^3.3.7",
"css-loader": "^0.28.7",
"event-source-polyfill": "0.0.12",
"extract-text-webpack-plugin": "^3.0.2",
"file-loader": "^1.1.5",
"isomorphic-fetch": "^2.2.1",
"jquery": "^3.2.1",
"json-loader": "^0.5.7",
"react": "^16.2.0",
"react-dom": "^16.2.0",
"react-hot-loader": "^3.1.3",
"react-router-dom": "^4.2.2",
"style-loader": "^0.19.0",
"typescript": "^2.6.2",
"url-loader": "^0.6.2",
"webpack": "^3.10.0",
"webpack-hot-middleware": "^2.21.0"
},
"dependencies": {
"material-ui": "^0.20.0"
"awesome-typescript-loader": "3.2.1",
"bootstrap": "3.3.7",
"css-loader": "0.28.4",
"event-source-polyfill": "0.0.9",
"extract-text-webpack-plugin": "2.1.2",
"file-loader": "0.11.2",
"isomorphic-fetch": "2.2.1",
"jquery": "3.2.1",
"json-loader": "0.5.4",
"react": "15.6.1",
"react-dom": "15.6.1",
"react-hot-loader": "3.0.0-beta.7",
"react-router-dom": "4.1.1",
"style-loader": "0.18.2",
"typescript": "2.4.1",
"url-loader": "0.5.9",
"webpack": "2.5.1",
"webpack-hot-middleware": "2.18.2"
}
}
}

View file

@ -36,14 +36,16 @@ module.exports = (env) => {
})
].concat(isDevBuild
? [
// Plugins that apply in development builds only
new webpack.SourceMapDevToolPlugin({
filename: "[file].map",
filename: "[file].map", // Remove this line if you prefer inline source maps
moduleFilenameTemplate:
path.relative(bundleOutputDir,
"[resourcePath]")
"[resourcePath]") // Point sourcemap entries to the original file locations on disk
})
]
: [
// Plugins that apply in production builds only
new webpack.optimize.UglifyJsPlugin(),
new ExtractTextPlugin("site.css")
])

View file

@ -37,7 +37,7 @@ module.exports = (env) => {
new webpack.ProvidePlugin({
$: "jquery",
jQuery: "jquery"
}),
}), // Maps these identifiers to the jQuery package (because Bootstrap expects it to be a global variable)
new webpack.DllPlugin({
path: path.join(__dirname, "wwwroot", "dist", "[name]-manifest.json"),
name: "[name]_[hash]"