Runique Admin

List view — Pagination, sorting, search and filters

The admin list view handles all its operations at the SQL level: pagination, column sorting, full-text search and value filters. Nothing is loaded into memory.

Displayed columns — list_display

By default, all entity columns are shown. Declaring list_display restricts the display to an ordered selection:

admin! {
    users: users::Model => RegisterForm {
        title: "Users",
        list_display: [
            ["username", "Username"],
            ["email", "Email"],
            ["is_active", "Active"],
        ]
    }
}

Each entry is a ["column_name", "Label"] pair. Columns declared in list_display also serve as the sorting whitelist: only these columns (and id) accept a sort_by parameter.

Available in the Tera context via visible_columns (list of names) and column_labels (corresponding labels).

Foreign key resolution

An optional third element in each list_display entry resolves a related table's label instead of displaying the raw ID:

admin! {
    orders: order::Model => order::AdminForm {
        title: "Orders",
        list_display: [
            ["number", "N°"],
            ["user_id", "Customer", "eihwaz_users.username"],   // ← FK
            ["status", "Status"],
        ],
    }
}

The third element syntax is "table.column". The daemon automatically generates:

  • In the list view: a SELECT CAST(id AS TEXT), column FROM table WHERE id IN (...) post-processing query that replaces each ID with the resolved label.
  • In create and edit forms: a <select> dropdown populated from the related table, with the existing value pre-selected in edit mode.

Resolution is compatible with i32, i64 and UUID — the identifier is cast to TEXT before comparison.

FK columns are automatically excluded from full-text search (searching a raw ID is meaningless). Non-FK columns remain indexed normally.

Common examples

["menu_id",  "Menu",     "menus.title"]
["theme_id", "Theme",    "themes.label"]
["user_id",  "Customer", "eihwaz_users.username"]

Configuring builtins — configure

list_display inside a resource body only applies to resources you declare. To configure display for builtin resources (users, droits, groupes) or to centralise all display config, use the top-level configure {} block:

admin! {
    configure {
        users:  { list_display: [["id", "ID"], ["username", "Username"], ["email", "Email"]] },
        droits: { list_display: [["id", "ID"], ["nom", "Name"]] },
    }
    blog: blog::Model => BlogForm { title: "Blog" }
}

The configure {} block supports list_display, list_exclude and list_filter. list_display and list_exclude are mutually exclusive.

Declaring list_filter enables a sidebar showing the distinct values of each field:

admin! {
    users: users::Model => RegisterForm {
        title: "Users",
        list_filter: [
            ["is_active", "Active"],                    // default: 10 values per page
            ["is_superuser", "Superuser"],              // default: 10 values per page
            ["username", "Username", 5],                // explicit limit: 5 values per page
        ]
    }
}
  • For each column, the daemon generates a SQL query that loads distinct values with LIMIT / OFFSET.
  • Sidebar pagination (‹ 1/N ›) is fully server-side via the fp_{column} URL parameter — no JavaScript required.
  • The per-page limit is configured per column via the optional 3rd element (default: 10).
  • Values are displayed as-is (CAST(column AS TEXT)). Do not use list_filter on foreign key (FK) or id columns — the raw value (35, 128…) is not human-readable. Use the search bar instead.
  • Good candidates: booleans, enumerations, short codes (lang, status, block_type).
  • Clicking a value applies a WHERE column = value filter to the SQL query.
  • Multiple filters on different columns are combined with AND.

Column sorting

Each column header is clickable. The resulting URL:

/admin/users/list?sort_by=email&sort_dir=asc&page=1
  • sort_by: column name (must be in list_display or be id)
  • sort_dir: asc or desc
  • Changing the sort automatically resets to page 1

The current direction is shown by ▲ / ▼ in the header. Clicking the same column a second time reverses the direction.

The search bar filters records across all visible text columns (ILIKE '%term%'). It preserves the active sort parameters.

/admin/users/list?search=alice&sort_by=email&sort_dir=asc

The entry counter reflects the filtered result.

Pagination

Pagination is computed at the SQL level (LIMIT / OFFSET). Page size is configured at the application level:

.with_admin(|a| {
    a.site_title("Administration")
     .auth(RuniqueAdminAuth::new())
     .page_size(15)   // ← entries per page (list views AND history)
})

page_size applies to both the resource list view and the history view (/admin/history). The default value is 10.

Active filters and search are preserved in pagination links.

URL parameters

ParameterValueDescription
pageinteger ≥ 1Current page (default: 1)
sort_bycolumn nameSort column
sort_dirasc | descSort direction (default: asc)
searchstringSearch term
filter_{column}valueActive filter on a column
fp_{column}integer ≥ 0Current page of a sidebar filter group (0-indexed)

All parameters can be combined. Priority order: filters → search → sort → pagination.