Skip to content

Repository files navigation

Adminizer — Admin Panel for AdonisJS

adonisjs-adminizer-provider is a package for AdonisJS 7+ that allows you to quickly add a fully-featured administrative panel to your application. Supports user and group management, media files, change history, notifications, filters, and multilingual support.

Features

  • CRUD for system and business models — automatically generated forms and lists
  • User and group management — built-in role system with manyToMany relationships
  • Authentication and self-registration — login, logout, user registration with default group configuration
  • Media manager — file uploads (images, videos, text documents), automatic image variant generation
  • Change history — tracking all create/update/delete actions on business models
  • Notifications — internal notification system with channels and read tracking
  • Saved filters — named filters with conditions, sorting, and visibility for users
  • Multilingual support (i18n) — support for multiple languages in the admin panel interface
  • Dashboard — admin panel start page with customizable title and text
  • AI Assistant — experimental AI assistant support (OpenAI, dummy)
  • Customizable navigation — additional links in navbar, custom sections

Requirements

  • Node.js 24+
  • AdonisJS ^7.0.0
  • Lucid ORM ^22.0.0
  • SQLite / PostgreSQL / MySQL

Installation

Step 1: Install the package

npm install adonisjs-adminizer-provider

Step 2: Configure the package

Run the configuration command, which automatically:

  • Adds the provider to .adonisrc.ts
  • Defines environment variables (JWT_SECRET, AP_PASSWORD_SALT)
  • Creates migrations (11 files) for system tables
  • Creates models (10 files) in app/models/adminizer/
  • Creates the configuration file config/adminizer.ts
node ace configure adonisjs-adminizer-provider

Step 3: Run migrations

node ace migration:run

After this, the admin panel is available at /admin.


Configuration

The configuration file config/adminizer.ts consists of three main parts.

1. models — Model Registration

Here you register system models (generated by the package) and your application's business models:

import AdminizerUser from '#models/adminizer/adminizer_user'
import AdminizerGroup from '#models/adminizer/adminizer_group'
import AdminizerFilter from '#models/adminizer/adminizer_filter'
import AdminizerFilterColumn from '#models/adminizer/adminizer_filter_column'
import AdminizerHistoryAction from '#models/adminizer/adminizer_history_action'
import AdminizerNotification from '#models/adminizer/adminizer_notification'
import AdminizerUserNotification from '#models/adminizer/adminizer_user_notification'
import AdminizerMedia from '#models/adminizer/adminizer_media'
import AdminizerMediaMeta from '#models/adminizer/adminizer_media_meta'
import AdminizerMediaAssociation from '#models/adminizer/adminizer_media_association'
import Category from '#models/category'
import Test from '#models/test'

export default defineConfig({
    models: {
        // System models (do not change unless necessary)
        AdminizerUser: {
            Model: AdminizerUser,
            overrides: {
                apiKey: { columnName: 'userApiKey' },
            },
        },
        AdminizerGroup: { Model: AdminizerGroup },
        AdminizerFilter: { Model: AdminizerFilter },
        AdminizerFilterColumn: { Model: AdminizerFilterColumn },
        AdminizerHistoryAction: { Model: AdminizerHistoryAction },
        AdminizerNotification: { Model: AdminizerNotification },
        AdminizerUserNotification: {
            Model: AdminizerUserNotification,
            overrides: {
                notificationId: {
                    type: 'association',
                    model: 'Notification',
                    via: 'notificationId',
                    sourceRelation: 'notification',
                },
            },
        },
        AdminizerMedia: { Model: AdminizerMedia },
        AdminizerMediaMeta: { Model: AdminizerMediaMeta },
        AdminizerMediaAssociation: { Model: AdminizerMediaAssociation },

        // Your application's business models
        Category: { Model: Category },
        Test: { Model: Test },
    },
    // ...
})

Each entry can include overrides to reassign column names or associations.

2. systemModels — System Role Mapping

