Add axios and state

master
Hamcha 2019-07-16 16:04:43 +02:00
parent 3508d3d8e8
commit 3d7f0bba10
13 changed files with 232 additions and 24 deletions

View File

@ -18,7 +18,8 @@
"vue-class-component": "^7.0.2",
"vue-property-decorator": "^8.1.0",
"vue-router": "^3.0.3",
"vuex": "^3.0.1"
"vuex": "^3.0.1",
"vuex-class": "^0.3.2"
},
"devDependencies": {
"@vue/cli-plugin-babel": "^3.8.0",
@ -28,10 +29,12 @@
"@vue/cli-service": "^3.8.0",
"@vue/eslint-config-prettier": "^4.0.1",
"@vue/eslint-config-typescript": "^4.0.0",
"axios": "^0.18.0",
"babel-eslint": "^10.0.1",
"eslint": "^5.16.0",
"eslint-plugin-vue": "^5.0.0",
"typescript": "^3.4.3",
"vue-cli-plugin-axios": "^0.0.4",
"vue-cli-plugin-tailwindcss": "^0.1.1",
"vue-template-compiler": "^2.6.10"
}

View File

@ -1,10 +1,12 @@
<template>
<div id="app">
<nav id="topnav">
<h1>
DIRETTO
</h1>
</nav>
<div id="navwrap">
<nav id="topnav">
<h1>
DIRETTO
</h1>
</nav>
</div>
<router-view />
</div>
</template>
@ -13,18 +15,27 @@
@import "assets/styles/theme";
#app {
display: flex;
@apply flex;
}
#navwrap {
@apply flex flex-1 flex-row px-2 justify-center;
background: var(--ink);
}
#topnav {
flex: 1;
display: flex;
flex-direction: row;
background: $ink;
@apply flex flex-auto flex-row w-full;
max-width: var(--maxwidth);
}
h1 {
font-size: 18pt;
font-weight: bolder;
@apply text-2xl font-bold;
}
</style>
<script lang="ts">
import { Component, Vue } from "vue-property-decorator";
@Component({})
export default class App extends Vue {}
</script>

View File

