Skip to content

Home > Frontend > Master/detail

Master detail pages

Master detail pages provide a general framework for quickly displaying and managing API resources

URLs and configuration

The URL for a master detail page is:

:page/:resource/:resourceId

  • page - maps to a configuration for displaying the resource/resourceId. A resource/resourceId can have manage pages
  • resource - mapes to a defined resource in the master-detail's config
  • resourceId - ID of resource instance

Master registry

  • The master page has a registry at: const registry
  • The lookups on this object are:
json:

registry: {
    :resource: {
        :page: {
            ...
        }
    }
}

The leave node (:page) can have the following configurations:

json
{
  // NOTE: you can only define one of master or listitem
  // on the standard list view, you can specify the component and props to pass to that ListItem
  listitem: {
    component: ..,
    props: {..}
  },
  // A specific component to render the master page
  master: ..,
  detail: { // the component used to render the detailview
    component: .., // component for displaying the master page
    props: { .. }
  },
}

ListItem

What is it:

configuration:

You can pass the following configuration to listitem

Adding a master-detail page

For this example, we will create a tasks master-detail page that uses the /checklistitem/ endpoint

Steps:

  1. Create an endpoint in the API
  2. Map the endpoint in useHttp.js
  3. Add configuration for master-detail in useMasterDetailRegistry.js

1. Create API Endpoint

.. this is done in the backend

2. Map the endpoint

In src/composeables/useHttp.js ensure that your endpoint is mapped

js
const REGISTRY = {
  ..
  "checklist": { service: 'api', path: "/checklists/" },
  ..
}

3. Add configuration

The minimal configuration that you can add is just to add an empty stub for your resource in src/composeables/userMasterDetailRegistry.js. In getRegistry, add a block:

js
const getRegistry = function (listReq, detailReq) {
    return {
      ...
      checklistitem: {
        index: {}
      }
      ...
    }
}

Now if you go to: /index/checklistitem/ you will see a json list of checklist items

Advanced topic: customize urls/names

In this example, we would prefer our url and resource name (on the frontend) to be tasks

  1. Add an alias in userHttp:
js
const REGISTRY = {
  ...
  "checklistitem": { service: 'api', path: "/checklistitems/" },
  "tasks": { service: 'api', path: "/checklistitems/" }, // alias
  ..
}
  1. Change mapping name in getRegistry:
js
const getRegistry = function (listReq, detailReq) {
    return {
      ...
      task: {
        index: {}
      }
      ...
    }
}

Customizing our master-detail

With minimal customization you can get started. With just the above we have a page that will spit out the json data that we are getting back from our resource endpoint.

All customization is done by specifying components to handle the display of the data received.

Conventions:

Pages are often made up of fairly

ListPages

ListItems

  • Location: /src/components/listitems/
  • Naming convention: :Resource:ListItem. For example: TaskListItem
    • You can specify variants of listitems. The variation should be at the start of the name. For example: MinimalTaskListItem

Required props:

  • Object: item - the object that is passed to the listitem

Common props:

  • Boolean: withMenu - if this listitem should include the action menu for this object
Basic ListItem

**Example: **

html
<template>
  <v-list-item>

    <v-list-item-title>{{ item.name }}</v-list-item-title>
    <v-list-item-subtitle>...</v-list-item-subtitle>

  </v-list-item>

</template>

<script setup >

// props
const props = defineProps({
  item: { type: Object, required: true }
})

</script>

Cards

Cards are used to show details of an object and are typically generated from the data from the detail view of a resources endpoint

  • Location: /src/components/cards/
  • Naming convention: :Resource:Card. For example: TaskCard
    • You can specify variants of cards. Common variants are:
      • Card: This is the typical component used to view the resource. e.g.: TaskCard
      • Page: A Page is a very detailed component used to display the maximum amount of information on a resource. e.g.: TaskPage
      • Preview: This component is used to preview information on a resource. It is typically displayed as a popover with more information that is shown the user hovers over a resource. e.g.: TaskPreviewCard

Required props:

  • Object: modelValue - the object that is passed to the card

Common props:

  • String resourceName - The resource
  • Number: objectId - can be used in conjunction with resourceName to fetch a complete object from the backend - useful if the model being passed in is not complete
  • Boolean withClose - if a close icon should be displayed (should emit @closed)
  • Boolean withMenu - if the ActionMenu for this resource should be displayed
Basic card

Example:

html

<template>
<v-card >
  <v-card-title ></v-card-title>
  <v-card-text ></v-card-text>
</v-card>
</template>

<script setup>

import { ref, computed, defineProps, defineEmits } from 'vue'

const emit = defineEmits(['update:modelValue'])

const props = defineProps({
  modelValue: { type: Object, required: true }
})

const task = computed(() => props.modelValue)

</script>

Customizing the list page

1. Adding a listitem

To add a listitem, we just need to add a listitem value for our page in the registry.

Edit: src/composeables/userMasterDetailRegistry.js

  • Import our listitem,
  • add it to the task node in getRegistry
json
tasks: {
  index: {
    listitem: {
      component: ChecklistItemListItem,
      params: {}
    }
  }
}

Notes:

  • You can pass extra information in the params field. This object will be added to v-bind on the component

2. Adding a list page component

If you want to completely customize the master page, you can provide a custom component for displaying the details.

Edit: src/composeables/userMasterDetailRegistry.js

json
tasks: {
  index: {
    listitem: {
      component: ChecklistItemListItem,
      params: {}
    }
  },
  calendar: {
    master: CalendarPage,
  }
}
  • In this example, I have added a whole new page (in addition to the default index page) - the "calendar" page will be available as a tab

You could of course just update the index page:

json
tasks: {
  index: {
    master: CalendarPage,
  },
}

3. Add some custom buttons

We can add a component to the navigation bar This allows us to, for example, add some quick filters to our list view

Edit: src/composeables/userMasterDetailRegistry.js

json
tasks: {
  index: {
    listitem: {
      component: ChecklistItemListItem,
      params: {}
    },
    extraNavigation: {
      component: ChecklistItemButtons,
      params: {}
    }
  }
}
  • This will include the ChecklistItemButtons component in the navigation bar

Adding alternate list views

For some resources, you may want to display the same data in a different way. For example, you may want to display the same data in a calendar or kanban view.

Step 1: Add a definition for our new page

Edit: src/composeables/userMasterDetailRegistry.js

The default page (the one we have been using so far) is called index. We can add a new page by adding a new stub with a new name.

json
tasks: {
  index: {
    ...
  },
  kanban: {
    master: {
      component: KanbanPage,
    },
    props: { // these will be v-binded to the component
      field: 'status',
      colValues: ['Not Started', 'In Progress', 'Completed']
    },
  }
}

Customizing the detail page

The detail page shows when the user clicks on a list item. It typically diplays as a slide-out side-navigation on the right

To add a component for the detail page, add the detail section:

json
      tasks: {
        index: {
          listitem: {
            component: ChecklistItemListItem,
            params: {}
          },
          detail: {
            component: ChecklistItemCard,
            params: {}
          },
        }
      }

MasterPage Components

Index

The default views, will display a list of ListItems for the provided resource

KanBan

Show items in a kanban board of columns defined by a field value

Calendar (coming soon)

Adding a "new" button