1<template>
2  <transition name="fade">
3    <b-progress v-if="!isLoadingComplete" height="0.4rem">
4      <b-progress-bar
5        :value="loadingIndicatorValue"
6        :aria-label="$t('global.ariaLabel.progressBar')"
7      />
8    </b-progress>
9  </transition>
10</template>
11
12<script>
13export default {
14  data() {
15    return {
16      loadingIndicatorValue: 0,
17      isLoadingComplete: false,
18      loadingIntervalId: null,
19      timeoutId: null
20    };
21  },
22  created() {
23    this.$root.$on('loader::start', () => {
24      this.startLoadingInterval();
25    });
26    this.$root.$on('loader::end', () => {
27      this.endLoadingInterval();
28    });
29    this.$root.$on('loader::hide', () => {
30      this.hideLoadingBar();
31    });
32  },
33  methods: {
34    startLoadingInterval() {
35      this.clearLoadingInterval();
36      this.clearTimeout();
37      this.loadingIndicatorValue = 0;
38      this.isLoadingComplete = false;
39      this.loadingIntervalId = setInterval(() => {
40        this.loadingIndicatorValue += 1;
41        if (this.loadingIndicatorValue > 100) this.clearLoadingInterval();
42      }, 100);
43    },
44    endLoadingInterval() {
45      this.clearLoadingInterval();
46      this.clearTimeout();
47      this.loadingIndicatorValue = 100;
48      this.timeoutId = setTimeout(() => {
49        // Let animation complete before hiding
50        // the loading bar
51        this.isLoadingComplete = true;
52      }, 1000);
53    },
54    hideLoadingBar() {
55      this.clearLoadingInterval();
56      this.clearTimeout();
57      this.loadingIndicatorValue = 0;
58      this.isLoadingComplete = true;
59    },
60    clearLoadingInterval() {
61      if (this.loadingIntervalId) clearInterval(this.loadingIntervalId);
62      this.loadingIntervalId = null;
63    },
64    clearTimeout() {
65      if (this.timeoutId) clearTimeout(this.timeoutId);
66      this.timeoutId = null;
67    }
68  }
69};
70</script>
71
72<style lang="scss" scoped>
73@import 'src/assets/styles/helpers';
74
75.progress {
76  position: absolute;
77  left: 0;
78  right: 0;
79  bottom: -0.4rem;
80  opacity: 1;
81  transition: opacity $duration--moderate-01 $standard-easing--productive;
82
83  &.fade-enter,
84  &.fade-leave-to {
85    opacity: 0;
86  }
87}
88</style>
89