From 068cdbc09d8b255b762207e5e73a0dab0fa3d6c9 Mon Sep 17 00:00:00 2001 From: Pierre Dittgen Date: Mon, 18 Jan 2021 10:44:02 +0100 Subject: [PATCH 01/33] Add requirements --- package-lock.json | 49 +++++++++++++++++++++++++++++++++++++++++++++++ package.json | 7 ++++++- 2 files changed, 55 insertions(+), 1 deletion(-) diff --git a/package-lock.json b/package-lock.json index 2d57e65..b53d981 100644 --- a/package-lock.json +++ b/package-lock.json @@ -3037,6 +3037,21 @@ "integrity": "sha512-Uvq6hVe90D0B2WEnUqtdgY1bATGz3mw33nH9Y+dmA+w5DHvUmBgkr5rM/KCHpCsiFNRUfokW/szpPPgMK2hm4A==", "dev": true }, + "axios": { + "version": "0.21.1", + "resolved": "https://registry.npmjs.org/axios/-/axios-0.21.1.tgz", + "integrity": "sha512-dKQiRHxGD9PPRIUNIWvZhPTPpl1rf/OxTYKsqKUDjBwYylTvV7SjSHJb9ratfyzM6wCdLCOYLzs73qpg5c4iGA==", + "requires": { + "follow-redirects": "^1.10.0" + }, + "dependencies": { + "follow-redirects": { + "version": "1.13.1", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.13.1.tgz", + "integrity": "sha512-SSG5xmZh1mkPGyKzjZP8zLjltIfpW32Y5QpdNJyjcfGxK3qo3NDDkZOZSFiGn1A6SclQxY9GzEwAHQ3dmYRWpg==" + } + } + }, "babel-code-frame": { "version": "6.26.0", "resolved": "https://registry.npmjs.org/babel-code-frame/-/babel-code-frame-6.26.0.tgz", @@ -4458,6 +4473,11 @@ "randomfill": "^1.0.3" } }, + "crypto-js": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/crypto-js/-/crypto-js-3.3.0.tgz", + "integrity": "sha512-DIT51nX0dCfKltpRiXV+/TVZq+Qq2NgF4644+K7Ttnla7zEzqc+kjJyiB96BHNyUTBxyjzRcZYpUdZa+QAqi6Q==" + }, "css-color-names": { "version": "0.0.4", "resolved": "https://registry.npmjs.org/css-color-names/-/css-color-names-0.0.4.tgz", @@ -9500,6 +9520,15 @@ "pinkie": "^2.0.0" } }, + "pkce": { + "version": "1.0.0-beta2", + "resolved": "https://registry.npmjs.org/pkce/-/pkce-1.0.0-beta2.tgz", + "integrity": "sha512-wTUwJYyhg1FjUuz9RjdmjorjeOB19Ch2GNIyLfWe5X7Ci4dbHU8ufhI3igZdG9mp43WqrePcIAEGXREuXpzcnA==", + "requires": { + "crypto-js": "^3.1.9-1", + "secure-random": "^1.1.2" + } + }, "pkg-dir": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-3.0.0.tgz", @@ -10814,6 +10843,11 @@ "ajv-keywords": "^3.1.0" } }, + "secure-random": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/secure-random/-/secure-random-1.1.2.tgz", + "integrity": "sha512-H2bdSKERKdBV1SwoqYm6C0y+9EA94v6SUBOWO8kDndc4NoUih7Dv6Tsgma7zO1lv27wIvjlD0ZpMQk7um5dheQ==" + }, "select-hose": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/select-hose/-/select-hose-2.0.0.tgz", @@ -12317,6 +12351,16 @@ "resolved": "https://registry.npmjs.org/vue/-/vue-2.6.10.tgz", "integrity": "sha512-ImThpeNU9HbdZL3utgMCq0oiMzAkt1mcgy3/E6zWC/G6AaQoeuFdsl9nDhTDU3X1R6FK7nsIUuRACVcjI+A2GQ==" }, + "vue-axios": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/vue-axios/-/vue-axios-3.2.2.tgz", + "integrity": "sha512-kRhbZOOp9p+iEB46mtC7tfwYlvmycLUsdNUjC+24So6PkhK9VathdEP0d5OcR2QDb/Z+JNTs4i8DzJEGbx9zOg==" + }, + "vue-client-only": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/vue-client-only/-/vue-client-only-2.0.0.tgz", + "integrity": "sha512-arhk1wtWAfLsJyxGMoEYhoBowM87/i6HLSG2LH/03Yog6i2d9JEN1peMP0Ceis+/n9DxdenGYZZTxbPPJyHciA==" + }, "vue-eslint-parser": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/vue-eslint-parser/-/vue-eslint-parser-2.0.3.tgz", @@ -12435,6 +12479,11 @@ "integrity": "sha512-4gDntzrifFnCEvyoO8PqyJDmguXgVPxKiIxrBKjIowvL9l+N66196+72XVYR8BBf1Uv1Fgt3bGevJ+sEmxfZzw==", "dev": true }, + "vuex": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/vuex/-/vuex-3.6.0.tgz", + "integrity": "sha512-W74OO2vCJPs9/YjNjW8lLbj+jzT24waTo2KShI8jLvJW8OaIkgb3wuAMA7D+ZiUxDOx3ubwSZTaJBip9G8a3aQ==" + }, "watchpack": { "version": "1.6.0", "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-1.6.0.tgz", diff --git a/package.json b/package.json index 1761249..ee452ad 100644 --- a/package.json +++ b/package.json @@ -11,12 +11,17 @@ "now-build": "vue-cli-service build" }, "dependencies": { + "axios": "^0.21.1", "babel-runtime": "^6.26.0", "bootstrap-vue": "^2.0.0-rc.15", + "pkce": "^1.0.0-beta2", "vue": "^2.6.6", + "vue-axios": "^3.2.2", + "vue-client-only": "^2.0.0", "vue-loading-overlay": "^3.2.0", "vue-markdown": "^2.2.4", - "vue-router": "^3.0.1" + "vue-router": "^3.0.1", + "vuex": "^3.6.0" }, "devDependencies": { "@vue/cli-plugin-babel": "^3.12.0", From 831163f96188bfe058411ad92f4aaa6b6fb956e0 Mon Sep 17 00:00:00 2001 From: Pierre Dittgen Date: Mon, 18 Jan 2021 10:45:55 +0100 Subject: [PATCH 02/33] Add code and component from playlists app --- src/components/NavUser.vue | 53 +++++++++++++++++++++++ src/services/Api.js | 58 ++++++++++++++++++++++++++ src/services/Auth.js | 81 ++++++++++++++++++++++++++++++++++++ src/store/index.js | 24 +++++++++++ src/store/modules/auth.js | 57 +++++++++++++++++++++++++ src/store/modules/folders.js | 58 ++++++++++++++++++++++++++ 6 files changed, 331 insertions(+) create mode 100644 src/components/NavUser.vue create mode 100644 src/services/Api.js create mode 100644 src/services/Auth.js create mode 100644 src/store/index.js create mode 100644 src/store/modules/auth.js create mode 100644 src/store/modules/folders.js diff --git a/src/components/NavUser.vue b/src/components/NavUser.vue new file mode 100644 index 0000000..4f6478c --- /dev/null +++ b/src/components/NavUser.vue @@ -0,0 +1,53 @@ + + + diff --git a/src/services/Api.js b/src/services/Api.js new file mode 100644 index 0000000..c85d552 --- /dev/null +++ b/src/services/Api.js @@ -0,0 +1,58 @@ +import axios from 'axios' +import store from '../store' + +const instance = axios.create() + +instance.interceptors.request.use(config => { + const token = store.state.auth.user.token + if (token) { + const headers = { + Authorization: `Bearer ${token}` + } + + config.headers = headers + + return config + } else { + return config + } +}, error => { + return Promise.reject(error) +}) + +instance.interceptors.response.use(response => { + return response +}) + +function defaultErrorCallback (res) { + console.error('API error', res) +} + +export default class Api { + constructor () { + this.API_BASE_URL = process.env.GRIDSOME_BASE_URL + this.UPLOADER_BASE_URL = 'http://localhost:3000/api' + } + + get (path, params, errorCallback) { + params = params || {} + errorCallback = errorCallback || defaultErrorCallback + + return instance.get(`${this.API_BASE_URL}/api/1/${path}/`, { params }).catch(errorCallback) + } + + post (path, data, errorCallback) { + errorCallback = errorCallback || defaultErrorCallback + return instance.post(`${this.API_BASE_URL}/api/1/${path}/`, data).catch(errorCallback) + } + + put (path, data, errorCallback) { + errorCallback = errorCallback || defaultErrorCallback + return instance.put(`${this.API_BASE_URL}/api/1/${path}/`, data).catch(errorCallback) + } + + delete (path, data, errorCallback) { + errorCallback = errorCallback || defaultErrorCallback + return instance.delete(`${this.API_BASE_URL}/api/1/${path}/`, data).catch(errorCallback) + } +} diff --git a/src/services/Auth.js b/src/services/Auth.js new file mode 100644 index 0000000..6e9c0bd --- /dev/null +++ b/src/services/Auth.js @@ -0,0 +1,81 @@ +import { create } from 'pkce' +import axios from 'axios' + +export default class Auth { + constructor() { + this.BASE_URL = process.env.VUE_APP_OAUTH_BASE_URL + this.redirectURI = process.env.VUE_APP_OAUTH_CALLBACK // @oauth_callback + this.clientId = process.env.VUE_APP_OAUTH_CLIENT_ID + this.clientSecret = process.env.VUE_APP_OAUTH_CLIENT_SECRET + } + + generateRandomString () { + let array = new Uint32Array(28); + window.crypto.getRandomValues(array); + return Array.from(array, dec => ('0' + dec.toString(16)).substr(-2)).join('') + } + + createBasicAuthHeader() { + const headerStr = btoa(`${this.clientId}:${this.clientSecret}`) + return { Authorization: `Basic ${headerStr}` } + } + + authUrl () { + const pkcePair = create() + const codeVerifier = pkcePair.codeVerifier + const codeChallenge = pkcePair.codeChallenge + localStorage.setItem("pkceCodeVerifier", codeVerifier) + + const state = this.generateRandomString() + localStorage.setItem("pkceState", state); + + const redirectURI = encodeURIComponent(this.redirectURI) + const encodedState = encodeURIComponent(state) + const encodedCC = encodeURIComponent(codeChallenge) + + return `${this.BASE_URL}/oauth/authorize?redirect_uri=${redirectURI}&response_type=code&state=${encodedState}&client_id=${this.clientId}&scope=default&code_challenge=${encodedCC}&code_challenge_method=S256` + } + + async retrieveToken(queryObject) { + if (localStorage.getItem("pkceState") !== queryObject.state) { + throw 'States are not matching' + } + let bodyFormData = new FormData(); + bodyFormData.append('grant_type', 'authorization_code') + bodyFormData.append('code', queryObject.code) + bodyFormData.append('redirect_uri', this.redirectURI) + bodyFormData.append('client_id', this.clientId) + bodyFormData.append('client_secret', this.clientSecret) + bodyFormData.append('code_verifier', localStorage.getItem('pkceCodeVerifier')) + try { + const response = await axios({ + method: 'post', + url: `${this.BASE_URL}/oauth/token`, + data: bodyFormData + }) + return response.data.access_token + } catch (e) { + throw e + } + } + + async proceedLogout(token) { + let bodyFormData = new FormData(); + bodyFormData.append('token', token) + try { + const response = await axios({ + method: 'post', + url: `${this.BASE_URL}/oauth/revoke`, + data: bodyFormData, + headers: this.createBasicAuthHeader() + }) + return response + } catch (e) { + // eslint-disable-next-line + console.log(e) + } finally { + localStorage.removeItem('pkceState'); + localStorage.removeItem('pkceCodeVerifier'); + } + } +} diff --git a/src/store/index.js b/src/store/index.js new file mode 100644 index 0000000..be45b4f --- /dev/null +++ b/src/store/index.js @@ -0,0 +1,24 @@ +import Vue from 'vue' +import Vuex from 'vuex' + +import auth from '@/store/modules/auth' +import folders from '@/store/modules/folders' + +Vue.use(Vuex) + +export default new Vuex.Store({ + strict: true, + modules: { + auth, + folders + }, + mutations: { + initialiseStore (state) { + if (localStorage.getItem('store')) { + this.replaceState( + Object.assign(state, JSON.parse(localStorage.getItem('store'))) + ) + } + } + } +}) diff --git a/src/store/modules/auth.js b/src/store/modules/auth.js new file mode 100644 index 0000000..ed773cc --- /dev/null +++ b/src/store/modules/auth.js @@ -0,0 +1,57 @@ +import Api from '@/services/Api.js' + +const $api = new Api() + +const module = { + namespaced: true, + state () { + return { + user: { + loggedIn: false, + token: '', + data: {} + } + } + } +} + +const mutations = { + setLoggedIn (state) { + state.user.loggedIn = true + }, + unsetLoggedIn (state) { + state.user.loggedIn = false + }, + setToken (state, token) { + state.user.token = token + }, + setUserData (state, data) { + state.user.data = data + } +} + +const actions = { + login ({ commit }, token) { + commit('setLoggedIn') + commit('setToken', token) + }, + fillUserData ({ commit }, data) { + commit('setUserData', data) + }, + // checkToken ({ commit, dispatch }) { + //$api.get('me', {}, (error) => { + // console.log(error) + checkToken ({ dispatch }) { + $api.get('me', {}, () => { + dispatch('logout') + }) + }, + logout ({ commit }) { + commit('unsetLoggedIn') + commit('setToken', '') + commit('setUserData', {}) + commit('folders/setFolders', [], { root: true }) + } +} + +export default { ...module, mutations, actions } diff --git a/src/store/modules/folders.js b/src/store/modules/folders.js new file mode 100644 index 0000000..f338b48 --- /dev/null +++ b/src/store/modules/folders.js @@ -0,0 +1,58 @@ +import Api from '@/services/Api.js' + +const $api = new Api() + +const module = { + namespaced: true, + state () { + return { + cache: [] + } + }, + getters: { + cache: state => state.cache + }, + mutations: { + setFolders (state, data) { + state.cache = data + } + }, + actions: { + createExample () { + const info = { + title: 'Mes playlists', + description: 'mes belles playlists', + private: true, + extras: { + playlist: true + } + } + + $api.post('datasets', info) + }, + async fetchMe ({ dispatch, commit }) { + const folders = [] + + try { + const res = await $api.get('me/datasets') + + for (const k in res.data) { + const dataset = res.data[k] + if ('playlist' in dataset.extras && !dataset.deleted) { + folders.push(dataset) + } + } + + if (folders.length === 0) { + dispatch('createExample') + } + } catch (e) { + // console.log(e) + } + + commit('setFolders', folders) + } + } +} + +export default module From 34af842494b25ae8471ce67880a22e01086e6c6d Mon Sep 17 00:00:00 2001 From: Pierre Dittgen Date: Mon, 18 Jan 2021 10:48:13 +0100 Subject: [PATCH 03/33] App header toolbar --- src/App.vue | 73 ++++++++++++++++++++++++++++++++++++++++++----------- 1 file changed, 58 insertions(+), 15 deletions(-) diff --git a/src/App.vue b/src/App.vue index 512dd43..6bb3a48 100644 --- a/src/App.vue +++ b/src/App.vue @@ -1,19 +1,62 @@ - + + From 1e03f338f0f38aafb3adcf907f0707dc38a205fc Mon Sep 17 00:00:00 2001 From: Pierre Dittgen Date: Mon, 18 Jan 2021 10:49:04 +0100 Subject: [PATCH 04/33] Integrate Vuex, VueAxios, store to app --- src/main.js | 22 +++++++++++++++++++++- 1 file changed, 21 insertions(+), 1 deletion(-) diff --git a/src/main.js b/src/main.js index 197ba18..793c8a4 100644 --- a/src/main.js +++ b/src/main.js @@ -1,4 +1,6 @@ + import Vue from 'vue' +import Vuex from 'vuex' import App from './App.vue' import router from './router' import BootstrapVue from 'bootstrap-vue' @@ -8,11 +10,29 @@ import 'vue-loading-overlay/dist/vue-loading.css' import 'bootstrap/dist/css/bootstrap.css' import 'bootstrap-vue/dist/bootstrap-vue.css' + +import axios from 'axios' +import VueAxios from 'vue-axios' + +import store from './store' + Vue.config.productionTip = false +Vue.use(VueAxios, axios) Vue.use(BootstrapVue) Vue.use(Loading) +Vue.use(Vuex) + new Vue({ router, - render: h => h(App) + render: h => h(App), + store, + mounted(){ + this.$store.subscribe((mutation, state) => { + localStorage.setItem('store', JSON.stringify(state)) + }) + this.$store.beforeCreate = function () { + this.$store.commit('initialiseStore') + } + } }).$mount('#app') From 820549078c98e295f962a2a6dbb3862039107037 Mon Sep 17 00:00:00 2001 From: Pierre Dittgen Date: Wed, 20 Jan 2021 15:14:30 +0100 Subject: [PATCH 05/33] wip --- .gitignore | 1 + src/router.js | 8 ++++- src/services/Api.js | 10 +++---- src/store/index.js | 4 +-- src/store/modules/auth.js | 3 +- src/store/modules/folders.js | 58 ------------------------------------ src/views/Login.vue | 54 +++++++++++++++++++++++++++++++++ 7 files changed, 69 insertions(+), 69 deletions(-) delete mode 100644 src/store/modules/folders.js create mode 100644 src/views/Login.vue diff --git a/.gitignore b/.gitignore index 185e663..136912d 100644 --- a/.gitignore +++ b/.gitignore @@ -13,6 +13,7 @@ yarn-error.log* # Editor directories and files .idea +.prettierrc .vscode *.suo *.ntvs* diff --git a/src/router.js b/src/router.js index 88df629..6477aad 100644 --- a/src/router.js +++ b/src/router.js @@ -1,6 +1,7 @@ import Vue from 'vue' import Router from 'vue-router' import Home from './views/Home.vue' +import Login from './views/Login.vue' Vue.use(Router) @@ -12,11 +13,16 @@ export default new Router({ path: '/:schema', name: 'home_schema', component: Home - }, + }, { path: '/', name: 'home', component: Home + }, + { + path: '/login', + name: 'login', + component: Login } ] }) diff --git a/src/services/Api.js b/src/services/Api.js index c85d552..8cea211 100644 --- a/src/services/Api.js +++ b/src/services/Api.js @@ -1,5 +1,5 @@ import axios from 'axios' -import store from '../store' +import store from '@/store' const instance = axios.create() @@ -24,14 +24,14 @@ instance.interceptors.response.use(response => { return response }) -function defaultErrorCallback (res) { - console.error('API error', res) +// function defaultErrorCallback (res) { + //console.error('API error', res) +function defaultErrorCallback () { } export default class Api { constructor () { - this.API_BASE_URL = process.env.GRIDSOME_BASE_URL - this.UPLOADER_BASE_URL = 'http://localhost:3000/api' + this.API_BASE_URL = process.env.VUE_APP_OAUTH_BASE_URL } get (path, params, errorCallback) { diff --git a/src/store/index.js b/src/store/index.js index be45b4f..00abd4c 100644 --- a/src/store/index.js +++ b/src/store/index.js @@ -2,15 +2,13 @@ import Vue from 'vue' import Vuex from 'vuex' import auth from '@/store/modules/auth' -import folders from '@/store/modules/folders' Vue.use(Vuex) export default new Vuex.Store({ strict: true, modules: { - auth, - folders + auth }, mutations: { initialiseStore (state) { diff --git a/src/store/modules/auth.js b/src/store/modules/auth.js index ed773cc..4950650 100644 --- a/src/store/modules/auth.js +++ b/src/store/modules/auth.js @@ -1,4 +1,4 @@ -import Api from '@/services/Api.js' +import Api from '@/services/Api' const $api = new Api() @@ -50,7 +50,6 @@ const actions = { commit('unsetLoggedIn') commit('setToken', '') commit('setUserData', {}) - commit('folders/setFolders', [], { root: true }) } } diff --git a/src/store/modules/folders.js b/src/store/modules/folders.js deleted file mode 100644 index f338b48..0000000 --- a/src/store/modules/folders.js +++ /dev/null @@ -1,58 +0,0 @@ -import Api from '@/services/Api.js' - -const $api = new Api() - -const module = { - namespaced: true, - state () { - return { - cache: [] - } - }, - getters: { - cache: state => state.cache - }, - mutations: { - setFolders (state, data) { - state.cache = data - } - }, - actions: { - createExample () { - const info = { - title: 'Mes playlists', - description: 'mes belles playlists', - private: true, - extras: { - playlist: true - } - } - - $api.post('datasets', info) - }, - async fetchMe ({ dispatch, commit }) { - const folders = [] - - try { - const res = await $api.get('me/datasets') - - for (const k in res.data) { - const dataset = res.data[k] - if ('playlist' in dataset.extras && !dataset.deleted) { - folders.push(dataset) - } - } - - if (folders.length === 0) { - dispatch('createExample') - } - } catch (e) { - // console.log(e) - } - - commit('setFolders', folders) - } - } -} - -export default module diff --git a/src/views/Login.vue b/src/views/Login.vue new file mode 100644 index 0000000..3273a93 --- /dev/null +++ b/src/views/Login.vue @@ -0,0 +1,54 @@ + + + From 2bb4949e27e2bcbfe44c8d83f4f727ee80e32a29 Mon Sep 17 00:00:00 2001 From: Pierre Dittgen Date: Thu, 21 Jan 2021 11:38:16 +0100 Subject: [PATCH 06/33] Fix cycle import --- src/components/NavUser.vue | 3 +++ src/store/modules/auth.js | 9 +-------- 2 files changed, 4 insertions(+), 8 deletions(-) diff --git a/src/components/NavUser.vue b/src/components/NavUser.vue index 4f6478c..a2d8614 100644 --- a/src/components/NavUser.vue +++ b/src/components/NavUser.vue @@ -22,8 +22,10 @@ From 716d8ebaa2342db07e379659a21cdad5a43d2113 Mon Sep 17 00:00:00 2001 From: Pierre Dittgen Date: Thu, 21 Jan 2021 12:30:22 +0100 Subject: [PATCH 08/33] Use $api as a singleton --- src/components/NavUser.vue | 4 +--- src/services/Api.js | 2 +- src/store/modules/auth.js | 4 +++- src/views/Login.vue | 3 +-- 4 files changed, 6 insertions(+), 7 deletions(-) diff --git a/src/components/NavUser.vue b/src/components/NavUser.vue index 1f6266c..6148156 100644 --- a/src/components/NavUser.vue +++ b/src/components/NavUser.vue @@ -22,10 +22,8 @@ diff --git a/src/router.js b/src/router.js index 6477aad..3e553f8 100644 --- a/src/router.js +++ b/src/router.js @@ -9,11 +9,6 @@ export default new Router({ mode: 'history', base: process.env.BASE_URL, routes: [ - { - path: '/:schema', - name: 'home_schema', - component: Home - }, { path: '/', name: 'home', diff --git a/src/views/Login.vue b/src/views/Login.vue index adaa37f..e4de204 100644 --- a/src/views/Login.vue +++ b/src/views/Login.vue @@ -20,17 +20,24 @@ export default { async mounted() { if (!this.$store.state.auth.user.loggedIn) { try { - await this.getoken() + await this.getToken() } catch (e) { // console.error(e.response.data) this.$router.push("/") } this.$store.dispatch("auth/login", this.token).then(() => { - $api.get("me").then(response => { - this.$store.dispatch("auth/fillUserData", response.data).then(() => { - this.$router.push("/") - }) - }) + $api.get("me").then( + response => { + this.$store + .dispatch("auth/fillUserData", response.data) + .then(() => { + this.$router.push("/") + }) + }, + err => { + console.log({ err }) + } + ) }) } else { // console.log("Logged in", this.$store.state.auth.user) @@ -38,15 +45,8 @@ export default { } }, methods: { - async getoken() { - const queryObject = {} - window.location.search - .substr(1) - .split("&") - .forEach(item => { - queryObject[item.split("=")[0]] = item.split("=")[1] - }) - this.token = await $auth.retrieveToken(queryObject) + async getToken() { + this.token = await $auth.retrieveToken({ ...this.$route.query }) } } } From c7df9be7e70b8aa6ee128e071ccbd9c06148531d Mon Sep 17 00:00:00 2001 From: Pierre Dittgen Date: Fri, 22 Jan 2021 18:07:50 +0100 Subject: [PATCH 10/33] Improve user dropdown --- src/components/NavUser.vue | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/components/NavUser.vue b/src/components/NavUser.vue index 6148156..158d791 100644 --- a/src/components/NavUser.vue +++ b/src/components/NavUser.vue @@ -9,11 +9,12 @@ - Profile + Mon profil + Se déconnecter From 88dd51ba1cade5e890459e181343650abac27b43 Mon Sep 17 00:00:00 2001 From: Pierre Dittgen Date: Fri, 22 Jan 2021 18:08:06 +0100 Subject: [PATCH 11/33] restore schema route --- src/router.js | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/router.js b/src/router.js index 3e553f8..4c01ac5 100644 --- a/src/router.js +++ b/src/router.js @@ -18,6 +18,11 @@ export default new Router({ path: '/login', name: 'login', component: Login + }, + { + path: '/:schema', + name: 'home_schema', + component: Home } ] }) From b15842495c483a5cfe340651be122c6dae8dc092 Mon Sep 17 00:00:00 2001 From: Pierre Dittgen Date: Fri, 22 Jan 2021 18:08:29 +0100 Subject: [PATCH 12/33] Comment log --- src/views/Login.vue | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/views/Login.vue b/src/views/Login.vue index e4de204..8fc3694 100644 --- a/src/views/Login.vue +++ b/src/views/Login.vue @@ -34,8 +34,8 @@ export default { this.$router.push("/") }) }, - err => { - console.log({ err }) + () => { + //console.log({ err }) } ) }) From 9da19ff7afc0cca0f26eb2d4a48c33d87a6944a9 Mon Sep 17 00:00:00 2001 From: Pierre Dittgen Date: Tue, 26 Jan 2021 17:01:00 +0100 Subject: [PATCH 13/33] wip --- src/router.js | 19 +- src/views/PublishForm.vue | 143 ++++++++++++ src/views/SchemaForm.vue | 476 ++++++++++++++++++++++---------------- 3 files changed, 432 insertions(+), 206 deletions(-) create mode 100644 src/views/PublishForm.vue diff --git a/src/router.js b/src/router.js index 4c01ac5..fc01ee4 100644 --- a/src/router.js +++ b/src/router.js @@ -2,6 +2,8 @@ import Vue from 'vue' import Router from 'vue-router' import Home from './views/Home.vue' import Login from './views/Login.vue' +import PublishForm from './views/PublishForm.vue' +import qs from 'qs' Vue.use(Router) @@ -19,10 +21,25 @@ export default new Router({ name: 'login', component: Login }, + { + path: '/publish-form', + name: 'publish-form', + component: PublishForm + }, { path: '/:schema', name: 'home_schema', component: Home } - ] + ], + // set custom query resolver + parseQuery(query) { + return qs.parse(query); + }, + stringifyQuery(query) { + var result = qs.stringify(query); + + return result ? ('?' + result) : ''; + } + }) diff --git a/src/views/PublishForm.vue b/src/views/PublishForm.vue new file mode 100644 index 0000000..2f1ecc1 --- /dev/null +++ b/src/views/PublishForm.vue @@ -0,0 +1,143 @@ + + diff --git a/src/views/SchemaForm.vue b/src/views/SchemaForm.vue index cce28ea..5681a85 100644 --- a/src/views/SchemaForm.vue +++ b/src/views/SchemaForm.vue @@ -1,21 +1,55 @@ From c52f1a00772d65d9d0cb67c1766492ff8f78508c Mon Sep 17 00:00:00 2001 From: Pierre Dittgen Date: Wed, 27 Jan 2021 17:07:40 +0100 Subject: [PATCH 14/33] Remove /publish-form route --- src/router.js | 17 ----- src/views/PublishForm.vue | 143 -------------------------------------- 2 files changed, 160 deletions(-) delete mode 100644 src/views/PublishForm.vue diff --git a/src/router.js b/src/router.js index fc01ee4..7b18e7c 100644 --- a/src/router.js +++ b/src/router.js @@ -2,8 +2,6 @@ import Vue from 'vue' import Router from 'vue-router' import Home from './views/Home.vue' import Login from './views/Login.vue' -import PublishForm from './views/PublishForm.vue' -import qs from 'qs' Vue.use(Router) @@ -21,25 +19,10 @@ export default new Router({ name: 'login', component: Login }, - { - path: '/publish-form', - name: 'publish-form', - component: PublishForm - }, { path: '/:schema', name: 'home_schema', component: Home } ], - // set custom query resolver - parseQuery(query) { - return qs.parse(query); - }, - stringifyQuery(query) { - var result = qs.stringify(query); - - return result ? ('?' + result) : ''; - } - }) diff --git a/src/views/PublishForm.vue b/src/views/PublishForm.vue deleted file mode 100644 index 2f1ecc1..0000000 --- a/src/views/PublishForm.vue +++ /dev/null @@ -1,143 +0,0 @@ - - From 58a0d1f296c77e45dd4dbaa3358d3d7d87daee4b Mon Sep 17 00:00:00 2001 From: Pierre Dittgen Date: Wed, 27 Jan 2021 17:09:13 +0100 Subject: [PATCH 15/33] Introduce new Publish modal --- src/components/PublishForm.vue | 101 +++++++++++++++++++++++++++++++++ src/views/SchemaForm.vue | 49 +++++++++++----- 2 files changed, 135 insertions(+), 15 deletions(-) create mode 100644 src/components/PublishForm.vue diff --git a/src/components/PublishForm.vue b/src/components/PublishForm.vue new file mode 100644 index 0000000..6db8d01 --- /dev/null +++ b/src/components/PublishForm.vue @@ -0,0 +1,101 @@ + + diff --git a/src/views/SchemaForm.vue b/src/views/SchemaForm.vue index 5681a85..4c3711e 100644 --- a/src/views/SchemaForm.vue +++ b/src/views/SchemaForm.vue @@ -21,13 +21,13 @@ class="mr-2" >Télécharger le CSV + Publier sur data.gouv.fr Ajouter une ligne + + + + ({ + value: org.id, + text: org.name + })) } }, methods: { @@ -288,17 +315,9 @@ export default { this.addLine() } }, - publish() { - // console.log({ user: this.user }) - console.log({ schema: this.schema }) - this.$router.push({ - name: 'publish-form', - query: { - schemaName: this.schema.title, - header: JSON.stringify(this.fieldNames), - rows: JSON.stringify(this.lines) - } - }) + enableDisablePublishButton(formState) { + console.log({ formState }) + this.publishButtonDisabled = !formState } } } From 5a57114328dd3442c989561f46164f2942b7508a Mon Sep 17 00:00:00 2001 From: Pierre Dittgen Date: Thu, 28 Jan 2021 11:34:49 +0100 Subject: [PATCH 16/33] Format --- src/views/Login.vue | 21 +++++++++++---------- 1 file changed, 11 insertions(+), 10 deletions(-) diff --git a/src/views/Login.vue b/src/views/Login.vue index 8fc3694..ff8cc58 100644 --- a/src/views/Login.vue +++ b/src/views/Login.vue @@ -6,8 +6,8 @@