Skip to main content

Frontend OpenSDK Capability Guide

Capability Overview

Since version 6.3, Guandata BI has provided a new OpenSDK that supports customized scenarios such as data retrieval, information interaction, page customization, and style updates through specific method calls.

Applicable scenarios: Custom Charts, StarNova integration, frontend plugins, and custom filters.

Sample code: https://github.com/GuandataOSS/sdk-demo

Supported language: JavaScript

Capability list:

API Category API Name Available Since
Data Retrieval Get Current User Information ≥ 6.3.0
Interaction Notifications
Route Navigation
Style Updates Hide Specific Elements
Insert or Remove Styles
Event Registration Event Registration
Web Component Registration Register Web Component Elements ≥ 5.2.0
Custom Selectors Register a Custom Selector ≥ 7.2.0
Get Custom Selectors
Resource Loading Asynchronously Load Scripts
Get Resource URLs
Note

For versions earlier than 6.6:

  • Operations involving window, document, Function, globalThis, navigator, fetch, and XMLHttpRequest are supported only in Custom Charts and StarNova.
  • For security reasons, these capabilities are not available in frontend plugins.

Data Retrieval

Get Current Logged-In User Information

Available since: ≥ 6.3.0

Usage

GD.getUser()

Request Parameters

None

Return Value

Object

FieldTypeDescription
domIdstringDomain ID
domainNamestringDomain name
uIdstringUser ID
loginIdstringLogin account
rolestring[]Account roles in the role list, excluding system roles and custom roles
userPropertiesObject[]User properties

The userProperties object has the following structure:

FieldTypeDescription
keystringField name
aliasstringAlias
valuestringField value
isUserDefinedbooleanWhether it is a user-defined property

Interaction

Description

SDKs and plugins may load before BI rendering is complete. Do not call event-* methods immediately after loading finishes.

Trigger Notifications

Description: After a specific operation, display a success or failure message to the user. The notification style is consistent with Guandata BI.

Available since: ≥ 6.3.0

Usage

GD.dispatch(msgType, { msg, ntfType: 0 })

Request Parameters

FieldTypeDescription
msgTypestringMessage type: event-SYS_FETCH_SUCCESS for success messages and event-SYS_FETCH_FAIL for failure messages
msgstringMessage content
ntfTypeintRequired. Default value is 0

Examples

GD.dispatch('event-SYS_FETCH_SUCCESS', { msg: 'Operation succeeded', ntfType: 0 })
GD.dispatch('event-SYS_FETCH_FAIL', { msg: 'Operation failed: reason...', ntfType: 0 })

Route Navigation

Available since: ≥ 6.3.0

Usage

Navigate: GD.dispatch('event-SYS_ROUTE_PUSH', url)

Replace: GD.dispatch('event-SYS_ROUTE_REPLACE', url)

Go back: GD.dispatch('event-SYS_ROUTE_BACK')

Request Parameters

FieldTypeDescription
urlstringTarget URL

Style Updates

Hide Page Elements

Description: Hide specific elements on a page, such as the export button on a Dashboard page.

For the full frontend page hiding capability, see Frontend Page Element Hiding.

Available since: ≥ 6.3.0

Usage

GD.dispatch('config-display-control', { hiddenKeys })

Request Parameters

FieldTypeDescription
hiddenKeysstring[]Array of hidden element IDs

Supported element IDs

IDHidden ElementAvailable Since
webapp_exportExport button in the desktop application header
page_operation_batch_exportDashboard page header menu: Batch Export PDF / Batch Export Excel

Example

GD.dispatch('config-display-control', { hiddenKeys: ['webapp_export'] })

Insert or Remove Styles

Available since: ≥ 6.3.0

Usage

GD.dispatch('style', { title, content })

Request Parameters

FieldTypeDescription
titlestringStyle title
contentstringStyle content. URLs are supported. If omitted, the inserted style content for the corresponding title is removed.

Regular CSS selectors such as a and h1 can be modified.

Example

// Insert a style titled "Grayscale"
GD.dispatch('style', { title: 'Grayscale', content: 'body{ filter: grayscale(1); }' })
// Remove the inserted "Grayscale" style
GD.dispatch('style', { title: 'Grayscale' })


// Load a style from an external URL
GD.dispatch('style', { title: 'ExternalLink1', content: 'http*' })

Event Registration

Basic Event Registration Method

Available since: ≥ 6.3.0

Usage

