Admin UI Configuration
The Admin UI is configured through the ActiveAdminConfiguration object passed to addActiveAdmin().
Configuration Overview
| Property | Type | Default | Description |
|---|---|---|---|
| path | string | /active-admin | Base path for admin UI |
| title | string | Function | ActiveQL UI | Page title |
| entities | object | {} | Per-entity configuration |
| pageSize | number | 20 | Items per page |
| viewPath | string | admin/views | Custom view directory |
| menu | object | auto-generated | Menu structure |
| selectVsSearchThreshold | number | 10 | When to show search vs dropdown |
| locale | string | en | Locale for formatting |
| uploadTempPath | string | data/temp/ | Temporary upload directory |
| login | Function | - | Login handler |
| principalForToken | Function | - | Token validation |
| init | Function | - | Post-init hook |
Basic Example
import { addActiveAdmin } from 'activeql-active-admin';
const config = {
path: '/admin',
title: 'My Application Admin',
pageSize: 25,
locale: 'de',
entities: {
User: {
// Entity configuration
},
Product: {
// Entity configuration
}
}
};
await addActiveAdmin(config);path
path?: string| Type | Default | Description |
|---|---|---|
string | /active-admin | Base URL path for admin UI |
The admin UI will be accessible at this path. All entity routes will be nested under it.
Example
{
path: '/admin'
}The admin UI will be available at http://localhost:3000/admin.
title
title?: string | ((activeAdmin: ActiveAdmin) => string)| Type | Default | Description |
|---|---|---|
string | Function | ActiveQL UI | Page title displayed in header |
Can be a static string or a function returning a string.
Example
{
title: 'My Application Admin'
}
// Or dynamic
{
title: (activeAdmin) => `Admin - ${process.env.APP_NAME}`
}entities
entities?: { [name: string]: EntityUIConfiguration }| Type | Default | Description |
|---|---|---|
object | {} | Per-entity UI configuration |
See Entity configuration for details.
Example
{
entities: {
User: {
collectionTitle: () => 'Users',
itemTitle: (ui, item) => item.email,
fields: {
email: { label: 'Email Address' }
}
}
}
}pageSize
pageSize?: number| Type | Default | Description |
|---|---|---|
number | 20 | Number of items per page in index views |
Example
{
pageSize: 50
}viewPath
viewPath?: string| Type | Default | Description |
|---|---|---|
string | admin/views | Directory for custom view templates |
You can provide custom Eta templates to override the default views.
Example
{
viewPath: 'src/admin/views'
}menu
menu?: { [name: string]: MenuType | MenuTypeFn }| Type | Default | Description |
|---|---|---|
object | auto-generated | Menu structure |
See Menu configuration for details.
Example
{
menu: {
'Main': ['User', 'Product'],
'Settings': [
{ label: 'System Settings', path: '/settings' }
]
}
}selectVsSearchThreshold
selectVsSearchThreshold?: number| Type | Default | Description |
|---|---|---|
number | 10 | Item count threshold for dropdown vs search |
When an association has fewer items than this threshold, a dropdown is shown. Otherwise, a search field is used.
Example
{
selectVsSearchThreshold: 25
}locale
locale?: string| Type | Default | Description |
|---|---|---|
string | en | Locale for number and date formatting |
Example
{
locale: 'de'
}uploadTempPath
uploadTempPath?: string| Type | Default | Description |
|---|---|---|
string | data/temp/ | Directory for temporary file uploads |
Example
{
uploadTempPath: '/tmp/uploads/'
}login
login?: (runtime: ActiveQLServer, props: { email: string, password: string }) => Promise<{ token?: string }>| Type | Default | Description |
|---|---|---|
Function | - | Custom login handler |
See Authentication for details.
Example
{
login: async (runtime, { email, password }) => {
const user = await authenticateUser(email, password);
if (user) {
return { token: generateJWT(user) };
}
return {};
}
}principalForToken
principalForToken?: (token: string, runtime: ActiveQLServer) => Promise<Principal | undefined>| Type | Default | Description |
|---|---|---|
Function | - | Token validation handler |
See Authentication for details.
Example
{
principalForToken: async (token, runtime) => {
try {
const decoded = verifyJWT(token);
return new Principal(decoded.userId, decoded.roles);
} catch {
return undefined;
}
}
}init
init?: (activeAdmin: ActiveAdmin) => void| Type | Default | Description |
|---|---|---|
Function | - | Called after initialization |
Use this hook for post-initialization setup.
Example
{
init: (activeAdmin) => {
console.log('Admin UI initialized at', activeAdmin.path);
}
}saveFiles
saveFiles?: (entity: Entity, item: any, files: any) => Promise<void>| Type | Default | Description |
|---|---|---|
Function | LocalFileHandler | Custom file save handler |
Override the default file persistence logic.
getFileUrl
getFileUrl?: (entity: Entity, url: string) => string| Type | Default | Description |
|---|---|---|
Function | LocalFileHandler | Custom file URL generation |
Override how file download URLs are generated.
Complete Example
import { addActiveAdmin } from 'activeql-active-admin';
const config = {
path: '/admin',
title: 'E-Commerce Admin',
pageSize: 25,
locale: 'en',
selectVsSearchThreshold: 15,
uploadTempPath: '/tmp/uploads/',
entities: {
User: {
collectionTitle: () => 'Users',
itemTitle: (ui, item) => `${item.firstName} ${item.lastName}`,
fields: {
email: { label: 'Email' },
firstName: { label: 'First Name' },
lastName: { label: 'Last Name' }
},
index: { fields: ['email', 'firstName', 'lastName'] }
},
Product: {
collectionTitle: () => 'Products',
itemTitle: (ui, item) => item.name,
fields: {
name: { label: 'Product Name' },
price: { label: 'Price' }
}
}
},
menu: {
'Main': ['User', 'Product'],
'Reports': [
{ label: 'Sales Report', path: '/reports/sales' }
]
},
login: async (runtime, { email, password }) => {
const user = await runtime.entity('User').findOneByAttribute({ email });
if (user && await verifyPassword(password, user.password)) {
return { token: generateJWT(user) };
}
return {};
},
principalForToken: async (token, runtime) => {
const decoded = verifyJWT(token);
return new Principal(decoded.userId, decoded.roles);
},
init: (activeAdmin) => {
console.log('Admin initialized');
}
};
await addActiveAdmin(config);