Improve settings-modal async loading, update vue to 2.6.11 to be able

to use Vue.observable, to implmement resettable async component
This commit is contained in:
Henry Jameson 2020-05-25 16:11:05 +03:00
parent a6ca923a76
commit 7951192cd9
7 changed files with 110 additions and 9 deletions

View File

@ -29,11 +29,11 @@
"portal-vue": "^2.1.4", "portal-vue": "^2.1.4",
"sanitize-html": "^1.13.0", "sanitize-html": "^1.13.0",
"v-click-outside": "^2.1.1", "v-click-outside": "^2.1.1",
"vue": "^2.5.13", "vue": "^2.6.11",
"vue-chat-scroll": "^1.2.1", "vue-chat-scroll": "^1.2.1",
"vue-i18n": "^7.3.2", "vue-i18n": "^7.3.2",
"vue-router": "^3.0.1", "vue-router": "^3.0.1",
"vue-template-compiler": "^2.3.4", "vue-template-compiler": "^2.6.11",
"vuelidate": "^0.7.4", "vuelidate": "^0.7.4",
"vuex": "^3.0.1", "vuex": "^3.0.1",
"whatwg-fetch": "^2.0.3" "whatwg-fetch": "^2.0.3"

View File

@ -0,0 +1,13 @@
<template>
<div class="big-spinner">
<i class="icon-spin4 animate-spin" />
</div>
</template>
<style lang="scss">
.big-spinner {
font-size: 15em;
line-height: 0;
opacity: .6;
}
</style>

View File

@ -0,0 +1,41 @@
<template>
<div class="error-window panel">
<div class="panel-heading">
<span class="title">
{{ $t('general.generic_error') }}
</span>
</div>
<div class="panel-body">
<p>
{{ $t('general.error_retry') }}
</p>
<button
class="btn"
@click="closeAllModals"
>
{{ $t('general.close') }}
</button>
</div>
</div>
</template>
<script>
export default {
methods: {
closeAllModals () {
// TODO make a global hook to close all modals?
this.$store.dispatch('closeSettingsModal')
this.$emit('resetAsyncComponent')
}
}
}
</script>
<style lang="scss">
.error-window {
.btn {
margin: .5em;
padding: .5em 2em;
}
}
</style>

View File

