@swimlane/swimlane-element
v2.5.0
Published
`SwimlaneElement` is a simple base class for creating Swimlane platform widgets using [lit-html](https://lit-html.polymer-project.org/) templating.
Downloads
14,299
Maintainers
Keywords
Readme
SwimlaneElement
SwimlaneElement is a simple base class for creating Swimlane platform widgets using lit-html templating.
Building
Run npm run build to build SwimlaneElement. The build artifacts will be stored in the build/ directory.
Development server
Run npm run start to serve the demo.
Release
- Checkout master (
git checkout master) - Pull master (
git pull) - Refresh node modules (
npm ci) - Examine log to determine next version (X.Y.Z)
- Run
git checkout -b release/X.Y.Z - Update version in
package.json. - Update changelog in
CHANGELOG.md - Run
git commit -am "(release): X.Y.Z" - Run
git tag X.Y.Z - Run
git push origin HEAD --tags - Run
npm run publish - Submit PR
Overview
LitElement (https://lit-element.polymer-project.org/) is a webcomponent base class that uses lit-html (https://lit-html.polymer-project.org/) templating library. LitElement (https://lit-element.polymer-project.org/) uses lit-html to render into the element's Shadow DOM and adds API to react to changes in properties.
SwimlaneElement extends from LitElement to add API for interacting with records or reports in the Swimlane platform.
Getting Started
/**
* Import `SwimlaneElement` class.
* The `css` and `html` methods are also imported from `swimlane-element`.
*/
import { SwimlaneElement, css, html } from '@swimlane/swimlane-element@1';
/**
* The `recordFrameTemplate` is a template function see templates below.
*/
import { recordFrameTemplate } from '@swimlane/swimlane-element@1/templates.js';
/**
* A Swimlane widget is implemented as an anonymous class which extends the `SwimlaneElement` class.
*/
export default class extends SwimlaneElement {
/**
* The `styles()` getter is a static class getter, in other words, it is a property defined on the class constructor.
* This style getter method does not have access to any properties stored in the objects.
* This getter defines styles common to all instances of this widget.
* Defining this in your widget is optional.
*/
static get styles() {
return [super.styles, css`
.frame::after {
content: "Record Output";
}
`];
}
/**
* The `render` method is an instance method and, therefore, has access to properties stored in the object (i.e. `record` and `report`, see properties below.
* The render method is scheduled by `LitElement` Lifecycle events and must return a `lit-html` template.
* Defining this method in your widget is required.
*/
render() {
return recordFrameTemplate(html`
<pre>${JSON.stringify(this.record, undefined, 2)}</pre>
`);
}
}Properties
LitElement efficiently manages declared properties and attributes. By default SwimlaneElement declares record or report properties as well as the 'contextData' property. Documentation on how LitElement handles properties and attributes can be found here.
this.record- Available to record widgets, an object containing key-value pairs for each field on the record.this.report- Available to report widgets, an object containingdata,rawData, andquery.this.contextData- Available to both record and report widgets, an object containing data such asapplication,currentUser,origin, andtoken.
Templates
To define a template for a SwimlaneElement component, write a render function that returns a lit-html template. More details on writing render methods can be found in the documentation for LitElement and lit-html. The swimlane-element library includes predefined templates designed for the Swimlane platform. These templates can be imported from @swimlane/swimlane-element@1/templates.js.
recordFrameTemplate- A base template for rendering a frame on the record page. This function takes as arguments a template to render inside the frame and an optionalrowsheight value. Without a definedrowsvalue the frame will auto size to the content.reportFrameTemplate- A base template for rendering a frame on the dashboards. This function takes as arguments a template to render inside the frame and an optionalrowsheight value. Without a definedrowsvalue the frame will auto size to the content.
Styles
As with LitElement there are "three main places in which you can define styles for your host element" ref. The two most common methods for SwimlaneElements will be to Define styles in a static styles property or Define styles in a style element.
Events
Documentation on how to handle events in LitElement can be found here. SwimlaneElement adds the following methods for emitting Swimlane widget events:
Record Widget Methods
this.updateRecordValue(key, value): Available to record widgets. Updates record data by field key.this.addComment(key, value): Available to record widgets. Adds a new comment by field key. Returns a Promise that resolves with the comment details or rejects with an error.this.triggerIntegration(taskId): Available to record widgets. Triggers an integration. Returns a Promise that resolves when the integration is triggered or rejects with an error.this.triggerSave(): Available to record widgets. Triggers record save on the record page. Returns a Promise that resolves when the record is saved or rejects with an error.this.triggerButton(buttonId): Available to record widgets. Triggers the specified button on the record page.this.triggerNotification(type, title, message): Available to both record and report widgets. Triggers a native toast notification in the platform with the specified type ('success', 'error', 'info', 'warning'), title, and message.this.getFieldId(key): Returns the field ID for a given field key from the context data.
Hero AI Companion Methods
this.hero.companion.open(): Opens the Hero AI companion sidebar. Returns a Promise that resolves when the companion is opened.this.hero.companion.close(): Closes the Hero AI companion sidebar. Returns a Promise that resolves when the companion is closed.this.hero.companion.fullScreen(): Opens the Hero AI companion in fullscreen mode. Returns a Promise that resolves when the companion is opened in fullscreen.this.hero.companion.newConversation(options): Starts a new conversation with the Hero AI companion. Accepts an options object with configuration for the conversation. Returns a Promise that resolves when the new conversation is started.this.hero.companion.setMessage(options): Sets a message in the Hero AI companion input field. Accepts an options object withmessage(required) andautoSend(optional, defaults to false). Returns a Promise that resolves when the message is set.
Configuration Methods
this.setConfig(config, replaceAll): Sets or updates the widget configuration. IfreplaceAllis true, replaces the entire config; otherwise merges with existing config.
Lifecycle
LitElement watches properties and attributes for changes and asynchronously renders the template to the element's shadow DOM. Documentation of LitElement lifecycle methods and properties can be found here. In addition to the HtmlElement and LitElement lifecycle methods, SwimlaneElement adds the resizedCallback method.
resizedCallback- This method (called whenever the element is resized) but default simply callsrequestUpdate.
Examples
Basic
// SwimlaneElement and html are the basic required imports
import { SwimlaneElement, html } from '@swimlane/swimlane-element@1';
// Create and export a class definition for your widget that extends the SwimlaneElement base class
export default class extends SwimlaneElement {
// The render callback renders your element's template.
// It should always return the same template given the same properties and should not perform
// any side effects such as setting properties or manipulating the DOM.
render() {
// Return the template using the html template tag.
return html`
<div>Hello world!</div>
`;
}
}Record data
import { SwimlaneElement, html } from '@swimlane/swimlane-element@1';
export default class extends SwimlaneElement {
// The render callback is called each time the record data changes.
// lit-html is optimized for handling frequent updates and updating the DOM efficiently
render() {
return html`
<div>
Current count: ${this.record['count']}
</div>
`;
}
}Handling events
import { SwimlaneElement, html } from '@swimlane/swimlane-element@1';
export default class extends SwimlaneElement {
render() {
return html`
<div>
Current count: [${this.record['count']}]
<!-- Use @[eventname] syntax to register inline event handlers -->
<button @click=${() => this.updateRecordValue('count', this.record['count'] + 1)}>+</button>
<!-- You can also pass a function reference directly. -->
<button @click=${this._onDecrement}>-</button>
</div>
`;
}
_onDecrement() {
this.updateRecordValue('count', this.record['count'] - 1)
}
}Styles in a static styles property
import { SwimlaneElement, html } from '@swimlane/swimlane-element@1';
export default class extends SwimlaneElement {
/**
* Styles should be added as a static getter. They are evaluated once, and then added
* in the element's shadow dom.
*/
static get styles() {
return css`
:host {
display: block;
}
.message {
color: blue;
}
`;
}
render() {
return html`
<div class="message">
Current count: ${this.record['count']}
</div>
`;
}
}Swimlane styles
import { SwimlaneElement, html } from '@swimlane/swimlane-element@1';
import { recordFrameTemplate } from '@swimlane/swimlane-element@1/templates.js';
export default class extends SwimlaneElement {
/**
* The styles getter may return a array.
* Add `super.styles` to get swimlane default styles.
* Overide the `.frame::after` style to set a label for the frame.
*/
static get styles() {
return [super.styles, css`
:host {
display: block;
}
.message {
color: blue;
}
.frame::after {
content: "Current Count";
}
`];
}
/**
* Wrap the template in `recordFrameTemplate` function to add a frame.
* The seoncd argument (optional) is the row count height.
*/
render() {
return recordFrameTemplate(html`
<div class="message">
${this.record['count']}
</div>
`, 2);
}
}Styles in a style element.
import { SwimlaneElement, html } from '@swimlane/swimlane-element@1';
export default class extends SwimlaneElement {
render() {
const color = this.record['count'] > 10 ? 'red' : 'blue';
return html`
<-- styles defined here are dynamic, and will update when properties update.
<style>
.message {
color: ${color};
}
</style>
<div class="message">
Current count: ${this.record['count']}
</div>
`;
}
}Full Demo
import { SwimlaneElement, css, html } from '@swimlane/swimlane-element@1';
import { recordFrameTemplate } from '@swimlane/swimlane-element@1/templates.js';
export default class extends SwimlaneElement {
static get styles() {
return [super.styles, css`
:host {
text-align: center;
}
.frame::after {
content: "Current Count";
}
button {
font-size: xx-large;
margin-top: 10px;
height: 60px;
width: 60px;
border-radius: 5px;
background-color: #ffbb47;
color: #07080b;
bordeR: 0;
}
.message {
font-size: xx-large;
}
`];
}
render() {
const color = this.record['count'] > 10 ? '#FF4514' : '#1483FF';
return recordFrameTemplate(html`
<style>
.message {
color: ${color};
}
</style>
<div>
<div class="message">
${this.record['count']}
</div>
<button @click=${this._onIncrement}>+</button>
<button @click=${this._onDecrement}>-</button>
</div>
`, 2);
}
_onIncrement() {
this.updateRecordValue('count', this.record['count'] + 1)
}
_onDecrement() {
this.updateRecordValue('count', this.record['count'] - 1)
}
}Credits
SwimlaneElement is a Swimlane open-source project; we believe in giving back to the open-source community by sharing some of the projects we build for our application. Swimlane is an automated cyber security operations and incident response platform that enables cyber security teams to leverage threat intelligence, speed up incident response and automate security operations.
