@memori.ai/memori-react 8.8.5 → 8.9.0
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/CHANGELOG.md +38 -0
- package/README.md +28 -0
- package/dist/components/Avatar/AvatarView/AvatarComponent/avatarComponent.js +0 -1
- package/dist/components/Avatar/AvatarView/AvatarComponent/avatarComponent.js.map +1 -1
- package/dist/components/Avatar/AvatarView/AvatarComponent/components/FullbodyAvatar/fullbodyAvatar.js +0 -10
- package/dist/components/Avatar/AvatarView/AvatarComponent/components/FullbodyAvatar/fullbodyAvatar.js.map +1 -1
- package/dist/components/Avatar/AvatarView/AvatarComponent/components/controllers/AvatarAnimator.js +0 -9
- package/dist/components/Avatar/AvatarView/AvatarComponent/components/controllers/AvatarAnimator.js.map +1 -1
- package/dist/components/Chat/Chat.css +31 -0
- package/dist/components/Chat/Chat.js +18 -4
- package/dist/components/Chat/Chat.js.map +1 -1
- package/dist/components/ChatBubble/ChatBubble.js +1 -2
- package/dist/components/ChatBubble/ChatBubble.js.map +1 -1
- package/dist/components/ChatInputs/ChatInputs.css +23 -0
- package/dist/components/ChatInputs/ChatInputs.d.ts +1 -0
- package/dist/components/ChatInputs/ChatInputs.js +37 -21
- package/dist/components/ChatInputs/ChatInputs.js.map +1 -1
- package/dist/components/ChatTextArea/ChatTextArea.css +31 -0
- package/dist/components/ChatTextArea/ChatTextArea.d.ts +1 -0
- package/dist/components/ChatTextArea/ChatTextArea.js +9 -2
- package/dist/components/ChatTextArea/ChatTextArea.js.map +1 -1
- package/dist/components/FilePreview/FilePreview.css +39 -0
- package/dist/components/Header/Header.js +3 -16
- package/dist/components/Header/Header.js.map +1 -1
- package/dist/components/MediaWidget/LinkItemWidget.js +1 -1
- package/dist/components/MediaWidget/LinkItemWidget.js.map +1 -1
- package/dist/components/MediaWidget/MediaItemWidget.js +5 -9
- package/dist/components/MediaWidget/MediaItemWidget.js.map +1 -1
- package/dist/components/MemoriArtifactSystem/components/ArtifactHandler/ArtifactHandler.js +65 -51
- package/dist/components/MemoriArtifactSystem/components/ArtifactHandler/ArtifactHandler.js.map +1 -1
- package/dist/components/MemoriArtifactSystem/utils/ArtifactAPI.d.ts +5 -0
- package/dist/components/MemoriArtifactSystem/utils/ArtifactAPI.js +287 -0
- package/dist/components/MemoriArtifactSystem/utils/ArtifactAPI.js.map +1 -0
- package/dist/components/MemoriWidget/MemoriWidget.d.ts +12 -0
- package/dist/components/MemoriWidget/MemoriWidget.js +12 -3
- package/dist/components/MemoriWidget/MemoriWidget.js.map +1 -1
- package/dist/components/Snippet/Snippet.js +4 -3
- package/dist/components/Snippet/Snippet.js.map +1 -1
- package/dist/components/StartPanel/StartPanel.css +14 -0
- package/dist/components/StartPanel/StartPanel.js +2 -2
- package/dist/components/StartPanel/StartPanel.js.map +1 -1
- package/dist/components/UploadButton/UploadDocuments/UploadDocuments.js +0 -21
- package/dist/components/UploadButton/UploadDocuments/UploadDocuments.js.map +1 -1
- package/dist/components/VenueWidget/VenueWidget.js +0 -1
- package/dist/components/VenueWidget/VenueWidget.js.map +1 -1
- package/dist/components/layouts/HiddenChat.js +0 -15
- package/dist/components/layouts/HiddenChat.js.map +1 -1
- package/dist/components/layouts/chat.css +2 -2
- package/dist/context/visemeContext.js +0 -6
- package/dist/context/visemeContext.js.map +1 -1
- package/dist/helpers/constants.d.ts +11 -0
- package/dist/helpers/constants.js +24 -2
- package/dist/helpers/constants.js.map +1 -1
- package/dist/helpers/tts/useTTS.js +0 -3
- package/dist/helpers/tts/useTTS.js.map +1 -1
- package/dist/helpers/utils.d.ts +1 -0
- package/dist/helpers/utils.js +6 -1
- package/dist/helpers/utils.js.map +1 -1
- package/dist/index.js.map +1 -1
- package/dist/locales/de.json +2 -0
- package/dist/locales/en.json +2 -0
- package/dist/locales/es.json +2 -0
- package/dist/locales/fr.json +2 -0
- package/dist/locales/it.json +2 -0
- package/esm/components/Avatar/AvatarView/AvatarComponent/avatarComponent.js +0 -1
- package/esm/components/Avatar/AvatarView/AvatarComponent/avatarComponent.js.map +1 -1
- package/esm/components/Avatar/AvatarView/AvatarComponent/components/FullbodyAvatar/fullbodyAvatar.js +0 -10
- package/esm/components/Avatar/AvatarView/AvatarComponent/components/FullbodyAvatar/fullbodyAvatar.js.map +1 -1
- package/esm/components/Avatar/AvatarView/AvatarComponent/components/controllers/AvatarAnimator.js +0 -9
- package/esm/components/Avatar/AvatarView/AvatarComponent/components/controllers/AvatarAnimator.js.map +1 -1
- package/esm/components/Chat/Chat.css +31 -0
- package/esm/components/Chat/Chat.js +19 -5
- package/esm/components/Chat/Chat.js.map +1 -1
- package/esm/components/ChatBubble/ChatBubble.js +1 -2
- package/esm/components/ChatBubble/ChatBubble.js.map +1 -1
- package/esm/components/ChatInputs/ChatInputs.css +23 -0
- package/esm/components/ChatInputs/ChatInputs.d.ts +1 -0
- package/esm/components/ChatInputs/ChatInputs.js +37 -21
- package/esm/components/ChatInputs/ChatInputs.js.map +1 -1
- package/esm/components/ChatTextArea/ChatTextArea.css +31 -0
- package/esm/components/ChatTextArea/ChatTextArea.d.ts +1 -0
- package/esm/components/ChatTextArea/ChatTextArea.js +9 -2
- package/esm/components/ChatTextArea/ChatTextArea.js.map +1 -1
- package/esm/components/FilePreview/FilePreview.css +39 -0
- package/esm/components/Header/Header.js +3 -16
- package/esm/components/Header/Header.js.map +1 -1
- package/esm/components/MediaWidget/LinkItemWidget.js +1 -1
- package/esm/components/MediaWidget/LinkItemWidget.js.map +1 -1
- package/esm/components/MediaWidget/MediaItemWidget.js +5 -9
- package/esm/components/MediaWidget/MediaItemWidget.js.map +1 -1
- package/esm/components/MemoriArtifactSystem/components/ArtifactHandler/ArtifactHandler.js +65 -51
- package/esm/components/MemoriArtifactSystem/components/ArtifactHandler/ArtifactHandler.js.map +1 -1
- package/esm/components/MemoriArtifactSystem/utils/ArtifactAPI.d.ts +5 -0
- package/esm/components/MemoriArtifactSystem/utils/ArtifactAPI.js +282 -0
- package/esm/components/MemoriArtifactSystem/utils/ArtifactAPI.js.map +1 -0
- package/esm/components/MemoriWidget/MemoriWidget.d.ts +12 -0
- package/esm/components/MemoriWidget/MemoriWidget.js +12 -3
- package/esm/components/MemoriWidget/MemoriWidget.js.map +1 -1
- package/esm/components/Snippet/Snippet.js +4 -3
- package/esm/components/Snippet/Snippet.js.map +1 -1
- package/esm/components/StartPanel/StartPanel.css +14 -0
- package/esm/components/StartPanel/StartPanel.js +3 -3
- package/esm/components/StartPanel/StartPanel.js.map +1 -1
- package/esm/components/UploadButton/UploadDocuments/UploadDocuments.js +0 -21
- package/esm/components/UploadButton/UploadDocuments/UploadDocuments.js.map +1 -1
- package/esm/components/VenueWidget/VenueWidget.js +0 -1
- package/esm/components/VenueWidget/VenueWidget.js.map +1 -1
- package/esm/components/layouts/HiddenChat.js +0 -15
- package/esm/components/layouts/HiddenChat.js.map +1 -1
- package/esm/components/layouts/chat.css +2 -2
- package/esm/context/visemeContext.js +0 -6
- package/esm/context/visemeContext.js.map +1 -1
- package/esm/helpers/constants.d.ts +11 -0
- package/esm/helpers/constants.js +22 -1
- package/esm/helpers/constants.js.map +1 -1
- package/esm/helpers/tts/useTTS.js +0 -3
- package/esm/helpers/tts/useTTS.js.map +1 -1
- package/esm/helpers/utils.d.ts +1 -0
- package/esm/helpers/utils.js +4 -0
- package/esm/helpers/utils.js.map +1 -1
- package/esm/index.js.map +1 -1
- package/esm/locales/de.json +2 -0
- package/esm/locales/en.json +2 -0
- package/esm/locales/es.json +2 -0
- package/esm/locales/fr.json +2 -0
- package/esm/locales/it.json +2 -0
- package/package.json +1 -1
- package/src/components/Avatar/AvatarView/AvatarComponent/avatarComponent.tsx +0 -1
- package/src/components/Avatar/AvatarView/AvatarComponent/components/FullbodyAvatar/fullbodyAvatar.tsx +0 -17
- package/src/components/Avatar/AvatarView/AvatarComponent/components/controllers/AvatarAnimator.ts +0 -20
- package/src/components/Chat/Chat.css +31 -0
- package/src/components/Chat/Chat.stories.tsx +503 -9
- package/src/components/Chat/Chat.tsx +23 -3
- package/src/components/Chat/__snapshots__/Chat.test.tsx.snap +73 -73
- package/src/components/ChatBubble/ChatBubble.tsx +1 -2
- package/src/components/ChatBubble/__snapshots__/ChatBubble.test.tsx.snap +25 -25
- package/src/components/ChatInputs/ChatInputs.css +23 -0
- package/src/components/ChatInputs/ChatInputs.tsx +36 -14
- package/src/components/ChatTextArea/ChatTextArea.css +31 -0
- package/src/components/ChatTextArea/ChatTextArea.tsx +11 -1
- package/src/components/FilePreview/FilePreview.css +39 -0
- package/src/components/Header/Header.tsx +0 -13
- package/src/components/MediaWidget/LinkItemWidget.tsx +1 -1
- package/src/components/MediaWidget/MediaItemWidget.stories.tsx +33 -0
- package/src/components/MediaWidget/MediaItemWidget.tsx +7 -10
- package/src/components/MediaWidget/__snapshots__/LinkItemWidget.test.tsx.snap +4 -4
- package/src/components/MediaWidget/__snapshots__/MediaItemWidget.test.tsx.snap +6 -6
- package/src/components/MediaWidget/__snapshots__/MediaWidget.test.tsx.snap +2 -2
- package/src/components/MemoriArtifactSystem/ArtifactDrawer.stories.tsx +766 -2
- package/src/components/MemoriArtifactSystem/components/ArtifactHandler/ArtifactHandler.tsx +103 -89
- package/src/components/MemoriArtifactSystem/utils/ArtifactAPI.test.tsx +307 -0
- package/src/components/MemoriArtifactSystem/utils/ArtifactAPI.tsx +373 -0
- package/src/components/MemoriWidget/MemoriWidget.tsx +26 -4
- package/src/components/Snippet/Snippet.tsx +3 -2
- package/src/components/StartPanel/StartPanel.css +14 -0
- package/src/components/StartPanel/StartPanel.tsx +23 -10
- package/src/components/StartPanel/__snapshots__/StartPanel.test.tsx.snap +206 -84
- package/src/components/UploadButton/UploadDocuments/UploadDocuments.tsx +0 -23
- package/src/components/VenueWidget/VenueWidget.tsx +0 -1
- package/src/components/layouts/HiddenChat.tsx +0 -16
- package/src/components/layouts/__snapshots__/Chat.test.tsx.snap +204 -82
- package/src/components/layouts/__snapshots__/FullPage.test.tsx.snap +408 -164
- package/src/components/layouts/__snapshots__/HiddenChat.test.tsx.snap +204 -82
- package/src/components/layouts/__snapshots__/Totem.test.tsx.snap +204 -82
- package/src/components/layouts/__snapshots__/ZoomedFullBody.test.tsx.snap +204 -82
- package/src/components/layouts/chat.css +2 -2
- package/src/context/visemeContext.tsx +0 -7
- package/src/helpers/constants.ts +28 -3
- package/src/helpers/tts/useTTS.ts +0 -2
- package/src/helpers/utils.ts +5 -0
- package/src/index.tsx +0 -1
- package/src/locales/de.json +2 -0
- package/src/locales/en.json +2 -0
- package/src/locales/es.json +2 -0
- package/src/locales/fr.json +2 -0
- package/src/locales/it.json +2 -0
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
// ArtifactSystem.stories.tsx
|
|
2
|
-
import React from 'react';
|
|
2
|
+
import React, { useEffect } from 'react';
|
|
3
3
|
import type { Meta, StoryObj } from '@storybook/react';
|
|
4
|
-
import { ArtifactProvider } from './context/ArtifactContext';
|
|
4
|
+
import { ArtifactProvider, useArtifact } from './context/ArtifactContext';
|
|
5
5
|
import ArtifactHandler from './components/ArtifactHandler/ArtifactHandler';
|
|
6
6
|
import ArtifactDrawer from './components/ArtifactDrawer/ArtifactDrawer';
|
|
7
|
+
import { ArtifactAPIBridge } from './utils/ArtifactAPI';
|
|
7
8
|
import Chat from '../Chat/Chat';
|
|
8
9
|
import {
|
|
9
10
|
Message,
|
|
@@ -11,6 +12,9 @@ import {
|
|
|
11
12
|
Tenant,
|
|
12
13
|
} from '@memori.ai/memori-api-client/dist/types';
|
|
13
14
|
import { sanitizeText } from '../../helpers/sanitizer';
|
|
15
|
+
import { ArtifactData } from './types/artifact.types';
|
|
16
|
+
|
|
17
|
+
// Note: Window.MemoriArtifactAPI types are defined in MemoriWidget.tsx
|
|
14
18
|
|
|
15
19
|
// Mock data for Chat component
|
|
16
20
|
const mockMemori: Memori = {
|
|
@@ -69,6 +73,7 @@ const mockSetAttachmentsMenuOpen = (attachmentsMenuOpen: 'link' | 'media') => {
|
|
|
69
73
|
// Story decorator to provide context
|
|
70
74
|
const withArtifactProvider = (Story: any) => (
|
|
71
75
|
<ArtifactProvider>
|
|
76
|
+
<ArtifactAPIBridge pushMessage={mockPushMessage} />
|
|
72
77
|
<Story />
|
|
73
78
|
</ArtifactProvider>
|
|
74
79
|
);
|
|
@@ -578,6 +583,304 @@ This combination gives you a complete, styled web page ready for deployment.`,
|
|
|
578
583
|
),
|
|
579
584
|
};
|
|
580
585
|
|
|
586
|
+
export const ThreeArtifactsInOneMessage: Story = {
|
|
587
|
+
args: {},
|
|
588
|
+
render: () => (
|
|
589
|
+
<Chat
|
|
590
|
+
memori={mockMemori}
|
|
591
|
+
tenant={mockTenant}
|
|
592
|
+
sessionID="test-session"
|
|
593
|
+
history={[
|
|
594
|
+
{
|
|
595
|
+
text: `I'll create a complete web component for you with HTML, CSS, and JavaScript:
|
|
596
|
+
|
|
597
|
+
<output class="memori-artifact" data-mimetype="html" data-title="Dashboard Component">
|
|
598
|
+
<!DOCTYPE html>
|
|
599
|
+
<html lang="en">
|
|
600
|
+
<head>
|
|
601
|
+
<meta charset="UTF-8">
|
|
602
|
+
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
603
|
+
<title>Dashboard</title>
|
|
604
|
+
</head>
|
|
605
|
+
<body>
|
|
606
|
+
<div id="dashboard" class="dashboard-container">
|
|
607
|
+
<h1>Sales Dashboard</h1>
|
|
608
|
+
<div class="stats-grid">
|
|
609
|
+
<div class="stat-card">
|
|
610
|
+
<h3>Revenue</h3>
|
|
611
|
+
<p id="revenue">$0</p>
|
|
612
|
+
</div>
|
|
613
|
+
<div class="stat-card">
|
|
614
|
+
<h3>Customers</h3>
|
|
615
|
+
<p id="customers">0</p>
|
|
616
|
+
</div>
|
|
617
|
+
<div class="stat-card">
|
|
618
|
+
<h3>Growth</h3>
|
|
619
|
+
<p id="growth">0%</p>
|
|
620
|
+
</div>
|
|
621
|
+
</div>
|
|
622
|
+
</div>
|
|
623
|
+
</body>
|
|
624
|
+
</html>
|
|
625
|
+
</output>
|
|
626
|
+
|
|
627
|
+
<output class="memori-artifact" data-mimetype="css" data-title="Dashboard Styles">
|
|
628
|
+
/* Dashboard Styles */
|
|
629
|
+
.dashboard-container {
|
|
630
|
+
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
|
|
631
|
+
max-width: 1200px;
|
|
632
|
+
margin: 0 auto;
|
|
633
|
+
padding: 40px 20px;
|
|
634
|
+
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
|
|
635
|
+
min-height: 100vh;
|
|
636
|
+
}
|
|
637
|
+
|
|
638
|
+
h1 {
|
|
639
|
+
color: white;
|
|
640
|
+
text-align: center;
|
|
641
|
+
font-size: 2.5rem;
|
|
642
|
+
margin-bottom: 40px;
|
|
643
|
+
text-shadow: 2px 2px 4px rgba(0, 0, 0, 0.3);
|
|
644
|
+
}
|
|
645
|
+
|
|
646
|
+
.stats-grid {
|
|
647
|
+
display: grid;
|
|
648
|
+
grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
|
|
649
|
+
gap: 24px;
|
|
650
|
+
margin-top: 30px;
|
|
651
|
+
}
|
|
652
|
+
|
|
653
|
+
.stat-card {
|
|
654
|
+
background: white;
|
|
655
|
+
border-radius: 16px;
|
|
656
|
+
padding: 32px;
|
|
657
|
+
box-shadow: 0 10px 30px rgba(0, 0, 0, 0.2);
|
|
658
|
+
transition: transform 0.3s ease, box-shadow 0.3s ease;
|
|
659
|
+
text-align: center;
|
|
660
|
+
}
|
|
661
|
+
|
|
662
|
+
.stat-card:hover {
|
|
663
|
+
transform: translateY(-8px);
|
|
664
|
+
box-shadow: 0 15px 40px rgba(0, 0, 0, 0.3);
|
|
665
|
+
}
|
|
666
|
+
|
|
667
|
+
.stat-card h3 {
|
|
668
|
+
color: #667eea;
|
|
669
|
+
font-size: 1.2rem;
|
|
670
|
+
margin-bottom: 16px;
|
|
671
|
+
font-weight: 600;
|
|
672
|
+
text-transform: uppercase;
|
|
673
|
+
letter-spacing: 1px;
|
|
674
|
+
}
|
|
675
|
+
|
|
676
|
+
.stat-card p {
|
|
677
|
+
color: #333;
|
|
678
|
+
font-size: 2.5rem;
|
|
679
|
+
font-weight: bold;
|
|
680
|
+
margin: 0;
|
|
681
|
+
}
|
|
682
|
+
</output>
|
|
683
|
+
|
|
684
|
+
<output class="memori-artifact" data-mimetype="javascript" data-title="Dashboard Logic">
|
|
685
|
+
// Dashboard Data Management
|
|
686
|
+
class Dashboard {
|
|
687
|
+
constructor() {
|
|
688
|
+
this.data = {
|
|
689
|
+
revenue: 0,
|
|
690
|
+
customers: 0,
|
|
691
|
+
growth: 0
|
|
692
|
+
};
|
|
693
|
+
this.init();
|
|
694
|
+
}
|
|
695
|
+
|
|
696
|
+
init() {
|
|
697
|
+
// Simulate loading data
|
|
698
|
+
this.loadData();
|
|
699
|
+
|
|
700
|
+
// Update every 5 seconds
|
|
701
|
+
setInterval(() => this.updateData(), 5000);
|
|
702
|
+
}
|
|
703
|
+
|
|
704
|
+
loadData() {
|
|
705
|
+
// Simulate API call
|
|
706
|
+
this.data = {
|
|
707
|
+
revenue: 124500,
|
|
708
|
+
customers: 1234,
|
|
709
|
+
growth: 23.5
|
|
710
|
+
};
|
|
711
|
+
this.render();
|
|
712
|
+
}
|
|
713
|
+
|
|
714
|
+
updateData() {
|
|
715
|
+
// Simulate real-time updates
|
|
716
|
+
this.data.revenue += Math.floor(Math.random() * 1000);
|
|
717
|
+
this.data.customers += Math.floor(Math.random() * 10);
|
|
718
|
+
this.data.growth += (Math.random() - 0.5) * 2;
|
|
719
|
+
this.render();
|
|
720
|
+
}
|
|
721
|
+
|
|
722
|
+
render() {
|
|
723
|
+
const revenueEl = document.getElementById('revenue');
|
|
724
|
+
const customersEl = document.getElementById('customers');
|
|
725
|
+
const growthEl = document.getElementById('growth');
|
|
726
|
+
|
|
727
|
+
if (revenueEl) {
|
|
728
|
+
revenueEl.textContent = '$' + this.data.revenue.toLocaleString();
|
|
729
|
+
}
|
|
730
|
+
|
|
731
|
+
if (customersEl) {
|
|
732
|
+
customersEl.textContent = this.data.customers.toLocaleString();
|
|
733
|
+
}
|
|
734
|
+
|
|
735
|
+
if (growthEl) {
|
|
736
|
+
growthEl.textContent = '+' + this.data.growth.toFixed(1) + '%';
|
|
737
|
+
}
|
|
738
|
+
}
|
|
739
|
+
}
|
|
740
|
+
|
|
741
|
+
// Initialize when DOM is ready
|
|
742
|
+
if (document.readyState === 'loading') {
|
|
743
|
+
document.addEventListener('DOMContentLoaded', () => {
|
|
744
|
+
new Dashboard();
|
|
745
|
+
});
|
|
746
|
+
} else {
|
|
747
|
+
new Dashboard();
|
|
748
|
+
}
|
|
749
|
+
</output>
|
|
750
|
+
|
|
751
|
+
Each artifact serves a specific purpose:
|
|
752
|
+
- **HTML**: The structure and content
|
|
753
|
+
- **CSS**: Beautiful styling with gradients and animations
|
|
754
|
+
- **JavaScript**: Interactive data management and updates
|
|
755
|
+
|
|
756
|
+
You can click on each card to view and modify the code!`,
|
|
757
|
+
fromUser: false,
|
|
758
|
+
timestamp: new Date().toISOString(),
|
|
759
|
+
},
|
|
760
|
+
]}
|
|
761
|
+
pushMessage={mockPushMessage}
|
|
762
|
+
simulateUserPrompt={mockSimulateUserPrompt}
|
|
763
|
+
onChangeUserMessage={mockOnChangeUserMessage}
|
|
764
|
+
sendMessage={mockSendMessage}
|
|
765
|
+
setEnableFocusChatInput={mockSetEnableFocusChatInput}
|
|
766
|
+
stopAudio={mockStopAudio}
|
|
767
|
+
startListening={mockStartListening}
|
|
768
|
+
stopListening={mockStopListening}
|
|
769
|
+
setSendOnEnter={mockSetSendOnEnter}
|
|
770
|
+
setAttachmentsMenuOpen={mockSetAttachmentsMenuOpen}
|
|
771
|
+
showInputs={false}
|
|
772
|
+
isChatlogPanel={false}
|
|
773
|
+
/>
|
|
774
|
+
),
|
|
775
|
+
};
|
|
776
|
+
|
|
777
|
+
export const FiveArtifactsMixedTypes: Story = {
|
|
778
|
+
args: {},
|
|
779
|
+
render: () => (
|
|
780
|
+
<Chat
|
|
781
|
+
memori={mockMemori}
|
|
782
|
+
tenant={mockTenant}
|
|
783
|
+
sessionID="test-session"
|
|
784
|
+
history={[
|
|
785
|
+
{
|
|
786
|
+
text: `Here's a complete project setup with multiple files:
|
|
787
|
+
|
|
788
|
+
<output class="memori-artifact" data-mimetype="html" data-title="index.html">
|
|
789
|
+
<!DOCTYPE html>
|
|
790
|
+
<html>
|
|
791
|
+
<head>
|
|
792
|
+
<title>My Project</title>
|
|
793
|
+
<link rel="stylesheet" href="styles.css">
|
|
794
|
+
</head>
|
|
795
|
+
<body>
|
|
796
|
+
<div id="app"></div>
|
|
797
|
+
<script src="app.js"></script>
|
|
798
|
+
</body>
|
|
799
|
+
</html>
|
|
800
|
+
</output>
|
|
801
|
+
|
|
802
|
+
<output class="memori-artifact" data-mimetype="css" data-title="styles.css">
|
|
803
|
+
body {
|
|
804
|
+
margin: 0;
|
|
805
|
+
padding: 20px;
|
|
806
|
+
font-family: Arial, sans-serif;
|
|
807
|
+
background: #f5f5f5;
|
|
808
|
+
}
|
|
809
|
+
|
|
810
|
+
#app {
|
|
811
|
+
max-width: 800px;
|
|
812
|
+
margin: 0 auto;
|
|
813
|
+
background: white;
|
|
814
|
+
padding: 30px;
|
|
815
|
+
border-radius: 8px;
|
|
816
|
+
box-shadow: 0 2px 10px rgba(0,0,0,0.1);
|
|
817
|
+
}
|
|
818
|
+
</output>
|
|
819
|
+
|
|
820
|
+
<output class="memori-artifact" data-mimetype="javascript" data-title="app.js">
|
|
821
|
+
const app = document.getElementById('app');
|
|
822
|
+
app.innerHTML = '<h1>Hello World!</h1>';
|
|
823
|
+
console.log('App initialized');
|
|
824
|
+
</output>
|
|
825
|
+
|
|
826
|
+
<output class="memori-artifact" data-mimetype="json" data-title="package.json">
|
|
827
|
+
{
|
|
828
|
+
"name": "my-project",
|
|
829
|
+
"version": "1.0.0",
|
|
830
|
+
"description": "A simple web project",
|
|
831
|
+
"main": "app.js",
|
|
832
|
+
"scripts": {
|
|
833
|
+
"start": "serve .",
|
|
834
|
+
"build": "webpack"
|
|
835
|
+
},
|
|
836
|
+
"dependencies": {
|
|
837
|
+
"serve": "^14.0.0"
|
|
838
|
+
}
|
|
839
|
+
}
|
|
840
|
+
</output>
|
|
841
|
+
|
|
842
|
+
<output class="memori-artifact" data-mimetype="markdown" data-title="README.md">
|
|
843
|
+
# My Project
|
|
844
|
+
|
|
845
|
+
## Overview
|
|
846
|
+
A simple web application starter template.
|
|
847
|
+
|
|
848
|
+
## Getting Started
|
|
849
|
+
1. Install dependencies: \`npm install\`
|
|
850
|
+
2. Start the server: \`npm start\`
|
|
851
|
+
3. Open http://localhost:3000
|
|
852
|
+
|
|
853
|
+
## Features
|
|
854
|
+
- Clean HTML structure
|
|
855
|
+
- Modern CSS styling
|
|
856
|
+
- JavaScript functionality
|
|
857
|
+
- Package management with npm
|
|
858
|
+
|
|
859
|
+
## License
|
|
860
|
+
MIT
|
|
861
|
+
</output>
|
|
862
|
+
|
|
863
|
+
All files are ready! You now have a complete project structure with HTML, CSS, JavaScript, configuration, and documentation.`,
|
|
864
|
+
fromUser: false,
|
|
865
|
+
timestamp: new Date().toISOString(),
|
|
866
|
+
},
|
|
867
|
+
]}
|
|
868
|
+
pushMessage={mockPushMessage}
|
|
869
|
+
simulateUserPrompt={mockSimulateUserPrompt}
|
|
870
|
+
onChangeUserMessage={mockOnChangeUserMessage}
|
|
871
|
+
sendMessage={mockSendMessage}
|
|
872
|
+
setEnableFocusChatInput={mockSetEnableFocusChatInput}
|
|
873
|
+
stopAudio={mockStopAudio}
|
|
874
|
+
startListening={mockStartListening}
|
|
875
|
+
stopListening={mockStopListening}
|
|
876
|
+
setSendOnEnter={mockSetSendOnEnter}
|
|
877
|
+
setAttachmentsMenuOpen={mockSetAttachmentsMenuOpen}
|
|
878
|
+
showInputs={false}
|
|
879
|
+
isChatlogPanel={false}
|
|
880
|
+
/>
|
|
881
|
+
),
|
|
882
|
+
};
|
|
883
|
+
|
|
581
884
|
export const ConversationFlow: Story = {
|
|
582
885
|
args: {},
|
|
583
886
|
render: () => (
|
|
@@ -670,3 +973,464 @@ export const NoArtifacts: Story = {
|
|
|
670
973
|
/>
|
|
671
974
|
),
|
|
672
975
|
};
|
|
976
|
+
|
|
977
|
+
// ========================================
|
|
978
|
+
// ArtifactAPI Bridge Stories
|
|
979
|
+
// ========================================
|
|
980
|
+
|
|
981
|
+
export const APIBridge_CreateSimpleArtifact: Story = {
|
|
982
|
+
args: {},
|
|
983
|
+
render: () => {
|
|
984
|
+
const TestComponent = () => {
|
|
985
|
+
const { state } = useArtifact();
|
|
986
|
+
|
|
987
|
+
useEffect(() => {
|
|
988
|
+
// Wait a bit for the API to be available
|
|
989
|
+
setTimeout(() => {
|
|
990
|
+
console.log('MemoriArtifactAPI available:', !!window.MemoriArtifactAPI);
|
|
991
|
+
}, 100);
|
|
992
|
+
}, []);
|
|
993
|
+
|
|
994
|
+
const createHTMLArtifact = () => {
|
|
995
|
+
window.MemoriArtifactAPI?.createAndOpenArtifact(
|
|
996
|
+
'<h1>🎉 Created from API!</h1><p>This artifact was created using <code>window.MemoriArtifactAPI.createAndOpenArtifact()</code></p><p>You can use this API to create artifacts programmatically from any JavaScript code.</p>',
|
|
997
|
+
'html',
|
|
998
|
+
'API Test Artifact'
|
|
999
|
+
);
|
|
1000
|
+
};
|
|
1001
|
+
|
|
1002
|
+
const createMarkdownArtifact = () => {
|
|
1003
|
+
window.MemoriArtifactAPI?.createAndOpenArtifact(
|
|
1004
|
+
`# Artifact Created via API
|
|
1005
|
+
|
|
1006
|
+
## This is a test
|
|
1007
|
+
|
|
1008
|
+
This artifact was created using the global API:
|
|
1009
|
+
|
|
1010
|
+
\`\`\`javascript
|
|
1011
|
+
window.MemoriArtifactAPI.createAndOpenArtifact(content, 'markdown', 'Title');
|
|
1012
|
+
\`\`\`
|
|
1013
|
+
|
|
1014
|
+
### Features:
|
|
1015
|
+
- ✅ Programmatic control
|
|
1016
|
+
- ✅ Multiple MIME types
|
|
1017
|
+
- ✅ Easy integration`,
|
|
1018
|
+
'markdown',
|
|
1019
|
+
'API Markdown Example'
|
|
1020
|
+
);
|
|
1021
|
+
};
|
|
1022
|
+
|
|
1023
|
+
const createJavaScriptArtifact = () => {
|
|
1024
|
+
window.MemoriArtifactAPI?.createAndOpenArtifact(
|
|
1025
|
+
`// Example function created via API
|
|
1026
|
+
function greet(name) {
|
|
1027
|
+
console.log(\`Hello, \${name}!\`);
|
|
1028
|
+
return \`Welcome, \${name}\`;
|
|
1029
|
+
}
|
|
1030
|
+
|
|
1031
|
+
// Call it
|
|
1032
|
+
const message = greet('Developer');
|
|
1033
|
+
console.log(message);`,
|
|
1034
|
+
'javascript',
|
|
1035
|
+
'JavaScript via API'
|
|
1036
|
+
);
|
|
1037
|
+
};
|
|
1038
|
+
|
|
1039
|
+
const checkState = () => {
|
|
1040
|
+
const state = window.MemoriArtifactAPI?.getState();
|
|
1041
|
+
console.log('Current artifact state:', state);
|
|
1042
|
+
alert(JSON.stringify(state, null, 2));
|
|
1043
|
+
};
|
|
1044
|
+
|
|
1045
|
+
return (
|
|
1046
|
+
<>
|
|
1047
|
+
{/* Conditionally render ArtifactDrawer to avoid hooks error */}
|
|
1048
|
+
{state.isDrawerOpen && <ArtifactDrawer />}
|
|
1049
|
+
|
|
1050
|
+
<div style={{ padding: '20px', maxWidth: '800px', margin: '0 auto' }}>
|
|
1051
|
+
<h1>🧪 Artifact API Test Lab</h1>
|
|
1052
|
+
<p>
|
|
1053
|
+
Test the global <code>window.MemoriArtifactAPI</code> by clicking the buttons below.
|
|
1054
|
+
Open the browser console to see the API in action.
|
|
1055
|
+
</p>
|
|
1056
|
+
|
|
1057
|
+
<div style={{ display: 'flex', flexDirection: 'column', gap: '12px', marginTop: '20px' }}>
|
|
1058
|
+
<button
|
|
1059
|
+
onClick={createHTMLArtifact}
|
|
1060
|
+
style={{
|
|
1061
|
+
padding: '12px 20px',
|
|
1062
|
+
fontSize: '16px',
|
|
1063
|
+
cursor: 'pointer',
|
|
1064
|
+
backgroundColor: '#9333ea',
|
|
1065
|
+
color: 'white',
|
|
1066
|
+
border: 'none',
|
|
1067
|
+
borderRadius: '8px',
|
|
1068
|
+
}}
|
|
1069
|
+
>
|
|
1070
|
+
📄 Create HTML Artifact
|
|
1071
|
+
</button>
|
|
1072
|
+
|
|
1073
|
+
<button
|
|
1074
|
+
onClick={createMarkdownArtifact}
|
|
1075
|
+
style={{
|
|
1076
|
+
padding: '12px 20px',
|
|
1077
|
+
fontSize: '16px',
|
|
1078
|
+
cursor: 'pointer',
|
|
1079
|
+
backgroundColor: '#7c3aed',
|
|
1080
|
+
color: 'white',
|
|
1081
|
+
border: 'none',
|
|
1082
|
+
borderRadius: '8px',
|
|
1083
|
+
}}
|
|
1084
|
+
>
|
|
1085
|
+
📝 Create Markdown Artifact
|
|
1086
|
+
</button>
|
|
1087
|
+
|
|
1088
|
+
<button
|
|
1089
|
+
onClick={createJavaScriptArtifact}
|
|
1090
|
+
style={{
|
|
1091
|
+
padding: '12px 20px',
|
|
1092
|
+
fontSize: '16px',
|
|
1093
|
+
cursor: 'pointer',
|
|
1094
|
+
backgroundColor: '#6d28d9',
|
|
1095
|
+
color: 'white',
|
|
1096
|
+
border: 'none',
|
|
1097
|
+
borderRadius: '8px',
|
|
1098
|
+
}}
|
|
1099
|
+
>
|
|
1100
|
+
💻 Create JavaScript Artifact
|
|
1101
|
+
</button>
|
|
1102
|
+
|
|
1103
|
+
<button
|
|
1104
|
+
onClick={checkState}
|
|
1105
|
+
style={{
|
|
1106
|
+
padding: '12px 20px',
|
|
1107
|
+
fontSize: '16px',
|
|
1108
|
+
cursor: 'pointer',
|
|
1109
|
+
backgroundColor: '#5b21b6',
|
|
1110
|
+
color: 'white',
|
|
1111
|
+
border: 'none',
|
|
1112
|
+
borderRadius: '8px',
|
|
1113
|
+
}}
|
|
1114
|
+
>
|
|
1115
|
+
📊 Check Current State
|
|
1116
|
+
</button>
|
|
1117
|
+
|
|
1118
|
+
<button
|
|
1119
|
+
onClick={() => window.MemoriArtifactAPI?.closeArtifact()}
|
|
1120
|
+
style={{
|
|
1121
|
+
padding: '12px 20px',
|
|
1122
|
+
fontSize: '16px',
|
|
1123
|
+
cursor: 'pointer',
|
|
1124
|
+
backgroundColor: '#ef4444',
|
|
1125
|
+
color: 'white',
|
|
1126
|
+
border: 'none',
|
|
1127
|
+
borderRadius: '8px',
|
|
1128
|
+
}}
|
|
1129
|
+
>
|
|
1130
|
+
❌ Close Artifact
|
|
1131
|
+
</button>
|
|
1132
|
+
|
|
1133
|
+
<button
|
|
1134
|
+
onClick={() => window.MemoriArtifactAPI?.toggleFullscreen()}
|
|
1135
|
+
style={{
|
|
1136
|
+
padding: '12px 20px',
|
|
1137
|
+
fontSize: '16px',
|
|
1138
|
+
cursor: 'pointer',
|
|
1139
|
+
backgroundColor: '#3b82f6',
|
|
1140
|
+
color: 'white',
|
|
1141
|
+
border: 'none',
|
|
1142
|
+
borderRadius: '8px',
|
|
1143
|
+
}}
|
|
1144
|
+
>
|
|
1145
|
+
⛶ Toggle Fullscreen
|
|
1146
|
+
</button>
|
|
1147
|
+
</div>
|
|
1148
|
+
|
|
1149
|
+
<div style={{ marginTop: '30px', padding: '15px', backgroundColor: '#f3f4f6', borderRadius: '8px' }}>
|
|
1150
|
+
<h3>💡 Console Commands</h3>
|
|
1151
|
+
<p>Try these in the browser console:</p>
|
|
1152
|
+
<pre style={{ backgroundColor: 'white', padding: '10px', borderRadius: '4px', overflow: 'auto' }}>
|
|
1153
|
+
{`// Create an artifact
|
|
1154
|
+
window.MemoriArtifactAPI.createAndOpenArtifact(
|
|
1155
|
+
'<h1>Test</h1>',
|
|
1156
|
+
'html',
|
|
1157
|
+
'My Title'
|
|
1158
|
+
);
|
|
1159
|
+
|
|
1160
|
+
// Check state
|
|
1161
|
+
window.MemoriArtifactAPI.getState();
|
|
1162
|
+
|
|
1163
|
+
// Close
|
|
1164
|
+
window.MemoriArtifactAPI.closeArtifact();`}
|
|
1165
|
+
</pre>
|
|
1166
|
+
</div>
|
|
1167
|
+
</div>
|
|
1168
|
+
</>
|
|
1169
|
+
);
|
|
1170
|
+
};
|
|
1171
|
+
|
|
1172
|
+
return <TestComponent />;
|
|
1173
|
+
},
|
|
1174
|
+
};
|
|
1175
|
+
|
|
1176
|
+
export const APIBridge_ProcessOutputElements: Story = {
|
|
1177
|
+
args: {},
|
|
1178
|
+
render: () => {
|
|
1179
|
+
const TestComponent = () => {
|
|
1180
|
+
const { state } = useArtifact();
|
|
1181
|
+
|
|
1182
|
+
const createFromOutput = () => {
|
|
1183
|
+
const outputs = document.querySelectorAll('.memori-artifact[data-sample="true"]');
|
|
1184
|
+
outputs.forEach((output) => {
|
|
1185
|
+
const artifactId = window.MemoriArtifactAPI?.createFromOutputElement(output as HTMLOutputElement);
|
|
1186
|
+
console.log('Created artifact:', artifactId);
|
|
1187
|
+
});
|
|
1188
|
+
alert(`Processed ${outputs.length} artifacts. Check console for IDs.`);
|
|
1189
|
+
};
|
|
1190
|
+
|
|
1191
|
+
const addDynamicOutput = () => {
|
|
1192
|
+
const container = document.getElementById('dynamic-container');
|
|
1193
|
+
if (container) {
|
|
1194
|
+
const output = document.createElement('output');
|
|
1195
|
+
output.className = 'memori-artifact';
|
|
1196
|
+
output.setAttribute('data-mimetype', 'html');
|
|
1197
|
+
output.setAttribute('data-title', 'Dynamic Artifact');
|
|
1198
|
+
output.setAttribute('data-sample', 'true');
|
|
1199
|
+
output.innerHTML = `
|
|
1200
|
+
<div style="padding: 20px; background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); color: white; border-radius: 8px;">
|
|
1201
|
+
<h2>🚀 Dynamically Added!</h2>
|
|
1202
|
+
<p>This artifact was added to the DOM dynamically and then processed.</p>
|
|
1203
|
+
<p>Timestamp: ${new Date().toLocaleTimeString()}</p>
|
|
1204
|
+
</div>
|
|
1205
|
+
`;
|
|
1206
|
+
container.appendChild(output);
|
|
1207
|
+
}
|
|
1208
|
+
};
|
|
1209
|
+
|
|
1210
|
+
return (
|
|
1211
|
+
<>
|
|
1212
|
+
{/* Conditionally render ArtifactDrawer to avoid hooks error */}
|
|
1213
|
+
{state.isDrawerOpen && <ArtifactDrawer />}
|
|
1214
|
+
|
|
1215
|
+
<div style={{ padding: '20px', maxWidth: '800px', margin: '0 auto' }}>
|
|
1216
|
+
<h1>🔄 Process Output Elements</h1>
|
|
1217
|
+
<p>
|
|
1218
|
+
This story demonstrates processing <code><output class="memori-artifact"></code> elements
|
|
1219
|
+
using <code>createFromOutputElement</code>.
|
|
1220
|
+
</p>
|
|
1221
|
+
|
|
1222
|
+
<div style={{ display: 'flex', flexDirection: 'column', gap: '12px', marginTop: '20px' }}>
|
|
1223
|
+
<button
|
|
1224
|
+
onClick={createFromOutput}
|
|
1225
|
+
style={{
|
|
1226
|
+
padding: '12px 20px',
|
|
1227
|
+
fontSize: '16px',
|
|
1228
|
+
cursor: 'pointer',
|
|
1229
|
+
backgroundColor: '#9333ea',
|
|
1230
|
+
color: 'white',
|
|
1231
|
+
border: 'none',
|
|
1232
|
+
borderRadius: '8px',
|
|
1233
|
+
}}
|
|
1234
|
+
>
|
|
1235
|
+
🔍 Create From Output Elements
|
|
1236
|
+
</button>
|
|
1237
|
+
|
|
1238
|
+
<button
|
|
1239
|
+
onClick={addDynamicOutput}
|
|
1240
|
+
style={{
|
|
1241
|
+
padding: '12px 20px',
|
|
1242
|
+
fontSize: '16px',
|
|
1243
|
+
cursor: 'pointer',
|
|
1244
|
+
backgroundColor: '#7c3aed',
|
|
1245
|
+
color: 'white',
|
|
1246
|
+
border: 'none',
|
|
1247
|
+
borderRadius: '8px',
|
|
1248
|
+
}}
|
|
1249
|
+
>
|
|
1250
|
+
➕ Add Dynamic Output
|
|
1251
|
+
</button>
|
|
1252
|
+
</div>
|
|
1253
|
+
|
|
1254
|
+
<div id="dynamic-container" style={{ marginTop: '30px' }}>
|
|
1255
|
+
<h3>Existing Output Elements:</h3>
|
|
1256
|
+
|
|
1257
|
+
<output className="memori-artifact" data-mimetype="html" data-title="Sample HTML" data-sample="true">
|
|
1258
|
+
<div style={{ padding: '15px', border: '2px solid #9333ea', borderRadius: '8px' }}>
|
|
1259
|
+
<h3>Sample Artifact 1</h3>
|
|
1260
|
+
<p>This is a static output element in the DOM.</p>
|
|
1261
|
+
</div>
|
|
1262
|
+
</output>
|
|
1263
|
+
|
|
1264
|
+
<output className="memori-artifact" data-mimetype="markdown" data-title="Sample Markdown" data-sample="true">
|
|
1265
|
+
{`# Sample Markdown
|
|
1266
|
+
|
|
1267
|
+
This is **another** static output element.
|
|
1268
|
+
|
|
1269
|
+
- Item 1
|
|
1270
|
+
- Item 2
|
|
1271
|
+
- Item 3`}
|
|
1272
|
+
</output>
|
|
1273
|
+
</div>
|
|
1274
|
+
|
|
1275
|
+
<div style={{ marginTop: '30px', padding: '15px', backgroundColor: '#f3f4f6', borderRadius: '8px' }}>
|
|
1276
|
+
<h3>💡 How it works</h3>
|
|
1277
|
+
<ol>
|
|
1278
|
+
<li>Click "Create From Output Elements" to process <code><output></code> elements</li>
|
|
1279
|
+
<li>Each element gets converted to an artifact and added to history</li>
|
|
1280
|
+
<li>Click "Add Dynamic Output" to inject a new element</li>
|
|
1281
|
+
<li>Process again to handle the new element</li>
|
|
1282
|
+
<li>The artifacts will appear in the chat history</li>
|
|
1283
|
+
</ol>
|
|
1284
|
+
</div>
|
|
1285
|
+
</div>
|
|
1286
|
+
</>
|
|
1287
|
+
);
|
|
1288
|
+
};
|
|
1289
|
+
|
|
1290
|
+
return <TestComponent />;
|
|
1291
|
+
},
|
|
1292
|
+
};
|
|
1293
|
+
|
|
1294
|
+
export const APIBridge_WebSocketSimulation: Story = {
|
|
1295
|
+
args: {},
|
|
1296
|
+
render: () => {
|
|
1297
|
+
const TestComponent = () => {
|
|
1298
|
+
const { state } = useArtifact();
|
|
1299
|
+
|
|
1300
|
+
const simulateWebSocket = () => {
|
|
1301
|
+
// Simulate receiving a message with artifacts from WebSocket
|
|
1302
|
+
const artifactContent = `
|
|
1303
|
+
<div style="padding: 20px; background: white; border-radius: 8px; box-shadow: 0 2px 10px rgba(0,0,0,0.1);">
|
|
1304
|
+
<h2>📊 Sales Report Q4 2024</h2>
|
|
1305
|
+
<div style="display: flex; gap: 20px; margin-top: 20px;">
|
|
1306
|
+
<div style="flex: 1; padding: 15px; background: #ecfdf5; border-radius: 8px;">
|
|
1307
|
+
<h3>Revenue</h3>
|
|
1308
|
+
<p style="font-size: 24px; font-weight: bold; color: #059669;">$124,500</p>
|
|
1309
|
+
</div>
|
|
1310
|
+
<div style="flex: 1; padding: 15px; background: #fef3c7; border-radius: 8px;">
|
|
1311
|
+
<h3>Customers</h3>
|
|
1312
|
+
<p style="font-size: 24px; font-weight: bold; color: #d97706;">1,234</p>
|
|
1313
|
+
</div>
|
|
1314
|
+
<div style="flex: 1; padding: 15px; background: #dbeafe; border-radius: 8px;">
|
|
1315
|
+
<h3>Growth</h3>
|
|
1316
|
+
<p style="font-size: 24px; font-weight: bold; color: #2563eb;">+23%</p>
|
|
1317
|
+
</div>
|
|
1318
|
+
</div>
|
|
1319
|
+
</div>
|
|
1320
|
+
`;
|
|
1321
|
+
|
|
1322
|
+
// Use the API to create and open the artifact
|
|
1323
|
+
window.MemoriArtifactAPI?.createAndOpenArtifact(
|
|
1324
|
+
artifactContent,
|
|
1325
|
+
'html',
|
|
1326
|
+
'Data Visualization'
|
|
1327
|
+
);
|
|
1328
|
+
|
|
1329
|
+
// Update chat display
|
|
1330
|
+
const chatContainer = document.getElementById('chat-simulation');
|
|
1331
|
+
if (chatContainer) {
|
|
1332
|
+
const messageHTML = `
|
|
1333
|
+
<div style="padding: 10px; margin: 10px 0; background: #f9fafb; border-radius: 8px;">
|
|
1334
|
+
<p><strong>Bot:</strong> I've created a visualization for you. Click the artifact card to view it.</p>
|
|
1335
|
+
<div style="padding: 10px; margin-top: 10px; background: #e0e7ff; border-radius: 4px; cursor: pointer;" onclick="window.MemoriArtifactAPI?.createAndOpenArtifact(\`${artifactContent.replace(/`/g, '\\`')}\`, 'html', 'Data Visualization')">
|
|
1336
|
+
📊 Data Visualization
|
|
1337
|
+
</div>
|
|
1338
|
+
</div>
|
|
1339
|
+
`;
|
|
1340
|
+
chatContainer.innerHTML += messageHTML;
|
|
1341
|
+
}
|
|
1342
|
+
|
|
1343
|
+
console.log('WebSocket artifact created via API');
|
|
1344
|
+
};
|
|
1345
|
+
|
|
1346
|
+
const clearChat = () => {
|
|
1347
|
+
const chatContainer = document.getElementById('chat-simulation');
|
|
1348
|
+
if (chatContainer) {
|
|
1349
|
+
chatContainer.innerHTML = '<p style="color: #6b7280;">Chat cleared. Click "Simulate WebSocket Message" to add new content.</p>';
|
|
1350
|
+
}
|
|
1351
|
+
};
|
|
1352
|
+
|
|
1353
|
+
return (
|
|
1354
|
+
<>
|
|
1355
|
+
{/* Conditionally render ArtifactDrawer to avoid hooks error */}
|
|
1356
|
+
{state.isDrawerOpen && <ArtifactDrawer />}
|
|
1357
|
+
|
|
1358
|
+
<div style={{ padding: '20px', maxWidth: '900px', margin: '0 auto' }}>
|
|
1359
|
+
<h1>🌐 WebSocket Integration Simulation</h1>
|
|
1360
|
+
<p>
|
|
1361
|
+
This demonstrates how <code>createAndOpenArtifact</code> can be used with WebSocket or Action Cable
|
|
1362
|
+
to create artifacts from messages received dynamically.
|
|
1363
|
+
</p>
|
|
1364
|
+
|
|
1365
|
+
<div style={{ display: 'flex', gap: '12px', marginTop: '20px' }}>
|
|
1366
|
+
<button
|
|
1367
|
+
onClick={simulateWebSocket}
|
|
1368
|
+
style={{
|
|
1369
|
+
padding: '12px 20px',
|
|
1370
|
+
fontSize: '16px',
|
|
1371
|
+
cursor: 'pointer',
|
|
1372
|
+
backgroundColor: '#9333ea',
|
|
1373
|
+
color: 'white',
|
|
1374
|
+
border: 'none',
|
|
1375
|
+
borderRadius: '8px',
|
|
1376
|
+
}}
|
|
1377
|
+
>
|
|
1378
|
+
📡 Simulate WebSocket Message
|
|
1379
|
+
</button>
|
|
1380
|
+
|
|
1381
|
+
<button
|
|
1382
|
+
onClick={clearChat}
|
|
1383
|
+
style={{
|
|
1384
|
+
padding: '12px 20px',
|
|
1385
|
+
fontSize: '16px',
|
|
1386
|
+
cursor: 'pointer',
|
|
1387
|
+
backgroundColor: '#64748b',
|
|
1388
|
+
color: 'white',
|
|
1389
|
+
border: 'none',
|
|
1390
|
+
borderRadius: '8px',
|
|
1391
|
+
}}
|
|
1392
|
+
>
|
|
1393
|
+
🗑️ Clear Chat
|
|
1394
|
+
</button>
|
|
1395
|
+
</div>
|
|
1396
|
+
|
|
1397
|
+
<div
|
|
1398
|
+
id="chat-simulation"
|
|
1399
|
+
style={{
|
|
1400
|
+
marginTop: '30px',
|
|
1401
|
+
padding: '20px',
|
|
1402
|
+
backgroundColor: 'white',
|
|
1403
|
+
border: '1px solid #e5e7eb',
|
|
1404
|
+
borderRadius: '12px',
|
|
1405
|
+
minHeight: '200px',
|
|
1406
|
+
}}
|
|
1407
|
+
>
|
|
1408
|
+
<p style={{ color: '#6b7280' }}>Click "Simulate WebSocket Message" to receive a message with an artifact...</p>
|
|
1409
|
+
</div>
|
|
1410
|
+
|
|
1411
|
+
<div style={{ marginTop: '30px', padding: '15px', backgroundColor: '#f3f4f6', borderRadius: '8px' }}>
|
|
1412
|
+
<h3>💡 Implementation Example</h3>
|
|
1413
|
+
<pre style={{ backgroundColor: 'white', padding: '10px', borderRadius: '4px', overflow: 'auto', fontSize: '13px' }}>
|
|
1414
|
+
{`// Rails Action Cable
|
|
1415
|
+
consumer.subscriptions.create("ChatChannel", {
|
|
1416
|
+
received(data) {
|
|
1417
|
+
if (data.artifact) {
|
|
1418
|
+
// Create artifact directly from received data
|
|
1419
|
+
window.MemoriArtifactAPI?.createAndOpenArtifact(
|
|
1420
|
+
data.artifact.content,
|
|
1421
|
+
data.artifact.mimeType,
|
|
1422
|
+
data.artifact.title
|
|
1423
|
+
);
|
|
1424
|
+
}
|
|
1425
|
+
}
|
|
1426
|
+
});`}
|
|
1427
|
+
</pre>
|
|
1428
|
+
</div>
|
|
1429
|
+
</div>
|
|
1430
|
+
</>
|
|
1431
|
+
);
|
|
1432
|
+
};
|
|
1433
|
+
|
|
1434
|
+
return <TestComponent />;
|
|
1435
|
+
},
|
|
1436
|
+
};
|