# Row Actions, Selection & Bulk Operations

# Row Actions, Selection & Bulk Operations

<details>
<summary>Relevant source files</summary>

The following files were used as context for generating this wiki page:

- [.devin/config.local.json](.devin/config.local.json)
- [.devin/rules/code-guardrails.md](.devin/rules/code-guardrails.md)
- [.devin/rules/file-operations.md](.devin/rules/file-operations.md)
- [.devin/rules/temp-files.md](.devin/rules/temp-files.md)
- [.devin/rules/workflow.md](.devin/rules/workflow.md)
- [src/lib/components/entity-list-table/EntityListTable.svelte](src/lib/components/entity-list-table/EntityListTable.svelte)
- [src/lib/components/entity-list-table/components/BulkActionsToolbar.svelte](src/lib/components/entity-list-table/components/BulkActionsToolbar.svelte)
- [src/lib/components/entity-list-table/composables/index.ts](src/lib/components/entity-list-table/composables/index.ts)
- [src/lib/components/entity-list-table/composables/useBulkActions.svelte.ts](src/lib/components/entity-list-table/composables/useBulkActions.svelte.ts)
- [src/lib/components/entity-list-table/composables/useDialogs.svelte.ts](src/lib/components/entity-list-table/composables/useDialogs.svelte.ts)
- [src/lib/components/entity-list-table/composables/useRowActions.svelte.ts](src/lib/components/entity-list-table/composables/useRowActions.svelte.ts)
- [src/lib/components/entity-list-table/composables/useRowRangeSelection.svelte.ts](src/lib/components/entity-list-table/composables/useRowRangeSelection.svelte.ts)
- [src/lib/components/entity-list-table/composables/useSelection.svelte.ts](src/lib/components/entity-list-table/composables/useSelection.svelte.ts)
- [src/lib/components/entity-list-table/composables/useSheetPanelManagement.svelte.ts](src/lib/components/entity-list-table/composables/useSheetPanelManagement.svelte.ts)
- [src/lib/components/entity-list-table/composables/useSorting.svelte.ts](src/lib/components/entity-list-table/composables/useSorting.svelte.ts)
- [src/lib/components/entity-list-table/composables/useToolbarMode.svelte.ts](src/lib/components/entity-list-table/composables/useToolbarMode.svelte.ts)
- [src/lib/components/entity-list-table/dialogs/BulkDeleteDialog.svelte](src/lib/components/entity-list-table/dialogs/BulkDeleteDialog.svelte)
- [src/lib/components/entity-list-table/dialogs/BulkRestoreDialog.svelte](src/lib/components/entity-list-table/dialogs/BulkRestoreDialog.svelte)
- [src/lib/components/entity-list-table/handlers/selection.ts](src/lib/components/entity-list-table/handlers/selection.ts)
- [src/lib/components/entity-list-table/index.ts](src/lib/components/entity-list-table/index.ts)
- [src/lib/components/entity-list-table/toolbar/EntityListToolbar.svelte](src/lib/components/entity-list-table/toolbar/EntityListToolbar.svelte)

</details>



This section details the interactive layer of the `EntityListTable`, covering how users select records, perform individual row operations, and execute bulk actions across multiple entities. These systems utilize Svelte 5 runes for reactive state management and modular composables to handle API interactions.

## Row Actions

Individual row operations (Edit, Delete, Restore, Duplicate, Preview) are managed by the `useRowActions` composable. This logic is decoupled from the UI to allow consistent behavior across Table and Card views.

### Implementation Details
`useRowActions` provides handlers that either navigate the user (Edit), open side panels (Preview/Version History), or trigger confirmation dialogs (Delete/Restore/Duplicate).

*   **API Integration**: It uses `apiFetch` to communicate with the backend entity endpoints.
    *   **Delete**: `DELETE /api/v1/entities/{entity}/{uuid}` [src/lib/components/entity-list-table/composables/useRowActions.svelte.ts:131-133]().
    *   **Restore**: `POST /api/v1/entities/{entity}/{uuid}/restore` [src/lib/components/entity-list-table/composables/useRowActions.svelte.ts:173-175]().
    *   **Duplicate**: `POST /api/v1/entities/${entity}/duplicate` with the source UUID in the request body [src/lib/components/entity-list-table/composables/useRowActions.svelte.ts:215-219]().
*   **Error Handling**: Errors are intercepted and pushed to the global error system using `pushRFC7807Error` for structured backend errors or `pushImpactError` for generic failures [src/lib/components/entity-list-table/composables/useRowActions.svelte.ts:150-158]().
*   **Version History**: It facilitates loading the audit trail via `loadVersionHistory` [src/lib/components/entity-list-table/composables/useRowActions.svelte.ts:46]().

**Sources:** [src/lib/components/entity-list-table/composables/useRowActions.svelte.ts:56-220](), [src/lib/components/entity-list-table/EntityListTable.svelte:61]()

## Selection System

The selection system supports both simple checkbox toggles and advanced range selection.

