@walkme/client-shell-sdk

This package is used to interact with the containing shell application.

Usage no npm install needed!

<script type="module">
  import walkmeClientShellSdk from 'https://cdn.skypack.dev/@walkme/client-shell-sdk';
</script>

README

shell-sdk

This package is used to interact with the containing shell application.

If you are reading this then you are developing an app to run inside an Iframe in walkme-os application.

Install

npm i @walkme/client-shell-sdk

Integration

1. Create an instance

Create a single instance of the SDK in the global scope of the app or if you are using a react application you can create a context provider to manage the SDK instance like so:

import React, { ReactElement, ReactNode } from 'react';
import { ShellSDK } from '@walkme-os/shell-sdk';

const initalContext = {
    sdk: new ShellSDK('example-app'), // replace with your app name
};
export const SDKContext = React.createContext(initalContext);

export const SDKProvider = ({ children }: { children: ReactNode }): ReactElement => {
    return <SDKContext.Provider value={initalContext}>{children}</SDKContext.Provider>;
};

Then in you app root, wrap with the Provider like so:

import { SDKProvider } from './app/sdk-provider';

ReactDOM.render(
    <SDKProvider>
        <App />
    </SDKProvider>
    document.getElementById('root')
);

Now you can access the sdk instance from anywhare in the app using useContext

2. Setting up listeners and handlers

The SDK sends messages from the shell application and can also recieve requests so you first need to set up event listeners. Your main App component should resemble this:

export const App = (): ReactElement => {
    const { sdk } = useContext(SDKContext);
    /*
     * Replace the elements below with your own.
     *
     */
    const [envs, setenvs] = useState([]);
    const [currentEnv, setcurrentEnv] = useState<Environment>();
    const [systems, setsystems] = useState([]);
    const [system, setsystem] = useState(null);

    useEffect(() => {
        async function init() {
            try {
                await sdk.connect();
            } catch (error) {
                console.log(error);
                return;
            }

            // Get data from the Shell
            const token = await sdk.getToken(); //Store this token to access walkme APIs

            const sys = await sdk.getSystems();
            setsystems(sys as []);

            const env = await sdk.getEnvironments();
            setenvs(env as []);

            const sysData = await sdk.getSystemData(); // current system
            setsystem(sysData);

            const envData = await sdk.getEnvironmentData(); // current environment
            setcurrentEnv(envData);

            // Set event listeners for changes and events ariving from the shell
            sdk.onSystemChange((payload) => {
                setsystem(payload);
                return Promise.resolve('ok'); // indicate that the app accepts the change. If you choose to return Promise.reject('reason') the shell will fallback to the previous state
            });
            sdk.onEnvironmentChange((payload) => {
                setcurrentEnv(payload);
                return Promise.resolve('ok');
            });
            sdk.onLanguageChange((payload) => {
                //...
                return Promise.resolve('ok');
            });

            await sdk.sendExtraAppData({
                sideMenu: [
                    {
                        icon: 'assets/course_icon.svg',
                        url: 'local-app/courses',
                        label: 'Courses',
                    },
                    {
                        icon: 'assets/users_icon.svg',
                        url: 'local-app/users',
                        label: 'Users',
                    },
                ],
            });
        }
        init();
    }, [sdk]);

    const openPreview = () => {
        sdk.openPreview({
            title: 'Course Preview',
            src:
                'https://cdn.walkme.com/sdk/apps/application-preview-ui/0.1/index.html?userGuid=2d0f07cc394e40c6a8a12fe1a696cc2f&app=teachme',
            style: { height: '100vh' },
        });
    };
    return (
        <div>...</div>
    );
};

export default App;
* Important: Each event that the shell sends to the app is a "promise" that the app can either resolve or reject

API

connect

Should be the first function to call once the app is loaded

returns: a promise once the connection with the shell is established

Event Handlers:

All event handlers accept a callback function to handle the affects of the event in the App. If the callback returns Promise.resolve() the system will be changed If the callback returns Promise.reject() the system will not be changed in the shell and it will fall back to the previous state

onSystemChange(function callback(systemData){...})

Accepts: a callback to be triggered once the system is changed in the shell.

returns: void

onEnvironmentChange(function callback(systemData){...})

Accepts: a callback to be triggered once the environment is changed in the shell.

returns: void

onLanguageChange(function callback(systemData){...})

Accepts: a callback to be triggered once the language is changed in the shell.

returns: void

onRouteChange(function callback(systemData){...})

Accepts: a callback to be triggered once the route is changed in the shell.

returns: void

Request information from the Shell

getToken()

Gets the current JWT token from the Shell application.

returns: A promise with the token data object

getSystems()

Gets the currently available systems to for the current user

returns: a promise with the Array of System data

getEnvironments()

Gets the currently available systems to for the current user

returns: a promise with the Array of Environments data

getSystemData()

Gets the system data od the current system

returns: a promise with the System data

getEnvironmentData()

Gets the system data od the current environment

returns: a promise with the Environment data

sendExtraAppData(data)

Send the shell data related to the app. Currently it expects the data regarding the menu in the form of

{
    sideMenu: [
        {
            icon: 'url of icon in the left menu',
            url: 'local-app/courses', // route to go to when clicking
            label: 'Courses', // the lable
        },
    ],
}

openPreview(previewProps)

Open an iframe with the preview information

{
    title?: string;
    src: string;
    style?: Record<string, string>;
}

changeRoute(newRoute)

Lets the Shell know when the app changes route so it can show the new route in the address bar