xref: /openbmc/webui-vue/src/components/Global/LoadingBar.vue (revision 313d15cf9f14e8a264f97a3370c3be4e494e5e0d)
1<template>
2  <transition name="fade">
3    <b-progress v-if="!isLoadingComplete">
4      <b-progress-bar
5        striped
6        animated
7        :value="loadingIndicatorValue"
8        :aria-label="$t('global.ariaLabel.progressBar')"
9      />
10    </b-progress>
11  </transition>
12</template>
13
14<script>
15export default {
16  data() {
17    return {
18      loadingIndicatorValue: 0,
19      isLoadingComplete: false,
20      loadingIntervalId: null,
21      timeoutId: null,
22    };
23  },
24  created() {
25    this.$eventBus.on('loader-start', () => {
26      this.startLoadingInterval();
27    });
28    this.$eventBus.on('loader-end', () => {
29      this.endLoadingInterval();
30    });
31    this.$eventBus.on('loader-hide', () => {
32      this.hideLoadingBar();
33    });
34  },
35  beforeUnmount() {
36    this.$eventBus.off('loader-start', this.handleLoaderStart);
37    this.$eventBus.off('loader-end', this.handleLoaderEnd);
38    this.$eventBus.off('loader-hide', this.handleLoaderHide);
39  },
40  methods: {
41    startLoadingInterval() {
42      this.clearLoadingInterval();
43      this.clearTimeout();
44      this.loadingIndicatorValue = 0;
45      this.isLoadingComplete = false;
46      this.loadingIntervalId = setInterval(() => {
47        this.loadingIndicatorValue += 1;
48        if (this.loadingIndicatorValue > 100) this.clearLoadingInterval();
49      }, 100);
50    },
51    endLoadingInterval() {
52      this.clearLoadingInterval();
53      this.clearTimeout();
54      this.loadingIndicatorValue = 100;
55      this.timeoutId = setTimeout(() => {
56        // Let animation complete before hiding
57        // the loading bar
58        this.isLoadingComplete = true;
59      }, 1000);
60    },
61    hideLoadingBar() {
62      this.clearLoadingInterval();
63      this.clearTimeout();
64      this.loadingIndicatorValue = 0;
65      this.isLoadingComplete = true;
66    },
67    clearLoadingInterval() {
68      if (this.loadingIntervalId) clearInterval(this.loadingIntervalId);
69      this.loadingIntervalId = null;
70    },
71    clearTimeout() {
72      if (this.timeoutId) clearTimeout(this.timeoutId);
73      this.timeoutId = null;
74    },
75  },
76};
77</script>
78
79<style lang="scss" scoped>
80.progress {
81  position: relative;
82  top: 0px;
83  left: 0;
84  right: 0;
85  bottom: -0.4rem;
86  opacity: 1;
87  transition: opacity $duration--moderate-01 $standard-easing--productive;
88  height: 0.4rem;
89
90  &.fade-enter, // Remove this vue2 based only class when switching to vue3
91  &.fade-enter-from, // This is vue3 based only class modified from 'fade-enter'
92  &.fade-leave-to {
93    opacity: 0;
94  }
95}
96.progress-bar {
97  background-color: $loading-color;
98}
99</style>
100