@memori.ai/memori-react 9.0.0-alpha.4 → 9.0.0-alpha.6

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.
Files changed (268) hide show
  1. package/CHANGELOG.md +62 -0
  2. package/dist/components/AgeVerificationModal/AgeVerificationModal.js +5 -2
  3. package/dist/components/AgeVerificationModal/AgeVerificationModal.js.map +1 -1
  4. package/dist/components/Avatar/Avatar.js +5 -10
  5. package/dist/components/Avatar/Avatar.js.map +1 -1
  6. package/dist/components/Avatar/AvatarView/AvatarComponent/components/FullbodyAvatar/fullbodyAvatar.js +8 -1
  7. package/dist/components/Avatar/AvatarView/AvatarComponent/components/FullbodyAvatar/fullbodyAvatar.js.map +1 -1
  8. package/dist/components/Avatar/AvatarView/AvatarComponent/components/controllers/MorphTargetController.js +1 -1
  9. package/dist/components/Avatar/AvatarView/AvatarComponent/components/controllers/MorphTargetController.js.map +1 -1
  10. package/dist/components/Avatar/AvatarView/AvatarComponent/constants.d.ts +2 -0
  11. package/dist/components/Avatar/AvatarView/AvatarComponent/constants.js +14 -5
  12. package/dist/components/Avatar/AvatarView/AvatarComponent/constants.js.map +1 -1
  13. package/dist/components/ChatBubble/ChatBubble.js +22 -16
  14. package/dist/components/ChatBubble/ChatBubble.js.map +1 -1
  15. package/dist/components/CompletionProviderStatus/CompletionProviderStatus.js +6 -3
  16. package/dist/components/CompletionProviderStatus/CompletionProviderStatus.js.map +1 -1
  17. package/dist/components/DateSelector/DateSelector.d.ts +2 -1
  18. package/dist/components/DateSelector/DateSelector.js +17 -7
  19. package/dist/components/DateSelector/DateSelector.js.map +1 -1
  20. package/dist/components/FilePreview/FilePreview.js +22 -5
  21. package/dist/components/FilePreview/FilePreview.js.map +1 -1
  22. package/dist/components/Header/ChatConsumptionDropdown.js +1 -1
  23. package/dist/components/Header/ChatConsumptionDropdown.js.map +1 -1
  24. package/dist/components/Header/Header.css +2 -1
  25. package/dist/components/Header/Header.js +1 -1
  26. package/dist/components/Header/Header.js.map +1 -1
  27. package/dist/components/MediaWidget/MediaItemWidget.js +14 -12
  28. package/dist/components/MediaWidget/MediaItemWidget.js.map +1 -1
  29. package/dist/components/MediaWidget/MediaItemWidget.utils.d.ts +3 -2
  30. package/dist/components/MediaWidget/MediaItemWidget.utils.js +28 -6
  31. package/dist/components/MediaWidget/MediaItemWidget.utils.js.map +1 -1
  32. package/dist/components/MediaWidget/MediaPreviewModal.js +6 -7
  33. package/dist/components/MediaWidget/MediaPreviewModal.js.map +1 -1
  34. package/dist/components/MemoriArtifactSystem/components/ArtifactActions/styles.css +5 -4
  35. package/dist/components/MemoriArtifactSystem/components/ArtifactDrawer/ArtifactDrawer.css +90 -38
  36. package/dist/components/MemoriArtifactSystem/components/ArtifactDrawer/ArtifactDrawer.d.ts +1 -0
  37. package/dist/components/MemoriArtifactSystem/components/ArtifactDrawer/ArtifactDrawer.js +14 -9
  38. package/dist/components/MemoriArtifactSystem/components/ArtifactDrawer/ArtifactDrawer.js.map +1 -1
  39. package/dist/components/MemoriArtifactSystem/components/ArtifactHandler/ArtifactHandler.js +2 -2
  40. package/dist/components/MemoriArtifactSystem/components/ArtifactHandler/ArtifactHandler.js.map +1 -1
  41. package/dist/components/MemoriWidget/MemoriWidget.js +632 -280
  42. package/dist/components/MemoriWidget/MemoriWidget.js.map +1 -1
  43. package/dist/components/StartPanel/StartPanel.js +10 -5
  44. package/dist/components/StartPanel/StartPanel.js.map +1 -1
  45. package/dist/components/UploadButton/UploadButton.js +21 -5
  46. package/dist/components/UploadButton/UploadButton.js.map +1 -1
  47. package/dist/components/UploadButton/UploadDocuments/UploadDocuments.js +123 -59
  48. package/dist/components/UploadButton/UploadDocuments/UploadDocuments.js.map +1 -1
  49. package/dist/components/layouts/Chat.js +25 -30
  50. package/dist/components/layouts/Chat.js.map +1 -1
  51. package/dist/components/layouts/FullPage.js +5 -8
  52. package/dist/components/layouts/FullPage.js.map +1 -1
  53. package/dist/components/layouts/HiddenChat.js +2 -1
  54. package/dist/components/layouts/HiddenChat.js.map +1 -1
  55. package/dist/components/layouts/WebsiteAssistant/WebsiteAssistant.js +5 -1
  56. package/dist/components/layouts/WebsiteAssistant/WebsiteAssistant.js.map +1 -1
  57. package/dist/components/layouts/WebsiteAssistant/website-assistant.css +3 -4
  58. package/dist/components/layouts/ZoomedFullBody.js +4 -7
  59. package/dist/components/layouts/ZoomedFullBody.js.map +1 -1
  60. package/dist/components/layouts/chat.css +19 -31
  61. package/dist/components/layouts/fullpage.css +52 -19
  62. package/dist/components/layouts/zoomed-full-body.css +40 -1
  63. package/dist/helpers/constants.d.ts +3 -0
  64. package/dist/helpers/constants.js +27 -1
  65. package/dist/helpers/constants.js.map +1 -1
  66. package/dist/helpers/credits.d.ts +5 -2
  67. package/dist/helpers/credits.js +5 -1
  68. package/dist/helpers/credits.js.map +1 -1
  69. package/dist/helpers/message.d.ts +1 -1
  70. package/dist/helpers/message.js +4 -4
  71. package/dist/helpers/message.js.map +1 -1
  72. package/dist/helpers/nats/getNatsConfig.d.ts +9 -0
  73. package/dist/helpers/nats/getNatsConfig.js +65 -0
  74. package/dist/helpers/nats/getNatsConfig.js.map +1 -0
  75. package/dist/helpers/nats/isSessionExpiredError.d.ts +3 -0
  76. package/dist/helpers/nats/isSessionExpiredError.js +36 -0
  77. package/dist/helpers/nats/isSessionExpiredError.js.map +1 -0
  78. package/dist/helpers/nats/useNats.d.ts +12 -0
  79. package/dist/helpers/nats/useNats.js +75 -0
  80. package/dist/helpers/nats/useNats.js.map +1 -0
  81. package/dist/helpers/nats/useNatsSession.d.ts +28 -0
  82. package/dist/helpers/nats/useNatsSession.js +212 -0
  83. package/dist/helpers/nats/useNatsSession.js.map +1 -0
  84. package/dist/helpers/usePressTooltip.d.ts +13 -0
  85. package/dist/helpers/usePressTooltip.js +23 -0
  86. package/dist/helpers/usePressTooltip.js.map +1 -0
  87. package/dist/helpers/utils.d.ts +21 -0
  88. package/dist/helpers/utils.js +75 -4
  89. package/dist/helpers/utils.js.map +1 -1
  90. package/dist/locales/de.json +1 -0
  91. package/dist/locales/en.json +1 -0
  92. package/dist/locales/es.json +1 -0
  93. package/dist/locales/fr.json +1 -0
  94. package/dist/locales/it.json +1 -0
  95. package/dist/styles.css +1 -1
  96. package/dist/types/integration.d.ts +3 -0
  97. package/dist/types/integration.js +16 -0
  98. package/dist/types/integration.js.map +1 -0
  99. package/dist/version.d.ts +1 -1
  100. package/dist/version.js +1 -1
  101. package/esm/components/AgeVerificationModal/AgeVerificationModal.js +5 -2
  102. package/esm/components/AgeVerificationModal/AgeVerificationModal.js.map +1 -1
  103. package/esm/components/Avatar/Avatar.js +5 -10
  104. package/esm/components/Avatar/Avatar.js.map +1 -1
  105. package/esm/components/Avatar/AvatarView/AvatarComponent/components/FullbodyAvatar/fullbodyAvatar.js +9 -2
  106. package/esm/components/Avatar/AvatarView/AvatarComponent/components/FullbodyAvatar/fullbodyAvatar.js.map +1 -1
  107. package/esm/components/Avatar/AvatarView/AvatarComponent/components/controllers/MorphTargetController.js +2 -2
  108. package/esm/components/Avatar/AvatarView/AvatarComponent/components/controllers/MorphTargetController.js.map +1 -1
  109. package/esm/components/Avatar/AvatarView/AvatarComponent/constants.d.ts +2 -0
  110. package/esm/components/Avatar/AvatarView/AvatarComponent/constants.js +13 -4
  111. package/esm/components/Avatar/AvatarView/AvatarComponent/constants.js.map +1 -1
  112. package/esm/components/ChatBubble/ChatBubble.js +22 -16
  113. package/esm/components/ChatBubble/ChatBubble.js.map +1 -1
  114. package/esm/components/CompletionProviderStatus/CompletionProviderStatus.js +6 -3
  115. package/esm/components/CompletionProviderStatus/CompletionProviderStatus.js.map +1 -1
  116. package/esm/components/DateSelector/DateSelector.d.ts +2 -1
  117. package/esm/components/DateSelector/DateSelector.js +17 -7
  118. package/esm/components/DateSelector/DateSelector.js.map +1 -1
  119. package/esm/components/FilePreview/FilePreview.js +24 -7
  120. package/esm/components/FilePreview/FilePreview.js.map +1 -1
  121. package/esm/components/Header/ChatConsumptionDropdown.js +1 -1
  122. package/esm/components/Header/ChatConsumptionDropdown.js.map +1 -1
  123. package/esm/components/Header/Header.css +2 -1
  124. package/esm/components/Header/Header.js +1 -1
  125. package/esm/components/Header/Header.js.map +1 -1
  126. package/esm/components/MediaWidget/MediaItemWidget.js +16 -14
  127. package/esm/components/MediaWidget/MediaItemWidget.js.map +1 -1
  128. package/esm/components/MediaWidget/MediaItemWidget.utils.d.ts +3 -2
  129. package/esm/components/MediaWidget/MediaItemWidget.utils.js +27 -6
  130. package/esm/components/MediaWidget/MediaItemWidget.utils.js.map +1 -1
  131. package/esm/components/MediaWidget/MediaPreviewModal.js +6 -7
  132. package/esm/components/MediaWidget/MediaPreviewModal.js.map +1 -1
  133. package/esm/components/MemoriArtifactSystem/components/ArtifactActions/styles.css +5 -4
  134. package/esm/components/MemoriArtifactSystem/components/ArtifactDrawer/ArtifactDrawer.css +90 -38
  135. package/esm/components/MemoriArtifactSystem/components/ArtifactDrawer/ArtifactDrawer.d.ts +1 -0
  136. package/esm/components/MemoriArtifactSystem/components/ArtifactDrawer/ArtifactDrawer.js +14 -9
  137. package/esm/components/MemoriArtifactSystem/components/ArtifactDrawer/ArtifactDrawer.js.map +1 -1
  138. package/esm/components/MemoriArtifactSystem/components/ArtifactHandler/ArtifactHandler.js +2 -2
  139. package/esm/components/MemoriArtifactSystem/components/ArtifactHandler/ArtifactHandler.js.map +1 -1
  140. package/esm/components/MemoriWidget/MemoriWidget.js +632 -280
  141. package/esm/components/MemoriWidget/MemoriWidget.js.map +1 -1
  142. package/esm/components/StartPanel/StartPanel.js +10 -5
  143. package/esm/components/StartPanel/StartPanel.js.map +1 -1
  144. package/esm/components/UploadButton/UploadButton.js +21 -5
  145. package/esm/components/UploadButton/UploadButton.js.map +1 -1
  146. package/esm/components/UploadButton/UploadDocuments/UploadDocuments.js +123 -59
  147. package/esm/components/UploadButton/UploadDocuments/UploadDocuments.js.map +1 -1
  148. package/esm/components/layouts/Chat.js +25 -30
  149. package/esm/components/layouts/Chat.js.map +1 -1
  150. package/esm/components/layouts/FullPage.js +5 -8
  151. package/esm/components/layouts/FullPage.js.map +1 -1
  152. package/esm/components/layouts/HiddenChat.js +2 -1
  153. package/esm/components/layouts/HiddenChat.js.map +1 -1
  154. package/esm/components/layouts/WebsiteAssistant/WebsiteAssistant.js +5 -1
  155. package/esm/components/layouts/WebsiteAssistant/WebsiteAssistant.js.map +1 -1
  156. package/esm/components/layouts/WebsiteAssistant/website-assistant.css +3 -4
  157. package/esm/components/layouts/ZoomedFullBody.js +4 -7
  158. package/esm/components/layouts/ZoomedFullBody.js.map +1 -1
  159. package/esm/components/layouts/chat.css +19 -31
  160. package/esm/components/layouts/fullpage.css +52 -19
  161. package/esm/components/layouts/zoomed-full-body.css +40 -1
  162. package/esm/helpers/constants.d.ts +3 -0
  163. package/esm/helpers/constants.js +26 -0
  164. package/esm/helpers/constants.js.map +1 -1
  165. package/esm/helpers/credits.d.ts +5 -2
  166. package/esm/helpers/credits.js +5 -1
  167. package/esm/helpers/credits.js.map +1 -1
  168. package/esm/helpers/message.d.ts +1 -1
  169. package/esm/helpers/message.js +2 -2
  170. package/esm/helpers/message.js.map +1 -1
  171. package/esm/helpers/nats/getNatsConfig.d.ts +9 -0
  172. package/esm/helpers/nats/getNatsConfig.js +61 -0
  173. package/esm/helpers/nats/getNatsConfig.js.map +1 -0
  174. package/esm/helpers/nats/isSessionExpiredError.d.ts +3 -0
  175. package/esm/helpers/nats/isSessionExpiredError.js +32 -0
  176. package/esm/helpers/nats/isSessionExpiredError.js.map +1 -0
  177. package/esm/helpers/nats/useNats.d.ts +12 -0
  178. package/esm/helpers/nats/useNats.js +72 -0
  179. package/esm/helpers/nats/useNats.js.map +1 -0
  180. package/esm/helpers/nats/useNatsSession.d.ts +28 -0
  181. package/esm/helpers/nats/useNatsSession.js +208 -0
  182. package/esm/helpers/nats/useNatsSession.js.map +1 -0
  183. package/esm/helpers/usePressTooltip.d.ts +13 -0
  184. package/esm/helpers/usePressTooltip.js +20 -0
  185. package/esm/helpers/usePressTooltip.js.map +1 -0
  186. package/esm/helpers/utils.d.ts +21 -0
  187. package/esm/helpers/utils.js +68 -3
  188. package/esm/helpers/utils.js.map +1 -1
  189. package/esm/locales/de.json +1 -0
  190. package/esm/locales/en.json +1 -0
  191. package/esm/locales/es.json +1 -0
  192. package/esm/locales/fr.json +1 -0
  193. package/esm/locales/it.json +1 -0
  194. package/esm/styles.css +1 -1
  195. package/esm/types/integration.d.ts +3 -0
  196. package/esm/types/integration.js +11 -0
  197. package/esm/types/integration.js.map +1 -0
  198. package/esm/version.d.ts +1 -1
  199. package/esm/version.js +1 -1
  200. package/package.json +6 -4
  201. package/src/components/AgeVerificationModal/AgeVerificationModal.tsx +6 -1
  202. package/src/components/Avatar/Avatar.stories.tsx +45 -28
  203. package/src/components/Avatar/Avatar.test.tsx +54 -0
  204. package/src/components/Avatar/Avatar.tsx +8 -12
  205. package/src/components/Avatar/AvatarView/AvatarComponent/components/FullbodyAvatar/fullbodyAvatar.tsx +12 -5
  206. package/src/components/Avatar/AvatarView/AvatarComponent/components/controllers/MorphTargetController.ts +2 -1
  207. package/src/components/Avatar/AvatarView/AvatarComponent/constants.ts +16 -4
  208. package/src/components/Avatar/__snapshots__/Avatar.test.tsx.snap +164 -0
  209. package/src/components/ChatBubble/ChatBubble.tsx +41 -12
  210. package/src/components/CompletionProviderStatus/CompletionProviderStatus.tsx +8 -4
  211. package/src/components/DateSelector/DateSelector.stories.tsx +11 -2
  212. package/src/components/DateSelector/DateSelector.tsx +28 -9
  213. package/src/components/FilePreview/FilePreview.tsx +28 -7
  214. package/src/components/Header/ChatConsumptionDropdown.tsx +5 -1
  215. package/src/components/Header/Header.css +2 -1
  216. package/src/components/Header/Header.tsx +1 -0
  217. package/src/components/MediaWidget/MediaItemWidget.tsx +26 -13
  218. package/src/components/MediaWidget/MediaItemWidget.utils.test.ts +45 -2
  219. package/src/components/MediaWidget/MediaItemWidget.utils.ts +39 -6
  220. package/src/components/MediaWidget/MediaPreviewModal.tsx +9 -7
  221. package/src/components/MemoriArtifactSystem/ArtifactDrawer.stories.tsx +218 -2252
  222. package/src/components/MemoriArtifactSystem/components/ArtifactActions/styles.css +5 -4
  223. package/src/components/MemoriArtifactSystem/components/ArtifactDrawer/ArtifactDrawer.css +90 -38
  224. package/src/components/MemoriArtifactSystem/components/ArtifactDrawer/ArtifactDrawer.tsx +31 -14
  225. package/src/components/MemoriArtifactSystem/components/ArtifactHandler/ArtifactHandler.tsx +4 -3
  226. package/src/components/MemoriWidget/MemoriWidget.tsx +785 -331
  227. package/src/components/StartPanel/StartPanel.stories.tsx +22 -0
  228. package/src/components/StartPanel/StartPanel.test.tsx +64 -1
  229. package/src/components/StartPanel/StartPanel.tsx +26 -3
  230. package/src/components/StartPanel/__snapshots__/StartPanel.test.tsx.snap +261 -0
  231. package/src/components/UploadButton/UploadButton.tsx +30 -11
  232. package/src/components/UploadButton/UploadDocuments/UploadDocuments.tsx +148 -61
  233. package/src/components/UploadButton/__snapshots__/UploadButton.test.tsx.snap +2 -2
  234. package/src/components/layouts/Chat.tsx +16 -19
  235. package/src/components/layouts/FullPage.tsx +32 -25
  236. package/src/components/layouts/HiddenChat.tsx +4 -0
  237. package/src/components/layouts/WebsiteAssistant/WebsiteAssistant.tsx +8 -0
  238. package/src/components/layouts/WebsiteAssistant/website-assistant.css +3 -4
  239. package/src/components/layouts/ZoomedFullBody.tsx +30 -24
  240. package/src/components/layouts/__snapshots__/Chat.test.tsx.snap +6 -3
  241. package/src/components/layouts/__snapshots__/FullPage.test.tsx.snap +824 -810
  242. package/src/components/layouts/__snapshots__/ZoomedFullBody.test.tsx.snap +280 -273
  243. package/src/components/layouts/chat.css +19 -31
  244. package/src/components/layouts/fullpage.css +52 -19
  245. package/src/components/layouts/layouts.stories.tsx +131 -12
  246. package/src/components/layouts/zoomed-full-body.css +40 -1
  247. package/src/helpers/constants.ts +32 -1
  248. package/src/helpers/credits.ts +16 -1
  249. package/src/helpers/message.test.ts +28 -1
  250. package/src/helpers/message.ts +4 -4
  251. package/src/helpers/nats/getNatsConfig.ts +145 -0
  252. package/src/helpers/nats/isSessionExpiredError.test.ts +38 -0
  253. package/src/helpers/nats/isSessionExpiredError.ts +51 -0
  254. package/src/helpers/nats/useNats.ts +124 -0
  255. package/src/helpers/nats/useNatsSession.ts +394 -0
  256. package/src/helpers/usePressTooltip.ts +29 -0
  257. package/src/helpers/utils.test.ts +162 -0
  258. package/src/helpers/utils.ts +108 -3
  259. package/src/index.stories.tsx +32 -0
  260. package/src/locales/de.json +1 -0
  261. package/src/locales/en.json +1 -0
  262. package/src/locales/es.json +1 -0
  263. package/src/locales/fr.json +1 -0
  264. package/src/locales/it.json +1 -0
  265. package/src/styles.css +4 -7
  266. package/src/types/integration.test.ts +32 -0
  267. package/src/types/integration.ts +31 -0
  268. package/src/version.ts +1 -1
