Skip to main content

Elfsquad CPQ

Elfsquad CPQ is a software for eliminating all errors in the pre-production process, connecting the end customer to the product and production flawlessly. Configure, Price and Quote (CPQ) are the basic parts of the calculation- and quotation process. You can read more about how to use it in detail in their documentation.

In DynaMaker the Elfsquad CPQ software exists as a plugin and it is very easy to use! To explain how it works, we will go through:

  1. Elfsquad account
  2. DynaMaker plugin

1. Elfsquad Account

A. Login

You need an account in Elfsquad to be able to use it in DynaMaker. You can use the same account for multiple applications. You can log in at https://login.elfsquad.io/.

There are some things that we need to do in the Elfsquad CPQ software before jumping into the DynaMaker app. We will need 3 ids: Client, Secret and Model Ids.

B. OpenId Client & Secret

To be able to connect any Elfsquad app with a DynaMaker app, we need to create an ID. For this:

  • In your Elfsquad account dashboard, go to Integrations.
  • Under Connected applications, create an OpenId Client.

You can rename this OpenId Client if you want, but the most important things to keep for later are the Client Id and the Secret, which will be used in DynaMaker to enable the connection. Don't forget to select Client Secret Post under Token auth method.

C. Feature Model Id

The Feature Model Id can be found in different places. For example, if you go into the Step Editor and select your Elfsquad app to edit, you can find the Feature Model Id in the URL:

D. Enable Third-Party Visualization

To visualize your DynaMaker app in the Elfsquad app:

  • In Editor/Step Editor, edit the Elfsquad app you want to add the DynaMaker app to.
  • Enable the Third-Party Visualization option.
  • Add the link of the deployed app in the field Third party visualization URL
  • Check the box Send data on "configurationUpdate".
  • Save your changes.
  • Repeat all these in all Elfsquad app steps that you want to show the DynaMaker app.

E. Add Reference Values

As a last step in the Elfsquad plugin, you need to connect all the parameters in the Elfsquad app that you want to use in your DynaMaker app. This is done automatically by the in-built plugin in DynaMaker only if those Elfsquad parameters have a reference.

This reference will be the first part of the variable that is going to be used in DynaMaker, so choose a simple name without any special characters. Try to use a consistent and code-friendly naming convention in all your variables, e.g. OPENING_WIDTH, opening_width or openingWidth.

Since the reference field does not have to be unique across different features in Elfsquad, the variable name in DynaMaker will consist of the reference value and the node ID. The result will be something like this: width_9c4a18ad_2d06_462a_97ff_29a90f056baa. Although width would be a nicer variable name, this pattern enables the reuse of features in Elfsquad. If you reuse your width feature, it will have a unique ID appended each time, and thus you can differentiate between a door width and the total width for example.

It's recommended also to give a reference not only to the options of an Elfsquad dropdown parameter, but also to the parent. For example if you have an Elfsquad parameter Size, whose options are Small (with reference small), Medium (medium) and Large (large), you could add its reference as size. Later in DynaMaker you wouldn't need to go through all the options but just to read the value of the parent, i.e. Size. Doing so the child reference selected will be the value of the parent (as selectionGroups, explained later).

With this the Elfsquad app is ready to be used in DynaMaker. Now let's go into the DynaMaker app and connect these parameters.

2. DynaMaker Plugin

A. Enable Plugin

To enable the Elfsquad Plugin in DynaMaker, you need to:

  • Open Settings of the plugin Elfsquad in your app dashboard.
  • Fill in the required fields with the Feature Model, Client and Secret Ids.
  • Synchronized plugin
  • Save plugin

If the synchronization does not work, double check all the IDs and the secret.

Now this plugin will show up as a new import in your components and UI.

B. Use Plugin in UI

The UI of the DynaMaker app will be the bridge between the Elfsquad parameters and the components.

  • Go to the UI of your app.
  • Import PLUGINS in edit/hide imports... at the top of the code editor as if it's a component.
  • Now that you can use PLUGINS, call the function onConfigurationUpdate from the plugin, which will be triggered automatically with every change in the Elfsquad app:
PLUGINS.ELFSQUAD.onConfigurationUpdate((parsedConfiguration, rawConfiguration) => {
const assemblyComponent = ACTIONS.getAssemblyComponent()

const oldHeight = assemblyComponent.getProperty('height')
assemblyComponent.setPropertiesFromData(rawConfiguration) // function to create later in assembly

const newHeight = assemblyComponent.getProperty('height')

const needsUpdateCamera = oldHeight !== newHeight
Studio.requestGeometryUpdate().then(() => {
if (needsUpdateCamera) {
Studio.setCameraToFitBounds({ travelTime: 750 })
}
})
})

Here for example we take rawConfiguration (Elfsquad data) that we send to a new function assemblyComponent.setPropertiesFromData() in which we handle all the Elfsquad parameter values. Additionally, we have added extra logic to detect if the property height of the assembly has changed. If so, we update the camera accordingly. However, don't forget to update the geometry (Studio.requestGeometryUpdate()) or you won't see any changes.

