@memori.ai/memori-react 7.21.1 → 7.23.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.
Files changed (106) hide show
  1. package/CHANGELOG.md +56 -0
  2. package/dist/components/CompletionProviderStatus/CompletionProviderStatus.css +33 -23
  3. package/dist/components/CompletionProviderStatus/CompletionProviderStatus.js +85 -8
  4. package/dist/components/CompletionProviderStatus/CompletionProviderStatus.js.map +1 -1
  5. package/dist/components/KnownFacts/KnownFacts.js +1 -1
  6. package/dist/components/KnownFacts/KnownFacts.js.map +1 -1
  7. package/dist/components/StartPanel/StartPanel.css +29 -0
  8. package/dist/components/StartPanel/StartPanel.js +2 -1
  9. package/dist/components/StartPanel/StartPanel.js.map +1 -1
  10. package/dist/components/Typing/Typing.js +49 -47
  11. package/dist/components/Typing/Typing.js.map +1 -1
  12. package/dist/components/UploadButton/UploadButton.d.ts +1 -0
  13. package/dist/components/UploadButton/UploadButton.js +142 -3
  14. package/dist/components/UploadButton/UploadButton.js.map +1 -1
  15. package/dist/components/icons/Alert.d.ts +5 -0
  16. package/dist/components/icons/Alert.js +6 -0
  17. package/dist/components/icons/Alert.js.map +1 -0
  18. package/dist/components/icons/Info.d.ts +5 -0
  19. package/dist/components/icons/Info.js +6 -0
  20. package/dist/components/icons/Info.js.map +1 -0
  21. package/dist/components/icons/Warning.js +1 -1
  22. package/dist/components/icons/Warning.js.map +1 -1
  23. package/dist/components/ui/ConfirmDialog.css +42 -0
  24. package/dist/components/ui/ConfirmDialog.d.ts +11 -0
  25. package/dist/components/ui/ConfirmDialog.js +12 -0
  26. package/dist/components/ui/ConfirmDialog.js.map +1 -0
  27. package/dist/components/ui/Drawer.css +121 -96
  28. package/dist/components/ui/Drawer.d.ts +15 -6
  29. package/dist/components/ui/Drawer.js +44 -13
  30. package/dist/components/ui/Drawer.js.map +1 -1
  31. package/dist/locales/de.json +15 -0
  32. package/dist/locales/en.json +15 -0
  33. package/dist/locales/es.json +15 -0
  34. package/dist/locales/fr.json +7 -0
  35. package/dist/locales/it.json +15 -0
  36. package/dist/styles.css +6 -4
  37. package/esm/components/CompletionProviderStatus/CompletionProviderStatus.css +33 -23
  38. package/esm/components/CompletionProviderStatus/CompletionProviderStatus.js +85 -8
  39. package/esm/components/CompletionProviderStatus/CompletionProviderStatus.js.map +1 -1
  40. package/esm/components/KnownFacts/KnownFacts.js +1 -1
  41. package/esm/components/KnownFacts/KnownFacts.js.map +1 -1
  42. package/esm/components/StartPanel/StartPanel.css +29 -0
  43. package/esm/components/StartPanel/StartPanel.js +2 -1
  44. package/esm/components/StartPanel/StartPanel.js.map +1 -1
  45. package/esm/components/Typing/Typing.js +49 -47
  46. package/esm/components/Typing/Typing.js.map +1 -1
  47. package/esm/components/UploadButton/UploadButton.d.ts +1 -0
  48. package/esm/components/UploadButton/UploadButton.js +142 -3
  49. package/esm/components/UploadButton/UploadButton.js.map +1 -1
  50. package/esm/components/icons/Alert.d.ts +5 -0
  51. package/esm/components/icons/Alert.js +4 -0
  52. package/esm/components/icons/Alert.js.map +1 -0
  53. package/esm/components/icons/Info.d.ts +5 -0
  54. package/esm/components/icons/Info.js +4 -0
  55. package/esm/components/icons/Info.js.map +1 -0
  56. package/esm/components/icons/Warning.js +1 -1
  57. package/esm/components/icons/Warning.js.map +1 -1
  58. package/esm/components/ui/ConfirmDialog.css +42 -0
  59. package/esm/components/ui/ConfirmDialog.d.ts +11 -0
  60. package/esm/components/ui/ConfirmDialog.js +9 -0
  61. package/esm/components/ui/ConfirmDialog.js.map +1 -0
  62. package/esm/components/ui/Drawer.css +121 -96
  63. package/esm/components/ui/Drawer.d.ts +15 -6
  64. package/esm/components/ui/Drawer.js +45 -14
  65. package/esm/components/ui/Drawer.js.map +1 -1
  66. package/esm/locales/de.json +15 -0
  67. package/esm/locales/en.json +15 -0
  68. package/esm/locales/es.json +15 -0
  69. package/esm/locales/fr.json +7 -0
  70. package/esm/locales/it.json +15 -0
  71. package/esm/styles.css +6 -4
  72. package/package.json +1 -1
  73. package/src/components/BlockedMemoriBadge/__snapshots__/BlockedMemoriBadge.test.tsx.snap +10 -0
  74. package/src/components/CompletionProviderStatus/CompletionProviderStatus.css +33 -23
  75. package/src/components/CompletionProviderStatus/CompletionProviderStatus.stories.tsx +274 -21
  76. package/src/components/CompletionProviderStatus/CompletionProviderStatus.tsx +117 -21
  77. package/src/components/CompletionProviderStatus/__snapshots__/CompletionProviderStatus.test.tsx.snap +39 -21
  78. package/src/components/KnownFacts/KnownFacts.tsx +1 -1
  79. package/src/components/StartPanel/StartPanel.css +29 -0
  80. package/src/components/StartPanel/StartPanel.tsx +47 -0
  81. package/src/components/StartPanel/__snapshots__/StartPanel.test.tsx.snap +827 -7
  82. package/src/components/Typing/Typing.tsx +52 -47
  83. package/src/components/UploadButton/UploadButton.tsx +206 -5
  84. package/src/components/UploadButton/__snapshots__/UploadButton.test.tsx.snap +1 -1
  85. package/src/components/icons/Alert.tsx +31 -0
  86. package/src/components/icons/Info.tsx +31 -0
  87. package/src/components/icons/Warning.tsx +2 -1
  88. package/src/components/layouts/__snapshots__/Chat.test.tsx.snap +74 -0
  89. package/src/components/layouts/__snapshots__/FullPage.test.tsx.snap +148 -0
  90. package/src/components/layouts/__snapshots__/Totem.test.tsx.snap +74 -0
  91. package/src/components/layouts/__snapshots__/ZoomedFullBody.test.tsx.snap +74 -0
  92. package/src/components/ui/ConfirmDialog.css +42 -0
  93. package/src/components/ui/ConfirmDialog.stories.tsx +216 -0
  94. package/src/components/ui/ConfirmDialog.test.tsx +124 -0
  95. package/src/components/ui/ConfirmDialog.tsx +58 -0
  96. package/src/components/ui/Drawer.css +121 -96
  97. package/src/components/ui/Drawer.stories.tsx +152 -67
  98. package/src/components/ui/Drawer.test.tsx +6 -2
  99. package/src/components/ui/Drawer.tsx +195 -89
  100. package/src/components/ui/__snapshots__/ConfirmDialog.test.tsx.snap +35 -0
  101. package/src/locales/de.json +15 -0
  102. package/src/locales/en.json +15 -0
  103. package/src/locales/es.json +15 -0
  104. package/src/locales/fr.json +7 -0
  105. package/src/locales/it.json +15 -0
  106. package/src/styles.css +6 -4
