This is an internal documentation. There is a good chance you’re looking for something else. See Disclaimer.

Custom Widgets

Custom widgets are independent applications, tocco-apps, that can be embedded on external websites.

Widget package

Create a new package for your widget in the widgets folder:

yarn plop Package

Add the widget to a bundle:

yarn plop Bundle app

The src/main.js is the entry point of the widget.

Env

Define the env inside the initApp of the main.js. There is a helper function env.setInputEnvs(input) which sets the env vars from the input automatically. Without the correct envs the core component will not behave properly for widgets (e.g. entity-detail should not render the meta-information inside the footer).

import {env} from 'tocco-util'
...

const initApp = (id, input, events, publicPath) => {
    const content = <MyWidget />

    // set env from input
    env.setInputEnvs(input)

    const store = appFactory.createStore(reducers, sagas, input, packageName)
    ...
    return appFactory.createApp(packageName, content, store, {...})
}

Input / PropTypes

The widgets receives the config from the Widget Config entity as input object with some additional meta information:

  • appContext object containing the widgetConfigKey

  • backendUrl

  • locale

Note

The selection prop type, which has been added automatically, can be removed for widgets.

Example:

src/main.js
import PropTypes from 'prop-types'
import {appContext} from 'tocco-util'

const initApp = (...) => {
  ...
}

...

const ExampleWidgetApp = props => {
  ...
}

ExampleWidgetApp.propTypes = {
    appContext: appContext.propTypes.isRequired,
    backendUrl: PropTypes.string,
    locale: PropTypes.string,
    ...
}

Name

Description

Example

appContext

Meta information about the embedded widget. Available embedTypes are: admin, legacy-admin, widget, legacy-widget

{
  "embedType": "widget",
  "widgetConfigKey": "123",
}

backendUrl

The base url of the nice2 backend.

https://master.tocco.ch

locale

The locale of the widget. If the locale is set the widget should render this locale instead of the logged in user.

de-CH

Visibility status integration

Your widget app will get a function onVisibilityStatusChange as an input property. This can be used to communicate to the system running the widget that some state, in which it might want to display some content, was reached. An example are the status list and detail in the entity-browser app that get triggered when the user navigates to one of the corresponding sites, or the success status in the event-registration app that gets triggered when the registration is successfully created.

See Visibility status configuration on how to configure visibility status to be available on a widget config.

When implementing your own visibility status, we recommend creating a visibilityStatus.js status file in the root of your src folder, containing an object of all your implemented visibility status and then only using the values defined in there. This ensures no typo is made when changing visibilty status which would create hard to debug errors, as well as serving as a common way to document all available status in code.

Instead of passing onVisibilityStatusChange through your app and calling it by hand, use the action creator externalEvents.fireVisibilityStatusChangeEvent.

Example visibilityStatus.js
export const VisibilityStatus = {
    list: 'list',
    detail: 'detail',
    success: 'success'
}
Example app that uses fireVisibilityStatusChangeEvent to change to success state
// ExampleAppContainer.js
import {connect} from 'react-redux'
import {externalEvents} from 'tocco-app-extensions'

const mapActionCreators = {
    fireVisibilityStatusChangeEvent: externalEvents.fireVisibilityStatusChangeEvent
}

const mapStateToProps = state => ({})

export default connect(mapStateToProps, mapActionCreators)(ExampleApp)

// ExampleApp.js
import {VisibilityStatus} from './visibilityStatus'

const ExampleApp = ({fireVisibilityStatusChangeEvent}) => {
    fireVisibilityStatusChangeEvent([VisibilityStatus.success])
}

For externalEvents.fireVisibilityStatusChangeEvent to work you’ll have to make sure that externalEvents has been added to your apps store with the correct events.

Part of a main.js that adds externalEvents to the store
const EXTERNAL_EVENTS = ['onVisibilityStatusChange']

const initApp = (id, input, events, publicPath) => {
    const store = appFactory.createStore(reducers, sagas, input, packageName)
    externalEvents.addToStore(store, state => appFactory.getEvents(EXTERNAL_EVENTS, state.input))
}