You can also set the assembly properties directly in the function PLUGINS.ELFSQUAD.onConfigurationUpdate() and use parsedConfiguration instead. However it might be cleaner to do it in the components that are being affected. It's up to you how you want to do it, but if you use rawConfiguration and parse the data later (as we show in the next section) you will be able to create presets directly with the raw data that Elfsquad is sending (very useful for finding bugs in specific Elfsquad configurations).

Additionally, there are some functions that can be triggered from the Elfsquad configurator:

  • onStepChange() to react to step changes in Elfsquad:
    PLUGINS.ELFSQUAD.onStepChange((parsedData, rawData) => {
    console.log(`Step changed to '${parsedData.title}' with ID '${parsedData.id}'`)
    })
  • updateConfigurationValue() to send back a value of a single feature to Elfsquad:
    PLUGINS.ELFSQUAD.updateConfigurationValue({
    id: PLUGINS.ELFSQUAD.definition.values.width_de87ac38_9450_3efb_ab1e_08da432e87a1.id,
    value: component.getProperty('width'),
    })
  • updateConfigurationValues() to send back values of multiple features at the same time to Elfsquad:
    PLUGINS.ELFSQUAD.updateConfigurationValues([
    {
    id: PLUGINS.ELFSQUAD.definition.values.position_x_83t3rdss_7863_sgsf_zwg4_sdhts3xhasfg.id,
    value: component.getProperty('position-x'),
    },
    {
    id: PLUGINS.ELFSQUAD.definition.values.position_y_d9ouihju_9453_8rfv_s34v_sdfsr22e87a2.id,
    value: component.getProperty('position-y'),
    },
    ])

C. Use Plugin in Component

In case you want to have a cleaner UI and update the properties within the component itself, you could do it with the previously mentioned function assemblyComponent.setPropertiesFromData().

  • In your component, import PLUGINS as if it's a subcomponent,
  • Create a class function setPropertiesFromData() which could look like:
export class Component extends STUDIO.BaseComponent<Properties> {
constructor() {
// properties etc
}

setPropertiesFromData(data: PLUGINS.ELFSQUAD.ElfsquadConfiguration) {
const result = PLUGINS.ELFSQUAD.parseConfiguration(data)

const { selectionGroups, values, texts } = result

const ralColor = selectionGroups['RAL_COLOR_4cb91b31_e7d5_43f7_bd1b_09f9cfa7b2cb']
const openingWidth = values['OPENING_WIDTH_7d5e4750_e7dd_4c7a_9ec0_a3ddf7c8b79e']
const hasDoor = values['HAS_DOOR_2a0b7cb6_f7d0_452e_b247_de20f556da8b']

if (ralColor !== undefined) {
// parameter dropdown with multiple choices
this.properties.ralColor = ralColor
}

if (openingWidth !== undefined) {
// parameter with input field
this.properties.openingWidth = openingWidth.value
}

if (hasDoor !== undefined) {
// parameter with checkbox (true or false)
this.properties.hasDoor = hasDoor.selected
}
}

// other functions like generateGeometry()
}

In this case we have shown 3 different types of parameters that are found in Elfsquad (there are more of course). The most common ones are dropdowns, input fields and parameters with checkbox. These are represented by RAL_COLOR, OPENING_WIDTH and HAS_DOOR respectively. If it's an assembly, remember to run this.update() at the end to propagate the new properties to any possible subcomponent.

See that there are 5 sets of variables as a result of PLUGINS.ELFSQUAD.parseConfiguration(data):

  • selectionGroups: with all the parent features giving the child feature selected in each (e.g. like before, for a parent feature Size with options Small, Medium and Large then one could directly get which size option has been selected through the parent as const sizeSelected = selectionGroups['SIZE_4cb23b31_edsf_78f7_968b_09f9c645b2cb']).

  • values: (most used) with the values of all Elfsquad features with references, including selected: boolean to see if the value is selected or not.

  • texts: with the values of those Elfsquad features that are purely a string (i.e. input text field).

  • included: with the values of the Elfsquad configuration models as included that are used within the Elfsquad model (separated Elfsquad configuration models are not supported yet).

  • dynamicGroups: with data regarding Elfsquad dynamic groups.

In order to make sure you use the same Elfsquad references, you could create a dataset or a set of constants with all the strings to make sure you don't misspell them. If the strings don't match, naturally the parameter will show up as undefined and could cause undesired bugs. So make sure you use the same references and use if-statements to check whether the values you are trying to get from result are undefined or not. Alternatively, you could use console.warn() or console.log() to aid you when finding bugs. Don't forget to debug to see exactly what you are getting.

Notice that this plugin requires a matching setup in both DynaMaker and Elfsquad. So if you find problems of undefined variables, make sure to double-check the references, that the plugin is up-to-date (synchronized and saved) and the DynaMaker app is enabled to be shown in the Elfsquad app (i.e. third-party visualization).

Of course, you can reach us at support@dynamaker.com if you feel that the problem comes specifically from the plugin.

D. Hide UI

When the configurator is handled completely by Elfsquad, you might not need the tabs of DynaMaker anymore. To hide them entirely, you need to override the CSS in the app in STYLE by adding:

.sky-toolbar-container {
display: none;
}

This will only hide the tabs to the left (or right) of your app. You could still add any other UI items, like a menu, QuickBar or metrics. You can read more about other CSS snippets here.