@@ -1,55 +1,53 @@
1
1
  import { useEffect, useState } from 'react';
2
2
 
3
3
  const separator = ' ';
4
- const defaultDelay = 3;
4
+ const defaultDelay = 15;
5
+ const timeoutMs = 20 * 1000;
6
+ const newWordInterval = 50;
5
7
  const defaultSentences = {
6
8
  en: [
7
- {
8
- delayAfter: defaultDelay,
9
- text: 'Generating an accurate and fancy response...',
10
- },
11
- {
12
- delayAfter: defaultDelay,
13
- text: 'Generating a response that will blow your mind...',
14
- },
15
- {
16
- delayAfter: defaultDelay,
17
- text: 'Generating a response that will make you smile...',
18
- },
19
- { delayAfter: defaultDelay, text: 'Thinking of a response...' },
20
- {
21
- delayAfter: defaultDelay,
22
- text: 'Thinking of a response that will make you smile...',
23
- },
24
- { delayAfter: defaultDelay, text: 'Gathering my thoughts...' },
25
- {
26
- delayAfter: defaultDelay,
27
- text: 'Gathering my thoughts to give you a response...',
28
- },
9
+ { delayAfter: defaultDelay, text: 'Processing in progress...' },
10
+ { delayAfter: defaultDelay, text: "I'm thinking..." },
11
+ { delayAfter: defaultDelay, text: 'Analysing the request...' },
12
+ { delayAfter: defaultDelay, text: 'Preparing the reply...' },
13
+ { delayAfter: defaultDelay, text: 'Gathering information...' },
14
+ { delayAfter: defaultDelay, text: 'Formulating ideas...' },
15
+ { delayAfter: defaultDelay, text: 'One moment please...' },
16
+ { delayAfter: defaultDelay, text: 'Almost ready...' },
17
+ { delayAfter: defaultDelay, text: 'Connecting concepts...' },
18
+ { delayAfter: defaultDelay, text: 'Organising ideas...' },
19
+ { delayAfter: defaultDelay, text: 'Evaluating options...' },
20
+ { delayAfter: defaultDelay, text: 'Looking for the best solution...' },
21
+ { delayAfter: defaultDelay, text: 'Working for you...' },
22
+ { delayAfter: defaultDelay, text: 'Please wait...' },
23
+ { delayAfter: defaultDelay, text: 'Processing data...' },
24
+ { delayAfter: defaultDelay, text: 'Calculating response...' },
25
+ { delayAfter: defaultDelay, text: 'Synthesising information...' },
26
+ { delayAfter: defaultDelay, text: 'Generating content...' },
27
+ { delayAfter: defaultDelay, text: 'Reflecting on question...' },
28
+ { delayAfter: defaultDelay, text: 'Refining the answer' },
29
29
  ],
30
30
  it: [
31
- {
32
- delayAfter: defaultDelay,
33
- text: 'Sto generando una risposta accurata e fantasiosa...',
34
- },
35
- {
36
- delayAfter: defaultDelay,
37
- text: 'Sto generando una risposta che ti farà impazzire...',
38
- },
39
- {
40
- delayAfter: defaultDelay,
41
- text: 'Sto generando una risposta che ti farà sorridere...',
42
- },
43
- { delayAfter: defaultDelay, text: 'Sto pensando ad una risposta...' },
44
- {
45
- delayAfter: defaultDelay,
46
- text: 'Sto pensando ad una risposta che ti farà sorridere...',
47
- },
48
- { delayAfter: defaultDelay, text: 'Sto raccogliendo i miei pensieri...' },
49
- {
50
- delayAfter: defaultDelay,
51
- text: 'Sto raccogliendo i miei pensieri per darti una risposta...',
52
- },
31
+ { delayAfter: defaultDelay, text: 'Elaborazione in corso...' },
32
+ { delayAfter: defaultDelay, text: 'Sto pensando...' },
33
+ { delayAfter: defaultDelay, text: 'Analizzando la richiesta...' },
34
+ { delayAfter: defaultDelay, text: 'Preparando la risposta...' },
35
+ { delayAfter: defaultDelay, text: 'Raccogliendo informazioni...' },
36
+ { delayAfter: defaultDelay, text: 'Formulando idee...' },
37
+ { delayAfter: defaultDelay, text: 'Un momento per favore...' },
38
+ { delayAfter: defaultDelay, text: 'Quasi pronto...' },
39
+ { delayAfter: defaultDelay, text: 'Connettendo i concetti...' },
40
+ { delayAfter: defaultDelay, text: 'Organizzando le idee...' },
41
+ { delayAfter: defaultDelay, text: 'Valutando le opzioni...' },
42
+ { delayAfter: defaultDelay, text: 'Cercando la soluzione migliore...' },
43
+ { delayAfter: defaultDelay, text: 'Sto lavorando per te...' },
44
+ { delayAfter: defaultDelay, text: 'Attendere prego...' },
45
+ { delayAfter: defaultDelay, text: 'Elaborazione dati in corso...' },
46
+ { delayAfter: defaultDelay, text: 'Calcolando la risposta...' },
47
+ { delayAfter: defaultDelay, text: 'Sintetizzando informazioni...' },
48
+ { delayAfter: defaultDelay, text: 'Generando contenuti...' },
49
+ { delayAfter: defaultDelay, text: 'Sto riflettendo sulla domanda...' },
50
+ { delayAfter: defaultDelay, text: 'Perfezionando la risposta...' },
53
51
  ],
54
52
  };
