@mitodl/smoot-design 0.0.0-a2e4e1e → 0.0.0-bafccd3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +4 -0
- package/dist/bundles/{remoteTutorDrawer.es.js → aiDrawerManager.es.js} +17612 -17240
- package/dist/bundles/aiDrawerManager.es.js.map +1 -0
- package/dist/bundles/aiDrawerManager.umd.js +245 -0
- package/dist/bundles/aiDrawerManager.umd.js.map +1 -0
- package/dist/cjs/VERSION.d.ts +12 -0
- package/dist/cjs/VERSION.js +15 -0
- package/dist/cjs/ai.d.ts +3 -3
- package/dist/cjs/ai.js +5 -1
- package/dist/cjs/bundles/{RemoteTutorDrawer/RemoteTutorDrawer.d.ts → AiDrawer/AiDrawer.d.ts} +11 -13
- package/dist/cjs/bundles/{RemoteTutorDrawer/RemoteTutorDrawer.js → AiDrawer/AiDrawer.js} +27 -41
- package/dist/cjs/bundles/{RemoteTutorDrawer/RemoteTutorDrawer.stories.d.ts → AiDrawer/AiDrawer.stories.d.ts} +4 -3
- package/dist/cjs/bundles/{RemoteTutorDrawer/RemoteTutorDrawer.stories.js → AiDrawer/AiDrawer.stories.js} +32 -51
- package/dist/cjs/bundles/AiDrawer/AiDrawerManager.d.ts +12 -0
- package/dist/cjs/bundles/AiDrawer/AiDrawerManager.js +51 -0
- package/dist/cjs/bundles/AiDrawer/AiDrawerManager.stories.d.ts +6 -0
- package/dist/cjs/bundles/AiDrawer/AiDrawerManager.stories.js +267 -0
- package/dist/cjs/bundles/{RemoteTutorDrawer/RemoteTutorDrawer.test.js → AiDrawer/AiDrawerManager.test.js} +22 -18
- package/dist/cjs/bundles/{RemoteTutorDrawer → AiDrawer}/FlashcardsScreen.js +1 -1
- package/dist/cjs/bundles/aiDrawerManager.d.ts +6 -0
- package/dist/cjs/bundles/aiDrawerManager.js +44 -0
- package/dist/cjs/components/AiChat/AiChat.d.ts +3 -3
- package/dist/cjs/components/AiChat/AiChat.js +65 -53
- package/dist/cjs/components/AiChat/AiChat.stories.d.ts +0 -4
- package/dist/cjs/components/AiChat/AiChat.stories.js +5 -54
- package/dist/cjs/components/AiChat/AiChatContext.d.ts +26 -0
- package/dist/cjs/components/AiChat/AiChatContext.js +106 -0
- package/dist/cjs/components/AiChat/AiChatContext.stories.d.ts +14 -0
- package/dist/cjs/components/AiChat/AiChatContext.stories.js +75 -0
- package/dist/cjs/components/AiChat/AiChatMarkdown.stories.d.ts +15 -0
- package/dist/cjs/components/AiChat/AiChatMarkdown.stories.js +282 -0
- package/dist/cjs/components/AiChat/Markdown.d.ts +7 -0
- package/dist/cjs/components/AiChat/Markdown.js +14 -0
- package/dist/cjs/components/AiChat/test-utils/api.js +40 -1
- package/dist/cjs/components/AiChat/types.d.ts +25 -11
- package/dist/cjs/components/AiChat/types.js +1 -1
- package/dist/cjs/components/AiChat/utils.d.ts +1 -1
- package/dist/cjs/components/AiChat/utils.js +1 -1
- package/dist/cjs/components/LinkAdapter/LinkAdapter.js +1 -1
- package/dist/cjs/components/TabButtons/TabButtonList.js +1 -1
- package/dist/cjs/index.d.ts +1 -0
- package/dist/cjs/index.js +3 -1
- package/dist/cjs/utils/retryingFetch.d.ts +19 -0
- package/dist/cjs/utils/retryingFetch.js +98 -0
- package/dist/cjs/utils/retryingFetch.test.js +48 -0
- package/dist/esm/VERSION.d.ts +12 -0
- package/dist/esm/VERSION.js +12 -0
- package/dist/esm/ai.d.ts +3 -3
- package/dist/esm/ai.js +2 -1
- package/dist/esm/bundles/{RemoteTutorDrawer/RemoteTutorDrawer.d.ts → AiDrawer/AiDrawer.d.ts} +11 -13
- package/dist/esm/bundles/{RemoteTutorDrawer/RemoteTutorDrawer.js → AiDrawer/AiDrawer.js} +26 -40
- package/dist/esm/bundles/{RemoteTutorDrawer/RemoteTutorDrawer.stories.d.ts → AiDrawer/AiDrawer.stories.d.ts} +4 -3
- package/dist/esm/bundles/{RemoteTutorDrawer/RemoteTutorDrawer.stories.js → AiDrawer/AiDrawer.stories.js} +31 -50
- package/dist/esm/bundles/AiDrawer/AiDrawerManager.d.ts +12 -0
- package/dist/esm/bundles/AiDrawer/AiDrawerManager.js +48 -0
- package/dist/esm/bundles/AiDrawer/AiDrawerManager.stories.d.ts +6 -0
- package/dist/esm/bundles/AiDrawer/AiDrawerManager.stories.js +264 -0
- package/dist/esm/bundles/AiDrawer/AiDrawerManager.test.d.ts +1 -0
- package/dist/esm/bundles/{RemoteTutorDrawer/RemoteTutorDrawer.test.js → AiDrawer/AiDrawerManager.test.js} +22 -18
- package/dist/esm/bundles/{RemoteTutorDrawer → AiDrawer}/FlashcardsScreen.js +1 -1
- package/dist/esm/bundles/aiDrawerManager.d.ts +6 -0
- package/dist/esm/bundles/aiDrawerManager.js +41 -0
- package/dist/esm/components/AiChat/AiChat.d.ts +3 -3
- package/dist/esm/components/AiChat/AiChat.js +65 -54
- package/dist/esm/components/AiChat/AiChat.stories.d.ts +0 -4
- package/dist/esm/components/AiChat/AiChat.stories.js +4 -53
- package/dist/esm/components/AiChat/AiChatContext.d.ts +26 -0
- package/dist/esm/components/AiChat/AiChatContext.js +102 -0
- package/dist/esm/components/AiChat/AiChatContext.stories.d.ts +14 -0
- package/dist/esm/components/AiChat/AiChatContext.stories.js +72 -0
- package/dist/esm/components/AiChat/AiChatMarkdown.stories.d.ts +15 -0
- package/dist/esm/components/AiChat/AiChatMarkdown.stories.js +279 -0
- package/dist/esm/components/AiChat/Markdown.d.ts +7 -0
- package/dist/esm/components/AiChat/Markdown.js +12 -0
- package/dist/esm/components/AiChat/test-utils/api.js +40 -1
- package/dist/esm/components/AiChat/types.d.ts +25 -11
- package/dist/esm/components/AiChat/types.js +1 -1
- package/dist/esm/components/AiChat/utils.d.ts +1 -1
- package/dist/esm/components/AiChat/utils.js +1 -1
- package/dist/esm/components/LinkAdapter/LinkAdapter.js +1 -1
- package/dist/esm/components/TabButtons/TabButtonList.js +1 -1
- package/dist/esm/index.d.ts +1 -0
- package/dist/esm/index.js +1 -0
- package/dist/esm/utils/retryingFetch.d.ts +19 -0
- package/dist/esm/utils/retryingFetch.js +96 -0
- package/dist/esm/utils/retryingFetch.test.d.ts +1 -0
- package/dist/esm/utils/retryingFetch.test.js +46 -0
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/package.json +11 -7
- package/dist/bundles/remoteTutorDrawer.umd.js +0 -207
- package/dist/cjs/bundles/remoteTutorDrawer.d.ts +0 -7
- package/dist/cjs/bundles/remoteTutorDrawer.js +0 -40
- package/dist/esm/bundles/remoteTutorDrawer.d.ts +0 -7
- package/dist/esm/bundles/remoteTutorDrawer.js +0 -37
- /package/dist/cjs/bundles/{RemoteTutorDrawer/RemoteTutorDrawer.test.d.ts → AiDrawer/AiDrawerManager.test.d.ts} +0 -0
- /package/dist/cjs/bundles/{RemoteTutorDrawer → AiDrawer}/FlashcardsScreen.d.ts +0 -0
- /package/dist/{esm/bundles/RemoteTutorDrawer/RemoteTutorDrawer.test.d.ts → cjs/utils/retryingFetch.test.d.ts} +0 -0
- /package/dist/esm/bundles/{RemoteTutorDrawer → AiDrawer}/FlashcardsScreen.d.ts +0 -0
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* This file is auto-generated at build time.
|
|
3
|
+
* Run node ./scripts/set_version.js to update the version.
|
|
4
|
+
* Do not update this file manually.
|
|
5
|
+
*
|
|
6
|
+
* NOTES:
|
|
7
|
+
* - In development, VERSION will always be "0.0.0"
|
|
8
|
+
* - The version should not simply be imported from package.json. This would
|
|
9
|
+
* result in all of the package.json being included in the bundled code, which
|
|
10
|
+
* is not desired.
|
|
11
|
+
*/
|
|
12
|
+
export declare const VERSION = "0.0.0-bafccd3";
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* This file is auto-generated at build time.
|
|
3
|
+
* Run node ./scripts/set_version.js to update the version.
|
|
4
|
+
* Do not update this file manually.
|
|
5
|
+
*
|
|
6
|
+
* NOTES:
|
|
7
|
+
* - In development, VERSION will always be "0.0.0"
|
|
8
|
+
* - The version should not simply be imported from package.json. This would
|
|
9
|
+
* result in all of the package.json being included in the bundled code, which
|
|
10
|
+
* is not desired.
|
|
11
|
+
*/
|
|
12
|
+
export const VERSION = "0.0.0-bafccd3";
|
package/dist/esm/ai.d.ts
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
export { AiChat } from "./components/AiChat/AiChat";
|
|
2
|
-
export
|
|
3
|
-
export type { AiChatMessage } from "./components/AiChat/types";
|
|
1
|
+
export { AiChat, AiChatDisplay } from "./components/AiChat/AiChat";
|
|
2
|
+
export { AiChatProvider, useAiChat } from "./components/AiChat/AiChatContext";
|
|
3
|
+
export type { AiChatMessage, AiChatContextProps, AiChatDisplayProps, AiChatProps, } from "./components/AiChat/types";
|
package/dist/esm/ai.js
CHANGED
|
@@ -1 +1,2 @@
|
|
|
1
|
-
export { AiChat } from "./components/AiChat/AiChat";
|
|
1
|
+
export { AiChat, AiChatDisplay } from "./components/AiChat/AiChat";
|
|
2
|
+
export { AiChatProvider, useAiChat } from "./components/AiChat/AiChatContext";
|
package/dist/esm/bundles/{RemoteTutorDrawer/RemoteTutorDrawer.d.ts → AiDrawer/AiDrawer.d.ts}
RENAMED
|
@@ -1,8 +1,7 @@
|
|
|
1
1
|
import { FC } from "react";
|
|
2
|
-
import { AiChatMessage } from "../../components/AiChat/types";
|
|
3
|
-
|
|
4
|
-
type
|
|
5
|
-
type: "smoot-design::tutor-drawer-open";
|
|
2
|
+
import type { AiChatProps, AiChatMessage } from "../../components/AiChat/types";
|
|
3
|
+
type AiDrawerInitMessage = {
|
|
4
|
+
type: "smoot-design::ai-drawer-open" | "smoot-design::tutor-drawer-open";
|
|
6
5
|
payload: {
|
|
7
6
|
blockType?: "problem" | "video";
|
|
8
7
|
target?: string;
|
|
@@ -24,13 +23,8 @@ type RemoteTutorDrawerInitMessage = {
|
|
|
24
23
|
};
|
|
25
24
|
};
|
|
26
25
|
};
|
|
27
|
-
type
|
|
26
|
+
type AiDrawerProps = {
|
|
28
27
|
className?: string;
|
|
29
|
-
/**
|
|
30
|
-
* The origin of the messages that will be received to open the chat.
|
|
31
|
-
* The drawer will ignore all message events not from this origin.
|
|
32
|
-
*/
|
|
33
|
-
messageOrigin: string;
|
|
34
28
|
/**
|
|
35
29
|
* Transform the body of the request before sending it to the server.
|
|
36
30
|
* Its result will be merged with the per-message requestBody opt, with
|
|
@@ -50,8 +44,12 @@ type RemoteTutorDrawerProps = {
|
|
|
50
44
|
/**
|
|
51
45
|
* Pass to target a specific drawer instance where multiple are on the page.
|
|
52
46
|
*/
|
|
47
|
+
/** @deprecated The AiDrawerManager now handles multiple AiDrawer instance removing the need to target */
|
|
53
48
|
target?: string;
|
|
49
|
+
payload?: AiDrawerInitMessage["payload"];
|
|
50
|
+
open?: boolean;
|
|
51
|
+
onClose?: () => void;
|
|
54
52
|
};
|
|
55
|
-
declare const
|
|
56
|
-
export {
|
|
57
|
-
export type {
|
|
53
|
+
declare const AiDrawer: FC<AiDrawerProps>;
|
|
54
|
+
export { AiDrawer };
|
|
55
|
+
export type { AiDrawerProps, AiDrawerInitMessage };
|
|
@@ -22,6 +22,7 @@ import TabPanel from "@mui/lab/TabPanel";
|
|
|
22
22
|
import { AiChat } from "../../components/AiChat/AiChat";
|
|
23
23
|
import { ActionButton } from "../../components/Button/ActionButton";
|
|
24
24
|
import { FlashcardsScreen } from "./FlashcardsScreen";
|
|
25
|
+
import { VERSION } from "../../VERSION";
|
|
25
26
|
const Header = styled.div(({ theme }) => ({
|
|
26
27
|
display: "flex",
|
|
27
28
|
alignItems: "center",
|
|
@@ -149,6 +150,12 @@ const useContentFetch = (contentUrl) => {
|
|
|
149
150
|
}, [contentUrl]);
|
|
150
151
|
return { response, loading };
|
|
151
152
|
};
|
|
153
|
+
const DEFAULT_PROBLEM_INITIAL_MESSAGES = [
|
|
154
|
+
{
|
|
155
|
+
role: "assistant",
|
|
156
|
+
content: "Let's try to work on this problem together. It would be great to hear how you're thinking about solving it. Can you walk me through the approach you're considering?",
|
|
157
|
+
},
|
|
158
|
+
];
|
|
152
159
|
const DEFAULT_VIDEO_ENTRY_SCREEN_TITLE = "What do you want to know about this video?";
|
|
153
160
|
const DEFAULT_VIDEO_STARTERS = [
|
|
154
161
|
{ content: "What are the most important concepts introduced in the video?" },
|
|
@@ -157,23 +164,21 @@ const DEFAULT_VIDEO_STARTERS = [
|
|
|
157
164
|
},
|
|
158
165
|
{ content: "What are the key terms introduced in this video?" },
|
|
159
166
|
];
|
|
160
|
-
const ChatComponent = ({ payload, transformBody, fetchOpts, scrollElement, entryScreenEnabled, entryScreenTitle, conversationStarters, hasTabs, }) => {
|
|
167
|
+
const ChatComponent = ({ payload, transformBody, fetchOpts, scrollElement, entryScreenEnabled, entryScreenTitle, conversationStarters, initialMessages, hasTabs, needsMathJax, }) => {
|
|
161
168
|
if (!payload)
|
|
162
169
|
return null;
|
|
163
|
-
return (React.createElement(StyledAiChat, { chatId: payload.chatId, conversationStarters: conversationStarters, initialMessages:
|
|
170
|
+
return (React.createElement(StyledAiChat, { key: payload.chatId, chatId: payload.chatId, conversationStarters: conversationStarters, initialMessages: initialMessages, scrollElement: scrollElement, entryScreenEnabled: entryScreenEnabled, entryScreenTitle: entryScreenTitle, requestOpts: {
|
|
164
171
|
transformBody: (messages) => (Object.assign(Object.assign({}, payload.requestBody), transformBody === null || transformBody === void 0 ? void 0 : transformBody(messages))),
|
|
165
172
|
apiUrl: payload.apiUrl,
|
|
166
173
|
fetchOpts: Object.assign(Object.assign({}, DEFAULT_FETCH_OPTS), fetchOpts),
|
|
167
|
-
}, hasTabs: hasTabs }));
|
|
174
|
+
}, hasTabs: hasTabs, useMathJax: needsMathJax }));
|
|
168
175
|
};
|
|
169
176
|
const randomItems = (array, count) => {
|
|
170
177
|
const shuffled = [...array].sort(() => 0.5 - Math.random());
|
|
171
178
|
return shuffled.slice(0, count);
|
|
172
179
|
};
|
|
173
|
-
const
|
|
174
|
-
var _a, _b, _c, _d, _e, _f, _g
|
|
175
|
-
const [open, setOpen] = useState(false);
|
|
176
|
-
const [payload, setPayload] = useState(null);
|
|
180
|
+
const AiDrawer = ({ transformBody = identity, className, fetchOpts, payload, open, onClose, }) => {
|
|
181
|
+
var _a, _b, _c, _d, _e, _f, _g;
|
|
177
182
|
const [tab, setTab] = useState("chat");
|
|
178
183
|
const { response } = useContentFetch((_a = payload === null || payload === void 0 ? void 0 : payload.summary) === null || _a === void 0 ? void 0 : _a.apiUrl);
|
|
179
184
|
const [_wasKeyboardFocus, setWasKeyboardFocus] = useState(false);
|
|
@@ -193,25 +198,6 @@ const RemoteTutorDrawer = ({ messageOrigin, transformBody = identity, className,
|
|
|
193
198
|
setScrollElement(node);
|
|
194
199
|
}
|
|
195
200
|
};
|
|
196
|
-
useEffect(() => {
|
|
197
|
-
const cb = (event) => {
|
|
198
|
-
if (event.origin !== messageOrigin) {
|
|
199
|
-
if (process.env.NODE_ENV === "development") {
|
|
200
|
-
console.warn(`RemoteTutorDrawer: received message from unexpected origin: ${event.origin}`);
|
|
201
|
-
}
|
|
202
|
-
return;
|
|
203
|
-
}
|
|
204
|
-
if (event.data.type === "smoot-design::tutor-drawer-open" &&
|
|
205
|
-
event.data.payload.target === target) {
|
|
206
|
-
setOpen(true);
|
|
207
|
-
setPayload(event.data.payload);
|
|
208
|
-
}
|
|
209
|
-
};
|
|
210
|
-
window.addEventListener("message", cb);
|
|
211
|
-
return () => {
|
|
212
|
-
window.removeEventListener("message", cb);
|
|
213
|
-
};
|
|
214
|
-
}, [messageOrigin, target]);
|
|
215
201
|
useEffect(() => {
|
|
216
202
|
var _a;
|
|
217
203
|
(_a = scrollElement === null || scrollElement === void 0 ? void 0 : scrollElement.scrollTo) === null || _a === void 0 ? void 0 : _a.call(scrollElement, {
|
|
@@ -230,11 +216,11 @@ const RemoteTutorDrawer = ({ messageOrigin, transformBody = identity, className,
|
|
|
230
216
|
: DEFAULT_VIDEO_STARTERS));
|
|
231
217
|
}, [payload, response]);
|
|
232
218
|
if (!payload) {
|
|
233
|
-
return React.createElement("div", { "data-testid": "
|
|
219
|
+
return React.createElement("div", { "data-testid": "ai-drawer-waiting" });
|
|
234
220
|
}
|
|
235
|
-
const { blockType, chat } = payload;
|
|
221
|
+
const { title, blockType, chat } = payload;
|
|
236
222
|
const hasTabs = blockType === "video";
|
|
237
|
-
return (React.createElement(Drawer, { "data-
|
|
223
|
+
return (React.createElement(Drawer, { "data-smoot-version": VERSION, className: className, PaperProps: {
|
|
238
224
|
ref: paperRefCallback,
|
|
239
225
|
sx: {
|
|
240
226
|
width: "900px",
|
|
@@ -245,29 +231,29 @@ const RemoteTutorDrawer = ({ messageOrigin, transformBody = identity, className,
|
|
|
245
231
|
md: "0 32px",
|
|
246
232
|
},
|
|
247
233
|
},
|
|
248
|
-
}, anchor: "right", open: open, onClose:
|
|
234
|
+
}, anchor: "right", open: open, onClose: onClose, role: "dialog", "aria-modal": "true", keepMounted: true },
|
|
249
235
|
React.createElement(Header, null,
|
|
250
236
|
React.createElement(Title, null,
|
|
251
|
-
|
|
252
|
-
React.createElement(Typography, { variant: "body1", component: "
|
|
237
|
+
title ? React.createElement(RiSparkling2Line, null) : null,
|
|
238
|
+
React.createElement(Typography, { variant: "body1", component: "h1" }, (title === null || title === void 0 ? void 0 : title.includes("AskTIM")) ? (React.createElement(React.Fragment, null,
|
|
253
239
|
"Ask",
|
|
254
240
|
React.createElement("strong", null, "TIM"),
|
|
255
|
-
|
|
256
|
-
React.createElement(CloseButton, { variant: "text", size: "medium", onClick:
|
|
241
|
+
title.replace("AskTIM", ""))) : (title))),
|
|
242
|
+
React.createElement(CloseButton, { variant: "text", size: "medium", onClick: onClose, "aria-label": "Close" },
|
|
257
243
|
React.createElement(RiCloseLine, null))),
|
|
258
|
-
blockType === "problem" ? (React.createElement(ChatComponent, { payload: chat, transformBody: transformBody, fetchOpts: fetchOpts, scrollElement: scrollElement, entryScreenEnabled: (
|
|
244
|
+
blockType === "problem" ? (React.createElement(ChatComponent, { payload: chat, transformBody: transformBody, fetchOpts: fetchOpts, scrollElement: scrollElement, entryScreenEnabled: (_b = chat === null || chat === void 0 ? void 0 : chat.entryScreenEnabled) !== null && _b !== void 0 ? _b : false, entryScreenTitle: chat.entryScreenTitle, initialMessages: chat.initialMessages || DEFAULT_PROBLEM_INITIAL_MESSAGES, hasTabs: hasTabs, needsMathJax: true })) : null,
|
|
259
245
|
blockType === "video" ? (React.createElement(TabContext, { value: tab },
|
|
260
246
|
React.createElement(StyledTabButtonList, { styleVariant: "chat", onChange: (e, tab) => setTab(tab) },
|
|
261
247
|
React.createElement(TabButton, { value: "chat", label: "Chat" }),
|
|
262
|
-
((
|
|
248
|
+
((_c = response === null || response === void 0 ? void 0 : response.flashcards) === null || _c === void 0 ? void 0 : _c.length) ? (React.createElement(TabButton, { value: "flashcards", label: "Flashcards", onMouseDown: handleMouseDown, onFocus: handleFocus })) : null,
|
|
263
249
|
React.createElement(TabButton, { value: "summary", label: "Summary" })),
|
|
264
250
|
React.createElement(StyledTabPanel, { value: "chat", keepMounted: true },
|
|
265
|
-
React.createElement(ChatComponent, { payload:
|
|
266
|
-
((
|
|
251
|
+
React.createElement(ChatComponent, { payload: chat, transformBody: transformBody, fetchOpts: fetchOpts, scrollElement: scrollElement, entryScreenEnabled: (_d = chat === null || chat === void 0 ? void 0 : chat.entryScreenEnabled) !== null && _d !== void 0 ? _d : true, entryScreenTitle: (_e = chat.entryScreenTitle) !== null && _e !== void 0 ? _e : DEFAULT_VIDEO_ENTRY_SCREEN_TITLE, conversationStarters: conversationStarters, initialMessages: chat.initialMessages, hasTabs: hasTabs, needsMathJax: false })),
|
|
252
|
+
((_f = response === null || response === void 0 ? void 0 : response.flashcards) === null || _f === void 0 ? void 0 : _f.length) ? (React.createElement(StyledTabPanel, { value: "flashcards" },
|
|
267
253
|
React.createElement(FlashcardsScreen, { flashcards: response === null || response === void 0 ? void 0 : response.flashcards, wasKeyboardFocus: _wasKeyboardFocus }))) : null,
|
|
268
254
|
React.createElement(StyledTabPanel, { value: "summary" },
|
|
269
255
|
React.createElement(Typography, { variant: "h4", component: "h4" }),
|
|
270
256
|
React.createElement(StyledHTML, null,
|
|
271
|
-
React.createElement(Markdown, { rehypePlugins: [rehypeRaw] }, (
|
|
257
|
+
React.createElement(Markdown, { rehypePlugins: [rehypeRaw] }, (_g = response === null || response === void 0 ? void 0 : response.summary) !== null && _g !== void 0 ? _g : ""))))) : null));
|
|
272
258
|
};
|
|
273
|
-
export {
|
|
259
|
+
export { AiDrawer };
|
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
import type { Meta, StoryObj } from "@storybook/react";
|
|
2
|
-
import {
|
|
3
|
-
declare const meta: Meta<typeof
|
|
2
|
+
import { AiDrawer } from "./AiDrawer";
|
|
3
|
+
declare const meta: Meta<typeof AiDrawer>;
|
|
4
4
|
export default meta;
|
|
5
|
-
type Story = StoryObj<typeof
|
|
5
|
+
type Story = StoryObj<typeof AiDrawer>;
|
|
6
6
|
export declare const ProblemStory: Story;
|
|
7
|
+
export declare const ProblemDefaultInitialMessagesStory: Story;
|
|
7
8
|
export declare const EntryScreenStory: Story;
|
|
8
9
|
/**
|
|
9
10
|
* The chat entry screen is shown by default for the video blocks Tutor drawer.
|
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
/* eslint-disable react-hooks/rules-of-hooks */
|
|
2
2
|
import * as React from "react";
|
|
3
|
-
import invariant from "tiny-invariant";
|
|
4
3
|
import { http, HttpResponse } from "msw";
|
|
5
4
|
import { handlers } from "../../components/AiChat/test-utils/api";
|
|
6
|
-
import {
|
|
5
|
+
import { AiDrawer } from "./AiDrawer";
|
|
6
|
+
import { MathJaxContext } from "better-react-mathjax";
|
|
7
|
+
import Button from "@mui/material/Button";
|
|
7
8
|
const TEST_API_STREAMING = "http://localhost:4567/streaming";
|
|
8
9
|
const CONTENT_FILE_URL = "http://localhost:4567/api/v1/contentfiles/?edx_module_id=1";
|
|
9
10
|
const INITIAL_MESSAGES = [
|
|
@@ -17,50 +18,22 @@ const STARTERS = [
|
|
|
17
18
|
{ content: "I want to understand global warming. " },
|
|
18
19
|
{ content: "I am curious about AI applications for business" },
|
|
19
20
|
];
|
|
20
|
-
const buildIFrame = (payload) => (el) => {
|
|
21
|
-
var _a;
|
|
22
|
-
if (!el)
|
|
23
|
-
return;
|
|
24
|
-
const doc = el.contentDocument;
|
|
25
|
-
const parent = (_a = el.contentWindow) === null || _a === void 0 ? void 0 : _a.parent;
|
|
26
|
-
invariant(doc && parent);
|
|
27
|
-
const button = doc.createElement("button");
|
|
28
|
-
button.textContent = "Open drawer (send message to parent)";
|
|
29
|
-
doc.body.appendChild(button);
|
|
30
|
-
const div = doc.createElement("div");
|
|
31
|
-
doc.body.appendChild(div);
|
|
32
|
-
const label = doc.createElement("label");
|
|
33
|
-
label.textContent = "Message Data:";
|
|
34
|
-
div.appendChild(label);
|
|
35
|
-
const textarea = doc.createElement("textarea");
|
|
36
|
-
div.append(textarea);
|
|
37
|
-
textarea.style["display"] = "block";
|
|
38
|
-
textarea.style["width"] = "100%";
|
|
39
|
-
textarea.style["height"] = "500px";
|
|
40
|
-
const message = {
|
|
41
|
-
type: "smoot-design::tutor-drawer-open",
|
|
42
|
-
payload,
|
|
43
|
-
};
|
|
44
|
-
textarea.value = JSON.stringify(message, null, 2);
|
|
45
|
-
button.addEventListener("click", () => {
|
|
46
|
-
parent.postMessage(JSON.parse(textarea.value));
|
|
47
|
-
});
|
|
48
|
-
};
|
|
49
|
-
const IFrame = ({ payload }) => {
|
|
50
|
-
return (React.createElement("iframe", { width: "100%", height: "600px", ref: buildIFrame(payload), title: "button frame" }));
|
|
51
|
-
};
|
|
52
21
|
const meta = {
|
|
53
|
-
title: "smoot-design/AI/
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
22
|
+
title: "smoot-design/AI/AiDrawer",
|
|
23
|
+
component: AiDrawer,
|
|
24
|
+
render: ({ payload }) => {
|
|
25
|
+
const [open, setOpen] = React.useState(false);
|
|
26
|
+
return (React.createElement(React.Fragment, null,
|
|
27
|
+
React.createElement(Button, { variant: "outlined", onClick: () => setOpen(true) }, "Open Drawer"),
|
|
28
|
+
React.createElement("p", null, "Message data:"),
|
|
29
|
+
React.createElement("pre", null, JSON.stringify({ payload }, null, 2)),
|
|
30
|
+
React.createElement(MathJaxContext, null,
|
|
31
|
+
React.createElement(AiDrawer, { payload: payload, open: open, onClose: () => setOpen(false) }))));
|
|
32
|
+
},
|
|
57
33
|
};
|
|
58
34
|
export default meta;
|
|
59
35
|
export const ProblemStory = {
|
|
60
36
|
args: {
|
|
61
|
-
target: "problem-frame",
|
|
62
|
-
},
|
|
63
|
-
parameters: {
|
|
64
37
|
payload: {
|
|
65
38
|
blockType: "problem",
|
|
66
39
|
target: "problem-frame",
|
|
@@ -73,11 +46,21 @@ export const ProblemStory = {
|
|
|
73
46
|
},
|
|
74
47
|
},
|
|
75
48
|
};
|
|
76
|
-
export const
|
|
49
|
+
export const ProblemDefaultInitialMessagesStory = {
|
|
77
50
|
args: {
|
|
78
|
-
|
|
51
|
+
payload: {
|
|
52
|
+
blockType: "problem",
|
|
53
|
+
target: "problem-frame-default-initial-messages",
|
|
54
|
+
title: "AskTIM for help with Problem: Derivatives 1.1",
|
|
55
|
+
chat: {
|
|
56
|
+
apiUrl: TEST_API_STREAMING,
|
|
57
|
+
conversationStarters: STARTERS,
|
|
58
|
+
},
|
|
59
|
+
},
|
|
79
60
|
},
|
|
80
|
-
|
|
61
|
+
};
|
|
62
|
+
export const EntryScreenStory = {
|
|
63
|
+
args: {
|
|
81
64
|
payload: {
|
|
82
65
|
blockType: "problem",
|
|
83
66
|
target: "entry-screen-frame",
|
|
@@ -96,9 +79,6 @@ export const EntryScreenStory = {
|
|
|
96
79
|
*/
|
|
97
80
|
export const VideoStory = {
|
|
98
81
|
args: {
|
|
99
|
-
target: "video-frame",
|
|
100
|
-
},
|
|
101
|
-
parameters: {
|
|
102
82
|
payload: {
|
|
103
83
|
blockType: "video",
|
|
104
84
|
target: "video-frame",
|
|
@@ -110,6 +90,8 @@ export const VideoStory = {
|
|
|
110
90
|
apiUrl: CONTENT_FILE_URL,
|
|
111
91
|
},
|
|
112
92
|
},
|
|
93
|
+
},
|
|
94
|
+
parameters: {
|
|
113
95
|
msw: {
|
|
114
96
|
handlers: [
|
|
115
97
|
http.get(CONTENT_FILE_URL, () => {
|
|
@@ -126,9 +108,6 @@ export const VideoStory = {
|
|
|
126
108
|
*/
|
|
127
109
|
export const FlashcardConversationStartersStory = {
|
|
128
110
|
args: {
|
|
129
|
-
target: "starters-frame",
|
|
130
|
-
},
|
|
131
|
-
parameters: {
|
|
132
111
|
payload: {
|
|
133
112
|
blockType: "video",
|
|
134
113
|
target: "starters-frame",
|
|
@@ -139,6 +118,8 @@ export const FlashcardConversationStartersStory = {
|
|
|
139
118
|
apiUrl: CONTENT_FILE_URL,
|
|
140
119
|
},
|
|
141
120
|
},
|
|
121
|
+
},
|
|
122
|
+
parameters: {
|
|
142
123
|
msw: {
|
|
143
124
|
handlers: [
|
|
144
125
|
http.get(CONTENT_FILE_URL, () => {
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import * as React from "react";
|
|
2
|
+
import type { AiDrawerProps } from "./AiDrawer";
|
|
3
|
+
type AiDrawerManagerProps = {
|
|
4
|
+
/**
|
|
5
|
+
* The origin of the messages that will be received to open the chat.
|
|
6
|
+
* The drawer will ignore all message events not from this origin.
|
|
7
|
+
*/
|
|
8
|
+
messageOrigin: string;
|
|
9
|
+
} & AiDrawerProps;
|
|
10
|
+
declare const AiDrawerManager: ({ className, messageOrigin, transformBody, fetchOpts, target, }: AiDrawerManagerProps) => React.JSX.Element;
|
|
11
|
+
export { AiDrawerManager };
|
|
12
|
+
export type { AiDrawerManagerProps };
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import * as React from "react";
|
|
2
|
+
import { useEffect, useState } from "react";
|
|
3
|
+
import { AiDrawer } from "./AiDrawer";
|
|
4
|
+
import { MathJaxContext } from "better-react-mathjax";
|
|
5
|
+
const hashPayload = (payload) => {
|
|
6
|
+
const str = JSON.stringify(payload);
|
|
7
|
+
let hash = 5381;
|
|
8
|
+
for (let i = 0; i < str.length; i++) {
|
|
9
|
+
hash = (hash << 5) + hash + str.charCodeAt(i);
|
|
10
|
+
hash = hash & hash;
|
|
11
|
+
}
|
|
12
|
+
return Math.abs(hash).toString(36);
|
|
13
|
+
};
|
|
14
|
+
const AiDrawerManager = ({ className, messageOrigin, transformBody, fetchOpts, target, }) => {
|
|
15
|
+
const [drawerStates, setDrawerStates] = useState({});
|
|
16
|
+
useEffect(() => {
|
|
17
|
+
const cb = (event) => {
|
|
18
|
+
if (event.origin !== messageOrigin) {
|
|
19
|
+
if (process.env.NODE_ENV === "development") {
|
|
20
|
+
console.warn(`AiDrawerManager: received message from unexpected origin: ${event.origin}`);
|
|
21
|
+
}
|
|
22
|
+
return;
|
|
23
|
+
}
|
|
24
|
+
if ([
|
|
25
|
+
"smoot-design::ai-drawer-open",
|
|
26
|
+
"smoot-design::tutor-drawer-open", // legacy
|
|
27
|
+
].includes(event.data.type)) {
|
|
28
|
+
const key = hashPayload(event.data.payload);
|
|
29
|
+
event.data.payload.chat.chatId = event.data.payload.chat.chatId || key;
|
|
30
|
+
setDrawerStates((prev) => (Object.assign(Object.assign({}, prev), { [key]: { key, open: false, payload: event.data.payload } })));
|
|
31
|
+
requestAnimationFrame(() => {
|
|
32
|
+
setDrawerStates((prev) => (Object.assign(Object.assign({}, prev), { [key]: Object.assign(Object.assign({}, prev[key]), { open: true }) })));
|
|
33
|
+
});
|
|
34
|
+
}
|
|
35
|
+
};
|
|
36
|
+
window.addEventListener("message", cb);
|
|
37
|
+
return () => {
|
|
38
|
+
window.removeEventListener("message", cb);
|
|
39
|
+
};
|
|
40
|
+
}, [messageOrigin, target]);
|
|
41
|
+
if (Object.values(drawerStates).length === 0) {
|
|
42
|
+
return React.createElement("div", { "data-testid": "ai-drawer-manager-waiting" });
|
|
43
|
+
}
|
|
44
|
+
return (React.createElement(MathJaxContext, null, Object.values(drawerStates).map(({ key, open, payload }) => (React.createElement(AiDrawer, { key: key, className: className, transformBody: transformBody, fetchOpts: fetchOpts, payload: payload, open: open, onClose: () => {
|
|
45
|
+
setDrawerStates((prev) => (Object.assign(Object.assign({}, prev), { [key]: Object.assign(Object.assign({}, prev[key]), { open: false }) })));
|
|
46
|
+
} })))));
|
|
47
|
+
};
|
|
48
|
+
export { AiDrawerManager };
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import type { Meta, StoryObj } from "@storybook/react";
|
|
2
|
+
import { AiDrawerManager } from "./AiDrawerManager";
|
|
3
|
+
declare const meta: Meta<typeof AiDrawerManager>;
|
|
4
|
+
export default meta;
|
|
5
|
+
type Story = StoryObj<typeof AiDrawerManager>;
|
|
6
|
+
export declare const AiDrawerManagerStory: Story;
|