# Form Page Layout & Audit Box

# Form Page Layout & Audit Box

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

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

- [src/lib/components/AppPageLayout.svelte](src/lib/components/AppPageLayout.svelte)
- [src/lib/components/AppPageScaffold.svelte](src/lib/components/AppPageScaffold.svelte)
- [src/lib/components/FormPageLayout.svelte](src/lib/components/FormPageLayout.svelte)
- [src/lib/components/entity-list-table/utils/auditable-fields.ts](src/lib/components/entity-list-table/utils/auditable-fields.ts)
- [src/lib/components/entity-list-table/utils/cell-formatting.ts](src/lib/components/entity-list-table/utils/cell-formatting.ts)
- [src/lib/components/ui/metadata-loading/MetadataLoading.svelte](src/lib/components/ui/metadata-loading/MetadataLoading.svelte)
- [src/lib/composables/useAuditBox.ts](src/lib/composables/useAuditBox.ts)
- [src/lib/composables/useEntityMetadata.svelte.ts](src/lib/composables/useEntityMetadata.svelte.ts)
- [src/lib/template-interpolate.ts](src/lib/template-interpolate.ts)

</details>



The Form Page Layout and Audit Box system provides a standardized UI framework for entity creation and editing. It integrates entity metadata, auditable field tracking, and version history access into a cohesive layout used across the Primebrick backoffice.

## FormPageLayout Component

`FormPageLayout.svelte` is the primary wrapper for entity detail pages. It enforces a consistent structure consisting of a header, a scrollable content area, and a split footer containing audit information and form actions.

### Component Structure
The layout uses Svelte 5 snippets to define distinct regions:
*   **header**: Optional snippet for custom breadcrumbs and titles [src/lib/components/FormPageLayout.svelte:49-50]().
*   **title / headerExtras**: Standardized header configuration if the `header` snippet is not provided [src/lib/components/FormPageLayout.svelte:51-60]().
*   **children**: The main form content, rendered within a bordered, background-colored container [src/lib/components/FormPageLayout.svelte:62-66]().
*   **footerActions**: Snippet for primary form buttons (e.g., Save, Cancel), placed in the bottom-right of the layout [src/lib/components/FormPageLayout.svelte:157-159]().

### The Split Footer
The footer is divided into a 50/50 grid [src/lib/components/FormPageLayout.svelte:70]():
1.  **Left (Audit Box)**: Displays record metadata including version, creation date, update date, and the unique ID [src/lib/components/FormPageLayout.svelte:72-154]().
2.  **Right (Actions)**: Contains the `footerActions` snippet [src/lib/components/FormPageLayout.svelte:156-160]().

**Sources:**
*   [src/lib/components/FormPageLayout.svelte:1-160]()
*   [src/lib/components/AppPageScaffold.svelte:27-47]()

---

## Audit Box Logic (useAuditBox)

The `useAuditBox` composable encapsulates the logic for extracting and formatting audit-related fields from the entity's metadata and raw data.

### Field Extraction
It filters the `auditingColumns` provided in the metadata to categorize fields by their lifecycle purpose:
*   `getDeletedFields`: Returns columns starting with `deleted_` [src/lib/composables/useAuditBox.ts:19-21]().
*   `getUpdatedFields`: Returns columns starting with `updated_` [src/lib/composables/useAuditBox.ts:23-25]().
*   `getCreatedFields`: Returns columns starting with `created_` [src/lib/composables/useAuditBox.ts:31-33]().
*   `getSyncFields`: Returns columns starting with `last_synced_` [src/lib/composables/useAuditBox.ts:27-29]().

### Formatting Pipeline
The `formatValue` function handles the display of audit data, ensuring that technical values (like timestamps or UUIDs) are human-readable [src/lib/composables/useAuditBox.ts:39-81]():
1.  **Booleans**: Converts to "true"/"false" strings.
2.  **Badges**: Maps raw values to `labelText` defined in column metadata.
3.  **Dates/DateTimes**: Uses `formatUiDateTime` or `formatUiDate` with the current `uiLang` [src/lib/composables/useAuditBox.ts:58-67]().
4.  **Auditable Fallback**: Uses `getAuditableDisplayValue` to check for `_name` field suffixes (e.g., showing "John Doe" instead of the UUID in `created_by`) [src/lib/composables/useAuditBox.ts:71-75]().

### Data Flow: Audit Metadata to UI
The following diagram illustrates how raw entity data and metadata columns are processed by the composable for display in the `FormPageLayout`.

