Auto-generated admin panel for node.js with react Action

Interface

Action

Interface representing an Action in AdminJS. Look at 04. Customize actions to see where you can use this interface.

Example Action

const action = {
  actionType: 'record',
  icon: 'View',
  isVisible: true,
  handler: async () => {...},
  component: AdminJS.bundle('./my-action-component'),
}

There are 3 kinds of actions:

  1. Resource action, which is performed for an entire resource.
  2. Record action, invoked for an record in a resource
  3. Bulk action, invoked for an set of records in a resource

...and there are 7 actions predefined in AdminJS

  1. new (resource action) - create new records in a resource
  2. list (resource action) - list all records within a resource
  3. search (resource action) - search by query string
  4. edit (record action) - update records in a resource
  5. show (record action) - show details of given record
  6. delete (record action) - delete given record
  7. bulkDelete (bulk action) - delete given records

Users can also create their own actions or override those already existing by using ResourceOptions

const AdminJSOptions = {
  resources: [{
    resource: User,
    options: {
      actions: {
        // example of overriding existing 'new' action for
        // User resource.
        new: {
          icon: 'Add'
        },
        // Example of creating a new 'myNewAction' which will be
        // a resource action available for User model
        myNewAction: {
          actionType: 'resource',
          handler: async (request, response, context) => {...}
        }
      }
    }
  }]
}

const { ACTIONS } = require('adminjs')
// example of adding after filter for 'show' action for all resources
ACTIONS.show.after = async () => {...}

Members

After.<T> | Array.<After.<T>>

# after Optional

After action hook. When it is given - it is performed on the returned,

by handler function response.

You can use it to (just an idea)

  • create log of changes done in the app
  • prefetch additional data after original Handler is being performed

Creating a changelog example:

// example mongoose model
const ChangeLog = mongoose.model('ChangeLog', mongoose.Schema({
  // what action
  action: { type: String },
  // who
  userId: { type: mongoose.Types.ObjectId, ref: 'User' },
  // on which resource
  resource: { type: String },
  // was record involved (resource and recordId creates to polymorphic relation)
  recordId: { type: mongoose.Types.ObjectId },
}, { timestamps: true }))

// actual after function
const createLog = async (originalResponse, request, context) => {
  // checking if object doesn't have any errors or is a delete action
  if ((request.method === 'post'
       && originalResponse.record
       && !Object.keys(originalResponse.record.errors).length)
       || context.action.name === 'delete') {
    await ChangeLog.create({
      action: context.action.name,
      // assuming in the session we store _id of the current admin
      userId: context.currentAdmin && context.currentAdmin._id,
      resource: context.resource.id(),
      recordId: context.record && context.record.id(),
    })
  }
  return originalResponse
}

// and attaching this function to actions for all resources
const { ACTIONS } = require('adminjs')

ACTIONS.edit.after = [createLog]
ACTIONS.delete.after = [createLog]
ACTIONS.new.after = [createLog]

View Source adminjs/src/backend/actions/action.interface.ts, line 414

Before | Array.<Before>

# before Optional

Before action hook. When it is given - it is performed before the Action#handler

method.

Example of hashing password before creating it:

actions: {
  new: {
    before: async (request) => {
      if(request.payload.password) {
        request.payload = {
          ...request.payload,
          encryptedPassword: await bcrypt.hash(request.payload.password, 10),
          password: undefined,
        }
      }
      return request
    },
  }
}

View Source adminjs/src/backend/actions/action.interface.ts, line 388

string | number | Array.<(string|number)>

# containerWidth Optional

The max width of action HTML container.

You can put here an actual size in px or an array of widths, where different values will be responsible for different breakpoints. It is directly passed to action's wrapping Box component, to its width property.

Examples


// passing regular string
containerWidth: '800px'

// passing number for 100% width
containerWidth: 1

// passing values for different breakpoints
containerWidth: [1, 1/2, 1/3]

View Source adminjs/src/backend/actions/action.interface.ts, line 483

boolean | IsFunction

# isAccessible Optional

Indicates if the action can be invoked for given invocation context.

You can pass a boolean or function of type IsFunction, which takes ActionContext as an argument.

You can use it as a carrier between the hooks.

Example for isVisible function which allows the user to edit cars which belongs only to her:

const canEditCars = ({ currentAdmin, record }) => {
  return currentAdmin && (
    currentAdmin.role === 'admin'
    || currentAdmin._id === record.param('ownerId')
  )
}

new AdminJS({ resources: [{
  resource: Car,
  options: { actions: { edit: { isAccessible: canEditCars } } }
}]})
See:

View Source adminjs/src/backend/actions/action.interface.ts, line 241

boolean | IsFunction

# isVisible Optional

indicates if action should be visible for given invocation context.

It also can be a simple boolean value. True by default. The most common example of usage is to hide resources from the UI. So let say we have 2 resources User and Cars:

const User = mongoose.model('User', mongoose.Schema({
  email: String,
  encryptedPassword: String,
}))
const Car = mongoose.model('Car', mongoose.Schema({
  name: String,
  ownerId: { type: mongoose.Types.ObjectId, ref: 'User' },
})

so if we want to hide Users collection, but allow people to pick user when creating cars. We can do this like this:

new AdminJS({ resources: [{
  resource: User,
  options: { actions: { list: { isVisible: false } } }
}]})

In contrast - when we use Action#isAccessible instead - user wont be able to pick car owner.

See:

View Source adminjs/src/backend/actions/action.interface.ts, line 205

LayoutElementFunction | Array.<LayoutElement>

# layout Optional

Definition for the layout. Works with the edit and show actions.

With the help of LayoutElement you can put all the properties to whatever layout you like, without knowing React.

This is an example of defining a layout

const layout = [{ width: 1 / 2 }, [
    ['@H3', { children: 'Company data' }],
    'companyName',
    'companySize',
  ]],
  [
    ['@H3', { children: 'Contact Info' }],
    [{ flexDirection: 'row', flex: true }, [
      ['email', { pr: 'default', flexGrow: 1 }],
      ['address', { flexGrow: 1 }],
    ]],
  ],
]

Alternatively you can pass a function taking CurrentAdmin as an argument. This will allow you to show/hide given property for restricted users.

To see entire documentation and more examples visit LayoutElement

See:

View Source adminjs/src/backend/actions/action.interface.ts, line 505

boolean

# showFilter Optional

If filter should be visible on the sidebar. Only for _resource_ actions

Example of creating new resource action with filter

new AdminJS({ resources: [{
  resource: Car,
  options: { actions: {
    newAction: {
      type: 'resource',
      showFilter: true,
    }
  }}
}]})

View Source adminjs/src/backend/actions/action.interface.ts, line 271

Type Definitions

object

# ActionRequest

ActionRequest

Properties:
Name Type Attributes Description
params object

parameters passed in an URL

resourceId string

Id of current resource

recordId string <optional>

Id of current record (in case of record action)

recordIds string <optional>

Id of selected records (in case of bulk action) divided by commas

action string

Name of an action

query string <optional>

an optional search query string (for search resource action)

{...} any
payload Record.<string, any> <optional>

POST data passed to the backend

query Record.<string, any> <optional>

Elements of query string

method 'post' | 'get'

HTTP method

View Source adminjs/src/backend/actions/action.interface.ts, line 48