### Selection Composables
1.  **useSelection**: Manages the fundamental state of `selectedKeys` (an array of UUIDs). It provides helpers like `toggleRowSelect` and `toggleAllRows` [src/lib/components/entity-list-table/composables/useSelection.svelte.ts:19-75]().
2.  **useRowRangeSelection**: Implements "Shift + Click" and "Click + Drag" range selection.
    *   **Anchor Logic**: It tracks a `rangeAnchorIndex` on `mousedown` [src/lib/components/entity-list-table/composables/useRowRangeSelection.svelte.ts:38]().
    *   **Brush Selection**: As the user drags (`mousemove`), it calculates the range between the anchor and the current index, updating the selection snapshot [src/lib/components/entity-list-table/composables/useRowRangeSelection.svelte.ts:63-87]().
    *   **Safety Guards**: Range selection is disabled if inputs, buttons, or links are the event target [src/lib/components/entity-list-table/composables/useRowRangeSelection.svelte.ts:27]().

### Keyboard Navigation
The `useKeyboardNavigation` composable (integrated into the table lifecycle) allows users to move focus between rows using `ArrowUp`/`ArrowDown` and toggle selection using `Space` or `Enter`.

**Sources:** [src/lib/components/entity-list-table/composables/useSelection.svelte.ts:1-76](), [src/lib/components/entity-list-table/composables/useRowRangeSelection.svelte.ts:3-128](), [src/lib/components/entity-list-table/handlers/selection.ts:1-35]()

## Bulk Operations

When multiple rows are selected, the `EntityListTable` can switch to a "Bulk" mode, providing operations that affect the entire selection set.

### BulkActionsToolbar
The `BulkActionsToolbar` component dynamically replaces or complements the `FilterBar` based on the `toolbarMode` state managed by `useToolbarMode` [src/lib/components/entity-list-table/composables/useToolbarMode.svelte.ts:3-58]().

| Action | Description | Composable Method |
| :--- | :--- | :--- |
| **Bulk Export** | Exports selected rows to XLSX/CSV/PDF | `onBulkExport` |
| **Bulk Duplicate** | Duplicates up to 50 selected records | `confirmBulkDuplicate` |
| **Bulk Delete** | Soft-deletes all selected records | `confirmBulkDelete` |
| **Bulk Restore** | Restores selected records (if all are deleted) | `confirmBulkRestore` |

### useBulkActions
This composable handles the API orchestration for multi-record updates:
*   **Bulk Delete**: Calls `POST /api/v1/entities/{entity}/bulk-delete` with a JSON body containing `uuids: string[]` [src/lib/components/entity-list-table/composables/useBulkActions.svelte.ts:75-81]().
*   **Bulk Restore**: Calls `POST /api/v1/entities/{entity}/bulk-restore` [src/lib/components/entity-list-table/composables/useBulkActions.svelte.ts:153-159]().
*   **State Management**: It tracks `isDeleting`, `isRestoring`, and `isDuplicating` to show loading states in the UI [src/lib/components/entity-list-table/composables/useBulkActions.svelte.ts:59-61]().

**Sources:** [src/lib/components/entity-list-table/components/BulkActionsToolbar.svelte:53-139](), [src/lib/components/entity-list-table/composables/useBulkActions.svelte.ts:44-230]()

## Data Flow Diagrams

### Selection and Range Logic
This diagram bridges the user interaction (Natural Space) to the composables and handlers (Code Space).

```mermaid
graph TD
    User["User Interaction"] -- "Shift+Click / Drag" --> URRS["useRowRangeSelection"]
    User -- "Single Click Checkbox" --> SH["selection handlers"]
    
    URRS -- "applyRowRangeBrush()" --> US["useSelection"]
    SH -- "toggleRowSelect()" --> US
    
    subgraph "Code Entity Space: selection.ts"
        US["useSelection.svelte.ts"]
        URRS
    end
    
    US -- "updates" --> SK["selectedKeys ($state)"]
    SK -- "triggers" --> BAT["BulkActionsToolbar.svelte"]
```
**Sources:** [src/lib/components/entity-list-table/composables/useSelection.svelte.ts](), [src/lib/components/entity-list-table/composables/useRowRangeSelection.svelte.ts]()

### Bulk Action Execution Flow
This diagram tracks the flow from a UI click to the API call and subsequent list refresh.

```mermaid
sequenceDiagram
    participant UI as BulkActionsToolbar
    participant C as useBulkActions
    participant API as apiFetch
    participant L as EntityListTable (onRefresh)

    UI->>C: handleBulkDelete()
    C->>UI: openBulkDeleteDialog()
    Note over UI: User confirms in Dialog
    UI->>C: confirmBulkDeleteWrapper()
    C->>API: POST /api/v1/entities/{entity}/bulk-delete
    API-->>C: 200 OK
    C->>C: onSelectionChange([])
    C->>L: onRefresh()
    Note right of L: Table reloads data
```
**Sources:** [src/lib/components/entity-list-table/composables/useBulkActions.svelte.ts](), [src/lib/components/entity-list-table/components/BulkActionsToolbar.svelte]()

## Selection Counter & "Show Selected Only"

The `SelectionCounter` component displays the number of active selections and provides a toggle for `showSelectedOnly`.

*   **SelectionCounter**: Displays `selectedKeys.length`. If `showSelectedOnly` is enabled, the `EntityListTable` filters its internal `viewRows` to only include those whose keys exist in the selection set.
*   **Client-side Filtering**: This is a client-only mode; it does not trigger a new API request but filters the currently loaded dataset [src/lib/components/entity-list-table/EntityListTable.svelte:42]().

**Sources:** [src/lib/components/entity-list-table/EntityListTable.svelte:26](), [src/lib/components/entity-list-table/composables/useToolbarMode.svelte.ts:6-9]()

---
