Skip to main content

Customize the extension

In the previous steps you've created a new extension and learned how an Elfsquad extension is structured. The default extension code however, it not that useful.

In this step, you'll learn how to customize the extension and extend your Elfsquad environment with your own functionality. In the example, you'll make a simple dialog that displays information about your quotation.


Step 1: Create an index.html

Create a new file in the src folder and name it index.html. This file will be displayed in an iframe in the dialog.

import index.js

Import the index.js file. This file will contain the business logic.

Display information

This renders the average configuration value and margin, and includes placeholder values. The actual values will be calculated with JavaScript.

src/index.html
<html>
<head>
<script src="index.js"></script>
</head>

<body>
<table>
<tbody id="table-body">
<tr>
<td>Average configuration value</td>
<td id="average-configuration-value">...</td>
</tr>

<tr>
<td>Average configuration margin</td>
<td id="average-configuration-margin">...</td>
</tr>
</tbody>
</table>
</body>
</html>

Step 2: Update the index.ts

You already have an index.ts file in the src folder. The current contents of this file can be removed.

imports

Import the api and context object from the @elfsquad/custom-scripting package. The API is an abstraction around the JavaScript fetch API, and can be used for interacting with the Elfsquad API.

Context

The context object contains information about the context in which the dialog or action is executed, such as the identifier of the viewed entity.

Calling the Elfsquad API

This uses the previously imported api object to fetch the quotation groups for the quotation with the id, which you've previously retrieved from the context object.

src/index.ts
import { api, context } from '@elfsquad/custom-scripting';

const { quotationId } = context;

const processQuotationGroups = (quotationGroups: any) => {
const averageConfigurationValue = document.getElementById('average-configuration-value');
const averageConfigurationMargin = document.getElementById('average-configuration-margin');

const totalValue = quotationGroups.reduce((acc: number, group: any) => acc + group.value, 0);
const totalMargin = quotationGroups.reduce((acc: number, group: any) => acc + group.profitMargin, 0);

if (totalValue > 0) {
averageConfigurationValue!.innerText = (totalValue / quotationGroups.length).toFixed(2);
} else {
averageConfigurationValue!.innerText = '0.00';
}
if (totalMargin > 0) {
averageConfigurationMargin!.innerText = (totalMargin / quotationGroups.length).toFixed(2);
} else {
averageConfigurationMargin!.innerText = '0.00';
}
}

const qp = {
'$filter': `quotationId eq ${quotationId}`,
};

api.fetch('/data/1/quotationgroups?' + new URLSearchParams(qp))
.then((r: any) => return r.body['value'])
.then(processQuotationGroups)
.catch((e: any) => console.error('Error fetching quotation groups:', e));

Step 3. Update the elfsquadrc.yml

The elfsquadrc.yml file contains a background action by default. We'll have to change this to disable a dialog.

Executable type

The type of the executable has been changed from action to dialog.

Entrypoint

The entrypoint has been changed from index.js to index.html.

elfsquadrc.yml
identifier: "example-extension"
page_extensions:
quotation:
actions:
- position: right
color: primary

names:
en: Execute

executable:
type: "dialog"
entrypoint: "index.html"

Step 4. Update the package.json

Build script

The build script has been updated to copy the index.html file to the dist folder.

package.json
{
"name": "example-extension",
"scripts": {
"build": "esbuild src/index.ts --bundle --platform=node --outfile=dist/index.js && cp src/index.html dist/index.html"
},
"devDependencies": {
"esbuild": "^0.12.0",
"typescript": "^4.3.5"
},
"dependencies": {
"@elfsquad/custom-scripting": "^0.0.5"
}
}