55
53
 
@@ -98,9 +96,12 @@ const Typing = ({
98
96
  : ''
99
97
  );
100
98
  const [shownText, setShownText] = useState('');
99
+ const [elapsedTime, setElapsedTime] = useState(0);
101
100
 
102
101
  useEffect(() => {
103
102
  const interval = setInterval(() => {
103
+ setElapsedTime(prev => prev + newWordInterval);
104
+
104
105
  const letter = text[shownText.length];
105
106
  if (letter !== undefined && text.length > 0) {
106
107
  setShownText(prev => prev + letter);
@@ -119,7 +120,11 @@ const Typing = ({
119
120
  );
120
121
  setShownText('');
121
122
  setIndex(nextIndex);
122
- } else if (!sentences && !sentence && useDefaultSentences) {
123
+ } else if (
124
+ !sentences &&
125
+ !sentence &&
126
+ (useDefaultSentences || elapsedTime > timeoutMs)
127
+ ) {
123
128
  const sentence =
124
129
  defaultSentences[lang][
125
130
  Math.floor(Math.random() * defaultSentences[lang].length)
@@ -127,7 +132,7 @@ const Typing = ({
127
132
  setText(`${sentence.text}${getSeparatorString(sentence.delayAfter)}`);
128
133
  setShownText('');
129
134
  }
130
- }, 50);
135
+ }, newWordInterval);
131
136
 
132
137
  return () => clearInterval(interval);
133
138
  });
@@ -13,8 +13,9 @@ type UploadError = {
13
13
 
14
14
  /**
15
15
  * FileUploadButton component allows users to upload and convert files to text
16
- * Supports PDF and TXT files up to 10MB
16
+ * Supports PDF, TXT, CSV and XLSX files up to 10MB
17
17
  * Extracts text from PDFs using PDF.js
18
+ * Extracts text from XLSX using xlsx library
18
19
  */
19
20
 
20
21
  const MAX_FILE_SIZE = 10 * 1024 * 1024; // 10MB
@@ -22,11 +23,14 @@ const MAX_TEXT_LENGTH = 100000; // 100,000 characters
22
23
  const PDF_JS_VERSION = '3.11.174'; // Last stable version with .min.js files
23
24
  const WORKER_URL = `https://cdnjs.cloudflare.com/ajax/libs/pdf.js/${PDF_JS_VERSION}/pdf.worker.min.js`;
24
25
  const PDF_JS_URL = `https://cdnjs.cloudflare.com/ajax/libs/pdf.js/${PDF_JS_VERSION}/pdf.min.js`;
26
+ const XLSX_URL =
27
+ 'https://cdn.sheetjs.com/xlsx-0.20.0/package/dist/xlsx.full.min.js';
25
28
 
26
- // Add type definition for pdfjsLib
29
+ // Add type definitions for external libraries
27
30
  declare global {
28
31
  interface Window {
29
32
  pdfjsLib: any;
33
+ XLSX: any;
30
34
  }
31
35
  }
32
36
 
@@ -105,6 +109,16 @@ const FileUploadButton = ({
105
109
  // Return extracted text
106
110
  return text;
107
111
  } catch (error) {
112
+ setErrors(prev => [
113
+ ...prev,
114
+ {
115
+ message: `PDF extraction failed: ${
116
+ error instanceof Error ? error.message : 'Unknown error'
117
+ }`,
118
+ severity: 'error',
119
+ fileId: file.name,
120
+ },
121
+ ]);
108
122
  throw new Error(
109
123
  `PDF extraction failed: ${
110
124
  error instanceof Error ? error.message : 'Unknown error'
@@ -113,6 +127,191 @@ const FileUploadButton = ({
113
127
  }
114
128
  };
115
129
 
130
+ /**
131
+ * Extracts text from XLSX using xlsx library with enhanced error handling
132
+ * @param file XLSX file to process
133
+ * @returns Promise resolving to extracted text
134
+ */
135
+ const extractTextFromXLSX = async (file: File): Promise<string> => {
136
+ try {
137
+ // First, check if the XLSX library is loaded in the window object
138
+ // If not, dynamically load it by creating and appending a script tag
139
+ if (!window.XLSX) {
140
+ await new Promise((resolve, reject) => {
141
+ const script = document.createElement('script');
142
+ script.src = XLSX_URL;
143
+ script.onload = resolve;
144
+ script.onerror = reject;
145
+ document.head.appendChild(script);
146
+ });
147
+ }
148
+
149
+ // Convert the File object to ArrayBuffer for XLSX parsing
150
+ const arrayBuffer = await file.arrayBuffer();
151
+
152
+ // Check for minimum valid Excel file size
153
+ if (arrayBuffer.byteLength < 4) {
154
+ throw new Error('File appears to be corrupted or empty');
155
+ }
156
+
157
+ let workbook;
158
+ try {
159
+ // Try parsing with full options first
160
+ workbook = window.XLSX.read(arrayBuffer, {
161
+ type: 'array',
162
+ cellFormula: false, // Disable formula parsing to avoid potential issues
163
+ cellNF: false, // Disable number format parsing
164
+ cellHTML: false, // Disable HTML parsing
165
+ cellText: true, // Force text output
166
+ cellDates: false, // Disable date parsing to avoid errors
167
+ error: (e: any) => {
168
+ console.warn('Non-fatal XLSX error:', e);
169
+ }, // Log non-fatal errors
170
+ cellStyles: false, // Disable style parsing
171
+ });
172
+ } catch (initialError) {
173
+ console.warn(
174
+ 'Initial XLSX parsing failed, attempting recovery mode:',
175
+ initialError
176
+ );
177
+
178
+ // Fallback to a more permissive parsing method
179
+ try {
180
+ workbook = window.XLSX.read(arrayBuffer, {
181
+ type: 'array',
182
+ sheetRows: 1000, // Limit number of rows to parse
183
+ cellFormula: false,
184
+ cellStyles: false,
185
+ bookDeps: false, // Don't parse external dependencies
186
+ bookFiles: false, // Don't parse embedded files
187
+ bookProps: false, // Don't parse document properties
188
+ bookSheets: false, // Don't parse sheet properties
189
+ bookVBA: false, // Don't parse VBA
190
+ WTF: true, // "What the Formula" mode - ignores errors when possible
191
+ });
192
+ } catch (recoveryError) {
193
+ setErrors(prev => [
194
+ ...prev,
195
+ {
196
+ message: `File appears to be corrupted. Recovery attempt failed: ${
197
+ recoveryError instanceof Error
198
+ ? recoveryError.message
199
+ : 'Unknown error'
200
+ }`,
201
+ severity: 'error',
202
+ fileId: file.name,
203
+ },
204
+ ]);
205
+ throw new Error(
206
+ `File appears to be corrupted. Recovery attempt failed: ${
207
+ recoveryError instanceof Error
208
+ ? recoveryError.message
209
+ : 'Unknown error'
210
+ }`
211
+ );
212
+ }
213
+ }
214
+
215
+ // Verify that workbook contains at least one sheet
216
+ if (
217
+ !workbook ||
218
+ !workbook.SheetNames ||
219
+ workbook.SheetNames.length === 0
220
+ ) {
221
+ throw new Error('Excel file contains no valid worksheets');
222
+ }
223
+
224
+ let text = '';
225
+ let successfulSheets = 0;
226
+ const totalSheets = workbook.SheetNames.length;
227
+
228
+ // Loop through each sheet in the workbook
229
+ for (const sheetName of workbook.SheetNames) {
230
+ try {
231
+ const worksheet = workbook.Sheets[sheetName];
232
+ if (!worksheet) {
233
+ throw new Error(`Sheet ${sheetName} is empty or corrupted`);
234
+ }
235
+
236
+ // Safely get the dimensions of the sheet
237
+ const range = window.XLSX.utils.decode_range(
238
+ worksheet['!ref'] || 'A1:A1'
239
+ );
240
+
241
+ // Check if sheet seems abnormally large (possible corruption)
242
+ const rowCount = range.e.r - range.s.r + 1;
243
+ const colCount = range.e.c - range.s.c + 1;
244
+ if (rowCount > 10000 || colCount > 1000) {
245
+ throw new Error(
246
+ `Sheet ${sheetName} has suspicious dimensions (${rowCount}x${colCount}) and may be corrupted`
247
+ );
248
+ }
249
+
250
+ // Try to convert sheet to CSV
251
+ let csv;
252
+ try {
253
+ csv = window.XLSX.utils.sheet_to_csv(worksheet);
254
+ } catch (csvError) {
255
+ // If CSV conversion fails, try a more basic cell-by-cell approach
256
+ csv = '';
257
+ for (let r = range.s.r; r <= Math.min(range.e.r, 1000); ++r) {
258
+ let row = '';
259
+ for (let c = range.s.c; c <= Math.min(range.e.c, 100); ++c) {
260
+ const cell =
261
+ worksheet[window.XLSX.utils.encode_cell({ r: r, c: c })];
262
+ row += (cell ? String(cell.v || '') : '') + ',';
263
+ }
264
+ csv += row + '\n';
265
+ }
266
+ csv += '...(truncated due to potential corruption)';
267
+ }
268
+
269
+ // Add sheet name and content to final text
270
+ text += `Sheet: ${sheetName}\n${csv}\n\n`;
271
+ successfulSheets++;
272
+ } catch (sheetError) {
273
+ // Log sheet-specific error but continue with other sheets
274
+ text += `Sheet: ${sheetName}\nError extracting content: ${
275
+ sheetError instanceof Error ? sheetError.message : 'Unknown error'
276
+ }\n\n`;
277
+ }
278
+ }
279
+
280
+ // If we couldn't extract any sheets successfully
281
+ if (successfulSheets === 0) {
282
+ throw new Error(
283
+ 'Could not extract any valid content from the Excel file'
284
+ );
285
+ }
286
+
287
+ // If some sheets failed but others succeeded
288
+ if (successfulSheets < totalSheets) {
289
+ text =
290
+ `Warning: Only extracted ${successfulSheets} of ${totalSheets} sheets due to possible corruption.\n\n` +
291
+ text;
292
+ }
293
+
294
+ return text; // Return the extracted text from all sheets
295
+ } catch (error) {
296
+ setErrors(prev => [
297
+ ...prev,
298
+ {
299
+ message: `XLSX extraction failed: ${
300
+ error instanceof Error ? error.message : 'Unknown error'
301
+ }`,
302
+ severity: 'error',
303
+ fileId: file.name,
304
+ },
305
+ ]);
306
+ // If any error occurs during processing, throw with descriptive message
307
+ throw new Error(
308
+ `XLSX extraction failed: ${
309
+ error instanceof Error ? error.message : 'Unknown error'
310
+ }`
311
+ );
312
+ }
313
+ };
314
+
116
315
  /**
117
316
  * Validates uploaded file
118
317
  * Checks file type and size restrictions
@@ -121,7 +320,7 @@ const FileUploadButton = ({
121
320
  */
122
321
  const validateFile = (file: File): boolean => {
123
322
  const fileExt = `.${file.name.split('.').pop()?.toLowerCase()}`;
124
- const ALLOWED_FILE_TYPES = ['.pdf', '.txt'];
323
+ const ALLOWED_FILE_TYPES = ['.pdf', '.txt', '.json', '.xlsx', '.csv'];
125
324
 
126
325
  if (!ALLOWED_FILE_TYPES.includes(fileExt)) {
127
326
  addError({
@@ -161,8 +360,10 @@ const FileUploadButton = ({
161
360
 
162
361
  if (fileExt === 'pdf') {
163
362
  text = await extractTextFromPDF(file);
164
- } else if (fileExt === 'txt' || fileExt === 'json') {
363
+ } else if (fileExt === 'txt' || fileExt === 'json' || fileExt === 'csv') {
165
364
  text = await file.text();
365
+ } else if (fileExt === 'xlsx') {
366
+ text = await extractTextFromXLSX(file);
166
367
  }
167
368
 
168
369
  // Check text length limit
@@ -241,7 +442,7 @@ const FileUploadButton = ({
241
442
  <input
242
443
  ref={fileInputRef}
243
444
  type="file"
244
- accept=".pdf,.txt,.json"
445
+ accept=".pdf,.txt,.json,.xlsx,.csv"
245
446
  className="memori--upload-file-input"
246
447
  onChange={handleFileSelect}
247
448
  multiple
@@ -6,7 +6,7 @@ exports[`renders UploadButton unchanged 1`] = `
6
6
  class="relative file-upload-wrapper"
7
7
  >
8
8
  <input
9
- accept=".pdf,.txt,.json"
9
+ accept=".pdf,.txt,.json,.xlsx,.csv"
10
10
  class="memori--upload-file-input"
11
11
  multiple=""
12
12
  type="file"
@@ -0,0 +1,31 @@
1
+ import React from 'react';
2
+
3
+ const Alert = ({
4
+ className,
5
+ title,
6
+ }: {
7
+ className?: string;
8
+ title?: string;
9
+ }) => (
10
+ <svg
11
+ width="800px"
12
+ height="800px"
13
+ viewBox="0 0 24 24"
14
+ fill="none"
15
+ {...(!title ? { 'aria-hidden': 'true' } : {})}
16
+ xmlns="http://www.w3.org/2000/svg"
17
+ className={className}
18
+ aria-label={title}
19
+ color="currentColor"
20
+ >
21
+ <path
22
+ d="M12 16H12.01M12 8V12M12 21C16.9706 21 21 16.9706 21 12C21 7.02944 16.9706 3 12 3C7.02944 3 3 7.02944 3 12C3 16.9706 7.02944 21 12 21Z"
23
+ stroke="currentColor"
24
+ strokeWidth="2"
25
+ strokeLinecap="round"
26
+ strokeLinejoin="round"
27
+ />
28
+ </svg>
29
+ );
30
+
31
+ export default Alert;
@@ -0,0 +1,31 @@
1
+ import React from 'react';
2
+
3
+ const Info = ({ className, title }: { className?: string; title?: string }) => (
4
+ <svg
5
+ width="800px"
6
+ height="800px"
7
+ viewBox="0 0 24 24"
8
+ fill="none"
9
+ {...(!title ? { 'aria-hidden': 'true' } : {})}
10
+ xmlns="http://www.w3.org/2000/svg"
11
+ className={className}
12
+ aria-label={title}
13
+ >
14
+ <circle cx="12" cy="12" r="10" stroke="currentColor" strokeWidth="1.5" />
15
+ <path
16
+ d="M12 17V11"
17
+ stroke="currentColor"
18
+ strokeWidth="1.5"
19
+ strokeLinecap="round"
20
+ />
21
+ <circle
22
+ cx="1"
23
+ cy="1"
24
+ r="1"
25
+ transform="matrix(1 0 0 -1 11 9)"
26
+ fill="currentColor"
27
+ />
28
+ </svg>
29
+ );
30
+
31
+ export default Info;
@@ -15,8 +15,9 @@ const Warning = ({
15
15
  viewBox="0 0 1024 1024"
16
16
  className={className}
17
17
  aria-label={title}
18
+ color="currentColor"
18
19
  >
19
- <path d="M464 720a48 48 0 1096 0 48 48 0 10-96 0zm16-304v184c0 4.4 3.6 8 8 8h48c4.4 0 8-3.6 8-8V416c0-4.4-3.6-8-8-8h-48c-4.4 0-8 3.6-8 8zm475.7 440l-416-720c-6.2-10.7-16.9-16-27.7-16s-21.6 5.3-27.7 16l-416 720C56 877.4 71.4 904 96 904h832c24.6 0 40-26.6 27.7-48zm-783.5-27.9L512 239.9l339.8 588.2H172.2z"></path>
20
+ <path fill="currentColor" d="M464 720a48 48 0 1096 0 48 48 0 10-96 0zm16-304v184c0 4.4 3.6 8 8 8h48c4.4 0 8-3.6 8-8V416c0-4.4-3.6-8-8-8h-48c-4.4 0-8 3.6-8 8zm475.7 440l-416-720c-6.2-10.7-16.9-16-27.7-16s-21.6 5.3-27.7 16l-416 720C56 877.4 71.4 904 96 904h832c24.6 0 40-26.6 27.7-48zm-783.5-27.9L512 239.9l339.8 588.2H172.2z"></path>
20
21
  </svg>
21
22
  );
22
23
 
@@ -337,6 +337,80 @@ exports[`renders Chat layout unchanged 1`] = `
337
337
  </option>
338
338
  </select>
339
339
  </div>
340
+ <div
341
+ class="memori--start-privacy-explanation-container"
342
+ >
343
+ <p
344
+ class="memori--start-privacy-explanation"
345
+ >
346
+ Le conversazioni sono visibili all'autore dell'agente
347
+ </p>
348
+ <div
349
+ class="memori-tooltip memori-tooltip--align-right"
350
+ >
351
+ <div
352
+ class="memori-tooltip--content"
353
+ >
354
+ <div
355
+ class="memori--privacy-tooltip-content"
356
+ >
357
+ <p>
358
+
359
+ Tutte le conversazioni con questo agente sono visibili all'autore dell'agente
360
+ </p>
361
+ <ul
362
+ class="memori--privacy-tooltip-content-list"
363
+ >
364
+ <li>
365
+ Per utenti anonimi: l'autore vedrà il contenuto e l'indirizzo IP
366
+ </li>
367
+ <li>
368
+ Per utenti registrati: l'autore vedrà il contenuto e il nome utente
369
+ </li>
370
+ </ul>
371
+ <p>
372
+ L'autore utilizza queste informazioni per migliorare le funzionalità dell'agente. Continuando, accetti queste condizioni.
373
+ </p>
374
+ <a
375
+ href="https://memori.ai/en/privacy-policy"
376
+ rel="noopener noreferrer"
377
+ target="_blank"
378
+ >
379
+ Informativa sulla privacy
380
+ </a>
381
+ </div>
382
+ </div>
383
+ <div
384
+ class="memori-tooltip--trigger"
385
+ >
386
+ <svg
387
+ aria-hidden="true"
388
+ class="memori--start-privacy-explanation-icon"
389
+ fill="none"
390
+ focusable="false"
391
+ role="img"
392
+ stroke="currentColor"
393
+ stroke-linecap="round"
394
+ stroke-linejoin="round"
395
+ stroke-width="1.5"
396
+ viewBox="0 0 24 24"
397
+ xmlns="http://www.w3.org/2000/svg"
398
+ >
399
+ <circle
400
+ cx="12"
401
+ cy="12"
402
+ r="10"
403
+ />
404
+ <path
405
+ d="M9.09 9a3 3 0 015.83 1c0 2-3 3-3 3"
406
+ />
407
+ <path
408
+ d="M12 17L12.01 17"
409
+ />
410
+ </svg>
411
+ </div>
412
+ </div>
413
+ </div>
340
414
  <button
341
415
  class="memori-button memori-button--primary memori-button--rounded memori-button--padded memori--start-button"
342
416
  >