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
import * as ADK from "@symphony-ui/adk";

ADK.start({ id: "adk-example" }).then(() => {
  ADK.buttons.add("Click Me", "hashtag", (payload) => {
    console.log(`You clicked on a hashtag button`, payload);
    // Perform actions
  });
});

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
import * as ADK from "@symphony-ui/adk";

ADK.start({ id: "adk-example" }).then(() => {
  ADK.buttons.add("Click Me", "hashtag", (payload) => {
    console.log(`You clicked on a hashtag button`, payload);
    const params = "?context=" + encodeURIComponent(JSON.stringify(payload));
    ADK.modules.open("view-a" + params, { title: "ADK View A" });
  });
});

Once the view is opened, you can retrieve the query parameters and deserialize it.

src/views/view-a.jsx
import * as React from 'react';
import * as ADKReact from '@symphony-ui/adk-react';
import { useEffect, useState } from 'react';
import './view-a.css';

const ViewA = () => {
  const [ context, setContext ] = useState();

  useEffect(() => {
    const contextString = new URLSearchParams(window.location.search).get('context');
    if (contextString) {
      setContext(JSON.parse(decodeURIComponent(contextString)));
    }
  }, []);

  return (
    <div className="main-view">
      <main>
        { context && (
          <div>
            <strong>Context</strong>: {context.entity.name}
          </div>
        )}
      </main>
    </div>
  );
};

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.

src/index.js
import * as ADK from '@symphony-ui/adk';

ADK.start({ id: 'adk-example' }).then(() => {
  let context;
  ADK.expose({
    getContext: () => context,
  });

  ADK.buttons.add('Click Me', 'hashtag', (payload) => {
    console.log(`You clicked on a hashtag`, payload);
    context = payload;
    ADK.modules.open('view-a', { title: 'ADK View A' });
  });
});

Once the view is opened, you can make a call to the exposed getContext method via the useRemoteExecutor hook, which returns a promise.

src/views/view-a.jsx
import * as React from 'react';
import * as ADKReact from '@symphony-ui/adk-react';
import { useRemoteExecutor } from '@symphony-ui/adk-react';
import { useEffect, useState } from 'react';
import './view-a.css';

const ViewA = () => {
  const { name: theme, layout } = useClientTheme();
  const userId = useUserReferenceId();
  const [ context, setContext ] = useState();
  const remoteExecutor = useRemoteExecutor();

  useEffect(() => {
    remoteExecutor.getContext().then((result) => setContext(result));
  }, []);

  return (
    <div className="main-view">
      <main>
        { context && (
          <div>
            <strong>Context</strong>: {context.entity.name}
          </div>
        )}
      </main>
    </div>
  );
};

ADKReact.createView(<ViewA />, { id: 'adk-example' });

Last updated