# 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
  }
};
```