Maps internal adminizer model names to your Lucid models:

systemModels: {
    User: 'AdminizerUser',
    Group: 'AdminizerGroup',
    Filter: 'AdminizerFilter',
    FilterColumn: 'AdminizerFilterColumn',
    HistoryActions: 'AdminizerHistoryAction',
    Notification: 'AdminizerNotification',
    UserNotification: 'AdminizerUserNotification',
},

3. adminpanelConfig — Admin Panel Settings

Detailed information here

adminpanelConfig: {
    // Default model — records per page
    list: {
        defaultPageSize: 5
    },

    // ORM (always 'lucid' for this package)
    system: {
        defaultORM: 'lucid',
    },

    // Media manager
    mediamanager: {
        fileStoragePath: 'public',
        allowMIME: ['image/*', 'application/*', 'text/*', 'video/*'],
        maxByteSize: 1024 * 1024 * 2, // 2 MB
        imageSizes: {
            lg: { width: 750, height: 750 },
            sm: { width: 350, height: 350 },
        },
    },

    // Notifications
    notifications: {
        enabled: true,
        enableGeneral: true,
        initTab: 'general',
    },

    // Change history
    history: {
        enabled: true,
        adapter: "default",
        // excludeModels: ["SomeModel"] // Exclude a model from history
    },

    // Saved filters (experimental)
    filters: {
        enabled: false
    },

    // CORS
    cors: {
        enabled: false,
        origin: 'http://localhost:3000',
        path: 'api/*'
    },

    // AI Assistant (experimental)
    aiAssistant: {
        enabled: false,
        defaultModel: 'openai-data',
        models: ['openai-data', 'dummy'],
    },

    // Admin panel URL prefix
    routePrefix: '/admin',

    // Authentication
    auth: {
        enable: true
    },

    // New user registration
    registration: {
        enable: true,
        defaultUserGroup: "guest",
        confirmationRequired: false
    },

    // Dashboard
    dashboard: true,

    // Additional navbar links
    navbar: {
        additionalLinks: []
    },

    // Custom sections
    sections: [],

    // Dashboard welcome page
    welcome: {
        title: 'Demo AdonisJS adminpanel',
        text: 'Demo text'
    },

    // Multilingual support
    translation: {
        locales: ['en'],
        directory: 'custom-locales',
        defaultLocale: 'en'
    },

    // Documentation link
    showVersion: {
        link: 'https://docs.adminizer.org',
        hint: 'Adminizer documentation',
    },
}

Connecting Business Models

Simple Model

To connect a simple model, simply add it to models:

// config/adminizer.ts
import Test from '#models/test'

models: {
    Test: { Model: Test },
}

Model with mediamanager / single-file fields

Models with fields for file uploads (JSON type) are automatically recognized:

// database/migrations/create_categories_table.ts
schema.create('categories', (table) => {
    table.increments('id')
    table.string('slug').unique()
    table.string('title')
    table.text('description').nullable()
    table.json('svgs')          // Multiple SVG upload
    table.json('images')        // Multiple image upload
    table.json('single')        // Single file upload
    table.timestamp('created_at')
    table.timestamp('updated_at')
})
// config/adminizer.ts
import Category from '#models/category'

models: {
    Category: { Model: Category },
}

In adminpanelConfig.models you can configure field display:

adminpanelConfig: {
    models: {
        Category: {
            fields: {
                svgs: {
                    groupName: 'graphics',
                    accept: 'image/svg+xml',
                    displayName: 'SVG icons',
                },
                images: {
                    groupName: 'photos',
                    accept: 'image/*',
                    displayName: 'Images',
                },
                single: {
                    displayName: 'File',
                },
                createdAt: {
                    visible: false, // Hide field from UI
                },
                updatedAt: {
                    visible: false,
                },
            },
            // CRUD operation access control
            add: true,
            edit: true,
            view: true,
            remove: true,
        },
    },
}

