Links

Add Buttons and Handlers to an Extension App

Prerequisites

Complete the previous guide on building an extension app with app views

Add Buttons and Handler

Let's now add a button to the hashtag hover card and a handler to link the context. Use ADK.buttons.add to add a new button to the hashtag zone. To pass the context payload from the controller to the view, there are two options: either using query parameters or using ADK to invoke an exposed controller method from a view.
src/index.js
1
import * as ADK from "@symphony-ui/adk";
2
3
ADK.start({ id: "adk-example" }).then(() => {
4
ADK.buttons.add("Click Me", "hashtag", (payload) => {
5
console.log(`You clicked on a hashtag button`, payload);
6
// Perform actions
7
});
8
});

Option 1: Use query parameters to pass context

In this option, we serialize the contents of the context payload and pass it directly into the ADK.modules.open call as query parameters.
src/index.js
1
import * as ADK from "@symphony-ui/adk";
2
3
ADK.start({ id: "adk-example" }).then(() => {
4
ADK.buttons.add("Click Me", "hashtag", (payload) => {
5
console.log(`You clicked on a hashtag button`, payload);
6
const params = "?context=" + encodeURIComponent(JSON.stringify(payload));
7
ADK.modules.open("view-a" + params, { title: "ADK View A" });
8
});
9
});
Once the view is opened, you can retrieve the query parameters and deserialize it.
src/views/view-a.jsx
1
import * as React from 'react';
2
import * as ADKReact from '@symphony-ui/adk-react';
3
import { useEffect, useState } from 'react';
4
import './view-a.css';
5
6
const ViewA = () => {
7
const [ context, setContext ] = useState();
8
9
useEffect(() => {
10
const contextString = new URLSearchParams(window.location.search).get('context');
11
if (contextString) {
12
setContext(JSON.parse(decodeURIComponent(contextString)));
13
}
14
}, []);
15
16
return (
17
<div className="main-view">
18
<main>
19
{ context && (
20
<div>
21
<strong>Context</strong>: {context.entity.name}
22
</div>
23
)}
24
</main>
25
</div>
26
);
27
};
28
29
ADKReact.createView(<ViewA />, { id: 'adk-example' });

Option 2: Expose Method on Controller

In this option, we store the state of context on the controller, then expose a method to retrieve that state.
JavaScript
TypeScript
src/index.js
1
import * as ADK from '@symphony-ui/adk';
2
3
ADK.start({ id: 'adk-example' }).then(() => {
4
let context;
5
ADK.expose({
6
getContext: () => context,
7
});
8
9
ADK.buttons.add('Click Me', 'hashtag', (payload) => {
10
console.log(`You clicked on a hashtag`, payload);
11
context = payload;
12
ADK.modules.open('view-a', { title: 'ADK View A' });
13
});
14
});
src/index.ts
1
import * as ADK from '@symphony-ui/adk';
2
3
type ControllerApi = {
4
getContext: () => unknown,
5
};
6
7
ADK.start({ id: 'adk-example' }).then(() => {
8
let context;
9
ADK.expose<ControllerApi>({
10
getContext: () => context,
11
});
12
13
ADK.buttons.add('Click Me', 'hashtag', (payload) => {
14
console.log(`You clicked on a hashtag`, payload);
15
context = payload;
16
ADK.modules.open('view-a', { title: 'ADK View A' });
17
});
18
});
Once the view is opened, you can make a call to the exposed getContext method via the useRemoteExecutor hook, which returns a promise.
JavaScript
TypeScript
src/views/view-a.jsx
1
import * as React from 'react';
2
import * as ADKReact from '@symphony-ui/adk-react';
3
import { useRemoteExecutor } from '@symphony-ui/adk-react';
4
import { useEffect, useState } from 'react';
5
import './view-a.css';
6
7
const ViewA = () => {
8
const { name: theme, layout } = useClientTheme();
9
const userId = useUserReferenceId();
10
const [ context, setContext ] = useState();
11
const remoteExecutor = useRemoteExecutor();
12
13
useEffect(() => {
14
remoteExecutor.getContext().then((result) => setContext(result));
15
}, []);
16
17
return (
18
<div className="main-view">
19
<main>
20
{ context && (
21
<div>
22
<strong>Context</strong>: {context.entity.name}
23
</div>
24
)}
25
</main>
26
</div>
27
);
28
};
29
30
ADKReact.createView(<ViewA />, { id: 'adk-example' });
src/views/view-a.tsx
1
import * as React from 'react';
2
import * as ADKReact from '@symphony-ui/adk-react';
3
import { useRemoteExecutor } from '@symphony-ui/adk-react';
4
import { useEffect, useState } from 'react';
5
import './view-a.css';
6
7
type ControllerApi = {
8
getContext: () => Promise<unknown>,
9
};
10
11
const ViewA = () => {
12
const [ context, setContext ] = useState();
13
const remoteExecutor = useRemoteExecutor<ControllerApi>();
14
15
useEffect(() => {
16
remoteExecutor.getContext().then((result) => setContext(result));
17
}, []);
18
19
return (
20
<div className="main-view">
21
<main>
22
{ context && (
23
<div>
24
<strong>Context</strong>: {context.entity.name}
25
</div>
26
)}
27
</main>
28
</div>
29
);
30
};
31
32
ADKReact.createView(<ViewA />, { id: 'adk-example' });
Last modified 5mo ago