diff --git a/package.json b/package.json index 542086b4..4d68cc6e 100644 --- a/package.json +++ b/package.json @@ -29,11 +29,11 @@ "portal-vue": "^2.1.4", "sanitize-html": "^1.13.0", "v-click-outside": "^2.1.1", - "vue": "^2.5.13", + "vue": "^2.6.11", "vue-chat-scroll": "^1.2.1", "vue-i18n": "^7.3.2", "vue-router": "^3.0.1", - "vue-template-compiler": "^2.3.4", + "vue-template-compiler": "^2.6.11", "vuelidate": "^0.7.4", "vuex": "^3.0.1", "whatwg-fetch": "^2.0.3" diff --git a/src/components/big_spinner/big_spinner.vue b/src/components/big_spinner/big_spinner.vue new file mode 100644 index 00000000..cda28de5 --- /dev/null +++ b/src/components/big_spinner/big_spinner.vue @@ -0,0 +1,13 @@ + + + diff --git a/src/components/error_window/error_window.vue b/src/components/error_window/error_window.vue new file mode 100644 index 00000000..ddb4ba00 --- /dev/null +++ b/src/components/error_window/error_window.vue @@ -0,0 +1,41 @@ + + + + + diff --git a/src/components/settings_modal/settings_modal.js b/src/components/settings_modal/settings_modal.js index d38c5751..60d14649 100644 --- a/src/components/settings_modal/settings_modal.js +++ b/src/components/settings_modal/settings_modal.js @@ -1,9 +1,20 @@ 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 = { components: { Modal, - SettingsModalContent: () => import('./settings_modal_content.vue') + SettingsModalContent: getResettableAsyncComponent( + () => import('./settings_modal_content.vue'), + { + loading: BigSpinner, + error: ErrorWindow, + delay: 0, + timeout: 3000 + } + ) }, computed: { modalActivated () { diff --git a/src/i18n/en.json b/src/i18n/en.json index ad9c22bd..e3dc75d7 100644 --- a/src/i18n/en.json +++ b/src/i18n/en.json @@ -60,6 +60,7 @@ "submit": "Submit", "more": "More", "generic_error": "An error occured", + "error_retry": "Please try again", "optional": "optional", "show_more": "Show more", "show_less": "Show less", diff --git a/src/services/resettable_async_component.js b/src/services/resettable_async_component.js new file mode 100644 index 00000000..517bbd88 --- /dev/null +++ b/src/services/resettable_async_component.js @@ -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 diff --git a/yarn.lock b/yarn.lock index 0defefcb..61afa7ca 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2327,6 +2327,7 @@ dateformat@^1.0.6: de-indent@^1.0.2: version "1.0.2" 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: 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" loader-utils "^1.0.2" -vue-template-compiler@^2.3.4: - version "2.5.21" - resolved "https://registry.yarnpkg.com/vue-template-compiler/-/vue-template-compiler-2.5.21.tgz#a57ceb903177e8f643560a8d639a0f8db647054a" +vue-template-compiler@^2.6.11: + version "2.6.11" + resolved "https://registry.yarnpkg.com/vue-template-compiler/-/vue-template-compiler-2.6.11.tgz#c04704ef8f498b153130018993e56309d4698080" + integrity sha512-KIq15bvQDrcCjpGjrAhx4mUlyyHfdmTaoNfeoATHLAiWB+MU3cx4lOzMwrnUh9cCxy0Lt1T11hAFY6TQgroUAA== dependencies: de-indent "^1.0.2" he "^1.1.0" @@ -7914,9 +7916,10 @@ vue-template-es2015-compiler@^1.6.0: version "1.9.1" resolved "https://registry.yarnpkg.com/vue-template-es2015-compiler/-/vue-template-es2015-compiler-1.9.1.tgz#1ee3bc9a16ecbf5118be334bb15f9c46f82f5825" -vue@^2.5.13: - version "2.5.21" - resolved "https://registry.yarnpkg.com/vue/-/vue-2.5.21.tgz#3d33dcd03bb813912ce894a8303ab553699c4a85" +vue@^2.6.11: + version "2.6.11" + resolved "https://registry.yarnpkg.com/vue/-/vue-2.6.11.tgz#76594d877d4b12234406e84e35275c6d514125c5" + integrity sha512-VfPwgcGABbGAue9+sfrD4PuwFar7gPb1yl1UK1MwXoQPAw0BKSqWfoYCT/ThFrdEVWoI51dBuyCoiNU9bZDZxQ== vuelidate@^0.7.4: version "0.7.4"