AdminJS Documentation
repository·master·Indexed 26 days ago
https://github.com/softwarebrothers/adminjsAdminJS is an automatic admin interface for Node.js applications (version 7.8.17) that generates a management UI based on provided database models. It provides CRUD operations, custom business actions, form validation, and a customizable dashboard. The framework allows developers to implement custom database, record, and resource adapters by extending base classes like BaseDatabase and BaseResource, and offers decorators for fine-tuning actions, properties, and resources.
What's inside AdminJS
- AdminJS is an automatic admin interface designed to be plugged into Node.js applications. By providing your database models (e.g., posts, comments, products), AdminJS automatically generates a UI that allows developers or trusted users to manage application content. It is inspired by tools like Django Admin and Rails Admin.
Understand the AdminJS Data Model and Flattening
masterAdminJS uses a flattened data model for the
paramsproperty in both the backend (BaseRecord#params) and the frontend (RecordJSON.params).Instead of storing raw nested objects or arrays, AdminJS converts them into a flat
{ [key: string]: any }structure using dot notation for nested properties and index notation for arrays. This approach ensures that updates to specific nested fields (e.g., via an ORM like Mongoose) do not accidentally overwrite entire parent objects, and it allows for efficient data transmission using theFormDataformat (which requires string-based keys).Key Features of AdminJS
masterAdminJS provides several core capabilities for managing application data and logic:
- CRUD operations: Perform Create, Read, Update, and Delete actions on any data resource.
- Custom actions: Implement specific business logic as actions on your resources.
- Form validation: Automatically validate forms based on the schema defined in your resources.
- Dashboard: A full-featured dashboard that supports custom widgets.
- Resource decorators: Apply custom decorators to your resources to modify their behavior or appearance.
Use the onChange callback in custom components
masterWhen building custom property type components for the
editorfilterviews, you can use theonChangecallback to update the record's state. TheonChangefunction accepts two different signatures:- Single argument: Pass an entire
RecordJSONobject to replace the current record state. - Two arguments: Pass the
property.path(string) as the first argument and the newvalueas the second argument.
This is useful for creating components that trigger changes to other properties on the same record (e.g., a button that updates a name field).
import React from 'react' import { Button, Box } from '@adminjs/design-system' const ValueTrigger = (props) => { const { onChange, record } = props const handleClick = (): void => { // Passing the entire updated record as a single argument onChange({ ...record, params: { ...record.params, name: 'my new name', }, }) } return ( <Box mb="xxl"> <Button type="button" onClick={handleClick}>Set Name</Button> </Box> ) } export default ValueTrigger- Single argument: Pass an entire
React dependency requirements for AdminJS v6
masterAdminJS v6 requiresreactandreact-domversionv18.1.0+. If your project uses React outside of AdminJS, you must upgrade your project's React version to match. AdminJS v6 also usesstyled-componentsversionv5.3.5to ensure compatibility with React 18.Override default property rendering logic
masterYou can customize how specific properties are rendered in the AdminJS UI by passing a custom component to
PropertyOptions. TheBasePropertyComponentautomatically selects components based on property type and context (list, edit, show, or filter), but you can override this behavior for specific properties.To override a component, define a
componentsobject within the property's configuration in your resource options. You can target specific UI contexts such asshow,edit,list, orfilter.const AdminJS = require('adminjs') const ResourceModel = require('./resource-model') const AdminJSOptions = { resources: [{ resource: ResourceModel, options: { properties: { name: { components: { show: 'MyReactComponent', }, }, }, }, }], }Implement custom routing and authentication logic
masterIf you are not using a standard plugin like
@adminjs/express, you can manually implement the AdminJS router in your own HTTP framework.To do this, you must:
- Iterate through
Router.routesand map them to your framework's routing system. Note that you must convert AdminJS path parameters from{param}syntax to your framework's syntax (e.g.,:paramfor Express). - Instantiate the
route.Controllerwith theadmininstance and thecurrentAdmin(the authenticated user). - Call the controller method corresponding to
route.action, passing the request, params, query, and a payload containingfieldsandfiles. - Iterate through
Router.assetsto serve static files using the providedasset.srcpath. - Handle authentication by wrapping the route handlers with your own logic (e.g., checking a session).
const { Router } = require('adminjs') const { routes, assets } = Router const router = new express.Router() // 1. Handle Routes routes.forEach((route) => { // Convert {param} to :param for Express const expressPath = route.path.replace(/{/g, ':').replace(/}/g, '') const handler = async (req, res, next) => { try { // Implement authentication logic here const currentAdmin = null const controller = new route.Controller({ admin }, currentAdmin) const { params, query } = req const method = req.method.toLowerCase() const payload = { ...(req.fields || {}), ...(req.files || {}), } const html = await controller[route.action]({ ...req, params, query, payload, method, }, res) if (route.contentType) { res.set({ 'Content-Type': route.contentType }) } if (html) { res.send(html) } } catch (e) { next(e) } } if (route.method === 'GET') router.get(expressPath, handler) if (route.method === 'POST') router.post(expressPath, handler) }) // 2. Handle Assets assets.forEach((asset) => { router.get(asset.path, async (req, res) => { res.sendFile(path.resolve(asset.src)) }) })- Iterate through
Update AdminJS to v6
masterTo upgrade to version 6, use npm to install the latest version of
adminjs. This will update bothadminjsandadminjs-design-systemto the newest beta versions. If you haveadminjs-design-systemexplicitly listed in your dependencies, ensure you update it accordingly.npm install adminjsCustomize action layouts with LayoutElement
masterUse thelayoutproperty on anAction(such asedit,show, ornew) to change the default layout of the page. The layout is defined as anArray<LayoutElement>. AdminJS renders these elements using React components. While you don't need to know React, you can useBoxPropsto style the components, asBoxis the default wrapper.Populate references using the populator utility
masterThe
populatorutility fromadminjsis used to automatically populate all fields marked as 'reference' (viaPropertyOptions#reference) within a set of records. This is particularly useful when creating custom action handlers where you need to retrieve data directly from the database and want the returned JSON to include the full objects for referenced entities instead of just their IDs.const { populator } = require('adminjs') // action handler for showing product with categories const showProductsHandler = async (request, response, context) => { const { payload } = request const { _admin, currentAdmin } = context const ProductResource = _admin.findResource('Product') const product = await ProductResource.findOne() // product.populated is empty const [populatedProduct] = await populator([product]) // populatedProduct.populated - has a categoryId filled with Category params return { record: record.toJSON(currentAdmin) // returns RecordJSON with populated field as well } }Define and customize AdminJS Actions
masterActions in AdminJS can be applied to an entire resource, a specific record, or a set of selected records (bulk). You can create new actions or override existing built-in actions (like
new,edit,show,delete, etc.) within theoptions.actionsobject of a resource configuration.Action Types:
resource: Performed for an entire resource (e.g.,new,list,search).record: Invoked for a single record (e.g.,edit,show,delete).bulk: Invoked for a set of records (e.g.,bulkDelete).
Built-in Actions:
show,edit,list,delete,bulkDelete,new,search.
const AdminJSOptions = { resources: [{ resource: User, options: { actions: { // Overriding an existing action new: { icon: 'Add' }, // Creating a new resource action myNewAction: { actionType: 'resource', handler: async (request, response, context) => { // implementation } } } } }] }RichText input changes in AdminJS v6
masterAdminJS v6 has migrated the RichText implementation from Quill to TipTap due to security and support requirements. As a result, all previous Quill-related configurations are no longer valid and should be removed or updated to the new TipTap-based implementation.