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 go 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 the basic appearance of a resource and more complicated aspects, as to 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: 'Accessibility',
}
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 assigns Accessibility icon to it. Shat you give here is passed to Icon Component.

By default all the texts are "Start Cased". You can provide any translation text to it by using translation label: 09-i18n.

Renaming a Resource

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

const adminBroOptions = {
  resources: [
    { resource: Article, options: {...} },
  ], 
  locale: {
    translations: {
      labels: {
        Article: 'Amazing Article'
      }
    }
  },
}

Take a look at 09-i18n to read more about internationalization in AdminBro.

{ xxxProperties } - visibility of properties

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

Let's say that you have a resource city with 20 fields like name, lat, lng, population, pollution, .... 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 set up 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 an entire field from all views by simply setting isVisible to false.

Also, you can simply change the position of a field by using position option. By default all fields have position 100, except the title field which gets position -1 - means it will be at 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-passing-resources tutorial.

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 behavior by modifying 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.

Supported types can be found here

{ [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'
  availableValues: [
    {value: 'male', label: 'Male'},
    {value: 'female', label: 'Female'},
  ],
  ...
}

{ [propertyName].components } property appearance

You can also totally change the way of how property is rendered. The only thing you have to do is to change components 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: {
          components: {
            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-react-components.

Adding new properties

Also, you can add 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,
        }
      },
    }},
  ],
}

Then you will have to create city-in-a-list.jsx react component (or .tsx for TypeScript). To see how to do this visit 06-writing-react-components.

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.