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