From d9c98bfc78fe5243b49f28bffb8d280021dfbfe7 Mon Sep 17 00:00:00 2001 From: Libor Date: Tue, 24 Sep 2019 07:31:50 +0200 Subject: [PATCH 01/77] Project migrated to ASP.NET Core 3.0 Target framework change to netcoreapp3.0, Microsoft.AspNetCore.SpaServices.Extensions updated to 3.0.0, VueCliMiddleware updated to 3.0.0-preview7-1. VueCliMiddleware middleware is not 100% stable, waiting for some tests and production ready release to issue a PR. --- AspNetCoreVueStarter.csproj | 7 ++-- ClientApp/package-lock.json | 5 +++ ClientApp/package.json | 1 + ClientApp/src/filters/date.filter.ts | 5 +++ ClientApp/src/main.ts | 3 ++ ClientApp/src/models/Forecast.ts | 2 +- ClientApp/src/views/FetchData.vue | 41 ++++++++++--------- Controllers/SampleDataController.cs | 45 --------------------- Controllers/WeatherForecastController.cs | 40 +++++++++++++++++++ Models/WeatherForecast.cs | 18 +++++++++ Startup.cs | 50 +++++++++++++++--------- 11 files changed, 129 insertions(+), 88 deletions(-) create mode 100644 ClientApp/src/filters/date.filter.ts delete mode 100644 Controllers/SampleDataController.cs create mode 100644 Controllers/WeatherForecastController.cs create mode 100644 Models/WeatherForecast.cs diff --git a/AspNetCoreVueStarter.csproj b/AspNetCoreVueStarter.csproj index 596ffa7..8b01996 100644 --- a/AspNetCoreVueStarter.csproj +++ b/AspNetCoreVueStarter.csproj @@ -1,7 +1,7 @@  - netcoreapp2.2 + netcoreapp3.0 true Latest false @@ -19,9 +19,8 @@ - - - + + diff --git a/ClientApp/package-lock.json b/ClientApp/package-lock.json index 8252d2e..2ba38e4 100644 --- a/ClientApp/package-lock.json +++ b/ClientApp/package-lock.json @@ -3584,6 +3584,11 @@ "assert-plus": "^1.0.0" } }, + "date-fns": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/date-fns/-/date-fns-2.2.1.tgz", + "integrity": "sha512-4V1i5CnTinjBvJpXTq7sDHD4NY6JPcl15112IeSNNLUWQOQ+kIuCvRGOFZMQZNvkadw8F9QTyZxz59rIRU6K+w==" + }, "date-now": { "version": "0.1.4", "resolved": "https://registry.npmjs.org/date-now/-/date-now-0.1.4.tgz", diff --git a/ClientApp/package.json b/ClientApp/package.json index c8f2577..2fb7164 100644 --- a/ClientApp/package.json +++ b/ClientApp/package.json @@ -8,6 +8,7 @@ "lint": "vue-cli-service lint" }, "dependencies": { + "date-fns": "^2.2.1", "register-service-worker": "^1.6.2", "vue": "^2.6.10", "vue-class-component": "^7.1.0", diff --git a/ClientApp/src/filters/date.filter.ts b/ClientApp/src/filters/date.filter.ts new file mode 100644 index 0000000..07d3627 --- /dev/null +++ b/ClientApp/src/filters/date.filter.ts @@ -0,0 +1,5 @@ +import { format } from 'date-fns'; + +export default (date: Date) => { + return format(new Date(date), 'eeee, dd MMMM'); +}; diff --git a/ClientApp/src/main.ts b/ClientApp/src/main.ts index 8edb1ab..e409b51 100644 --- a/ClientApp/src/main.ts +++ b/ClientApp/src/main.ts @@ -6,9 +6,12 @@ import App from './App.vue'; import router from './router'; import store from '@/store/index'; import './registerServiceWorker'; +import dateFilter from '@/filters/date.filter'; Vue.config.productionTip = false; +Vue.filter('date', dateFilter); + new Vue({ vuetify, router, diff --git a/ClientApp/src/models/Forecast.ts b/ClientApp/src/models/Forecast.ts index 0a5cb56..af64f02 100644 --- a/ClientApp/src/models/Forecast.ts +++ b/ClientApp/src/models/Forecast.ts @@ -1,6 +1,6 @@ export class Forecast { constructor( - public dateFormatted: Date, + public date: Date, public temperatureC: number, public temperatureF: number, public summary: string, diff --git a/ClientApp/src/views/FetchData.vue b/ClientApp/src/views/FetchData.vue index 82e7127..f775d6d 100644 --- a/ClientApp/src/views/FetchData.vue +++ b/ClientApp/src/views/FetchData.vue @@ -14,11 +14,11 @@ class="elevation-1" > - diff --git a/ClientApp/src/components/Counter.vue b/ClientApp/src/components/Counter.vue index cb85812..0b9f36b 100644 --- a/ClientApp/src/components/Counter.vue +++ b/ClientApp/src/components/Counter.vue @@ -9,24 +9,27 @@ diff --git a/ClientApp/src/components/HelloWorld.vue b/ClientApp/src/components/HelloWorld.vue index 7632fca..6a09aec 100644 --- a/ClientApp/src/components/HelloWorld.vue +++ b/ClientApp/src/components/HelloWorld.vue @@ -7,7 +7,7 @@ —{{ author }} - + @@ -16,9 +16,9 @@ export default { name: 'HelloWorld', props: { quote: String, - author: String, - }, -}; + author: String + } +} diff --git a/ClientApp/src/filters/date.filter.ts b/ClientApp/src/filters/date.filter.ts index 07d3627..f1f5d82 100644 --- a/ClientApp/src/filters/date.filter.ts +++ b/ClientApp/src/filters/date.filter.ts @@ -1,5 +1,5 @@ -import { format } from 'date-fns'; +import { format } from 'date-fns' export default (date: Date) => { - return format(new Date(date), 'eeee, dd MMMM'); -}; + return format(new Date(date), 'eeee, dd MMMM') +} diff --git a/ClientApp/src/main.ts b/ClientApp/src/main.ts index 16cb91d..5ac03fa 100644 --- a/ClientApp/src/main.ts +++ b/ClientApp/src/main.ts @@ -1,21 +1,19 @@ -import 'core-js/stable'; -import 'regenerator-runtime/runtime'; -import Vue from 'vue'; -import './plugins/axios'; -import vuetify from './plugins/vuetify'; -import App from './App.vue'; -import router from './router'; -import store from '@/store/index'; -import './registerServiceWorker'; -import dateFilter from '@/filters/date.filter'; +import Vue from 'vue' +import './plugins/axios' +import vuetify from './plugins/vuetify' +import App from './App.vue' +import router from './router' +import store from '@/store/index' +import './registerServiceWorker' +import dateFilter from '@/filters/date.filter' -Vue.config.productionTip = false; +Vue.config.productionTip = false -Vue.filter('date', dateFilter); +Vue.filter('date', dateFilter) new Vue({ vuetify, router, store, - render: (h) => h(App), -}).$mount('#app'); + render: (h) => h(App) +}).$mount('#app') diff --git a/ClientApp/src/models/Forecast.ts b/ClientApp/src/models/Forecast.ts index af64f02..02c94b5 100644 --- a/ClientApp/src/models/Forecast.ts +++ b/ClientApp/src/models/Forecast.ts @@ -1,8 +1,6 @@ export class Forecast { - constructor( - public date: Date, - public temperatureC: number, - public temperatureF: number, - public summary: string, - ) {} + public date?: Date + public temperatureC?: number + public temperatureF?: number + public summary?: string } diff --git a/ClientApp/src/plugins/axios.ts b/ClientApp/src/plugins/axios.ts index f1d6b72..2fed3a1 100644 --- a/ClientApp/src/plugins/axios.ts +++ b/ClientApp/src/plugins/axios.ts @@ -1,7 +1,7 @@ -'use strict'; +'use strict' -import Vue from 'vue'; -import axios, { AxiosInstance, AxiosRequestConfig } from 'axios'; +import Vue from 'vue' +import axios, { AxiosInstance, AxiosRequestConfig } from 'axios' // Full config: https://github.com/axios/axios#request-config // axios.defaults.baseURL = process.env.baseURL || process.env.apiUrl || ''; @@ -12,28 +12,29 @@ const config = { // baseURL: process.env.baseURL || process.env.apiUrl || "" // timeout: 60 * 1000, // Timeout // withCredentials: true, // Check cross-site Access-Control -}; +} // tslint:disable-next-line: variable-name -const _axios = axios.create(config); +const _axios = axios.create(config) _axios.interceptors.request.use( // Do something before request is sent (conf: AxiosRequestConfig) => conf, // Do something with request error - (error: any) => Promise.reject(error), -); + // eslint-disable-next-line @typescript-eslint/no-explicit-any + (error: any) => Promise.reject(error) +) // Add a response interceptor _axios.interceptors.response.use( // Do something with response data - (response: any) => response, + (response) => response, // Do something with response error - (error: any) => Promise.reject(error), -); + (error) => Promise.reject(error) +) -function AxiosPlugin(vue: typeof Vue, options?: any): void { - vue.prototype.$axios = _axios; +function AxiosPlugin (vue: typeof Vue): void { + vue.prototype.$axios = _axios } declare module 'vue/types/vue' { @@ -42,6 +43,6 @@ declare module 'vue/types/vue' { } } -Vue.use(AxiosPlugin); +Vue.use(AxiosPlugin) -export default AxiosPlugin; +export default AxiosPlugin diff --git a/ClientApp/src/plugins/vuetify.ts b/ClientApp/src/plugins/vuetify.ts index c71ee65..86b767c 100644 --- a/ClientApp/src/plugins/vuetify.ts +++ b/ClientApp/src/plugins/vuetify.ts @@ -1,5 +1,5 @@ -import '@mdi/font/css/materialdesignicons.css'; -import Vue from 'vue'; +import '@mdi/font/css/materialdesignicons.css' +import Vue from 'vue' import Vuetify, { VAlert, VApp, @@ -10,8 +10,8 @@ import Vuetify, { VIcon, VToolbar, VDataTable, - VProgressLinear, -} from 'vuetify/lib'; + VProgressLinear +} from 'vuetify/lib' // vue-cli a-la-carte installation Vue.use(Vuetify, { @@ -25,9 +25,9 @@ Vue.use(Vuetify, { VIcon, VToolbar, VDataTable, - VProgressLinear, - }, -}); + VProgressLinear + } +}) const opts = { theme: { @@ -38,12 +38,12 @@ const opts = { accent: '#82B1FF', error: '#FF5252', info: '#2196F3', - success: '#4CAF50', - }, + success: '#4CAF50' + } // dark: { // } - }, - }, -}; + } + } +} -export default new Vuetify(opts); +export default new Vuetify(opts) diff --git a/ClientApp/src/registerServiceWorker.ts b/ClientApp/src/registerServiceWorker.ts index d3db583..9991891 100644 --- a/ClientApp/src/registerServiceWorker.ts +++ b/ClientApp/src/registerServiceWorker.ts @@ -1,26 +1,34 @@ -/* tslint:disable:no-console */ +/* eslint-disable no-console */ -import { register } from 'register-service-worker'; +import { register } from 'register-service-worker' if (process.env.NODE_ENV === 'production') { register(`${process.env.BASE_URL}service-worker.js`, { - ready() { + ready () { console.log( 'App is being served from cache by a service worker.\n' + - 'For more details, visit https://goo.gl/AFskqB', - ); + 'For more details, visit https://goo.gl/AFskqB' + ) }, - cached() { - console.log('Content has been cached for offline use.'); + registered () { + console.log('Service worker has been registered.') }, - updated() { - console.log('New content is available; please refresh.'); + cached () { + console.log('Content has been cached for offline use.') }, - offline() { - console.log('No internet connection found. App is running in offline mode.'); + updatefound () { + console.log('New content is downloading.') }, - error(error) { - console.error('Error during service worker registration:', error); + updated () { + console.log('New content is available; please refresh.') }, - }); + offline () { + console.log( + 'No internet connection found. App is running in offline mode.' + ) + }, + error (error) { + console.error('Error during service worker registration:', error) + } + }) } diff --git a/ClientApp/src/router.ts b/ClientApp/src/router.ts deleted file mode 100644 index 65b00d6..0000000 --- a/ClientApp/src/router.ts +++ /dev/null @@ -1,30 +0,0 @@ -import Vue from 'vue'; -import Router from 'vue-router'; -import Home from './views/Home.vue'; - -Vue.use(Router); - -export default new Router({ - mode: 'history', - base: process.env.BASE_URL, - routes: [ - { - path: '/', - name: 'home', - component: Home, - }, - { - path: '/counter', - name: 'counter', - // route level code-splitting - // this generates a separate chunk (about.[hash].js) for this route - // which is lazy-loaded when the route is visited. - component: () => import(/* webpackChunkName: "counter" */ './views/Counter.vue'), - }, - { - path: '/fetch-data', - name: 'fetch-data', - component: () => import(/* webpackChunkName: "fetch-data" */ './views/FetchData.vue'), - }, - ], -}); diff --git a/ClientApp/src/router/index.ts b/ClientApp/src/router/index.ts new file mode 100644 index 0000000..81d73b8 --- /dev/null +++ b/ClientApp/src/router/index.ts @@ -0,0 +1,33 @@ +import Vue from 'vue' +import VueRouter, { RouteConfig } from 'vue-router' +import Home from '../views/Home.vue' + +Vue.use(VueRouter) + +const routes: Array = [ + { + path: '/', + name: 'Home', + component: Home + }, + { + path: '/counter', + name: 'counter', + // route level code-splitting + // this generates a separate chunk (about.[hash].js) for this route + // which is lazy-loaded when the route is visited. + component: () => import(/* webpackChunkName: "counter" */ '../views/Counter.vue') + }, + { + path: '/fetch-data', + name: 'fetch-data', + component: () => import(/* webpackChunkName: "fetch-data" */ '../views/FetchData.vue') + } +] + +const router = new VueRouter({ + mode: 'history', + routes +}) + +export default router diff --git a/ClientApp/src/shims-tsx.d.ts b/ClientApp/src/shims-tsx.d.ts index 3b88b58..7ecd6a9 100644 --- a/ClientApp/src/shims-tsx.d.ts +++ b/ClientApp/src/shims-tsx.d.ts @@ -1,13 +1,13 @@ -import Vue, { VNode } from 'vue'; +import Vue, { VNode } from 'vue' declare global { - namespace JSX { - // tslint:disable no-empty-interface - interface Element extends VNode {} - // tslint:disable no-empty-interface - interface ElementClass extends Vue {} - interface IntrinsicElements { - [elem: string]: any; + namespace JSX { + // tslint:disable no-empty-interface + interface Element extends VNode {} + // tslint:disable no-empty-interface + interface ElementClass extends Vue {} + interface IntrinsicElements { + [elem: string]: any; + } } - } } diff --git a/ClientApp/src/shims-vue.d.ts b/ClientApp/src/shims-vue.d.ts index 8f6f410..b93ce22 100644 --- a/ClientApp/src/shims-vue.d.ts +++ b/ClientApp/src/shims-vue.d.ts @@ -1,4 +1,4 @@ declare module '*.vue' { - import Vue from 'vue'; - export default Vue; + import Vue from 'vue' + export default Vue } diff --git a/ClientApp/src/shims-vuetify.d.ts b/ClientApp/src/shims-vuetify.d.ts new file mode 100644 index 0000000..b88f945 --- /dev/null +++ b/ClientApp/src/shims-vuetify.d.ts @@ -0,0 +1,4 @@ +declare module 'vuetify/lib/framework' { + import Vuetify from 'vuetify' + export default Vuetify +} diff --git a/ClientApp/src/store/counter/actions.ts b/ClientApp/src/store/counter/actions.ts index 9b3b7d3..b0b8ace 100644 --- a/ClientApp/src/store/counter/actions.ts +++ b/ClientApp/src/store/counter/actions.ts @@ -1,13 +1,12 @@ -import { ActionTree } from 'vuex'; -import axios from 'axios'; -import { CounterState } from './types'; -import { RootState } from '../types'; +import { ActionTree } from 'vuex' +import { CounterState } from './types' +import { RootState } from '../types' export const actions: ActionTree = { - increment({ commit }): any { - commit('incrementCounter'); + increment ({ commit }) { + commit('incrementCounter') }, - reset({ commit }): any { - commit('resetCounter'); - }, -}; + reset ({ commit }) { + commit('resetCounter') + } +} diff --git a/ClientApp/src/store/counter/getters.ts b/ClientApp/src/store/counter/getters.ts index 0d44b58..f4b641b 100644 --- a/ClientApp/src/store/counter/getters.ts +++ b/ClientApp/src/store/counter/getters.ts @@ -1,9 +1,9 @@ -import { GetterTree } from 'vuex'; -import { CounterState } from './types'; -import { RootState } from '../types'; +import { GetterTree } from 'vuex' +import { CounterState } from './types' +import { RootState } from '../types' export const getters: GetterTree = { - currentCount(state): number { - return state.counter; - }, -}; + currentCount (state): number { + return state.counter + } +} diff --git a/ClientApp/src/store/counter/index.ts b/ClientApp/src/store/counter/index.ts index abc95d8..32baccc 100644 --- a/ClientApp/src/store/counter/index.ts +++ b/ClientApp/src/store/counter/index.ts @@ -1,20 +1,20 @@ -import { Module } from 'vuex'; -import { getters } from './getters'; -import { actions } from './actions'; -import { mutations } from './mutations'; -import { CounterState } from './types'; -import { RootState } from '../types'; +import { Module } from 'vuex' +import { getters } from './getters' +import { actions } from './actions' +import { mutations } from './mutations' +import { CounterState } from './types' +import { RootState } from '../types' export const state: CounterState = { - counter: 0, -}; + counter: 0 +} -const namespaced: boolean = true; +const namespaced = true export const counter: Module = { namespaced, state, getters, actions, - mutations, -}; + mutations +} diff --git a/ClientApp/src/store/counter/mutations.ts b/ClientApp/src/store/counter/mutations.ts index b7ed08f..f78ff40 100644 --- a/ClientApp/src/store/counter/mutations.ts +++ b/ClientApp/src/store/counter/mutations.ts @@ -1,11 +1,11 @@ -import { MutationTree } from 'vuex'; -import { CounterState } from './types'; +import { MutationTree } from 'vuex' +import { CounterState } from './types' export const mutations: MutationTree = { - incrementCounter(state) { - state.counter++; + incrementCounter (state) { + state.counter++ }, - resetCounter(state) { - state.counter = 0; - }, -}; + resetCounter (state) { + state.counter = 0 + } +} diff --git a/ClientApp/src/store/index.ts b/ClientApp/src/store/index.ts index fb4eae2..830fecd 100644 --- a/ClientApp/src/store/index.ts +++ b/ClientApp/src/store/index.ts @@ -1,19 +1,19 @@ -import Vue from 'vue'; -import Vuex, { StoreOptions } from 'vuex'; -import { RootState } from './types'; -import { counter } from './counter/index'; +import Vue from 'vue' +import Vuex, { StoreOptions } from 'vuex' +import { RootState } from './types' +import { counter } from './counter/index' -Vue.use(Vuex); +Vue.use(Vuex) // Vuex structure based on https://codeburst.io/vuex-and-typescript-3427ba78cfa8 const store: StoreOptions = { state: { - version: '1.0.0', // a simple property + version: '1.0.0' // a simple property }, modules: { - counter, - }, -}; + counter + } +} -export default new Vuex.Store(store); +export default new Vuex.Store(store) diff --git a/ClientApp/src/views/Counter.vue b/ClientApp/src/views/Counter.vue index 4909b25..e77b229 100644 --- a/ClientApp/src/views/Counter.vue +++ b/ClientApp/src/views/Counter.vue @@ -4,22 +4,20 @@

Counter

-

This is a simple example of a Vue.js component integrated with Vuex

+

This is a simple example of a Vue.js component test integrated with Vuex

-
+
- - diff --git a/ClientApp/src/views/FetchData-decorator.vue b/ClientApp/src/views/FetchData-decorator.vue index eed3753..a7926b5 100644 --- a/ClientApp/src/views/FetchData-decorator.vue +++ b/ClientApp/src/views/FetchData-decorator.vue @@ -13,11 +13,13 @@ :loading="loading" class="elevation-1" > - -