@ -3,6 +3,8 @@
--ink: #062f4f;
--posy: #813772;
--embers: #b82601;
--maxwidth: 960px;
}
body {

View File

@ -1,9 +1,11 @@
import Vue from "vue";
import "./plugins/axios";
import App from "./App.vue";
import router from "./router";
import store from "./store";
import store from "./store/index";
import "./registerServiceWorker";
import "@/assets/styles/main.css";
import "@/assets/styles/theme.css";
Vue.config.productionTip = false;

View File

@ -0,0 +1,61 @@
"use strict";
import Vue from "vue";
import axios from "axios";
// Full config: https://github.com/axios/axios#request-config
// axios.defaults.baseURL = process.env.baseURL || process.env.apiUrl || '';
// axios.defaults.headers.common['Authorization'] = AUTH_TOKEN;
// axios.defaults.headers.post['Content-Type'] = 'application/x-www-form-urlencoded';
let config = {
// baseURL: process.env.baseURL || process.env.apiUrl || ""
// timeout: 60 * 1000, // Timeout
// withCredentials: true, // Check cross-site Access-Control
};
const _axios = axios.create(config);
_axios.interceptors.request.use(
function(config) {
// Do something before request is sent
return config;
},
function(error) {
// Do something with request error
return Promise.reject(error);
}
);
// Add a response interceptor
_axios.interceptors.response.use(
function(response) {
// Do something with response data
return response;
},
function(error) {
// Do something with response error
return Promise.reject(error);
}
);
Plugin.install = function(Vue, options) {
Vue.axios = _axios;
window.axios = _axios;
Object.defineProperties(Vue.prototype, {
axios: {
get() {
return _axios;
}
},
$axios: {
get() {
return _axios;
}
}
});
};
Vue.use(Plugin);
export default Plugin;

View File

@ -1,10 +0,0 @@
import Vue from "vue";
import Vuex from "vuex";
Vue.use(Vuex);
export default new Vuex.Store({
state: {},
mutations: {},
actions: {}
});

View File

@ -0,0 +1,19 @@
import { ActionTree } from "vuex";
import { AppState } from "./types";
const actions: ActionTree<AppState, AppState> = {
// Add one or more sources
addSources({ commit, dispatch }, sources: EventSource[]) {
// Commit to state immediately
commit("appendSources", sources);
// Start fetching from each new source
sources.forEach(x => dispatch("fetchFromSource", x.url));
},
// Fetch events from a source url
async fetchFromSource({ commit }, url: string) {
//TODO
}
};
export default actions;

View File

@ -0,0 +1,17 @@
import { GetterTree } from "vuex";
import { AppState, Event, EventSource } from "./types";
const getters: GetterTree<AppState, AppState> = {
events(state): Event[] {
return Object.values(state.status)
.filter(x => x.fetched && x.error == null)
.map(x => x.events)
.flat();
},
sources(state): EventSource[] {
return state.sources;
}
};
export default getters;

20
src/store/index.ts 100644
View File

@ -0,0 +1,20 @@
import Vue from "vue";
import Vuex from "vuex";
import { AppState } from "./types";
import mutations from "./mutations";
import actions from "./actions";
import getters from "./getters";
Vue.use(Vuex);
const state: AppState = {
sources: [],
status: {}
};
export default new Vuex.Store<AppState>({
state,
mutations,
actions,
getters
});

View File

@ -0,0 +1,20 @@
import { MutationTree } from "vuex";
import { AppState, FetchStatus, EventSource } from "./types";
const mutations: MutationTree<AppState> = {
appendSources(state, payload: EventSource[]) {
// Add sources to list
state.sources = state.sources.concat(payload);
// Set "loading" state for all of them
payload.forEach(x => {
state.status[x.url] = { fetched: false };
});
},
setSourceStatus(state, payload: { url: string; status: FetchStatus }) {
state.status[payload.url] = payload.status;
}
};
export default mutations;

25
src/store/types.ts 100644
View File

@ -0,0 +1,25 @@
import { Dict } from "@/types";
export interface AppState {
sources: EventSource[];
status: Dict<FetchStatus>;
}
export interface EventSource {
url: string;
}
export interface Event {
source: string; // Source URL
data: EventData;
}
export interface EventData {
//TODO
}
export interface FetchStatus {
fetched: boolean;
error?: Error;
events?: Event[];
}

1
src/types.ts 100644
View File

@ -0,0 +1 @@
export type Dict<T> = { [key: string]: T };

View File

@ -1548,6 +1548,14 @@ aws4@^1.8.0:
resolved "https://registry.yarnpkg.com/aws4/-/aws4-1.8.0.tgz#f0e003d9ca9e7f59c7a508945d7b2ef9a04a542f"
integrity sha512-ReZxvNHIOv88FlT7rxcXIIC0fPt4KZqZbOlivyWtXLt8ESx84zd3kMC6iK5jVeS2qt+g7ftS7ye4fi06X5rtRQ==
axios@^0.18.0:
version "0.18.1"
resolved "https://registry.yarnpkg.com/axios/-/axios-0.18.1.tgz#ff3f0de2e7b5d180e757ad98000f1081b87bcea3"
integrity sha512-0BfJq4NSfQXd+SkFdrvFbG7addhYSBA2mQwISr46pD6E5iqkWg02RAs8vyTT/j0RTnoYmeXauBuSv1qKwR179g==
dependencies:
follow-redirects "1.5.10"
is-buffer "^2.0.2"
babel-code-frame@^6.22.0, babel-code-frame@^6.26.0:
version "6.26.0"
resolved "https://registry.yarnpkg.com/babel-code-frame/-/babel-code-frame-6.26.0.tgz#63fd43f7dc1e3bb7ce35947db8fe369a3f58c74b"
@ -2712,6 +2720,13 @@ debug@2.6.9, debug@^2.2.0, debug@^2.3.3:
dependencies:
ms "2.0.0"
debug@=3.1.0:
version "3.1.0"
resolved "https://registry.yarnpkg.com/debug/-/debug-3.1.0.tgz#5bb5a0672628b64149566ba16819e61518c67261"
integrity sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==
dependencies:
ms "2.0.0"
debug@^3.1.0, debug@^3.2.5, debug@^3.2.6:
version "3.2.6"
resolved "https://registry.yarnpkg.com/debug/-/debug-3.2.6.tgz#e83d17de16d8a7efb7717edbe5fb10135eee629b"
@ -3717,6 +3732,13 @@ flush-write-stream@^1.0.0:
inherits "^2.0.3"
readable-stream "^2.3.6"
follow-redirects@1.5.10:
version "1.5.10"
resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.5.10.tgz#7b7a9f9aea2fdff36786a94ff643ed07f4ff5e2a"
integrity sha512-0V5l4Cizzvqt5D44aTXbFZz+FtyXV1vrDN6qrelxtfYQKW0KO0W2T/hkE8xvGa/540LkZlkaUjO4ailYTFtHVQ==
dependencies:
debug "=3.1.0"
follow-redirects@^1.0.0:
version "1.7.0"
resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.7.0.tgz#489ebc198dc0e7f64167bd23b03c4c19b5784c76"
@ -4520,6 +4542,11 @@ is-buffer@^1.1.5:
resolved "https://registry.yarnpkg.com/is-buffer/-/is-buffer-1.1.6.tgz#efaa2ea9daa0d7ab2ea13a97b2b8ad51fefbe8be"
integrity sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==
is-buffer@^2.0.2:
version "2.0.3"
resolved "https://registry.yarnpkg.com/is-buffer/-/is-buffer-2.0.3.tgz#4ecf3fcf749cbd1e472689e109ac66261a25e725"
integrity sha512-U15Q7MXTuZlrbymiz95PJpZxu8IlipAp4dtS3wOdgPXx3mqBnslrWU14kxfHB+Py/+2PVKSr37dMAgM2A4uArw==
is-callable@^1.1.4:
version "1.1.4"
resolved "https://registry.yarnpkg.com/is-callable/-/is-callable-1.1.4.tgz#1e1adf219e1eeb684d691f9d6a05ff0d30a24d75"
@ -8343,6 +8370,11 @@ vue-class-component@^7.0.1, vue-class-component@^7.0.2:
resolved "https://registry.yarnpkg.com/vue-class-component/-/vue-class-component-7.1.0.tgz#b33efcb10e17236d684f70b1e96f1946ec793e87"
integrity sha512-G9152NzUkz0i0xTfhk0Afc8vzdXxDR1pfN4dTwE72cskkgJtdXfrKBkMfGvDuxUh35U500g5Ve4xL8PEGdWeHg==
vue-cli-plugin-axios@^0.0.4:
version "0.0.4"
resolved "https://registry.yarnpkg.com/vue-cli-plugin-axios/-/vue-cli-plugin-axios-0.0.4.tgz#29d4eb48275c7fe15b92e1fd5d95fbe2a966436f"
integrity sha512-p2b/fvPJuPBnvU8027PAAuU5DiOzUn2lku8XLG/f6c8FU0N+/MXWZAlOuHhqd9e7+KIZitwe/c8qlmv7TglbTg==
vue-cli-plugin-tailwindcss@^0.1.1:
version "0.1.1"
resolved "https://registry.yarnpkg.com/vue-cli-plugin-tailwindcss/-/vue-cli-plugin-tailwindcss-0.1.1.tgz#e961e6f70a621fdbbf7b86b72cf065e7631d4c93"
@ -8427,6 +8459,11 @@ vue@^2.6.10:
resolved "https://registry.yarnpkg.com/vue/-/vue-2.6.10.tgz#a72b1a42a4d82a721ea438d1b6bf55e66195c637"
integrity sha512-ImThpeNU9HbdZL3utgMCq0oiMzAkt1mcgy3/E6zWC/G6AaQoeuFdsl9nDhTDU3X1R6FK7nsIUuRACVcjI+A2GQ==
vuex-class@^0.3.2:
version "0.3.2"
resolved "https://registry.yarnpkg.com/vuex-class/-/vuex-class-0.3.2.tgz#c7e96a076c1682137d4d23a8dcfdc63f220e17a8"
integrity sha512-m0w7/FMsNcwJgunJeM+wcNaHzK2KX1K1rw2WUQf7Q16ndXHo7pflRyOV/E8795JO/7fstyjH3EgqBI4h4n4qXQ==
vuex@^3.0.1:
version "3.1.1"
resolved "https://registry.yarnpkg.com/vuex/-/vuex-3.1.1.tgz#0c264bfe30cdbccf96ab9db3177d211828a5910e"