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:
registry: {
:resource: {
:page: {
...
}
}
}The leave node (:page) can have the following configurations:
{
// 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
tasksmaster-detail page that uses the/checklistitem/endpoint
Steps:
- Create an endpoint in the API
- Map the endpoint in
useHttp.js - Add configuration for
master-detailinuseMasterDetailRegistry.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
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:
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
- Add an alias in
userHttp:
const REGISTRY = {
...
"checklistitem": { service: 'api', path: "/checklistitems/" },
"tasks": { service: 'api', path: "/checklistitems/" }, // alias
..
}- Change mapping name in
getRegistry:
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
- You can specify variants of listitems. The variation should be at the start of the name. For example:
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: **
<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
- Card: This is the typical component used to view the resource. e.g.:
- You can specify variants of cards. Common variants are:
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 withresourceNameto 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:
<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
listitemvalue for our page in the registry.
Edit: src/composeables/userMasterDetailRegistry.js
- Import our listitem,
- add it to the
tasknode in getRegistry
tasks: {
index: {
listitem: {
component: ChecklistItemListItem,
params: {}
}
}
}Notes:
- You can pass extra information in the
paramsfield. This object will be added tov-bindon 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
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:
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
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.
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:
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