@ -1,9 +1,20 @@
import Modal from 'src/components/modal/modal.vue' import Modal from 'src/components/modal/modal.vue'
import BigSpinner from 'src/components/big_spinner/big_spinner.vue'
import ErrorWindow from 'src/components/error_window/error_window.vue'
import getResettableAsyncComponent from 'src/services/resettable_async_component.js'
const SettingsModal = { const SettingsModal = {
components: { components: {
Modal, Modal,
SettingsModalContent: () => import('./settings_modal_content.vue') SettingsModalContent: getResettableAsyncComponent(
() => import('./settings_modal_content.vue'),
{
loading: BigSpinner,
error: ErrorWindow,
delay: 0,
timeout: 3000
}
)
}, },
computed: { computed: {
modalActivated () { modalActivated () {

View File

@ -60,6 +60,7 @@
"submit": "Submit", "submit": "Submit",
"more": "More", "more": "More",
"generic_error": "An error occured", "generic_error": "An error occured",
"error_retry": "Please try again",
"optional": "optional", "optional": "optional",
"show_more": "Show more", "show_more": "Show more",
"show_less": "Show less", "show_less": "Show less",

View File

@ -0,0 +1,32 @@
import Vue from 'vue'
/* By default async components don't have any way to recover, if component is
* failed, it is failed forever. This helper tries to remedy that by recreating
* async component when retry is requested (by user). You need to emit the
* `resetAsyncComponent` event from child to reset the component. Generally,
* this should be done from error component but could be done from loading or
* actual target component itself if needs to be.
*/
function getResettableAsyncComponent (asyncComponent, options) {
const asyncComponentFactory = () => () => ({
component: asyncComponent(),
...options
})
const observe = Vue.observable({ c: asyncComponentFactory() })
return {
functional: true,
render (createElement, { data, children }) {
// emit event resetAsyncComponent to reloading
data.on = {}
data.on.resetAsyncComponent = () => {
observe.c = asyncComponentFactory()
// parent.$forceUpdate()
}
return createElement(observe.c, data, children)
}
}
}
export default getResettableAsyncComponent

View File

@ -2327,6 +2327,7 @@ dateformat@^1.0.6:
de-indent@^1.0.2: de-indent@^1.0.2:
version "1.0.2" version "1.0.2"
resolved "https://registry.yarnpkg.com/de-indent/-/de-indent-1.0.2.tgz#b2038e846dc33baa5796128d0804b455b8c1e21d" resolved "https://registry.yarnpkg.com/de-indent/-/de-indent-1.0.2.tgz#b2038e846dc33baa5796128d0804b455b8c1e21d"
integrity sha1-sgOOhG3DO6pXlhKNCAS0VbjB4h0=
debug@2, debug@2.6.9, debug@^2.1.2, debug@^2.2.0, debug@^2.3.3, debug@^2.6.8, debug@^2.6.9: debug@2, debug@2.6.9, debug@^2.1.2, debug@^2.2.0, debug@^2.3.3, debug@^2.6.8, debug@^2.6.9:
version "2.6.9" version "2.6.9"
@ -7903,9 +7904,10 @@ vue-style-loader@^4.0.0, vue-style-loader@^4.0.1:
hash-sum "^1.0.2" hash-sum "^1.0.2"
loader-utils "^1.0.2" loader-utils "^1.0.2"
vue-template-compiler@^2.3.4: vue-template-compiler@^2.6.11:
version "2.5.21" version "2.6.11"
resolved "https://registry.yarnpkg.com/vue-template-compiler/-/vue-template-compiler-2.5.21.tgz#a57ceb903177e8f643560a8d639a0f8db647054a" resolved "https://registry.yarnpkg.com/vue-template-compiler/-/vue-template-compiler-2.6.11.tgz#c04704ef8f498b153130018993e56309d4698080"
integrity sha512-KIq15bvQDrcCjpGjrAhx4mUlyyHfdmTaoNfeoATHLAiWB+MU3cx4lOzMwrnUh9cCxy0Lt1T11hAFY6TQgroUAA==
dependencies: dependencies:
de-indent "^1.0.2" de-indent "^1.0.2"
he "^1.1.0" he "^1.1.0"
@ -7914,9 +7916,10 @@ vue-template-es2015-compiler@^1.6.0:
version "1.9.1" version "1.9.1"
resolved "https://registry.yarnpkg.com/vue-template-es2015-compiler/-/vue-template-es2015-compiler-1.9.1.tgz#1ee3bc9a16ecbf5118be334bb15f9c46f82f5825" resolved "https://registry.yarnpkg.com/vue-template-es2015-compiler/-/vue-template-es2015-compiler-1.9.1.tgz#1ee3bc9a16ecbf5118be334bb15f9c46f82f5825"
vue@^2.5.13: vue@^2.6.11:
version "2.5.21" version "2.6.11"
resolved "https://registry.yarnpkg.com/vue/-/vue-2.5.21.tgz#3d33dcd03bb813912ce894a8303ab553699c4a85" resolved "https://registry.yarnpkg.com/vue/-/vue-2.6.11.tgz#76594d877d4b12234406e84e35275c6d514125c5"
integrity sha512-VfPwgcGABbGAue9+sfrD4PuwFar7gPb1yl1UK1MwXoQPAw0BKSqWfoYCT/ThFrdEVWoI51dBuyCoiNU9bZDZxQ==
vuelidate@^0.7.4: vuelidate@^0.7.4:
version "0.7.4" version "0.7.4"