Configuring Custom Plugin
From your Custom Dashboards or Schemas Tabs configuration page, you can add the widgets:
You can also add a custom widget directly on your service page, but it will be applied and shown only in that service.
This will bring you to the custom plugin editor, which will be empty by default. Here you can build your widget and preview the output. Check the list of possible widgets and some samples below in this same page.
Custom Plugin JSON Format
A custom plugin is created by specifying an array of plugin option objects. The objects must follow this format:
Copy export type ICustomPluginSchema =
| ICustomPluginList
| ICustomPluginCard
| ICustomPluginSwaggerUI
| ICustomPluginIframe
| ICustomPluginDivider
| ICustomPluginTable
| ICustomPluginChart
| ICustomPluginMarkdown ;
export interface ICustomPluginList {
displayType : "list" ;
schema : string ;
title ?: string ;
fallbackText ?: string ;
item ?: {
title : string ;
subtitle ?: string ;
color ?: string ;
icon ?: string ;
tags ?: string ;
url ?: string ;
};
maxItems ?: number ;
sort ?: IQueryBuilderSort ;
filters ?: IQueryBuilderFilterCondition [];
dateRange ?: ICustomPluginDateRange ;
}
export interface ICustomPluginCard {
displayType : "card" ;
schema : string ;
title ?: string ;
fallbackText ?: string ;
item ?: {
title : string ;
subtitle ?: string ;
icon ?: string ;
url ?: string ;
};
maxItems ?: number ;
sort ?: IQueryBuilderSort ;
filters ?: IQueryBuilderFilterCondition [];
dateRange ?: ICustomPluginDateRange ;
}
export interface ICustomPluginSwaggerUI {
displayType : "swaggerUI" ;
schema : string ;
title ?: string ;
item ?: {
subtitle ?: string ;
title ?: string ;
url ?: string ;
};
maxItems ?: number ;
sort ?: IDataFlexibilitySort ;
filters ?: IDataFlexibilityFilterCondition [];
dateRange ?: ICustomPluginDateRange ;
}
export interface ICustomPluginIframe {
displayType : "iframe" ;
schema : string ;
title ?: string ;
url : string ;
}
export interface ICustomPluginTable {
displayType : "table" ;
schema : string ;
path ?: string ;
title ?: string ;
menu ?: ICustomPluginMenu ;
sort ?: IDataFlexibilitySort ;
filters ?: IDataFlexibilityFilterCondition [];
pageSize ?: number ;
columns ?: string [];
dateRange ?: ICustomPluginDateRange ;
}
export interface ICustomPluginMarkdown {
displayType : "markdown" ;
content ?: string ;
}
type DetailType = "MetaData" ;
type LinksType = "Links" ;
export interface ICustomWidgetAbout {
displayType : "about" ;
sections : {
general : string [];
details : DetailType [];
links : LinksType [];
};
}
export interface ICustomPluginDivider {
displayType : "divider" ;
title ?: string ;
}
export enum QueryBuilderSortDirection {
ASC = 'ASC' ,
DESC = 'DESC' ,
}
export interface IQueryBuilderSort {
field : string ;
direction : QueryBuilderSortDirection ;
}
export enum QueryBuilderFilterType {
compare = 'compare' ,
or = 'or' ,
and = 'and' ,
}
export type IQueryBuilderFilterCondition =
| IQueryBuilderFilterCompare
| IQueryBuilderFilterOr
| IQueryBuilderFilterAnd ;
export interface IQueryBuilderFilterCompare {
type : QueryBuilderFilterType . compare ;
field : string ;
value : string | number | boolean | ( string | number )[] | null ;
compare : QueryBuilderFilterCompare ;
}
export interface IQueryBuilderFilterOr {
type : QueryBuilderFilterType . or ;
conditions : IQueryBuilderFilterCondition [];
}
export interface IQueryBuilderFilterAnd {
type : QueryBuilderFilterType . and ;
conditions : IQueryBuilderFilterCondition [];
}
type RelativeDateUnit = "day" | "week" | "month" | "quarter" | "year" ;
interface IDateRangeRelativeOption {
title : string ;
start : {
value : number ;
unit : RelativeDateUnit ;
};
end : {
value : number ;
unit : RelativeDateUnit ;
};
}
export interface ICustomPluginDateRange {
enabled ?: boolean ;
defaultDateRangeTitle ?: string ;
hideDefaultRelativeOptions ?: boolean ;
relativeOptions ?: IDateRangeRelativeOption [];
}
In addition to this JSON format and following display type examples, Chart Widgets are also available.
This likely looks more complicated than it actually is, especially since we allow complex filtering and sorting. Here's a simple example just to show a list of items with some detailed information inline:
If the schema field is set to empty, the schema being edited itself is used as the data source.
Copy [{
"displayType" : "list" ,
"schema" : "<your_schema_name_here>" ,
"item" : {
"title" : "{{ item.name }}" ,
"subtitle" : "{{ item.description }}"
}
}]
And switching displayType
to card
looks like this:
The editor on the left-hand side will give you some hints if there are issues in the formatting for the code:
Complex examples
Here are a couple more examples of custom plugins with some varying configurations.
List View
This is an example of a plugin with some more detailed data, as well as a max number for the list of items.
Code snippet
Copy [{
"schema" : "<your_schema_here>" ,
"displayType" : "list" ,
"item" : {
"title" : "{{ item.name }}" ,
"subtitle" : "{{ item.severity }}" ,
"icon" : "{{ item.priority }}"
} ,
"maxItems" : 3
}]
This is an example of a plugin with filtering and sorting.
Code snippet
Copy [{
"schema" : "<your_schema_here>" ,
"displayType" : "list" ,
"item" : {
"title" : "{{ item.name }}" ,
"subtitle" : "{{ item.severity }}"
} ,
"filters" : [{
"type" : "compare" ,
"field" : "name" ,
"value" : "CVE-2024-0193" ,
"compare" : "like"
}]
}]
Swagger UI
This is an example of a plugin with basic configuration.
Code snippet
Copy [
{
"displayType" : "swaggerUI" ,
"schema" : "" ,
"item" : {
"title" : "{{ item.name }}" ,
"url" : "{{ item.details.URL }}"
}
}
]
This is an example of a plugin with relational schema's detail. In this example, we are adding a SwaggerUI widget to the service schema. We assume that the service schema has a relation named apiDocs.
Code snippet
Copy [
{
"displayType" : "swaggerUI" ,
"schema" : "apiDocs" ,
"item" : {
"title" : "{{ item.name }}" ,
"url" : "{{ item.details.URL }}"
}
}
]
Iframe
This is an example of a plugin with static iframe url
Code snippet
Copy [
{
"displayType" : "iframe" ,
"schema" : "" ,
"url" : "https://www.youtube.com/embed/jmDIyhwnUEs?si=ira340kUNOfUwLfF"
}
]
This is an example of a plugin with basic configuration
Code snippet
Copy [
{
"displayType" : "iframe" ,
"schema" : "" ,
"url" : "{{item.details.VideoURL}}"
}
]
Table View
This is an example of a plugin with basic configuration
Code snippet
Copy [{
"displayType" : "table" ,
"schema" : "<your_schema_here>" ,
}]
This is an example of a plugin with custom page size and sorting.
Code snippet
Copy [{
"displayType" : "table" ,
"schema" : "scorecards" ,
"pageSize" : 12 ,
"sort" : {
"field" : "evaluatePercentage" ,
"direction" : "ASC"
} ,
}]
This is an example of a plugin with filtering.
Code snippet
Copy [{
"displayType" : "table" ,
"schema" : "scorecards" ,
"pageSize" : 12 ,
"sort" : {
"field" : "evaluatePercentage" ,
"direction" : "ASC"
} ,
"filters" : [{
"type" : "compare" ,
"field" : "evaluatePercentage" ,
"value" : 10 ,
"compare" : "gte"
}] ,
}]
This is an example of a plugin with custom columns.
Code snippet
Copy [{
"displayType" : "table" ,
"schema" : "scorecards" ,
"pageSize" : 12 ,
"sort" : {
"field" : "evaluatePercentage" ,
"direction" : "ASC"
} ,
"filters" : [{
"type" : "compare" ,
"field" : "evaluatePercentage" ,
"value" : 10 ,
"compare" : "gte"
}] ,
"columns" : [ "name" , "evaluatePercentage" ]
}]
This is an example of a plugin with dynamic filters showcasing services owned by the active user or the teams the active user is part of via special keys of "{{me}}" and "{{my-teams}}".
Code snippet
Copy [{
"displayType" : "table" ,
"identifier" : "ExtendedServices" ,
"dateRange" : {
"enabled" : true
} ,
"filters" : [
{
"compare" : "in" ,
"field" : "owners.name" ,
"type" : "compare" ,
"value" : [ "{{me}}" , "{{my-teams}}" ]
}
]
}]
Date Range
This is an example of a plugin using a date range with default options.
Code snippet
Copy [
{
"displayType" : "table" ,
"schema" : "<your_schema_here>" ,
"columns" : [
"name" ,
"accruedCosts" ,
"priorPeriodCosts" ,
"changeCosts"
] ,
"dateRange" : {
"enabled" : true
}
}
]
This is an example of a plugin using a date range without the default relative date options.
Code snippet
Copy [
{
"displayType" : "table" ,
"schema" : "<your_schema_here>" ,
"columns" : [
"name" ,
"accruedCosts" ,
"priorPeriodCosts" ,
"changeCosts"
] ,
"dateRange" : {
"enabled" : true ,
"hideDefaultRelativeOptions" : true
}
}
]
This is an example of a plugin using a default date range period. If defaultDateRangeTitle is not set, the widget will use the "Last week" period by default. This configuration will not affect the preview.
Code snippet
Copy [
{
"displayType" : "table" ,
"schema" : "<your_schema_here>" ,
"columns" : [
"name" ,
"accruedCosts" ,
"priorPeriodCosts" ,
"changeCosts"
] ,
"dateRange" : {
"enabled" : true ,
"defaultDateRangeTitle" : "Last month"
}
}
]
This is an example of a plugin using a date range by adding custom relative date options.
Title: name to be shown on the left side of date picker dialog.
Start: relative date reference for the initial date. Ex. "2-week" is 2 weeks prior to today.
End: relative date reference for the ending date. Ex. "0-day" is today.
Value: number field.
Unit: can be one of the following; "day", "week", "month", "quarter", or "year".
Code snippet
Copy [
{
"displayType" : "table" ,
"schema" : "<your_schema_here>" ,
"columns" : [
"name" ,
"accruedCosts" ,
"priorPeriodCosts" ,
"changeCosts"
] ,
"dateRange" : {
"enabled" : true ,
"hideDefaultRelativeOptions" : true ,
"relativeOptions" : [
{
"title" : "Past 2 weeks" ,
"start" : {
"value" : 2 ,
"unit" : "week"
} ,
"end" : {
"value" : 0 ,
"unit" : "day"
}
}
]
}
}
]
Sample on how to add Buttons for creating or selecting new entities on a widget table
In this sample we are using a new relation created inside the Person schema to add a page for favorite services and applications and adding Buttons to create or map new items.
Code snippet
Copy [
{
"displayType" : "table" ,
"enableAddNewEntity" : true ,
"enableSelectNewEntity" : true ,
"schema" : "PersonFavServices"
}
]
Markdown text
This is an example of a plugin with markdown text.
Code snippet
Copy [
{
"displayType" : "markdown" ,
"content": "# Welcome to My Project\n\n#### \n\n~~Introduction Welcome to my project! This project is focused on providing an amazing experience through the use of modern web technologies.~~"
}
]
About widget
The main purpose of About widget is to display a selection of specific data on the current entity. By default, it will display all fields that are available to it, so this is an example of a basic configuration:
Code snippet
Copy [
{
"displayType" : "about"
}
]
In addition, you have the option to customize the displayed data. All of the fields are divided into 3 sections: general, details and links .
General - this section displays all dynamic fields that are set in your schema.
Details - this section displays all details, e.g. meta data
Links - and here you can see all the established links for the current entity
So here is an example of how you can customize the displayed data:
Code snippet
Copy [
{
"displayType" : "about" ,
"sections" : {
"general" : [
"Owners" ,
"Visibility Control" ,
"Viewers" ,
"Scorecard Metric Level"
] ,
"details" : [ "MetaData" ] ,
"links" : [ "Links" ]
}
}
]
DORA Metrics widgets samples
The widgets shared here use data from Deploys and Incidents schemas and it's relation with each other and services to live calculate and display the 4 Dora Metrics. This data is modelled using configure8 Data Flexibility feature. Check the full docs and samples about the schemas here: Deploys , Incidents .
Full Organization DORA Dashboard
You can build a dashboard that display data from all ORG (across all services) with the following JSON samples. This is how the dashboard looks:
Start by clicking the "Customize" button on the bottom of the Dashboard Menu. There you can add a new page. On the new page, click on the ... box at the top right and start adding tabs and widgets.
Sample JSON code for the widgetsDeployment Frequency:
Copy [
{
"displayType" : "chart" ,
"variant" : "line" ,
"dateRange" : {
"enabled" : true
} ,
"options" : {
"datasets" : [
{
"color" : "green" ,
"identifier" : "deploys" ,
"aggregate" : {
"field" : "Start" ,
"modifier" : "by_date"
} ,
"maxItems" : 200 ,
"filters" : [
{
"compare" : "gte" ,
"field" : "Start" ,
"type" : "compare" ,
"value" : {
"context" : "startDate"
}
} ,
{
"compare" : "lte" ,
"field" : "Start" ,
"type" : "compare" ,
"value" : {
"context" : "endDate"
}
}
] ,
"sort" : {
"direction" : "ASC" ,
"field" : "value"
}
}
] ,
"indexAxis" : "x"
}
}
]
Lead Time for Changes:
Copy [
{
"displayType" : "chart" ,
"variant" : "line" ,
"dateRange" : {
"enabled" : true
} ,
"options" : {
"datasets" : [
{
"color" : "orange" ,
"identifier" : "deploys" ,
"aggregate" : {
"field" : "Start" ,
"modifier" : "by_date"
} ,
"maxItems" : 200 ,
"data" : "{{item.DurationAVG}}" ,
"filters" : [
{
"compare" : "gte" ,
"field" : "Start" ,
"type" : "compare" ,
"value" : {
"context" : "startDate"
}
} ,
{
"compare" : "lte" ,
"field" : "Start" ,
"type" : "compare" ,
"value" : {
"context" : "endDate"
}
}
] ,
"sort" : {
"direction" : "ASC" ,
"field" : "value"
}
}
] ,
"indexAxis" : "x"
}
}
]
Change Failure Rate:
Copy [
{
"displayType" : "chart" ,
"variant" : "line" ,
"dateRange" : {
"enabled" : true
} ,
"options" : {
"datasets" : [
{
"identifier" : "ExtendedServices" ,
"data" : "{{item.DORACFR}}" ,
"aggregate" : {
"field" : "ServiceDeploys.Start" ,
"modifier" : "by_date"
} ,
"maxItems" : 200 ,
"filters" : [
{
"compare" : "gte" ,
"field" : "ServiceDeploys.Start" ,
"type" : "compare" ,
"value" : {
"context" : "startDate"
}
} ,
{
"compare" : "lte" ,
"field" : "ServiceDeploys.Start" ,
"type" : "compare" ,
"value" : {
"context" : "endDate"
}
}
] ,
"sort" : {
"direction" : "ASC" ,
"field" : "value"
} ,
"color" : "orange"
}
]
}
}
]
Mean Time to Restore:
Copy [
{
"displayType" : "chart" ,
"variant" : "line" ,
"dateRange" : {
"enabled" : true
} ,
"options" : {
"datasets" : [
{
"color" : "red" ,
"identifier" : "incidents" ,
"aggregate" : {
"field" : "Start" ,
"modifier" : "by_date"
} ,
"maxItems" : 200 ,
"filters" : [
{
"compare" : "gte" ,
"field" : "Start" ,
"type" : "compare" ,
"value" : {
"context" : "startDate"
}
} ,
{
"compare" : "lte" ,
"field" : "Start" ,
"type" : "compare" ,
"value" : {
"context" : "endDate"
}
}
] ,
"data" : "{{item.DurationAVG}}" ,
"sort" : {
"direction" : "ASC" ,
"field" : "value"
}
}
] ,
"indexAxis" : "x"
}
}
]
Service tab with DORA Dashboard
You can create a similar view in a tab for every service:
For that you need to extend the Service Schema and add a new tab .
Sample JSON code for the Services Widgets
Deployment Frequency:
Copy [
{
"displayType" : "chart" ,
"variant" : "line" ,
"dateRange" : {
"enabled" : true
} ,
"options" : {
"datasets" : [
{
"color" : "green" ,
"schema" : "ServiceDeploys" ,
"aggregate" : {
"field" : "Start" ,
"modifier" : "by_date"
} ,
"maxItems" : 200 ,
"filters" : [
{
"compare" : "gte" ,
"field" : "Start" ,
"type" : "compare" ,
"value" : {
"context" : "startDate"
}
} ,
{
"compare" : "lte" ,
"field" : "Start" ,
"type" : "compare" ,
"value" : {
"context" : "endDate"
}
}
] ,
"sort" : {
"direction" : "ASC" ,
"field" : "value"
}
}
] ,
"indexAxis" : "x"
}
}
]
Lead Time for Changes:
Copy [
{
"displayType" : "chart" ,
"variant" : "line" ,
"dateRange" : {
"enabled" : true
} ,
"options" : {
"datasets" : [
{
"color" : "orange" ,
"schema" : "ServiceDeploys" ,
"aggregate" : {
"field" : "Start" ,
"modifier" : "by_date"
} ,
"maxItems" : 200 ,
"data" : "{{item.DurationAVG}}" ,
"filters" : [
{
"compare" : "gte" ,
"field" : "Start" ,
"type" : "compare" ,
"value" : {
"context" : "startDate"
}
} ,
{
"compare" : "lte" ,
"field" : "Start" ,
"type" : "compare" ,
"value" : {
"context" : "endDate"
}
}
] ,
"sort" : {
"direction" : "ASC" ,
"field" : "value"
}
}
] ,
"indexAxis" : "x"
}
}
]
```
Change Failure Rate:
Copy [
{
"displayType" : "chart" ,
"variant" : "line" ,
"dateRange" : {
"enabled" : true
} ,
"options" : {
"datasets" : [
{
"schema" : "" ,
"data" : "{{item.DORACFR}}" ,
"aggregate" : {
"field" : "ServiceDeploys.Start" ,
"modifier" : "by_date"
} ,
"maxItems" : 200 ,
"filters" : [
{
"compare" : "gte" ,
"field" : "ServiceDeploys.Start" ,
"type" : "compare" ,
"value" : {
"context" : "startDate"
}
} ,
{
"compare" : "lte" ,
"field" : "ServiceDeploys.Start" ,
"type" : "compare" ,
"value" : {
"context" : "endDate"
}
}
] ,
"sort" : {
"direction" : "ASC" ,
"field" : "value"
} ,
"color" : "orange"
}
]
}
}
]
```
Mean Time to Restore:
Copy [
{
"displayType" : "chart" ,
"variant" : "line" ,
"dateRange" : {
"enabled" : true
} ,
"options" : {
"datasets" : [
{
"color" : "red" ,
"schema" : "ServiceIncidents" ,
"aggregate" : {
"field" : "Start" ,
"modifier" : "by_date"
} ,
"maxItems" : 200 ,
"filters" : [
{
"compare" : "gte" ,
"field" : "Start" ,
"type" : "compare" ,
"value" : {
"context" : "startDate"
}
} ,
{
"compare" : "lte" ,
"field" : "Start" ,
"type" : "compare" ,
"value" : {
"context" : "endDate"
}
}
] ,
"data" : "{{item.DurationAVG}}" ,
"sort" : {
"direction" : "ASC" ,
"field" : "value"
}
}
] ,
"indexAxis" : "x"
}
}
]