Model with Associations

Models with Lucid associations (belongsTo, hasMany, manyToMany) are automatically displayed in the UI:

// models/test.ts
import { belongsTo, HasMany, column, BaseModel } from '@adonisjs/lucid/orm'
import Example from '#models/example'

export default class Test extends BaseModel {
    @column({ isPrimary: true })
    declare id: number

    @column()
    declare name: string

    @column()
    declare description: string

    @column()
    declare exampleId: number

    @belongsTo(() => Example)
    declare example: Example
}
// config/adminizer.ts
models: {
    Test: { Model: Test },
}

Features

Authentication and Self-Registration

Built-in login and registration system for admin panel users. Configured in adminpanelConfig:

auth: {
    enable: true                    // Enable login
},
registration: {
    enable: true,                   // Enable registration
    defaultUserGroup: "guest",      // Default group
    confirmationRequired: false     // Require confirmation
},

After setting registration.enable: true, any visitor can register at /admin/register.

Media Manager

Full-featured media library:

  • Support for images, videos, text files, documents
  • Automatic creation of image thumbnails (lg, sm)
  • MIME type filtering
  • File size limits
  • File attachment to model records and widgets

Configured in adminpanelConfig.mediamanager:

mediamanager: {
    fileStoragePath: 'public',       // Storage folder
    allowMIME: ['image/*', 'application/*', 'text/*', 'video/*'],
    maxByteSize: 1024 * 1024 * 2,   // Max 2 MB
    imageSizes: {
        lg: { width: 750, height: 750 },
        sm: { width: 350, height: 350 },
    },
},

Change History

Automatically logs all create/update/delete operations on business models:

history: {
    enabled: true,
    adapter: "default",
    // excludeModels: ["SomeModel"]  // Exclude a model from history
},

Each record contains: action type, record ID, data, JSON diff between old and new versions.

Notifications

Internal notification system:

  • Create notifications through interface or code
  • Notification channels (general, personal, etc.)
  • Read tracking
  • Customizable metadata
notifications: {
    enabled: true,
    enableGeneral: true,
    initTab: 'general',
},

Saved Filters

Experimental feature — named filters for models:

  • Filter conditions (JSON)
  • Sort configuration
  • Visibility (private / group shared)
  • API key for external requests
filters: {
    enabled: true  // Disabled by default (experimental)
},

Multilingual Support (i18n)

Support for multiple languages in the admin panel interface:

translation: {
    locales: ['en', 'ru'],              // Available languages
    directory: 'custom-locales',        // Translations folder
    defaultLocale: 'en',                // Default language
},

Translations are stored in custom-locales/ relative to the project root.

Module System

Modules can be attached to adminizer on the fly. In AdonisJS, this can be done through a provider:

import type { ApplicationService } from '@adonisjs/core/types'
import {NotificationSenderApp} from "../app/adminizer_apps/notification-sender/NotificationSenderApp.js"; // your module

export default class AdminizerAppProvider {
  constructor(protected app: ApplicationService) {}

  /**
   * Register bindings to the container
   */
  register() {}

  /**
   * The container bindings have booted
   */
  async boot() {}

  /**
   * The application has been booted
   */
  async start() {}

  /**
   * The process has been started
   */
  async ready() {
      const adminizer = await this.app.container.make('adminizer');

      await adminizer.appManager.enable(new NotificationSenderApp());
  }

  /**
   * Preparing to shutdown the app
   */
  async shutdown() {}
}

For more detailed information about modules, see the documentation

Important!

Your provider must be placed below adonisjs-adminizer-provider in adonisrc.ts:

  {
    file: () => import('adonisjs-adminizer-provider/provider'),
        environment: ['web'],
},
{
    file: () => import('#providers/adminizer_app_provider'),
        environment: ['web'],
}

About

AdonisJS provider for Adminizer — a full-featured admin panel with a Lucid ORM adapter

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages