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