@@ -5,6 +5,8 @@ import { FileText as DocumentIcon } from 'lucide-react';
5
5
  import { Modal } from '@memori.ai/ui';
6
6
  import { useTranslation } from 'react-i18next';
7
7
  import memoriApiClient from '@memori.ai/memori-api-client';
8
+ import { officeNativeExtensions } from '../../../helpers/constants';
9
+ import { isOfficeNativeFilename } from '../../../helpers/utils';
8
10
  // Types
9
11
  type PreviewFile = {
10
12
  name: string;
@@ -165,64 +167,101 @@ const UploadDocuments: React.FC<UploadDocumentsProps> = ({
165
167
  }
166
168
  };
167
169
 
168
- const extractTextFromXLSX = async (file: File): Promise<string> => {
169
- try {
170
- if (!window.XLSX) {
171
- await new Promise((resolve, reject) => {
172
- const script = document.createElement('script');
173
- script.src = XLSX_URL;
174
- script.onload = resolve;
175
- script.onerror = reject;
176
- document.head.appendChild(script);
177
- });
178
- }
170
+ const loadXLSXLibrary = async (): Promise<void> => {
171
+ if (window.XLSX) return;
179
172
 
180
- const arrayBuffer = await file.arrayBuffer();
181
- const workbook = window.XLSX.read(arrayBuffer, {
182
- type: 'array',
183
- cellFormula: true,
184
- cellNF: true,
185
- cellText: true,
186
- cellDates: true,
173
+ await new Promise((resolve, reject) => {
174
+ const script = document.createElement('script');
175
+ script.src = XLSX_URL;
176
+ script.onload = resolve;
177
+ script.onerror = reject;
178
+ document.head.appendChild(script);
179
+ });
180
+ };
181
+
182
+ const readXLSXWorkbook = async (file: File) => {
183
+ await loadXLSXLibrary();
184
+
185
+ const arrayBuffer = await file.arrayBuffer();
186
+ return window.XLSX.read(arrayBuffer, {
187
+ type: 'array',
188
+ cellFormula: true,
189
+ cellNF: true,
190
+ cellText: true,
191
+ cellDates: true,
192
+ });
193
+ };
194
+
195
+ const formatXLSXWorkbookForDisplay = (workbook: {
196
+ SheetNames: string[];
197
+ Sheets: Record<string, unknown>;
198
+ }): string => {
199
+ let text = '';
200
+
201
+ for (const sheetName of workbook.SheetNames) {
202
+ const worksheet = workbook.Sheets[sheetName];
203
+ const data = window.XLSX.utils.sheet_to_json(worksheet, {
204
+ header: 1,
205
+ raw: false,
187
206
  });
188
207
 
189
- let text = '';
190
- for (const sheetName of workbook.SheetNames) {
191
- const worksheet = workbook.Sheets[sheetName];
192
- const data = window.XLSX.utils.sheet_to_json(worksheet, {
193
- header: 1,
194
- raw: false,
208
+ const colWidths = data.reduce((widths: number[], row: any[]) => {
209
+ row.forEach((cell, i) => {
210
+ const cellWidth = (cell || '').toString().length;
211
+ widths[i] = Math.max(widths[i] || 0, cellWidth);
195
212
  });
213
+ return widths;
214
+ }, []);
215
+
216
+ const formattedText = data.map((row: any[]) => {
217
+ return row
218
+ .map((cell, i) => {
219
+ const cellStr = (cell || '').toString();
220
+ return cellStr.padEnd(colWidths[i] + 2);
221
+ })
222
+ .join('|')
223
+ .trim();
224
+ });
196
225
 
197
- const colWidths = data.reduce((widths: number[], row: any[]) => {
198
- row.forEach((cell, i) => {
199
- const cellWidth = (cell || '').toString().length;
200
- widths[i] = Math.max(widths[i] || 0, cellWidth);
201
- });
202
- return widths;
203
- }, []);
204
-
205
- const formattedText = data.map((row: any[]) => {
206
- return row
207
- .map((cell, i) => {
208
- const cellStr = (cell || '').toString();
209
- return cellStr.padEnd(colWidths[i] + 2);
210
- })
211
- .join('|')
212
- .trim();
213
- });
226
+ if (formattedText.length > 0) {
227
+ const separator = colWidths
228
+ .map((w: number) => '-'.repeat(w + 2))
229
+ .join('+');
230
+ formattedText.splice(1, 0, separator);
231
+ }
214
232
 
215
- if (formattedText.length > 0) {
216
- const separator = colWidths
217
- .map((w: number) => '-'.repeat(w + 2))
218
- .join('+');
219
- formattedText.splice(1, 0, separator);
220
- }
233
+ text += `Sheet: ${sheetName}\n${formattedText.join('\n')}\n\n`;
234
+ }
235
+
236
+ return text;
237
+ };
221
238
 
222
- text += `Sheet: ${sheetName}\n${formattedText.join('\n')}\n\n`;
239
+ const formatXLSXWorkbookAsCsv = (workbook: {
240
+ SheetNames: string[];
241
+ Sheets: Record<string, unknown>;
242
+ }): string => {
243
+ let text = '';
244
+
245
+ for (const sheetName of workbook.SheetNames) {
246
+ const worksheet = workbook.Sheets[sheetName];
247
+ const csv = window.XLSX.utils.sheet_to_csv(worksheet, { raw: false });
248
+ if (csv.trim()) {
249
+ text += `Sheet: ${sheetName}\n${csv}\n\n`;
223
250
  }
251
+ }
224
252
 
225
- return text;
253
+ return text;
254
+ };
255
+
256
+ const extractTextFromXLSX = async (
257
+ file: File
258
+ ): Promise<{ display: string; asset: string }> => {
259
+ try {
260
+ const workbook = await readXLSXWorkbook(file);
261
+ return {
262
+ display: formatXLSXWorkbookForDisplay(workbook),
263
+ asset: formatXLSXWorkbookAsCsv(workbook),
264
+ };
226
265
  } catch (error) {
227
266
  console.error('XLSX extraction failed:', error);
228
267
  throw new Error(
@@ -235,21 +274,31 @@ const UploadDocuments: React.FC<UploadDocumentsProps> = ({
235
274
 
236
275
  const processDocumentFile = async (
237
276
  file: File
238
- ): Promise<{ text: string | null }> => {
239
- const fileExt = file.name.split('.').pop()?.toLowerCase() || '';
277
+ ): Promise<{
278
+ text: string | null;
279
+ textForAsset?: string;
280
+ uploadAsOriginal?: boolean;
281
+ }> => {
282
+ if (isOfficeNativeFilename(file.name)) {
283
+ return { text: null, uploadAsOriginal: true };
284
+ }
240
285
 
286
+ const ext = file.name.split('.').pop()?.toLowerCase() || '';
241
287
  try {
242
288
  let text: string | null = null;
289
+ let textForAsset: string | undefined;
243
290
 
244
- if (fileExt === 'pdf') {
291
+ if (ext === 'pdf') {
245
292
  text = await extractTextFromPDF(file);
246
- } else if (['txt', 'md', 'json', 'csv', 'html'].includes(fileExt)) {
293
+ } else if (['txt', 'md', 'json', 'csv', 'html'].includes(ext)) {
247
294
  text = await file.text();
248
- } else if (fileExt === 'xlsx') {
249
- text = await extractTextFromXLSX(file);
295
+ } else if (ext === 'xlsx') {
296
+ const extracted = await extractTextFromXLSX(file);
297
+ text = extracted.display;
298
+ textForAsset = extracted.asset;
250
299
  }
251
300
 
252
- return { text };
301
+ return { text, textForAsset };
253
302
  } catch (error) {
254
303
  console.error('Document processing failed:', error);
255
304
  throw new Error(
@@ -295,7 +344,12 @@ const UploadDocuments: React.FC<UploadDocumentsProps> = ({
295
344
  throw new Error(response.resultMessage || 'Upload failed');
296
345
  }
297
346
 
298
- return response.asset?.assetURL;
347
+ const assetURL = response.asset?.assetURL;
348
+ if (!assetURL) {
349
+ throw new Error('Upload failed: missing asset URL');
350
+ }
351
+
352
+ return assetURL;
299
353
  };
300
354
 
301
355
  const handleDocumentUpload = async (
@@ -360,11 +414,42 @@ const UploadDocuments: React.FC<UploadDocumentsProps> = ({
360
414
  const fileId = Math.random().toString(36).substr(2, 9);
361
415
 
362
416
  try {
363
- const { text } = await processDocumentFile(file);
417
+ const { text, textForAsset, uploadAsOriginal } =
418
+ await processDocumentFile(file);
419
+
420
+ if (uploadAsOriginal) {
421
+ // Office native format: upload the original file as asset, no text extraction
422
+ let assetUrl: string | undefined;
423
+ try {
424
+ assetUrl = await uploadAssetFile(file);
425
+ } catch (uploadError) {
426
+ console.error('Office asset upload failed:', uploadError);
427
+ onDocumentError?.({
428
+ message: t('upload.officeAssetUploadFailed', {
429
+ fileName: file.name,
430
+ defaultValue: `"${file.name}" could not be uploaded and was not added.`,
431
+ }),
432
+ severity: 'error',
433
+ });
434
+ }
435
+
436
+ if (!assetUrl) {
437
+ activeCount--;
438
+ onLoadingChange?.(true, activeCount);
439
+ continue;
440
+ }
364
441
 
365
- if (text) {
442
+ processedFiles.push({
443
+ name: file.name,
444
+ id: fileId,
445
+ content: '',
446
+ mimeType: file.type,
447
+ textAssetUrl: assetUrl,
448
+ });
449
+ } else if (text) {
366
450
  const baseName = file.name.replace(/\.[^/.]+$/, '') || file.name;
367
- const textFile = new File([text], `${baseName}.txt`, {
451
+ const assetText = textForAsset ?? text;
452
+ const textFile = new File([assetText], `${baseName}.txt`, {
368
453
  type: 'text/plain',
369
454
  });
370
455
 
@@ -429,7 +514,9 @@ const UploadDocuments: React.FC<UploadDocumentsProps> = ({
429
514
  <input
430
515
  ref={documentInputRef}
431
516
  type="file"
432
- accept=".pdf,.txt,.md,.json,.xlsx,.csv,.html"
517
+ accept={`.pdf,.txt,.md,.json,.xlsx,.csv,.html,${officeNativeExtensions.join(
518
+ ','
519
+ )}`}
433
520
  multiple
434
521
  className="memori--upload-file-input"
435
522
  onChange={handleDocumentUpload}
@@ -6,7 +6,7 @@ exports[`renders UploadButton unchanged 1`] = `
6
6
  class="memori--unified-upload-wrapper"
7
7
  >
8
8
  <input
9
- accept=".jpg,.jpeg,.png,.pdf,.txt,.json,.xlsx,.csv,.md,.html"
9
+ accept=".jpg,.jpeg,.png,.pdf,.txt,.json,.xlsx,.csv,.md,.html,.doc,.docx,.dotx,.xltx,.potx"
10
10
  class="memori--upload-file-input"
11
11
  multiple=""
12
12
  style="display: none;"
@@ -60,7 +60,7 @@ exports[`renders UploadButton unchanged 1`] = `
60
60
  class="memori--document-upload-wrapper"
61
61
  >
62
62
  <input
63
- accept=".pdf,.txt,.md,.json,.xlsx,.csv,.html"
63
+ accept=".pdf,.txt,.md,.json,.xlsx,.csv,.html,.doc,.docx,.dotx,.xltx,.potx"
64
64
  class="memori--upload-file-input"
65
65
  multiple=""
66
66
  type="file"
@@ -1,5 +1,6 @@
1
1
  import React, { useCallback, useEffect, useMemo, useState } from 'react';
2
2
  import { Button, Spin } from '@memori.ai/ui';
3
+ import ArtifactDrawer from '../MemoriArtifactSystem/components/ArtifactDrawer/ArtifactDrawer';
3
4
  import { useTranslation } from 'react-i18next';
4
5
  import {
5
6
  Expand,
@@ -229,31 +230,16 @@ const ChatLayout: React.FC<LayoutProps> = ({
229
230
 
230
231
  <div id="extension" />
231
232
 
232
- <div
233
- className={`memori-chat-layout--main ${
234
- useSideArtifactChrome
235
- ? 'memori-chat-layout--main-with-artifact'
236
- : ''
237
- }`}
238
- >
233
+ <div className="memori-chat-layout--main">
234
+ {/* Chat column — flex:1, shrinks when artifact column grows */}
239
235
  <div
240
236
  className={
241
237
  state.isFullscreen
242
238
  ? `memori-chat-layout-controls-hide`
243
- : `memori-chat-layout--controls ${
244
- useSideArtifactChrome
245
- ? 'memori-chat-layout--controls-with-artifact'
246
- : ''
247
- }`
239
+ : `memori-chat-layout--controls`
248
240
  }
249
241
  >
250
- <div
251
- className={`memori-chat-layout--header ${
252
- useSideArtifactChrome
253
- ? 'memori-chat-layout--header-with-artifact'
254
- : ''
255
- }`}
256
- >
242
+ <div className="memori-chat-layout--header">
257
243
  {Header && headerProps && mobileHeaderProps && (
258
244
  <div className="memori-fullpage-header-row">
259
245
  <Header
@@ -424,6 +410,17 @@ const ChatLayout: React.FC<LayoutProps> = ({
424
410
  ) : null}
425
411
  </div>
426
412
  </div>
413
+
414
+ {/* Artifact column — width 0→480px with CSS transition */}
415
+ <div
416
+ className={`memori--grid-column-artifact${
417
+ useSideArtifactChrome ? ' memori--grid-column-artifact--open' : ''
418
+ }`}
419
+ >
420
+ {useSideArtifactChrome && (
421
+ <ArtifactDrawer isLayoutColumn />
422
+ )}
423
+ </div>
427
424
  </div>
428
425
  </Spin>
429
426
  </>
@@ -216,7 +216,7 @@ const FullPageLayout: React.FC<LayoutProps> = ({
216
216
  {integrationBackground}
217
217
 
218
218
  <Spin spinning={loading}>
219
- {poweredBy}
219
+ {useSideArtifactChrome && poweredBy}
220
220
 
221
221
  {Header && headerProps && mobileHeaderProps && (
222
222
  <div className="memori-fullpage-top-header">
@@ -331,40 +331,47 @@ const FullPageLayout: React.FC<LayoutProps> = ({
331
331
  />
332
332
  )}
333
333
 
334
- <div className="memori--grid">
335
- {!useSideArtifactChrome && (
334
+ {/* Content row: grid (avatar+chat) + artifact column as full-height siblings */}
335
+ <div className="memori-fullpage-content-row">
336
+ <div className="memori--grid">
337
+ {/* Avatar column — hidden via CSS when artifact is open */}
336
338
  <div className="memori--grid-column memori--grid-column-left">
337
339
  {Avatar && avatarProps && (
338
340
  <Avatar chatProps={chatProps} {...avatarProps} />
339
341
  )}
340
342
 
341
343
  <div id="extension" />
344
+
345
+ {poweredBy}
346
+ </div>
347
+
348
+ {/* Chat column — flex:1, shrinks naturally when artifact column grows */}
349
+ <div className="memori-chat-layout--main">
350
+ <div
351
+ className={
352
+ state.isFullscreen
353
+ ? `memori-chat-layout-controls-hide`
354
+ : `memori-chat-layout--controls`
355
+ }
356
+ >
357
+ {sessionId && hasUserActivatedSpeak && Chat && chatProps ? (
358
+ <Chat {...chatProps} />
359
+ ) : startPanelProps ? (
360
+ <StartPanel {...startPanelProps} />
361
+ ) : null}
362
+ </div>
342
363
  </div>
343
- )}
364
+ </div>
365
+
366
+ {/* Artifact column — outside the padded grid, spans full content height */}
344
367
  <div
345
- className={`memori-chat-layout--main ${
346
- hasArtifact && !state.isChatLogPanelPresentation
347
- ? 'memori-chat-layout--main-with-artifact'
348
- : ''
368
+ className={`memori--grid-column-artifact${
369
+ useSideArtifactChrome ? ' memori--grid-column-artifact--open' : ''
349
370
  }`}
350
371
  >
351
- <div
352
- className={
353
- state.isFullscreen
354
- ? `memori-chat-layout-controls-hide`
355
- : `memori-chat-layout--controls ${
356
- useSideArtifactChrome
357
- ? 'memori-chat-layout--controls-with-artifact'
358
- : ''
359
- }`
360
- }
361
- >
362
- {sessionId && hasUserActivatedSpeak && Chat && chatProps ? (
363
- <Chat {...chatProps} />
364
- ) : startPanelProps ? (
365
- <StartPanel {...startPanelProps} />
366
- ) : null}
367
- </div>
372
+ {useSideArtifactChrome && (
373
+ <ArtifactDrawer isLayoutColumn />
374
+ )}
368
375
  </div>
369
376
  </div>
370
377
  </Spin>
@@ -23,6 +23,7 @@ import {
23
23
  X,
24
24
  } from 'lucide-react';
25
25
  import { getResourceUrl } from '../../helpers/media';
26
+ import ArtifactDrawer from '../MemoriArtifactSystem/components/ArtifactDrawer/ArtifactDrawer';
26
27
  import ChatInputs from '../ChatInputs/ChatInputs';
27
28
  import ShareButton from '../ShareButton/ShareButton';
28
29
  import MobileSessionPanel from '../MobileSessionPanel/MobileSessionPanel';
@@ -752,6 +753,9 @@ const HiddenChatLayout: React.FC<LayoutProps> = ({
752
753
  </div>
753
754
  </aside>
754
755
  </div>
756
+
757
+ {/* Artifact drawer — fixed overlay that pairs with the sidebar shift (right: 46%) */}
758
+ {useSideArtifactChrome && <ArtifactDrawer />}
755
759
  </>
756
760
  );
757
761
  };
@@ -4,6 +4,8 @@ import { LayoutProps } from '../../MemoriWidget/MemoriWidget';
4
4
  import Blob from '../../Blob/Blob';
5
5
  import { X } from 'lucide-react';
6
6
  import { useTranslation } from 'react-i18next';
7
+ import { useArtifact } from '../../MemoriArtifactSystem/context/ArtifactContext';
8
+ import ArtifactDrawer from '../../MemoriArtifactSystem/components/ArtifactDrawer/ArtifactDrawer';
7
9
 
8
10
  const WebsiteAssistantLayout: React.FC<LayoutProps> = ({
9
11
  Header,
@@ -22,6 +24,9 @@ const WebsiteAssistantLayout: React.FC<LayoutProps> = ({
22
24
  avatar3dHidden,
23
25
  }) => {
24
26
  const { t } = useTranslation();
27
+ const { state: artifactState } = useArtifact();
28
+ const useSideArtifactChrome =
29
+ artifactState.isDrawerOpen && !artifactState.isChatLogPanelPresentation;
25
30
  const [collapsed, _setCollapsed] = useState(true);
26
31
  const [expandedKey, setExpandedKey] = useState<string>();
27
32
 
@@ -131,6 +136,9 @@ const WebsiteAssistantLayout: React.FC<LayoutProps> = ({
131
136
  </>
132
137
  )}
133
138
  </div>
139
+
140
+ {/* Artifact drawer — fixed overlay beside the website assistant panel */}
141
+ {useSideArtifactChrome && <ArtifactDrawer />}
134
142
  </>
135
143
  );
136
144
  };
@@ -214,9 +214,7 @@
214
214
  @media (min-width: 1024px) {
215
215
  .memori-widget.memori-layout-website_assistant .memori-website_assistant--collapsed,
216
216
  .memori-widget.memori-layout-website_assistant .memori-website_assistant--expanded {
217
- width: 30vw;
218
- min-width: 400px;
219
- max-width: 480px;
217
+ width: 480px;
220
218
  border-radius: var(--memori-radius-box) 0 0 0;
221
219
  }
222
220
 
@@ -420,7 +418,8 @@
420
418
  transform: none !important;
421
419
  }
422
420
 
423
- .memori-layout-website_assistant.memori--avatar-readyplayerme-full .memori--avatar-wrapper > div {
421
+ .memori-layout-website_assistant.memori--avatar-readyplayerme-full .memori--avatar-wrapper > div,
422
+ .memori-layout-website_assistant.memori--avatar-avatar-configurator .memori--avatar-wrapper > div {
424
423
  transform: scale(1.7) translate(0px, 10vh);
425
424
  }
426
425
 
@@ -1,6 +1,7 @@
1
1
  import React, { useCallback, useEffect, useMemo, useState } from 'react';
2
2
  import { Button, Spin } from '@memori.ai/ui';
3
3
  import { useTranslation } from 'react-i18next';
4
+ import ArtifactDrawer from '../MemoriArtifactSystem/components/ArtifactDrawer/ArtifactDrawer';
4
5
  import {
5
6
  Expand,
6
7
  MapPin,
@@ -329,8 +330,10 @@ const ZoomedFullBodyLayout: React.FC<LayoutProps> = ({
329
330
  }}
330
331
  />
331
332
  )}
332
- <div className="memori--grid">
333
- {!useSideArtifactChrome && (
333
+ {/* Content row: grid (avatar+chat) + artifact column as full-height siblings */}
334
+ <div className="memori-fullpage-content-row">
335
+ <div className="memori--grid">
336
+ {/* Avatar column — hidden via CSS when artifact is open */}
334
337
  <div className="memori--grid-column memori--grid-column-left">
335
338
  {Avatar && avatarProps && (
336
339
  <Avatar chatProps={chatProps} isZoomed {...avatarProps} />
@@ -338,31 +341,34 @@ const ZoomedFullBodyLayout: React.FC<LayoutProps> = ({
338
341
 
339
342
  <div id="extension" />
340
343
  </div>
341
- )}
344
+
345
+ {/* Chat column — flex:1, shrinks naturally when artifact column grows */}
346
+ <div className="memori-chat-layout--main">
347
+ <div
348
+ className={
349
+ state.isFullscreen
350
+ ? `memori-chat-layout-controls-hide`
351
+ : `memori-chat-layout--controls`
352
+ }
353
+ >
354
+ {sessionId && hasUserActivatedSpeak && Chat && chatProps ? (
355
+ <Chat {...chatProps} />
356
+ ) : startPanelProps ? (
357
+ <StartPanel {...startPanelProps} />
358
+ ) : null}
359
+ </div>
360
+ </div>
361
+ </div>
362
+
363
+ {/* Artifact column — outside the padded grid, spans full content height */}
342
364
  <div
343
- className={`memori-chat-layout--main ${
344
- hasArtifact && !state.isChatLogPanelPresentation
345
- ? 'memori-chat-layout--main-with-artifact'
346
- : ''
365
+ className={`memori--grid-column-artifact${
366
+ useSideArtifactChrome ? ' memori--grid-column-artifact--open' : ''
347
367
  }`}
348
368
  >
349
- <div
350
- className={
351
- state.isFullscreen
352
- ? `memori-chat-layout-controls-hide`
353
- : `memori-chat-layout--controls ${
354
- useSideArtifactChrome
355
- ? 'memori-chat-layout--controls-with-artifact'
356
- : ''
357
- }`
358
- }
359
- >
360
- {sessionId && hasUserActivatedSpeak && Chat && chatProps ? (
361
- <Chat {...chatProps} />
362
- ) : startPanelProps ? (
363
- <StartPanel {...startPanelProps} />
364
- ) : null}
365
- </div>
369
+ {useSideArtifactChrome && (
370
+ <ArtifactDrawer isLayoutColumn />
371
+ )}
366
372
  </div>
367
373
  </div>
368
374
  </Spin>
@@ -207,13 +207,13 @@ exports[`renders Chat layout unchanged 1`] = `
207
207
  id="extension"
208
208
  />
209
209
  <div
210
- class="memori-chat-layout--main "
210
+ class="memori-chat-layout--main"
211
211
  >
212
212
  <div
213
- class="memori-chat-layout--controls "
213
+ class="memori-chat-layout--controls"
214
214
  >
215
215
  <div
216
- class="memori-chat-layout--header "
216
+ class="memori-chat-layout--header"
217
217
  >
218
218
  <div
219
219
  class="memori-fullpage-header-row"
@@ -734,6 +734,9 @@ exports[`renders Chat layout unchanged 1`] = `
734
734
  </div>
735
735
  </div>
736
736
  </div>
737
+ <div
738
+ class="memori--grid-column-artifact"
739
+ />
737
740
  </div>
738
741
  </div>
739
742
  <audio