custom_ui/frontend/src/stores/loading.js

138 lines
3.4 KiB
JavaScript

import { defineStore } from "pinia";
export const useLoadingStore = defineStore("loading", {
state: () => ({
// Global loading state
isLoading: false,
// Component-specific loading states for more granular control
componentLoading: {
dataTable: false,
form: false,
clients: false,
jobs: false,
timesheets: false,
warranties: false,
routes: false,
api: false,
},
// Loading messages for different contexts
loadingMessage: "Loading...",
// Track loading operations with custom keys
operations: new Map(),
}),
getters: {
// Check if any loading is happening
isAnyLoading: (state) => {
return (
state.isLoading ||
Object.values(state.componentLoading).some((loading) => loading) ||
state.operations.size > 0
);
},
// Get loading state for a specific component
getComponentLoading: (state) => (componentName) => {
return state.componentLoading[componentName] || false;
},
// Check if a specific operation is loading
isOperationLoading: (state) => (operationKey) => {
return state.operations.has(operationKey);
},
},
actions: {
// Set global loading state
setLoading(isLoading, message = "Loading...") {
this.isLoading = isLoading;
this.loadingMessage = message;
},
// Set component-specific loading state
setComponentLoading(componentName, isLoading, message = "Loading...") {
if (this.componentLoading.hasOwnProperty(componentName)) {
this.componentLoading[componentName] = isLoading;
} else {
this.componentLoading[componentName] = isLoading;
}
if (isLoading) {
this.loadingMessage = message;
}
},
// Start loading for a specific operation
startOperation(operationKey, message = "Loading...") {
this.operations.set(operationKey, {
startTime: Date.now(),
message: message,
});
this.loadingMessage = message;
},
// Stop loading for a specific operation
stopOperation(operationKey) {
this.operations.delete(operationKey);
},
// Clear all loading states
clearAllLoading() {
this.isLoading = false;
Object.keys(this.componentLoading).forEach((key) => {
this.componentLoading[key] = false;
});
this.operations.clear();
this.loadingMessage = "Loading...";
},
// Convenience methods for common operations
startApiCall(apiName = "api") {
this.setComponentLoading("api", true, `Loading ${apiName}...`);
},
stopApiCall() {
this.setComponentLoading("api", false);
},
startDataTableLoading(message = "Loading data...") {
this.setComponentLoading("dataTable", true, message);
},
stopDataTableLoading() {
this.setComponentLoading("dataTable", false);
},
startFormLoading(message = "Processing...") {
this.setComponentLoading("form", true, message);
},
stopFormLoading() {
this.setComponentLoading("form", false);
},
// Async wrapper for operations
async withLoading(operationKey, asyncOperation, message = "Loading...") {
try {
this.startOperation(operationKey, message);
const result = await asyncOperation();
return result;
} finally {
this.stopOperation(operationKey);
}
},
// Async wrapper for component loading
async withComponentLoading(componentName, asyncOperation, message = "Loading...") {
try {
this.setComponentLoading(componentName, true, message);
const result = await asyncOperation();
return result;
} finally {
this.setComponentLoading(componentName, false);
}
},
},
});