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); } }, }, });