# Column Visibility Settings

Data tables built with `DataLoader` allow each user to choose which columns are displayed. Right‑click any table header to open the visibility menu. Ticking a box shows or hides that column immediately and saves the preference. The menu lists every available column, including those hidden by default.


<!-- Screenshot omitted in repository for size reasons. See project wiki for a sample image of the menu. -->

Five metadata columns – `parent_id`, `isDeleted`, `updatedAt`, `pendingSync`, and `tenant_id` – are hidden automatically across **all** modules (along with `id` and `createdAt`). Matching is case-insensitive so variants like `isdeleted` or `updatedat` are also hidden. They remain available in the context menu so users can reveal them if needed.

Any column name containing `_id` follows the same rule: it starts hidden unless included in `columnsToShow`. Users may still toggle these ID columns from the visibility menu.

Selecting or clearing these checkboxes persists the choice in the `table_column_settings` table.  
You can also drag items in the same menu to reorder them. The position of each
column is saved in the `column_order` column so DataLoader can restore the
arrangement when the table is reloaded.

## Inheritance Hierarchy

Hidden columns can be defined globally by a **Super Admin**, per tenant by a **Tenant Admin**, and individually per **User**. When `DataLoader` loads a table it merges the lists in that order so user preferences override tenant or global defaults.

## Database Table

Column selections are stored in the `table_column_settings` table:

```sql
CREATE TABLE table_column_settings (
  id SERIAL PRIMARY KEY,
  table_name     varchar(100) NOT NULL,
  user_id        INTEGER DEFAULT NULL,
  tenant_id      INTEGER DEFAULT NULL,
  branch_id      INTEGER DEFAULT NULL,
  hidden_columns jsonb DEFAULT NULL,
  column_order  json DEFAULT NULL,
  isDeleted      BOOLEAN NOT NULL DEFAULT FALSE,
  updatedAt      timestamp NOT NULL DEFAULT current_timestamp
);
```

`column_order` stores an array representing the preferred sequence of columns.
When `NULL` the default order defined by the table schema is used.

`user_id` is populated for personal settings while `tenant_id` and `branch_id` scope the record to an organisation or location. Leaving these fields `NULL` makes the entry global.

## API Endpoints

Use the standard CRUD routes under `/api/table_column_settings` to modify which columns are hidden:

- `GET /api/table_column_settings?table_name=employees` – fetch settings for a table.
- `POST /api/table_column_settings` – create a new setting row.
- `PUT /api/table_column_settings/{id}` – update an existing row.
- `DELETE /api/table_column_settings/{id}` – remove a setting.

When a user changes visibility through the table's context menu, these endpoints
are called under the hood to create or update a row scoped to that user. Editing
the same table via API allows administrators to enforce defaults or reveal the
internal fields listed above.

Updates always reference the stored `tenant_id` and `branch_id` of the record so
that Super Admins can modify global or cross-branch rows regardless of the
current session.

Refer to this file whenever modifying column visibility behaviour.
