Tutorial

04. Customize resources

AdminBro works quite well with a default scaffolding, but what if you want to modify how the Resources look like? You can use ResourceOptions

Resource options

ResourceOptions are passed to the AdminBro along with other configuration options.

...
const Article = require('./models/article')

const adminBroOptions = {
  resources: [
    { resource: Article, options: {'...your options goes here'} },
  ],
  branding: {
    companyName: 'Amazing c.o.',
  },
  ...
}
...

When not passed - AdminBro will use defaults.

How a Resource can be modified?

You have lots of options. You can modify basic appearance of a resource and more complicate aspects, as how a particular field should be rendered.

In the next sections I will point out a couple of options.

{ parent } In the sidebar

By default AdminBro groups resources by the database they belong to. But you can change that and group them in a different way. It can be done by using a parent option.

So let say you want to group all text'ish resources into a content category in the sidebar. You can do this by passing the parent as an option:

const contentParent = {
  name: 'Content',
  icon: 'fa fa-file-text',
}
const adminBroOptions = {
  resources: [
    { resource: Article, options: { parent: contentParent } },
    { resource: BlogPost, options: { parent: contentParent } },
    { resource: Comment, options: { parent: contentParent } },
  ],
}

This will group all Resources together in a "Content" category in a sidebar - and it adds file-text icon from https://fontawesome.com/.

{ name } of a Resource

By default - the name of a Resource is taken from the database collection/table - you can change that by setting a name option.

const adminBroOptions = {
  resources: [
    { resource: Article, options: { name: 'Your custom name' } },
  ],
}

AdminBro has 2 fonts included by default:

You can add your own fonts by using: { assets.styles } setting in AdminBroOptions.

{ xxxProperties } - visibility of properties

It defines which properties should be visible in a list, edit, show and filter views.

Lets say that you have a resource city with 20 fields like: name, lat, lng, population, polution, .... By default AdminBro will render first DEFAULT_MAX_ITEMS_IN_LIST which is 8. What if you want to present just 3 of them in a different order.

You can do this by using listProperties option:

const adminBroOptions = {
  resources: [
    { resource: City, options: { listProperties: ['name', 'population', 'polution'] } },
  ],
}

The same goes with showProperties, editProperties and filterProperties.

{ properties.propertyName } - custom property options

AdminBro allows you to:

  • fully customize how each property should be presented
  • add custom properties

Everything thanks to PropertyOptions.

Visibility of properties { ...propertyName.position } and { ...propertyName.isVisible }

using xxxProperties is not the only way of handling which property should be seen on a list, edit, filter and show views. You can achieve a similar result by using position and isVisible options.

Using them have more sense if you want to disable one particular field, so instead of modifying entire xxxProperties array you can setup just one filed.

In the following example I will hide name field in the list, filter and the edit, but will leave it in a show view.

const adminBroOptions = {
  resources: [
    { resource: City, options: { properties: {
      name: {
        isVisible: { list: false, filter: false, show: true, edit: false },
      }
    }},
  ],
}

You can hide entire field from all views by simply setting isVisible to false.

Also you can simply change position of a field by using position option. By default all fields has position 100, except the title field which gets position -1 - means it will be in the beginning of a list.

Important notice about overriding xxxProperties: both { propertyName.position } and { propertyName.isVisible } will be overriden by xxxProperties if you set it.

{ propertyName.type } of a property

By default types of properties are computed by adapters, see 03. Adding resources torial.

So when you have a DATE field it will be rendered as a date with datepicker and custom from - to filter.

You can change this behaviour by modyfying its type. So for instance you can add a richtext editor to a content like that:

const adminBroOptions = {
  resources: [
    { resource: City, options: { properties: {
      content: { type: 'richtext' },
    }},
  ],
}

And you will see https://quilljs.com editor in place of a regular text field.

Those are supported types:

  • default
  • boolean
  • richtext
  • date
  • datetime
  • reference

{ propertyName.availableValues } narrow down the possible values

when you pass this option to a property it will render the select html element with all the available options.

{
  ...
  name: 'genre',
  label: 'Genre'
  availableOptions: [
    {value: 'male', label: 'Male'},
    {value: 'female', label: 'Female'},
  ],
  ...
}

{ propertyName.component } property appearance

You can also totally change the way of how property is rendered. The only thing you have to do is to change component responsible for rendering given field.

So let say we want to change the way how content property is rendered on the list:

const adminBroOptions = {
  resources: [{
    resource: City,
    options: {
      properties: {
        content: {
          component: {
            list: AdminBro.bundle('./city-content-in-list'),
          },
        },
      },
    },
  }],
}
// city-content-in-list.jsx
import React from 'react'

const CityContentInList = (props) => (
  <div>Some custom content...</div>
)

export default CityContentInList

You can read more about creating your own components in 06. Writing your own Components.

Adding new properties

Also you can add a new properties to the Resource by using a { properties.propertyName }. You just need to define some or all components (list, view, edit, filter). For example if you want to group 'lat' and 'lng' fields on the list and display them as a google map in a show view you can use something like this:

const adminBroOptions = {
  resources: [
    { resource: City, options: { properties: {
      lat: { isVisible: { list: false, show: false, edit: true, filter: true } },
      lng: { isVisible: { list: false, show: false, edit: true, filter: true } },
      map: {
        components: {
          show: AdminBro.bundle('./city-in-a-show'),
        },
        isVisible: {
          show: true, view: false, edit: false, filter: false,
        }
      },
    }},
  ],
}

What's next?

To see all available options - check out the ResourceOptions interface.

You can also read more about creating your own components in 06. Writing your own Components.