add loader bar
This commit is contained in:
6
package-lock.json
generated
6
package-lock.json
generated
@@ -5,6 +5,7 @@
|
||||
"packages": {
|
||||
"": {
|
||||
"dependencies": {
|
||||
"@marcoschulte/vue3-progress": "^0.0.7",
|
||||
"@tinymce/tinymce-vue": "^4.0.7",
|
||||
"@vitejs/plugin-vue": "^4.0.0",
|
||||
"@vuepic/vue-datepicker": "^3.6.4",
|
||||
@@ -518,6 +519,11 @@
|
||||
"@jridgewell/sourcemap-codec": "^1.4.10"
|
||||
}
|
||||
},
|
||||
"node_modules/@marcoschulte/vue3-progress": {
|
||||
"version": "0.0.7",
|
||||
"resolved": "https://registry.npmjs.org/@marcoschulte/vue3-progress/-/vue3-progress-0.0.7.tgz",
|
||||
"integrity": "sha512-gcvZW9gJ/isTD0sjorgvLOuoS2U5r5djMoLOwuN4YvhOvgOyYGWoQF1hubhouE/dVDPvWHmZsD0gvf6YD0x7fg=="
|
||||
},
|
||||
"node_modules/@nodelib/fs.scandir": {
|
||||
"version": "2.1.5",
|
||||
"resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz",
|
||||
|
||||
@@ -25,6 +25,7 @@
|
||||
"vitest": "^0.28.5"
|
||||
},
|
||||
"dependencies": {
|
||||
"@marcoschulte/vue3-progress": "^0.0.7",
|
||||
"@tinymce/tinymce-vue": "^4.0.7",
|
||||
"@vitejs/plugin-vue": "^4.0.0",
|
||||
"@vuepic/vue-datepicker": "^3.6.4",
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
@import "data-table.scss";
|
||||
@import "tinymce.scss";
|
||||
@import "prism.css";
|
||||
@import "progressbar.scss";
|
||||
|
||||
* {
|
||||
box-sizing: border-box;
|
||||
|
||||
28
resources/css/progressbar.scss
Normal file
28
resources/css/progressbar.scss
Normal file
@@ -0,0 +1,28 @@
|
||||
$vue3-progress-bar-container-z-index: 999999 !default;
|
||||
$vue3-progress-bar-container-transition: all 500ms ease !default;
|
||||
|
||||
$vue3-progress-bar-color: $primary-color-dark !default;
|
||||
$vue3-progress-bar-height: 4px !default;
|
||||
$vue3-progress-bar-transition: all 200ms ease !default;
|
||||
|
||||
.vue3-progress-bar-container {
|
||||
position: fixed;
|
||||
z-index: $vue3-progress-bar-container-z-index;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
opacity: 0;
|
||||
background-color: #eee;
|
||||
transition: $vue3-progress-bar-container-transition;
|
||||
&[active="true"] {
|
||||
opacity: 1;
|
||||
transition: none;
|
||||
}
|
||||
.vue3-progress-bar {
|
||||
width: 100%;
|
||||
height: $vue3-progress-bar-height;
|
||||
transform: translate3d(-100%, 0, 0);
|
||||
background-color: $vue3-progress-bar-color;
|
||||
transition: $vue3-progress-bar-transition;
|
||||
}
|
||||
}
|
||||
@@ -2,8 +2,7 @@
|
||||
<template v-if="loading">
|
||||
<transition name="fade">
|
||||
<div v-if="loading" class="sm-loader">
|
||||
<SMLoadingIconToolbox v-if="type.toLowerCase() == 'toolbox'" />
|
||||
<SMLoadingIconBalls v-else />
|
||||
<SMLoadingIcon />
|
||||
</div>
|
||||
</transition>
|
||||
</template>
|
||||
@@ -11,8 +10,7 @@
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import SMLoadingIconToolbox from "./SMLoadingIconToolbox.vue";
|
||||
import SMLoadingIconBalls from "./SMLoadingIcon.vue";
|
||||
import SMLoadingIcon from "./SMLoadingIcon.vue";
|
||||
|
||||
defineProps({
|
||||
loading: {
|
||||
@@ -20,11 +18,6 @@ defineProps({
|
||||
default: false,
|
||||
required: true,
|
||||
},
|
||||
type: {
|
||||
type: String,
|
||||
default: "",
|
||||
required: false,
|
||||
},
|
||||
});
|
||||
</script>
|
||||
|
||||
|
||||
@@ -1,49 +0,0 @@
|
||||
<template>
|
||||
<div class="sm-loading-icon-toolbox">
|
||||
<div class="loading-logo"></div>
|
||||
<div class="loading-bar"></div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style lang="scss">
|
||||
.sm-loading-icon-toolbox {
|
||||
display: inline-block;
|
||||
position: relative;
|
||||
width: 80px;
|
||||
height: 80px;
|
||||
|
||||
.loading-logo {
|
||||
background-image: url("/img/logo-small.png");
|
||||
background-size: contain;
|
||||
background-repeat: no-repeat;
|
||||
background-position: center;
|
||||
height: 130px;
|
||||
width: 130px;
|
||||
}
|
||||
|
||||
.loading-bar {
|
||||
width: 130px;
|
||||
height: 10px;
|
||||
background: #cfcfcf;
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
border: 1px solid #aaa;
|
||||
}
|
||||
|
||||
.loading-bar::before {
|
||||
content: "";
|
||||
width: 68px;
|
||||
height: 10px;
|
||||
background: $primary-color;
|
||||
position: absolute;
|
||||
left: -34px;
|
||||
animation: bluebar 1.5s infinite ease;
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes bluebar {
|
||||
50% {
|
||||
left: 96px;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -1,7 +1,7 @@
|
||||
/* https://blog.logrocket.com/axios-vs-fetch-best-http-requests/ */
|
||||
|
||||
import { useUserStore } from "../store/UserStore";
|
||||
import { ProgressFinisher, useProgress } from "@marcoschulte/vue3-progress";
|
||||
|
||||
const progresses = [] as ProgressFinisher[];
|
||||
interface ApiProgressData {
|
||||
loaded: number;
|
||||
total: number;
|
||||
@@ -82,6 +82,8 @@ export const api = {
|
||||
|
||||
let receivedData = false;
|
||||
|
||||
progresses.push(useProgress().start());
|
||||
|
||||
fetch(url, fetchOptions)
|
||||
.then((response) => {
|
||||
receivedData = true;
|
||||
@@ -173,6 +175,9 @@ export const api = {
|
||||
...rest,
|
||||
response: response && response.json(),
|
||||
});
|
||||
})
|
||||
.finally(() => {
|
||||
progresses.pop()?.finish();
|
||||
});
|
||||
});
|
||||
},
|
||||
|
||||
@@ -12,6 +12,7 @@ import SMColumn from "./components/SMColumn.vue";
|
||||
import { PromiseDialog } from "vue3-promise-dialog";
|
||||
import { VueReCaptcha } from "vue-recaptcha-v3";
|
||||
import "./lib/prism";
|
||||
import { Vue3ProgressPlugin } from "@marcoschulte/vue3-progress";
|
||||
|
||||
const pinia = createPinia();
|
||||
pinia.use(piniaPluginPersistedstate);
|
||||
@@ -27,6 +28,7 @@ createApp(App)
|
||||
autoHideBadge: true,
|
||||
},
|
||||
})
|
||||
.use(Vue3ProgressPlugin)
|
||||
.component("SMContainer", SMContainer)
|
||||
.component("SMRow", SMRow)
|
||||
.component("SMColumn", SMColumn)
|
||||
|
||||
@@ -2,6 +2,9 @@ import { createWebHistory, createRouter } from "vue-router";
|
||||
import { useUserStore } from "@/store/UserStore";
|
||||
import { useApplicationStore } from "../store/ApplicationStore";
|
||||
import { api } from "../helpers/api";
|
||||
import { useProgress } from "@marcoschulte/vue3-progress";
|
||||
|
||||
const progresses = [];
|
||||
|
||||
export const routes = [
|
||||
{
|
||||
@@ -371,22 +374,11 @@ const router = createRouter({
|
||||
|
||||
// export let activeRoutes = [];
|
||||
|
||||
let routerLoadingTimeout = null;
|
||||
|
||||
router.beforeEach(async (to, from, next) => {
|
||||
const userStore = useUserStore();
|
||||
const applicationStore = useApplicationStore();
|
||||
|
||||
if (routerLoadingTimeout != null) {
|
||||
clearTimeout(routerLoadingTimeout);
|
||||
routerLoadingTimeout = null;
|
||||
}
|
||||
|
||||
routerLoadingTimeout = window.setTimeout(() => {
|
||||
routerLoadingTimeout = null;
|
||||
applicationStore.setRouterLoading(true);
|
||||
}, 1000);
|
||||
|
||||
progresses.push(useProgress().start());
|
||||
applicationStore.clearDynamicTitle();
|
||||
|
||||
// Check Token
|
||||
@@ -470,13 +462,7 @@ router.beforeEach(async (to, from, next) => {
|
||||
});
|
||||
|
||||
router.afterEach((to, from) => {
|
||||
if (routerLoadingTimeout != null) {
|
||||
clearTimeout(routerLoadingTimeout);
|
||||
routerLoadingTimeout = null;
|
||||
}
|
||||
|
||||
const applicationStore = useApplicationStore();
|
||||
applicationStore.setRouterLoading(false);
|
||||
progresses.pop()?.finish();
|
||||
});
|
||||
|
||||
export default router;
|
||||
|
||||
@@ -2,14 +2,12 @@ import { defineStore } from "pinia";
|
||||
|
||||
export interface ApplicationStore {
|
||||
dynamicTitle: string;
|
||||
routerLoading: boolean;
|
||||
}
|
||||
|
||||
export const useApplicationStore = defineStore({
|
||||
id: "application",
|
||||
state: (): ApplicationStore => ({
|
||||
dynamicTitle: "",
|
||||
routerLoading: false,
|
||||
}),
|
||||
|
||||
actions: {
|
||||
|
||||
@@ -8,18 +8,14 @@
|
||||
</router-view>
|
||||
</main>
|
||||
<SMFooter />
|
||||
<SMLoader type="toolbox" :loading="applicationStore.routerLoading" />
|
||||
<vue3-progress-bar></vue3-progress-bar>
|
||||
<DialogWrapper :transition-attrs="{ name: 'fade' }" />
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import SMNavbar from "../components/SMNavbar.vue";
|
||||
import SMFooter from "../components/SMFooter.vue";
|
||||
import SMLoader from "../components/SMLoader.vue";
|
||||
import { DialogWrapper } from "vue3-promise-dialog";
|
||||
import { useApplicationStore } from "../store/ApplicationStore";
|
||||
|
||||
const applicationStore = useApplicationStore();
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
|
||||
Reference in New Issue
Block a user