Skip to content

Commit

Permalink
feat: add MainAppSlot for chatbot plugin (#1320)
Browse files Browse the repository at this point in the history
* feat: add MainAppSlot for chatbot plugin

* test: added test for MainAppSlot

* chore: add read me for plugin-slot
  • Loading branch information
awais-ansari authored Sep 25, 2024
1 parent e496bb6 commit 47b0501
Show file tree
Hide file tree
Showing 8 changed files with 136 additions and 8 deletions.
57 changes: 51 additions & 6 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 2 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@
"@fortawesome/free-brands-svg-icons": "6.6.0",
"@fortawesome/free-solid-svg-icons": "6.6.0",
"@fortawesome/react-fontawesome": "0.2.2",
"@openedx/frontend-plugin-framework": "^1.3.0",
"@openedx/paragon": "^22.1.1",
"@optimizely/react-sdk": "^2.9.1",
"@redux-devtools/extension": "3.3.0",
Expand All @@ -54,6 +55,7 @@
"query-string": "7.1.3",
"react": "^17.0.2",
"react-dom": "^17.0.2",
"react-error-boundary": "^4.0.13",
"react-helmet": "6.1.0",
"react-loading-skeleton": "3.4.0",
"react-redux": "7.2.9",
Expand Down
5 changes: 3 additions & 2 deletions src/MainApp.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import { Helmet } from 'react-helmet';
import { Navigate, Route, Routes } from 'react-router-dom';

import {
EmbeddedRegistrationRoute, NotFoundPage, registerIcons, UnAuthOnlyRoute, Zendesk,
EmbeddedRegistrationRoute, NotFoundPage, registerIcons, UnAuthOnlyRoute,
} from './common-components';
import configureStore from './data/configureStore';
import {
Expand All @@ -22,6 +22,7 @@ import {
import { updatePathWithQueryParams } from './data/utils';
import { ForgotPasswordPage } from './forgot-password';
import Logistration from './logistration/Logistration';
import MainAppSlot from './plugin-slots/MainAppSlot';
import { ProgressiveProfiling } from './progressive-profiling';
import { RecommendationsPage } from './recommendations';
import { RegistrationPage } from './register';
Expand All @@ -36,7 +37,6 @@ const MainApp = () => (
<Helmet>
<link rel="shortcut icon" href={getConfig().FAVICON_URL} type="image/x-icon" />
</Helmet>
{getConfig().ZENDESK_KEY && <Zendesk />}
<Routes>
<Route path="/" element={<Navigate replace to={updatePathWithQueryParams(REGISTER_PAGE)} />} />
<Route
Expand All @@ -57,6 +57,7 @@ const MainApp = () => (
<Route path={PAGE_NOT_FOUND} element={<NotFoundPage />} />
<Route path="*" element={<Navigate replace to={PAGE_NOT_FOUND} />} />
</Routes>
<MainAppSlot />
</AppProvider>
);

Expand Down
29 changes: 29 additions & 0 deletions src/plugin-slots/MainAppSlot/MainAppSlot.test.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
import { PluginSlot } from '@openedx/frontend-plugin-framework';
import { render } from '@testing-library/react';

import MainAppSlot from './index';

jest.mock('@openedx/frontend-plugin-framework', () => ({
PluginSlot: jest.fn(() => null),
}));

describe('MainAppSlot', () => {
it('renders without crashing', () => {
render(<MainAppSlot />);
});

it('renders a PluginSlot component', () => {
render(<MainAppSlot />);
expect(PluginSlot).toHaveBeenCalled();
});

it('passes the correct id prop to PluginSlot', () => {
render(<MainAppSlot />);
expect(PluginSlot).toHaveBeenCalledWith({ id: 'main_app_slot' }, {});
});

it('does not render any children', () => {
const { container } = render(<MainAppSlot />);
expect(container.firstChild).toBeNull();
});
});
41 changes: 41 additions & 0 deletions src/plugin-slots/MainAppSlot/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
# Main App Slot

### Slot ID: `main_app_slot`

## Description

This slot is used for adding content at the root level.

## Example

The following `env.config.jsx` will render a component at the MFE root level.

![Screenshot of Content added after the Main App Slot](./images/main_app_slot.png)

```js
import {
DIRECT_PLUGIN,
PLUGIN_OPERATIONS,
} from "@openedx/frontend-plugin-framework";
import { ExampleComponent } from "@openedx/frontend-plugin-example";

const config = {
pluginSlots: {
main_app_slot: {
plugins: [
{
op: PLUGIN_OPERATIONS.Insert,
widget: {
id: "example-component",
type: DIRECT_PLUGIN,
priority: 60,
RenderWidget: ExampleComponent,
},
},
],
},
},
};

export default config;
```
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
7 changes: 7 additions & 0 deletions src/plugin-slots/MainAppSlot/index.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import { PluginSlot } from '@openedx/frontend-plugin-framework';

const MainAppSlot = () => (
<PluginSlot id="main_app_slot" />
);

export default MainAppSlot;
3 changes: 3 additions & 0 deletions src/plugin-slots/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
# `frontend-app-authn` Plugin Slots

- [`main_app_slot`](./MainAppSlot/)

0 comments on commit 47b0501

Please sign in to comment.