GD.on(eventKey, callback, introduce)

Request Parameters

FieldTypeDescription
eventKeystringEvent name
callbackfunctionCallback function
introducestringMethod description (optional)

Supported event names

Method Description (Optional)Event PurposeAvailable Since
open-pageCustom route finished loading6.3.0
gd-readySDK initialization completed6.5.0
gd-route-changePage route changed6.5.0

Custom Route Loaded: open-page

Available event parameters

FieldTypeDescription
paramsobjectParameter object

params format

FieldTypeDescription
pathnamestringURL path
searchstringURL query
stateobjectState object

Example

function openRedirect ({ pathname, search }) {
  if (pathname !== '/open/redirect') return
  const obj = {};
  const searchParams = new URLSearchParams(search);
  const userInfo = GD.getUser()


  for (const [key, value] of searchParams) {
    obj[key] = value;
  }
  if (!obj.get('redirectUrl')) return
  location.href = `${obj.get('redirectUrl')}?loginId=${userInfo.loginId}`
}


GD.on('open-page', openRedirect, 'Append loginId during redirect')

SDK Initialization Completed: gd-ready

Example

let userInfo = GD.getUser()
console.log('userInfo-1', userInfo) // User information is not available yet
GD.on('gd-ready', () => {
    userInfo = GD.getUser()
    console.log('userInfo-2', userInfo) // User information is now available
})

Page Route Change: gd-route-change

Available event parameters

FieldTypeDescription
paramsobjectRoute change information

params format

FieldTypeDescription
pathnamestringPath portion of the current URL
hashstringHash portion of the current URL
searchstringQuery portion of the current URL

Example

class PortalFloatActionButton {
  // ...
}
customElements.define('portal-float-action-button', PortalFloatActionButton)

GD.on('gd-route-change', params => {
    const { pathname } = params
    console.log('params', params)
    if (['/home', '/m/portal'].includes(pathname)) {
        if (compDiv) return
        compDiv = document.createElement('div');
        compDiv.className = 'pos-absolute scroll-hidden';
        compDiv.style.right = '0';
        compDiv.style.bottom = '80px';
        compDiv.style.zIndex = '999';
        compDiv.style.width = '48px';
        compDiv.style.height = '48px';
        
        // Create the portal-float-action-button element
        const portalFloatActionButton = document.createElement('portal-float-action-button');
        const userInfo = GD.getUser()
        
        portalFloatActionButton.setAttribute('loginid', userInfo.loginId);
        portalFloatActionButton.setAttribute('userid', userInfo.uId);
        
        // Add the portal-float-action-button element to the new div
        compDiv.appendChild(portalFloatActionButton);
        
        // Add the new div to the body element
        document.getElementById('app').appendChild(compDiv);
    } else if (compDiv) {
        compDiv.remove()
        compDiv = null
    }
})

Web Component Registration

Basic Method

Available since: ≥ 6.3.0

Usage

window.customElements.define(elementKey, CustomElement)

Request Parameters

FieldTypeDescription
elementKeystringElement name
ComponentelementCustom element

Example - Open Route

Element name: open-page

Supported since: ≥ 6.3.0

