Note: This refers to software in development and is subject to change.
UI plugins allow you to add your own functionality to BriteCore without having to introduce any changes into BriteCore’s codebase. To do so, you need to:
- Know of a plugin slot that supports your functionality.
- Write a plugin using the BriteCore provided JavaScript library.
- Host your plugin in a publicly accessible location.
- Register the plugin (support is in development).
Plugin slots
Plugin slots are predefined sections of BriteCore’s UI where third parties can connect their plugins.
For example, BriteCore provides a plugin slot called britequote:risk-edit::bottom-row:button-row
, which lets users add custom action buttons into the quoting form.
Each plugin slot type may have instances spread in multiple locations in the UI; the standard format for naming is {product}:{page}:{location}:{slot-type}
. For example, the button-row
slot could be available in different places across the system:
britequote:risk-edit:bottom-row:button-row
Each plugin slot can be placed in multiple locations on a given page. The plugin slot name property controls in which part of the page a plugin slot should be available. For instance, the britequote:risk-edit:bottom-row:button-row
plugin slot is placed in the sidebar location of the quoting form.
Plugin slots reference
BriteCore UI offers slots in its UI where developers can extend the functionality of the UI.
button-row
The button-row
slot allows you to plug in action buttons on various pages. The slot is going to render the buttons that the plugin requested during its initialization and will call the plugin callbacks upon clicking the button.
Details
- Slot type: button-row.
- Slot instances in the UI:
britequote:risk-edit:bottom-row:button-row
andbritequote:risk-edit:sidebar:button-row
- Interface: requires an object upon initialization
Example initialization object:
{ buttons: [{
text: 'Capitalize',
callback: capitalizeFields
}]
}
The callback function must be defined in your plugin file and it will be called whenever the button is clicked.
The button-row
slot type allows developers to write plugins to read data from a page, process this data and send the results back to the page.
Such buttons can get the input data in a context object and do any computations, third party services lookups, validations, etc. As a result, they can emit events back to BriteCore UI with new data. Then, the latter can apply the changes on the data used by the page.
This button-row
slot type is currently available in two locations:
- britequote:risk-edit:sidebar:button-row
- britequote:risk-edit:bottom-row:button-row
Plugins connected to this slot will receive the following parameters in their context input object:
- riskType
- riskTypes
- riskTypeState
- riskState
- config
- pluginConfig
- quote
- rootRiskQuote
Plugins connected to this slot are expected to emit the following events up to BriteCore-UI:
- update-risk
- create-and-update-risk
- attachFileToQuote
- displayErrors
- displayMessage
- showLodaingIndicator
- create-and-update-risk
Write a plugin
JavaScript Library
BriteCore provides a beta JavaScript library you can use to build your plugins.
Add the script tag to your plugin HTML file:
<script src="https://d1zol2vqugn1g2.cloudfront.net/britecore-ui-plugins.js">
</script>
Then, you can use the BriteCorePlugin
helper so your plugin can communicate with BriteCore:
let plugin = new BriteCorePlugin('Plugin Name')
plugin.initialize({
'slot-name': slotInput
})
The slotInput
object will vary upon the plugin slot you want to connect to.
Example: the button-row
slot with a single button:
let plugin = new BriteCorePlugin('Plugin Name')
plugin.initialize({
'button-row': {
buttons: [{
text: 'Lookup',
callback: lookupDetails,
visible: true,
enabled: false,
}]
}
})
Hosting
Each plugin is a HTML document rendered in a hidden iframe. BriteCore’s UI queries the plugins available and renders any plugin on the specified pages.
Since BriteCore’s UI runs in a browser, the request for the plugin must occur without credentials to a publicly available location, or BriteCore must host the plugin placing the HTML file behind our authentication.
Plugins often query other restricted resources. If the plugin is served from a domain that also has access to the credentials, it’s possible to use those.
Example:
ABC Insurance Company allows logged in agents to quote. Upon logging in, ABC Insurance stores an access token in the local storage of the browser. A plugin served from https://www.ABCInsurance.com can access the local storage for that domain and use the access token to make further requests.
Integrating
A central plugin registry provides the following data to BriteCore’s UI:
{
"name": "vendor",
"base_url": "https://www.example.com",
"plugin_slots": [
{
"slot_name": "britequote:risk-edit:sidebar:button-row",
"plugin_file_path": "/my/plugin",
"execution_trigger": None,
"fields_to_watch": [],
}
],
}
The registry is currently within the source code, with plans to provide an API to manage the registry.
Example: Write a new BriteCore plugin to capitalize fields in the quoting form
Writing a new plugin will depend on which type of plugin you want to create. There must be an existent plugin slot that:
- Is in the UI location where you want load your plugin.
- Allows for the behavior you want your plugin to have.
Use case: the Capitalizer plugin
BriteCore UI provides a slot that allows a third party plugin to render an action button to execute actions on a quoting form: the button-row
slot.
Create the plugin HTML file
The contract that a plugin has to implement to connect to the button-row
slot requires you to provide a label for the button and a callback function capable of reading the form fields from a context object and sending a JSON Patch object with the changes you want to make to the form data.
Once you load the JavaScript library in your plugin HTML file, you can able to use the BriteCorePlugin helper class to connect your plugin to BriteCore via the initialize method.
This is how the Capitalizer plugin would look like:
<html>
<head>
<script src='https://d1zol2vqugn1g2.cloudfront.net/britecore-ui-plugins.js'></script>
<script>
const PLUGIN_NAME = 'Capitalizer'
function capitalize(thing) {
return thing.replace(/^\w/, c => c.toUpperCase())
}
function capitalizeFields (context) {
let fa = context.field_answers
const jsonPatch = [
{op: 'replace', path: '/field_answers/make', value: capitalize(fa.make)},
{op: 'replace', path: '/field_answers/model', value: capitalize(fa.model)},
]
this.emit(PLUGIN_NAME + '-update-risk', jsonPatch) // this namespaces the event and is important
}
let plugin = new BriteCorePlugin(PLUGIN_NAME)
plugin.initialize({
'button-row': {
buttons: [{
text: 'Capitalize',
callback: capitalizeFields,
visible: true,
enabled: true,
}]
}
})
</script>
</head>
</html>
We are initializing the plugin with an object where the keys are the slots that our plugin needs to interact with and the values are the objects expected during the slot initialization.
We are providing an array of objects containing a label, a callback function to handle the form data and send the JSON Patch object back, and two booleans for visibility and an enabled state.
Upon load, the BriteCorePlugin
object will start the connection to the plugin slot and, once that is done, it will emit an initialization event to the slot, sending along the object with the buttons it wants to be rendered. The slot will be waiting for such an event and will render the buttons wherever it is placed.
Object Reference
- quote: the response of this endpoint
- rootRiskQuote: the response of this endpoint
riskTypes keys and description include:
- id: Unique risk type ID
- label: Risk type label
- name: Risk type name
- parentRiskTypeId: Risk type ID of parent risk type
- __typename: Type of entity i.e. RiskType
Example:
[
{
"id": "246fcbdc-42e9-4cdc-9783-0efa82cef984",
"label": "Accident/Violation (5 Year History)",
"name": "violations",
"parentRiskTypeId": "e1711652-8450-4492-b965-ed3a016152c3",
"__typename": "RiskType"
},
{
"id": "e1711652-8450-4492-b965-ed3a016152c3",
"label": "Driver",
"name": "drivers",
"parentRiskTypeId": "6bf23139-95ff-45ed-856e-b079573d851a",
"__typename": "RiskType"
},
{
"id": "6bf23139-95ff-45ed-856e-b079573d851a",
"label": "Policy",
"name": "policy",
"parentRiskTypeId": null,
"__typename": "RiskType"
},
{
"id": "3cbccfb0-68e6-4b21-ac18-176c1ea70496",
"label": "Private Passenger Auto",
"name": "privatePassengerAutos",
"parentRiskTypeId": "6bf23139-95ff-45ed-856e-b079573d851a",
"__typename": "RiskType"
}
]
riskState keys and descriptions include:
- id: Unique risk ID.
- meta: Meta data information e.g. static_id.
- name: Risk name as calculated via risk_name_template.
- type: Risk type information e.g. Risk Type name, label and ID.
- number: Risk number is calculated based on type. It can be used in calculations to know how many risks of a particular type have been added.
- total_premium: Sum of all enabled items coverages premium.
- pro_rata: Sum of all enabled Items coverages pro rata.
- items: Enabled and soft deleted items on risk. If an item contains deleted_at key, this means that the item is soft deleted. This key will only be present for soft deleted items in Endorsement transactions.
- field_answers: Fields answers for enabled items.
- detached_answers: Field answers for items which are disabled/unchecked by user. Used later to repopulate associated fields of an item when it gets re-enabled.
- detached_items: Contains name of items having presence Default or Optional which are removed from risk.
- field_overrides: Contains replacement properties for fields defined in risk type state depending on the current risk state.
- item_overrides: Contains replacement properties for items defined in risk type state depending on the current risk state.
- calculations: Contains resolved shared calculations.
- rate_tables: Contains resolved rate tables.
- deleted_at: Contains a datetime string if the risk was soft deleted. This key will only be present for soft deleted risks in Endorsement transactions.
- children: Array containing child risks, if any.
Example:
{
"schema_version": "1.3",
"id": "c26fffcd-7897-4384-98c4-95de6b0902e8",
"meta": {
"static_id": "012f3c80-23d5-4b32-bda4-7961b2356002"
},
"name": "Vehicle 1",
"type": {
"label": "Vehicle",
"id": "3aa43696-8c18-49d6-8c6d-dc03b5081e98",
"name": "vehicles"
},
"number": 1,
"total_premium": 54.0,
"pro_rata": {
"value": 0.0
},
"items": {
"additionalEquipment": {
"premium": 45.0,
"pro_rata": {
"value": null
},
"limits": {
"perRiskLimit": 100.0,
"policyAggregateLimit": 500.0
},
"deductible": 20.0
},
"medicalExpense": {
"premium": 0.0,
"pro_rata": {
"value": 0
},
"deleted_at": "2020-07-28T00:00:00+00:00"
}
},
"field_answers": {
"additionalEquipmentCoverageLimit": "501-1000",
"vin": "5YJSA1E28HF190648",
"make": "Tesla",
"model": "Model S",
"chosenDriver": ""
},
"detached_answers": {
"towingLimit": "75"
},
"detached_items": ["towing"],
"field_overrides": {
"chosenDriver": {
"options": [
{
"value": "ef763124-8b7f-4016-ac54-7d07e4adfe70",
"label": "John Doe"
}
]
}
},
"item_overrides": {
"towing": {
"visible": false
}
},
"calculations": {
"driverFactor": 1.0
},
"rate_tables": {
"towingRateTable": 0
},
"deleted_at": null,
"children": []
}