138 lines
3.4 KiB
JavaScript
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);
|
|
}
|
|
},
|
|
},
|
|
});
|