Rendering scenario: pages under the /open/* route

Rendering parameters

FieldTypeDescription
pathnamestringURL path
searchstringURL query

Example code

class MyListComponent extends HTMLElement {
  async renderPage1() {
    this.innerHTML = `
      This is a page    `
  }


  async renderPage2() {
    this.innerHTML = `
      This is another page, visible only to administrators    `
    
  }


  connectedCallback() {
    const pathname = this.getAttribute('pathname')
    const userInfo = GD.getUser()
    if (pathname ==='/open/page1') {
      this.renderPage1();
    } else if (pathname === '/open/page2' && userInfo.role.includes('admin')) {
      this.renderPage2()
    } else {
      this.innerHTML = 'This page does not exist'
    }
  }
}


customElements.define('open-page', MyListComponent);

Example - Dashboard Floating Button

Element name: page-feedback

Supported since: ≥ 5.2.0

Rendering scenario: float at the bottom-right corner of Dashboard pages, including mobile

Rendering parameters

FieldTypeDescription
pgidstringPage ID

Example - No Permission on Dashboard / Large Screen

Element name: request-permission

Supported since: ≥ 6.3.0

Rendering scenario: inserted below the "No Access Permission" message

Rendering parameters

FieldTypeDescription
ridstringResource ID

Example code

class MyComponent extends HTMLElement {
  connectedCallback() {
    // Get rendering parameters
    const rId = this.getAttribute('rId');
    this.innerHTML = `
                      Page ID: ${rId}        Jump                     `;
  }
}


customElements.define('request-permission', MyComponent);

Custom Selectors

Register a Custom Selector

GD.registerCustomSelector

Description

Registers a custom selector component. Registered components can be selected when creating a new custom selector.

Usage

// Parameter type
interface ICustomSelector {
id: string // Unique identifier. The same ID overwrites the existing selector.
title: string // Selector title displayed in the list
desc: string // Selector description displayed in the list
tagName: string // Selector tag name used for Web Component registration and usage
configFormSchema: any[] // Configuration form definition in the standard Lego form format. See: https://guandata.yuque.com/guandataweb/dsebtl/iefgq3
load: () => void // Load function
}

// Usage example
const myCustomSelector = {
id: 'my-custom-selector',
title: 'My Custom Selector',
desc: 'This is a custom selector example',
tagName: 'custom-tag',
configFormSchema: [
// Configuration form definition
],
load: () => {
// Implement the selector loading logic here
class MyCustomElement extends HTMLElement { ... }

window.customElement.define(
'custom-tag', // Matches tagName
MyCustomElement
)
}
};

GD.registerCustomSelector(myCustomSelector)

Notes

  1. If the registered id already exists, the existing selector is overwritten instead of adding a new one.
  2. You can use GD.getCustomSelectors() to retrieve all registered custom selectors.

Get Custom Selectors

GD.getCustomSelectors

Description

Returns all custom selectors successfully registered through GD.registerCustomSelector. The return value is an array, and each item is the object originally passed to GD.registerCustomSelector().

Usage

GD.getCustomSelectors()
// => [ { id, title, tagName, ... }, { ... } ]

Resource Loading

Asynchronously Load Scripts

GD.asyncLoadScript

Description

Asynchronously loads external scripts or style files and returns a Promise representing the loading status. This function supports caching and uses the URL as the unique identifier to ensure the same resource is loaded only once.

Usage

// Load a regular script file
await GD.asyncLoadScript('https://example.com/script.js')
// Result: <script src="https://example.com/script.js" defer></script>

// Load an ES module script
await GD.asyncLoadScript('https://example.com/module.js', { type: 'module' })

// Load a CSS stylesheet
await GD.asyncLoadScript('https://example.com/styles.css', { tagName: 'link' })

// Set custom attributes
await GD.asyncLoadScript('https://example.com/script.js', {
async: true,
crossOrigin: 'anonymous',
integrity: 'sha384-...'
});

Notes

  1. Loaded scripts are cached to avoid loading the same resource repeatedly.
  2. Script loading has three states:
    1. Not loaded yet or load failed: reload is required
    2. Loading: returns the in-progress Promise
    3. Loaded successfully: returns the resolved Promise directly
  3. The default timeout is 120 seconds. After timeout, the load fails automatically and DOM elements are cleaned up.
  4. If loading fails, the created DOM element is removed and the cache state is reset.
  5. You can pass extra attributes in the options to customize script or style loading behavior for scenarios such as type="module".
  6. For CSS files, specify { tagName: 'link' } so a link element is created instead of a script element, producing <link rel="stylesheet" type="text/css" href="..." >.

Get Resource URLs

GD.getResourceUrl

Description

Returns several fixed resource URLs provided by BI.

Use it together with GD.asyncLoadScript to load Shoelace, Lit, and similar resources.

The following resources are currently available:

Resource NameDescription
litCore Lit framework resource. After loading, window.lit becomes available.
shoelaceShoelace autoloader. After loading, window.shoelaceAutoloader becomes available.
shoelace-theme-lightShoelace light theme CSS file
shoelace-theme-darkShoelace dark theme CSS file

Usage

// lit
const litUrl = GD.getResourceUrl('lit') // Example: "/static/vendor/lit@3.2.1/lit-core.min.js"
await GD.asyncLoadScript(litUrl, { type: 'module' })

// Shoelace autoloader and light/dark themes
await GD.asyncLoadScript(GD.getResourceUrl('shoelace'), { type: 'module' })
await GD.asyncLoadScript(GD.getResourceUrl('shoelace-theme-light'), { tagName: 'link' })
await GD.asyncLoadScript(GD.getResourceUrl('shoelace-theme-dark'), { tagName: 'link' })