Refactor layout components and add loading state
- Refactor the layout components to improve code organization and readability. - Add a new store called LoadingStore to manage the loading state. - Update AppLayout.vue, AppMenu.vue, AppTopbar.vue, ScenarioStore.js, and UserPrefStore.js to import and use the LoadingStore. - Add loading indicators in AppTopbar.vue and ScenarioList.vue components.
This commit is contained in:
@@ -64,6 +64,7 @@ const isOutsideClicked = (event) => {
|
|||||||
<div v-if="userPrefStore.userLoaded" class="layout-wrapper" :class="containerClass">
|
<div v-if="userPrefStore.userLoaded" class="layout-wrapper" :class="containerClass">
|
||||||
<app-topbar :page="page"></app-topbar>
|
<app-topbar :page="page"></app-topbar>
|
||||||
<div class="layout-sidebar">
|
<div class="layout-sidebar">
|
||||||
|
|
||||||
<app-sidebar></app-sidebar>
|
<app-sidebar></app-sidebar>
|
||||||
</div>
|
</div>
|
||||||
<div class="layout-main-container">
|
<div class="layout-main-container">
|
||||||
|
|||||||
@@ -1,8 +1,11 @@
|
|||||||
<script setup>
|
<script setup>
|
||||||
import { ref } from 'vue';
|
import { ref } from 'vue';
|
||||||
|
|
||||||
|
import { UserPrefStore } from '../stores/UserPrefStore.js';
|
||||||
import AppMenuItem from './AppMenuItem.vue';
|
import AppMenuItem from './AppMenuItem.vue';
|
||||||
|
|
||||||
|
const userPrefStore = UserPrefStore();
|
||||||
|
|
||||||
const model = ref([
|
const model = ref([
|
||||||
{
|
{
|
||||||
label: 'Scenarios',
|
label: 'Scenarios',
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ import { useAuth } from '@websanova/vue-auth/src/v3.js';
|
|||||||
import { useRouter } from 'vue-router';
|
import { useRouter } from 'vue-router';
|
||||||
|
|
||||||
|
|
||||||
|
import { LoadingStore } from '../stores/LoadingStore.js';
|
||||||
import { ScenarioStore } from '../stores/ScenarioStore.js';
|
import { ScenarioStore } from '../stores/ScenarioStore.js';
|
||||||
import { UserPrefStore } from '../stores/UserPrefStore.js';
|
import { UserPrefStore } from '../stores/UserPrefStore.js';
|
||||||
|
|
||||||
@@ -16,6 +17,7 @@ const router = useRouter();
|
|||||||
const props = defineProps(['page']);
|
const props = defineProps(['page']);
|
||||||
const userPrefStore = UserPrefStore();
|
const userPrefStore = UserPrefStore();
|
||||||
const scenario_store = ScenarioStore();
|
const scenario_store = ScenarioStore();
|
||||||
|
const loadingStore = LoadingStore()
|
||||||
|
|
||||||
const { onMenuToggle, toggleDarkMode, isDarkTheme } = useLayout();
|
const { onMenuToggle, toggleDarkMode, isDarkTheme } = useLayout();
|
||||||
|
|
||||||
@@ -54,6 +56,8 @@ const { onMenuToggle, toggleDarkMode, isDarkTheme } = useLayout();
|
|||||||
<div class="layout-topbar-actions">
|
<div class="layout-topbar-actions">
|
||||||
<div class="layout-config-menu">
|
<div class="layout-config-menu">
|
||||||
|
|
||||||
|
<ProgressSpinner v-if="loadingStore.isLoading" style="width: 25px; height: 25px; margin-top: 6px" strokeWidth="2" fill="transparent"/>
|
||||||
|
|
||||||
<button @click="router.push('/canvas')" class="layout-topbar-action" >
|
<button @click="router.push('/canvas')" class="layout-topbar-action" >
|
||||||
<i class="pi pi-file-edit"></i>
|
<i class="pi pi-file-edit"></i>
|
||||||
</button >
|
</button >
|
||||||
@@ -75,6 +79,7 @@ const { onMenuToggle, toggleDarkMode, isDarkTheme } = useLayout();
|
|||||||
<AppConfigurator />
|
<AppConfigurator />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<Dropdown
|
<Dropdown
|
||||||
v-model="userPrefStore.selectedApp"
|
v-model="userPrefStore.selectedApp"
|
||||||
:options="userPrefStore.availableApp"
|
:options="userPrefStore.availableApp"
|
||||||
|
|||||||
21
src/stores/LoadingStore.js
Normal file
21
src/stores/LoadingStore.js
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
import { defineStore } from 'pinia'
|
||||||
|
import { computed, ref } from 'vue'
|
||||||
|
|
||||||
|
|
||||||
|
export const LoadingStore = defineStore('loading_store', () => {
|
||||||
|
|
||||||
|
|
||||||
|
const scenario_loading = ref(false)
|
||||||
|
const user_loading = ref(false)
|
||||||
|
const another_loading = ref(false)
|
||||||
|
|
||||||
|
const isLoading = computed(() => {
|
||||||
|
return scenario_loading.value || user_loading.value || another_loading.value
|
||||||
|
})
|
||||||
|
|
||||||
|
return {isLoading,
|
||||||
|
user_loading,
|
||||||
|
scenario_loading,
|
||||||
|
another_loading
|
||||||
|
}
|
||||||
|
})
|
||||||
@@ -1,6 +1,7 @@
|
|||||||
import { defineStore } from 'pinia'
|
import { defineStore } from 'pinia'
|
||||||
import { computed, ref } from 'vue'
|
import { computed, ref } from 'vue'
|
||||||
import { ScenarioService } from '../service/ScenarioService'
|
import { ScenarioService } from '../service/ScenarioService'
|
||||||
|
import { LoadingStore } from './LoadingStore'
|
||||||
import { UserPrefStore } from './UserPrefStore'
|
import { UserPrefStore } from './UserPrefStore'
|
||||||
|
|
||||||
export const ScenarioStore = defineStore('scenario_store', () => {
|
export const ScenarioStore = defineStore('scenario_store', () => {
|
||||||
@@ -11,24 +12,31 @@ export const ScenarioStore = defineStore('scenario_store', () => {
|
|||||||
const applicationScenarios = ref([])
|
const applicationScenarios = ref([])
|
||||||
const filterString = ref('')
|
const filterString = ref('')
|
||||||
const allScenarios = ref([])
|
const allScenarios = ref([])
|
||||||
|
|
||||||
const userPrefStore = UserPrefStore()
|
const userPrefStore = UserPrefStore()
|
||||||
|
const loadingStore = LoadingStore()
|
||||||
|
|
||||||
|
|
||||||
async function fetchScenarios() {
|
async function fetchScenarios() {
|
||||||
|
loadingStore.scenario_loading = true;
|
||||||
await ScenarioService.getScenariosProject(userPrefStore.selectedProject).then(resp => {
|
await ScenarioService.getScenariosProject(userPrefStore.selectedProject).then(resp => {
|
||||||
projectScenarios.value = resp.data;
|
projectScenarios.value = resp.data;
|
||||||
allScenarios.value = [...projectScenarios.value]
|
allScenarios.value = [...projectScenarios.value]
|
||||||
|
loadingStore.scenario_loading = false;
|
||||||
});
|
});
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
async function fetchApplicationScenarios() {
|
async function fetchApplicationScenarios() {
|
||||||
|
loadingStore.scenario_loading = true;
|
||||||
|
|
||||||
await ScenarioService.getScenariosApplication(userPrefStore.selectedApp).then(resp=>{
|
await ScenarioService.getScenariosApplication(userPrefStore.selectedApp).then(resp=>{
|
||||||
console.log("response scenari", resp);
|
console.log("response scenari", resp);
|
||||||
applicationScenarios.value = resp.data
|
applicationScenarios.value = resp.data
|
||||||
allScenarios.value = [...projectScenarios.value, ...applicationScenarios.value]
|
allScenarios.value = [...projectScenarios.value, ...applicationScenarios.value]
|
||||||
|
loadingStore.scenario_loading = false;
|
||||||
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -47,5 +55,11 @@ export const ScenarioStore = defineStore('scenario_store', () => {
|
|||||||
})
|
})
|
||||||
|
|
||||||
|
|
||||||
return {filteredScenarios, projectScenarios, applicationScenarios, fetchScenarios,fetchApplicationScenarios,scenarios,filterString }
|
return {filteredScenarios,
|
||||||
|
projectScenarios,
|
||||||
|
applicationScenarios,
|
||||||
|
fetchScenarios,
|
||||||
|
fetchApplicationScenarios,
|
||||||
|
scenarios,
|
||||||
|
filterString }
|
||||||
})
|
})
|
||||||
@@ -1,19 +1,24 @@
|
|||||||
import { useAuth } from '@websanova/vue-auth/src/v3.js';
|
import { useAuth } from '@websanova/vue-auth/src/v3.js';
|
||||||
import { defineStore } from 'pinia';
|
import { defineStore } from 'pinia';
|
||||||
import { computed, ref } from 'vue';
|
import { computed, ref } from 'vue';
|
||||||
|
import { LoadingStore } from './LoadingStore';
|
||||||
|
|
||||||
export const UserPrefStore = defineStore('userpref_store', () => {
|
export const UserPrefStore = defineStore('userpref_store', () => {
|
||||||
|
|
||||||
const user = ref(null)
|
const user = ref(null)
|
||||||
const userLoaded = ref(false)
|
const userLoaded = ref(false)
|
||||||
const selectedApp = ref(null)
|
const selectedApp = ref(null)
|
||||||
|
const loadingStore = LoadingStore()
|
||||||
|
|
||||||
|
|
||||||
async function fetchUserData(){
|
async function fetchUserData(){
|
||||||
|
|
||||||
const auth = useAuth();
|
const auth = useAuth();
|
||||||
|
loadingStore.user_loading = true;
|
||||||
await auth.fetch().then((fetchedUser) => {
|
await auth.fetch().then((fetchedUser) => {
|
||||||
user.value = fetchedUser.data.data;
|
user.value = fetchedUser.data.data;
|
||||||
userLoaded.value = true;
|
userLoaded.value = true;
|
||||||
|
loadingStore.user_loading = false;
|
||||||
}).catch((error) => {
|
}).catch((error) => {
|
||||||
reject(error);
|
reject(error);
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -2,10 +2,7 @@
|
|||||||
<div>
|
<div>
|
||||||
<h1>Available Scenarios</h1>
|
<h1>Available Scenarios</h1>
|
||||||
</div>
|
</div>
|
||||||
<div v-if="loading" class="flex justify-center">
|
<div >
|
||||||
<ProgressSpinner style="width: 50px; height: 50px; margin-top: 50px" strokeWidth="3" fill="transparent"/>
|
|
||||||
</div>
|
|
||||||
<div v-else>
|
|
||||||
<DataView :value="scenario_store.filteredScenarios" :layout="layout" paginator :rows="8">
|
<DataView :value="scenario_store.filteredScenarios" :layout="layout" paginator :rows="8">
|
||||||
<template #header>
|
<template #header>
|
||||||
<div class="header-container">
|
<div class="header-container">
|
||||||
@@ -74,22 +71,21 @@
|
|||||||
<script setup>
|
<script setup>
|
||||||
import { ChevronRightIcon } from '@heroicons/vue/24/solid';
|
import { ChevronRightIcon } from '@heroicons/vue/24/solid';
|
||||||
import DataView from 'primevue/dataview';
|
import DataView from 'primevue/dataview';
|
||||||
import ProgressSpinner from 'primevue/progressspinner';
|
|
||||||
import { onMounted, ref } from 'vue';
|
import { onMounted, ref } from 'vue';
|
||||||
import { useRouter } from 'vue-router';
|
import { useRouter } from 'vue-router';
|
||||||
|
import { LoadingStore } from '../../stores/LoadingStore.js';
|
||||||
import { ScenarioStore } from '../../stores/ScenarioStore.js';
|
import { ScenarioStore } from '../../stores/ScenarioStore.js';
|
||||||
|
|
||||||
const router = useRouter()
|
const router = useRouter()
|
||||||
const layout = ref('grid');
|
const layout = ref('grid');
|
||||||
const options = ref(['list', 'grid']);
|
const options = ref(['list', 'grid']);
|
||||||
const loading = ref(true)
|
const loading = ref(true)
|
||||||
|
const loadingStore = LoadingStore()
|
||||||
|
|
||||||
const scenario_store = ScenarioStore();
|
const scenario_store = ScenarioStore();
|
||||||
|
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
loading.value = true;
|
|
||||||
scenario_store.fetchScenarios();
|
scenario_store.fetchScenarios();
|
||||||
loading.value = false;
|
|
||||||
});
|
});
|
||||||
|
|
||||||
const executeScenario = (id) => {
|
const executeScenario = (id) => {
|
||||||
|
|||||||
Reference in New Issue
Block a user