**Audit Box Data Transformation**
```mermaid
graph TD
    subgraph "Input Data"
        A["auditData (Record)"]
        B["auditingColumns (MetaColumn[])"]
    end

    subgraph "useAuditBox Composable"
        C["getCreatedFields()"]
        D["getUpdatedFields()"]
        E["formatValue()"]
        F["getAuditableDisplayValue()"]
    end

    subgraph "UI Elements"
        G["Version Badge"]
        H["Created At/By Label"]
        I["Updated At/By Label"]
        J["Entity ID Display"]
    end

    B --> C
    B --> D
    A --> E
    B --> E
    E --> F
    F --> H
    F --> I
    A --> G
    A --> J
```

**Sources:**
*   [src/lib/composables/useAuditBox.ts:1-96]()
*   [src/lib/components/entity-list-table/utils/auditable-fields.ts:43-65]()

---

## Entity Metadata Integration

The `useEntityMetadata` composable manages the lifecycle of fetching entity-specific configuration, which includes the `auditingColumns` required for the Audit Box.

### Metadata Loading & Validation
The `loadMetadata` function performs a fetch to the entity's metadata endpoint and includes critical validation guards:
*   **Validation**: It checks if `list.auditingColumns` exists and is non-empty. If missing, it logs a `[METADATA PARSING ERROR]` and pushes a `HIGH` impact error to the global error system [src/lib/composables/useEntityMetadata.svelte.ts:44-60]().
*   **State Management**: It exposes reactive `$state` for `meta`, `loading`, and `error` [src/lib/composables/useEntityMetadata.svelte.ts:30-32]().

### MetadataLoading Component
While metadata is being fetched, the `MetadataLoading.svelte` component is displayed. It features a rotating `RefreshCw` icon over a `Cloud` icon and displays localized loading text [src/lib/components/ui/metadata-loading/MetadataLoading.svelte:22-32]().

**Entity Metadata Interface**
| Property | Type | Description |
| :--- | :--- | :--- |
| `entity` | `string` | Internal entity identifier |
| `titleKey` | `string` | i18n key for the page title |
| `uid` | `string` | The primary key field name (e.g., "uuid") |
| `list.auditingColumns` | `MetaColumn[]` | Definition of fields used for the Audit Box |

**Sources:**
*   [src/lib/composables/useEntityMetadata.svelte.ts:5-12]()
*   [src/lib/composables/useEntityMetadata.svelte.ts:34-109]()
*   [src/lib/components/ui/metadata-loading/MetadataLoading.svelte:1-33]()

---

## Auditable Field Utilities

Centralized utilities in `auditable-fields.ts` and `cell-formatting.ts` ensure that audit data is displayed consistently between the `EntityListTable` and the `FormPageLayout`.

### Display Name Fallback
The function `getAuditableDisplayValue` implements the logic for "Friendly Names":
1.  Checks if a column key ends with `_by` (e.g., `updated_by`) [src/lib/components/entity-list-table/utils/auditable-fields.ts:52]().
2.  Looks for a corresponding `_name` field in the row data (e.g., `updated_by_name`) [src/lib/components/entity-list-table/utils/auditable-fields.ts:53-54]().
3.  Returns the `_name` value if it exists and is not blank; otherwise, returns the raw ID [src/lib/components/entity-list-table/utils/auditable-fields.ts:57-64]().

### Implementation Map
The following diagram shows the relationship between UI components and the utility functions that provide formatted data.

**System Component Mapping**
```mermaid
graph LR
    subgraph "UI Layer"
        FPL["FormPageLayout.svelte"]
        TC["TableCell.svelte"]
        VH["VersionHistoryPanel.svelte"]
    end

    subgraph "Logic Layer (Composables)"
        UAB["useAuditBox.ts"]
    end

    subgraph "Utility Layer"
        ADV["getAuditableDisplayValue()"]
        ISB["isBlankish()"]
        GDF["getDisplayNameFieldKey()"]
    end

    FPL --> UAB
    UAB --> ADV
    TC --> ADV
    VH --> ADV
    ADV --> GDF
    ADV --> ISB
```

**Sources:**
*   [src/lib/components/entity-list-table/utils/auditable-fields.ts:29-65]()
*   [src/lib/components/entity-list-table/utils/cell-formatting.ts:10-21]()

---

## Version History Integration

The Audit Box includes a version badge (e.g., `v3`) when the `version` field is present in the entity data [src/lib/components/FormPageLayout.svelte:76-89]().

Clicking this badge triggers `auditBox.openVersionHistory()`, which utilizes the global `openSheet` manager to display the `entity.versionHistory` side panel [src/lib/composables/useAuditBox.ts:83-85](). This panel receives the `entity` name and `rowUuid` to fetch the full audit trail from the backend.

**Sources:**
*   [src/lib/components/FormPageLayout.svelte:78-87]()
*   [src/lib/composables/useAuditBox.ts:83-85]()

---
