add global loading state, update to use real data for clients table
This commit is contained in:
parent
2cfe7ed8e6
commit
464c62d1e5
12 changed files with 1075 additions and 194 deletions
194
frontend/documentation/LOADING_USAGE.md
Normal file
194
frontend/documentation/LOADING_USAGE.md
Normal file
|
|
@ -0,0 +1,194 @@
|
|||
# Global Loading State Usage Guide
|
||||
|
||||
This document explains how to use the global loading state system in your Vue app.
|
||||
|
||||
## Overview
|
||||
|
||||
The loading system provides multiple ways to handle loading states:
|
||||
|
||||
1. **Global Loading Overlay** - Shows over the entire app
|
||||
2. **Component-specific Loading** - For individual components like DataTable and Form
|
||||
3. **Operation-specific Loading** - For tracking specific async operations
|
||||
|
||||
## Loading Store
|
||||
|
||||
### Basic Usage
|
||||
|
||||
```javascript
|
||||
import { useLoadingStore } from "../../stores/loading";
|
||||
|
||||
const loadingStore = useLoadingStore();
|
||||
|
||||
// Set global loading
|
||||
loadingStore.setLoading(true, "Processing...");
|
||||
|
||||
// Set component-specific loading
|
||||
loadingStore.setComponentLoading("dataTable", true, "Loading data...");
|
||||
|
||||
// Use async wrapper
|
||||
const data = await loadingStore.withLoading(
|
||||
"fetchUsers",
|
||||
() => Api.getUsers(),
|
||||
"Fetching user data...",
|
||||
);
|
||||
```
|
||||
|
||||
### Available Methods
|
||||
|
||||
- `setLoading(isLoading, message?)` - Global loading state
|
||||
- `setComponentLoading(componentName, isLoading, message?)` - Component loading
|
||||
- `startOperation(operationKey, message?)` - Start tracked operation
|
||||
- `stopOperation(operationKey)` - Stop tracked operation
|
||||
- `withLoading(operationKey, asyncFn, message?)` - Async wrapper
|
||||
- `withComponentLoading(componentName, asyncFn, message?)` - Component async wrapper
|
||||
|
||||
### Convenience Methods
|
||||
|
||||
- `startApiCall(apiName?)` - Quick API loading
|
||||
- `stopApiCall()` - Stop API loading
|
||||
- `startDataTableLoading(message?)` - DataTable loading
|
||||
- `stopDataTableLoading()` - Stop DataTable loading
|
||||
- `startFormLoading(message?)` - Form loading
|
||||
- `stopFormLoading()` - Stop Form loading
|
||||
|
||||
## DataTable Component
|
||||
|
||||
The DataTable component automatically integrates with the loading store:
|
||||
|
||||
```vue
|
||||
<template>
|
||||
<DataTable
|
||||
:data="tableData"
|
||||
:columns="columns"
|
||||
tableName="clients"
|
||||
:loading="customLoading"
|
||||
loadingMessage="Custom loading message..."
|
||||
emptyMessage="No clients found"
|
||||
/>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
// DataTable will automatically show loading when:
|
||||
// 1. props.loading is true
|
||||
// 2. Global loading store has loading for 'dataTable'
|
||||
// 3. Global loading store has loading for props.tableName
|
||||
// 4. Any global loading (if useGlobalLoading is true)
|
||||
|
||||
// You can also control it directly:
|
||||
const tableRef = ref();
|
||||
tableRef.value?.startLoading("Custom loading...");
|
||||
tableRef.value?.stopLoading();
|
||||
</script>
|
||||
```
|
||||
|
||||
## Form Component
|
||||
|
||||
The Form component also integrates with loading:
|
||||
|
||||
```vue
|
||||
<template>
|
||||
<Form
|
||||
:fields="formFields"
|
||||
formName="userForm"
|
||||
:loading="customLoading"
|
||||
loadingMessage="Saving user..."
|
||||
@submit="handleSubmit"
|
||||
/>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
// Form will disable all inputs and show loading buttons when:
|
||||
// 1. props.loading is true
|
||||
// 2. Global loading store has loading for 'form'
|
||||
// 3. Global loading store has loading for props.formName
|
||||
// 4. Internal isSubmitting is true
|
||||
|
||||
// Control directly:
|
||||
const formRef = ref();
|
||||
formRef.value?.startLoading("Processing...");
|
||||
formRef.value?.stopLoading();
|
||||
</script>
|
||||
```
|
||||
|
||||
## API Integration Example
|
||||
|
||||
```javascript
|
||||
// In your page component
|
||||
import { useLoadingStore } from "../../stores/loading";
|
||||
|
||||
const loadingStore = useLoadingStore();
|
||||
|
||||
// Method 1: Manual control
|
||||
const loadData = async () => {
|
||||
try {
|
||||
loadingStore.startDataTableLoading("Loading clients...");
|
||||
const data = await Api.getClients();
|
||||
tableData.value = data;
|
||||
} finally {
|
||||
loadingStore.stopDataTableLoading();
|
||||
}
|
||||
};
|
||||
|
||||
// Method 2: Using wrapper (recommended)
|
||||
const loadData = async () => {
|
||||
const data = await loadingStore.withComponentLoading(
|
||||
"clients",
|
||||
() => Api.getClients(),
|
||||
"Loading clients...",
|
||||
);
|
||||
tableData.value = data;
|
||||
};
|
||||
|
||||
// Method 3: For global overlay
|
||||
const performGlobalAction = async () => {
|
||||
const result = await loadingStore.withLoading(
|
||||
"globalOperation",
|
||||
() => Api.performHeavyOperation(),
|
||||
"Processing your request...",
|
||||
);
|
||||
return result;
|
||||
};
|
||||
```
|
||||
|
||||
## Global Loading Overlay
|
||||
|
||||
The `GlobalLoadingOverlay` component shows automatically when global loading is active:
|
||||
|
||||
```vue
|
||||
<!-- Already added to App.vue -->
|
||||
<GlobalLoadingOverlay />
|
||||
|
||||
<!-- Customizable props -->
|
||||
<GlobalLoadingOverlay
|
||||
:globalOnly="false" <!-- Show for any loading, not just global -->
|
||||
:minDisplayTime="500" <!-- Minimum display time in ms -->
|
||||
/>
|
||||
```
|
||||
|
||||
## Best Practices
|
||||
|
||||
1. **Use component-specific loading** for individual components
|
||||
2. **Use global loading** for app-wide operations (login, navigation, etc.)
|
||||
3. **Use operation tracking** for multiple concurrent operations
|
||||
4. **Always use try/finally** when manually controlling loading
|
||||
5. **Prefer async wrappers** over manual start/stop calls
|
||||
6. **Provide meaningful loading messages** to users
|
||||
|
||||
## Error Handling
|
||||
|
||||
```javascript
|
||||
const loadData = async () => {
|
||||
try {
|
||||
const data = await loadingStore.withComponentLoading(
|
||||
"clients",
|
||||
() => Api.getClients(),
|
||||
"Loading clients...",
|
||||
);
|
||||
tableData.value = data;
|
||||
} catch (error) {
|
||||
console.error("Failed to load clients:", error);
|
||||
// Show error message to user
|
||||
// Loading state is automatically cleared by the wrapper
|
||||
}
|
||||
};
|
||||
```
|
||||
Loading…
Add table
Add a link
Reference in a new issue