diff options
-rw-r--r-- | src/components/AppHeader/AppHeader.vue | 11 | ||||
-rw-r--r-- | src/components/Global/LoadingBar.vue | 85 | ||||
-rw-r--r-- | src/components/Mixins/LoadingBarMixin.js | 15 | ||||
-rw-r--r-- | src/main.js | 2 |
4 files changed, 112 insertions, 1 deletions
diff --git a/src/components/AppHeader/AppHeader.vue b/src/components/AppHeader/AppHeader.vue index 114d6c9d..d937293d 100644 --- a/src/components/AppHeader/AppHeader.vue +++ b/src/components/AppHeader/AppHeader.vue @@ -52,6 +52,7 @@ </b-navbar-nav> </b-navbar> </header> + <loading-bar /> </div> </template> @@ -61,10 +62,18 @@ import IconClose from '@carbon/icons-vue/es/close/20'; import IconMenu from '@carbon/icons-vue/es/menu/20'; import IconRenew from '@carbon/icons-vue/es/renew/20'; import StatusIcon from '../Global/StatusIcon'; +import LoadingBar from '../Global/LoadingBar'; export default { name: 'AppHeader', - components: { IconAvatar, IconClose, IconMenu, IconRenew, StatusIcon }, + components: { + IconAvatar, + IconClose, + IconMenu, + IconRenew, + StatusIcon, + LoadingBar + }, data() { return { isNavigationOpen: false diff --git a/src/components/Global/LoadingBar.vue b/src/components/Global/LoadingBar.vue new file mode 100644 index 00000000..1d8d68a8 --- /dev/null +++ b/src/components/Global/LoadingBar.vue @@ -0,0 +1,85 @@ +<template> + <transition name="fade"> + <b-progress + v-if="!isLoadingComplete" + :value="loadingIndicatorValue" + height="0.4rem" + /> + </transition> +</template> + +<script> +export default { + data() { + return { + loadingIndicatorValue: 0, + isLoadingComplete: false, + loadingIntervalId: null, + timeoutId: null + }; + }, + created() { + this.$root.$on('loader::start', () => { + this.startLoadingInterval(); + }); + this.$root.$on('loader::end', () => { + this.endLoadingInterval(); + }); + this.$root.$on('loader::hide', () => { + this.hideLoadingBar(); + }); + }, + methods: { + startLoadingInterval() { + this.clearLoadingInterval(); + this.clearTimeout(); + this.loadingIndicatorValue = 0; + this.isLoadingComplete = false; + this.loadingIntervalId = setInterval(() => { + this.loadingIndicatorValue += 1; + if (this.loadingIndicatorValue > 100) this.clearLoadingInterval(); + }, 100); + }, + endLoadingInterval() { + this.clearLoadingInterval(); + this.clearTimeout(); + this.loadingIndicatorValue = 100; + this.timeoutId = setTimeout(() => { + // Let animation complete before hiding + // the loading bar + this.isLoadingComplete = true; + }, 1000); + }, + hideLoadingBar() { + this.clearLoadingInterval(); + this.clearTimeout(); + this.loadingIndicatorValue = 0; + this.isLoadingComplete = true; + }, + clearLoadingInterval() { + if (this.loadingIntervalId) clearInterval(this.loadingIntervalId); + this.loadingIntervalId = null; + }, + clearTimeout() { + if (this.timeoutId) clearTimeout(this.timeoutId); + this.timeoutId = null; + } + } +}; +</script> + +<style lang="scss" scoped> +.progress { + position: absolute; + left: 0; + right: 0; + bottom: -0.4rem; + opacity: 1; + transition: opacity $duration--moderate-01 $standard-easing--productive; + + &.fade-enter, + &.fade-leave-to { + opacity: 0; + } +} +</style> diff --git a/src/components/Mixins/LoadingBarMixin.js b/src/components/Mixins/LoadingBarMixin.js new file mode 100644 index 00000000..111b40dc --- /dev/null +++ b/src/components/Mixins/LoadingBarMixin.js @@ -0,0 +1,15 @@ +const LoadingBarMixin = { + methods: { + startLoader() { + this.$root.$emit('loader::start'); + }, + endLoader() { + this.$root.$emit('loader::end'); + }, + hideLoader() { + this.$root.$emit('loader::hide'); + } + } +}; + +export default LoadingBarMixin; diff --git a/src/main.js b/src/main.js index b59afd9a..d9f1e787 100644 --- a/src/main.js +++ b/src/main.js @@ -24,6 +24,7 @@ import { ModalPlugin, NavbarPlugin, NavPlugin, + ProgressPlugin, TablePlugin, ToastPlugin, TooltipPlugin @@ -91,6 +92,7 @@ Vue.use(ListGroupPlugin); Vue.use(ModalPlugin); Vue.use(NavbarPlugin); Vue.use(NavPlugin); +Vue.use(ProgressPlugin); Vue.use(TablePlugin); Vue.use(ToastPlugin); Vue.use(TooltipPlugin); |