Tutorial

03. 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.',
  },
  ...
}
...

AdminBro will use the default settings if you omit options property.

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 them. For the full list visit the ResourceOptions interface.

{ 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 navigation 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 navigation as an option:

const contentNavigation = {
  name: 'content',
  icon: 'Accessibility',
}
const adminBroOptions = {
  resources: [
    { resource: Article, options: { navigation: contentNavigation } },
    { resource: BlogPost, options: { navigation: contentNavigation } },
    { resource: Comment, options: { navigation: contentNavigation } },
  ],
}

This will group all the Resources together, in a "Content" category in a sidebar - and it assigns the Accessibility icon to it. What you give here is passed to Icon Component.

As you see we passed name: 'content' but AdminBro changed that to 'Content'. This is because, by default, all texts are "Start Cased".

You can provide any translation text to it by using the translation label: see tutorial 09. Internationalization (i18n).

Renaming a Resource

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

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

Take a look at tutorial: 09. Internationalization (i18n) and 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 overwritten by xxxProperties if you set it.

{ [propertyName].isTitle }

As I mentioned a title property goes first in the list of all properties, and in smaller screens, only this property stays. Also, title property is the property on which you can search in autocomplete (by default).

AdminBro tries to pick title property automatically. It is the property with name "name" or "email". You can change this behavior by setting PropertyOptions#isTitle for the default property to false and, for the new property, to true.

{ [propertyName].type } of a property

By default types of properties are computed by adapters, see tutorial: 02. Adding 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 a 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 components in this tutorial: 05. Writing your own Components.

Adding new (virtual) 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 tutorial: 05. Writing your own Components.

What's next?

To see all available options - check out the

There is an another very important section in ResourceOptions - actions. It gives you the ability to modify existing actions like edit or delete or add new actions. Go to the next tutorial: 04. Customize actions to read more about them.

You can also read more about creating your own components in this tutorial: 05. Writing your own Components.

SoftwareBrothers

Proudly built and maintained by SoftwareBrothers

Software House with a passion for both JavaScript and TypeScript.

See what we do See what we believe in

Proudly built and maintained by

SoftwareBrothers