@memori.ai/memori-react 4.1.0 → 4.2.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 (100) hide show
  1. package/CHANGELOG.md +28 -0
  2. package/dist/components/AgeVerificationModal/AgeVerificationModal.js +5 -1
  3. package/dist/components/AgeVerificationModal/AgeVerificationModal.js.map +1 -1
  4. package/dist/components/Header/Header.css +1 -1
  5. package/dist/components/Header/Header.d.ts +3 -0
  6. package/dist/components/Header/Header.js +3 -2
  7. package/dist/components/Header/Header.js.map +1 -1
  8. package/dist/components/KnownFacts/KnownFacts.css +19 -0
  9. package/dist/components/KnownFacts/KnownFacts.d.ts +11 -0
  10. package/dist/components/KnownFacts/KnownFacts.js +157 -0
  11. package/dist/components/KnownFacts/KnownFacts.js.map +1 -0
  12. package/dist/components/MemoriWidget/MemoriWidget.js +8 -3
  13. package/dist/components/MemoriWidget/MemoriWidget.js.map +1 -1
  14. package/dist/components/SettingsDrawer/SettingsDrawer.js +1 -1
  15. package/dist/components/SettingsDrawer/SettingsDrawer.js.map +1 -1
  16. package/dist/components/StartPanel/StartPanel.css +2 -2
  17. package/dist/components/icons/ChevronLeft.d.ts +5 -0
  18. package/dist/components/icons/ChevronLeft.js +6 -0
  19. package/dist/components/icons/ChevronLeft.js.map +1 -0
  20. package/dist/components/icons/ChevronRight.d.ts +5 -0
  21. package/dist/components/icons/ChevronRight.js +6 -0
  22. package/dist/components/icons/ChevronRight.js.map +1 -0
  23. package/dist/components/ui/Button.css +29 -1
  24. package/dist/components/ui/Checkbox.css +17 -4
  25. package/dist/components/ui/Checkbox.d.ts +2 -1
  26. package/dist/components/ui/Checkbox.js +13 -3
  27. package/dist/components/ui/Checkbox.js.map +1 -1
  28. package/dist/components/ui/Drawer.css +22 -4
  29. package/dist/components/ui/Modal.d.ts +1 -1
  30. package/dist/components/ui/Select.js +1 -1
  31. package/dist/components/ui/Select.js.map +1 -1
  32. package/dist/components/ui/Table.css +113 -0
  33. package/dist/locales/en.json +20 -0
  34. package/dist/locales/it.json +20 -0
  35. package/dist/styles.css +8 -0
  36. package/esm/components/AgeVerificationModal/AgeVerificationModal.js +5 -1
  37. package/esm/components/AgeVerificationModal/AgeVerificationModal.js.map +1 -1
  38. package/esm/components/Header/Header.css +1 -1
  39. package/esm/components/Header/Header.d.ts +3 -0
  40. package/esm/components/Header/Header.js +3 -2
  41. package/esm/components/Header/Header.js.map +1 -1
  42. package/esm/components/KnownFacts/KnownFacts.css +19 -0
  43. package/esm/components/KnownFacts/KnownFacts.d.ts +11 -0
  44. package/esm/components/KnownFacts/KnownFacts.js +154 -0
  45. package/esm/components/KnownFacts/KnownFacts.js.map +1 -0
  46. package/esm/components/MemoriWidget/MemoriWidget.js +8 -3
  47. package/esm/components/MemoriWidget/MemoriWidget.js.map +1 -1
  48. package/esm/components/SettingsDrawer/SettingsDrawer.js +1 -1
  49. package/esm/components/SettingsDrawer/SettingsDrawer.js.map +1 -1
  50. package/esm/components/StartPanel/StartPanel.css +2 -2
  51. package/esm/components/icons/ChevronLeft.d.ts +5 -0
  52. package/esm/components/icons/ChevronLeft.js +4 -0
  53. package/esm/components/icons/ChevronLeft.js.map +1 -0
  54. package/esm/components/icons/ChevronRight.d.ts +5 -0
  55. package/esm/components/icons/ChevronRight.js +4 -0
  56. package/esm/components/icons/ChevronRight.js.map +1 -0
  57. package/esm/components/ui/Button.css +29 -1
  58. package/esm/components/ui/Checkbox.css +17 -4
  59. package/esm/components/ui/Checkbox.d.ts +2 -1
  60. package/esm/components/ui/Checkbox.js +13 -3
  61. package/esm/components/ui/Checkbox.js.map +1 -1
  62. package/esm/components/ui/Drawer.css +22 -4
  63. package/esm/components/ui/Modal.d.ts +1 -1
  64. package/esm/components/ui/Select.js +1 -1
  65. package/esm/components/ui/Select.js.map +1 -1
  66. package/esm/components/ui/Table.css +113 -0
  67. package/esm/locales/en.json +20 -0
  68. package/esm/locales/it.json +20 -0
  69. package/esm/styles.css +8 -0
  70. package/package.json +2 -2
  71. package/src/components/AgeVerificationModal/AgeVerificationModal.tsx +6 -0
  72. package/src/components/Header/Header.css +1 -1
  73. package/src/components/Header/Header.stories.tsx +37 -0
  74. package/src/components/Header/Header.test.tsx +54 -0
  75. package/src/components/Header/Header.tsx +18 -0
  76. package/src/components/Header/__snapshots__/Header.test.tsx.snap +203 -0
  77. package/src/components/KnownFacts/KnownFacts.css +19 -0
  78. package/src/components/KnownFacts/KnownFacts.stories.tsx +79 -0
  79. package/src/components/KnownFacts/KnownFacts.test.tsx +54 -0
  80. package/src/components/KnownFacts/KnownFacts.tsx +449 -0
  81. package/src/components/KnownFacts/__snapshots__/KnownFacts.test.tsx.snap +19 -0
  82. package/src/components/MemoriWidget/MemoriWidget.tsx +17 -2
  83. package/src/components/SettingsDrawer/SettingsDrawer.tsx +3 -1
  84. package/src/components/StartPanel/StartPanel.css +2 -2
  85. package/src/components/icons/ChevronLeft.tsx +28 -0
  86. package/src/components/icons/ChevronRight.tsx +28 -0
  87. package/src/components/ui/Button.css +29 -1
  88. package/src/components/ui/Checkbox.css +17 -4
  89. package/src/components/ui/Checkbox.stories.tsx +15 -0
  90. package/src/components/ui/Checkbox.test.tsx +5 -0
  91. package/src/components/ui/Checkbox.tsx +38 -23
  92. package/src/components/ui/Drawer.css +22 -4
  93. package/src/components/ui/Modal.tsx +1 -1
  94. package/src/components/ui/Select.tsx +5 -1
  95. package/src/components/ui/Table.css +113 -0
  96. package/src/components/ui/__snapshots__/Checkbox.test.tsx.snap +26 -0
  97. package/src/locales/en.json +20 -0
  98. package/src/locales/it.json +20 -0
  99. package/src/mocks/data.ts +11 -0
  100. package/src/styles.css +8 -0
@@ -0,0 +1,449 @@
1
+ import { KnownFact, Memori } from '@memori.ai/memori-api-client/dist/types';
2
+ import { useEffect, useState } from 'react';
3
+ import memoriApiClient from '@memori.ai/memori-api-client';
4
+ import Button from '../ui/Button';
5
+ import Drawer from '../ui/Drawer';
6
+ import Spin from '../ui/Spin';
7
+ import Modal from '../ui/Modal';
8
+ import toast from 'react-hot-toast';
9
+ import { getErrori18nKey } from '../../helpers/error';
10
+ import { useTranslation } from 'react-i18next';
11
+ import Delete from '../icons/Delete';
12
+ import Checkbox from '../ui/Checkbox';
13
+ import Select from '../ui/Select';
14
+ import ChevronLeft from '../icons/ChevronLeft';
15
+ import ChevronRight from '../icons/ChevronRight';
16
+
17
+ export interface Props {
18
+ apiURL: string;
19
+ sessionID: string;
20
+ memori: Memori;
21
+ initialKnownFacts?: KnownFact[];
22
+ visible?: boolean;
23
+ closeDrawer: () => void;
24
+ }
25
+
26
+ const KnownFacts = ({
27
+ apiURL,
28
+ sessionID,
29
+ memori,
30
+ visible = true,
31
+ initialKnownFacts = [],
32
+ closeDrawer,
33
+ }: Props) => {
34
+ const { t } = useTranslation();
35
+
36
+ const client = memoriApiClient(apiURL);
37
+ const { getKnownFactsPaginated, deleteKnownFact } = client.knownFacts;
38
+
39
+ const [knownFacts, setKnownFacts] = useState<KnownFact[]>(initialKnownFacts);
40
+ const [numberOfResults, setNumberOfResults] = useState(25);
41
+ const [pageIndex, setPageIndex] = useState(0);
42
+ const [knownFactsCount, setKnownFactsCount] = useState(
43
+ initialKnownFacts?.length ?? 0
44
+ );
45
+ const [loading, setLoading] = useState(false);
46
+
47
+ /**
48
+ * Fetch known facts
49
+ */
50
+ const fetchKnownFacts = async (
51
+ sessionId?: string,
52
+ from?: number,
53
+ howMany?: number
54
+ ) => {
55
+ if (!sessionID && !sessionId) return;
56
+ setLoading(true);
57
+ try {
58
+ const { knownFacts, count, ...response } = await getKnownFactsPaginated(
59
+ sessionId ?? sessionID,
60
+ from ?? pageIndex,
61
+ howMany ?? numberOfResults
62
+ );
63
+
64
+ setKnownFacts(knownFacts ?? []);
65
+ setKnownFactsCount(count ?? 0);
66
+
67
+ if (response.resultCode !== 0) {
68
+ console.error(response);
69
+ toast.error(t(getErrori18nKey(response.resultCode)));
70
+ }
71
+ } catch (err) {
72
+ console.error('KNOWN_FACTS/FETCH', err);
73
+ setKnownFacts(initialKnownFacts ?? []);
74
+ }
75
+
76
+ setLoading(false);
77
+ };
78
+ useEffect(() => {
79
+ fetchKnownFacts();
80
+ }, []);
81
+
82
+ /**
83
+ * Table selection
84
+ */
85
+ const [bulkDeleteModalVisible, setBulkDeleteModalVisible] = useState(false);
86
+ const [deleteModalVisibleFor, setDeleteModalVisibleFor] = useState<string>();
87
+ const [selectedRowKeys, setSelectedRowKeys] = useState<(string | number)[]>(
88
+ []
89
+ );
90
+ // const rowSelection = {
91
+ // selectedRowKeys,
92
+ // onChange: setSelectedRowKeys,
93
+ // };
94
+
95
+ // const columns = [
96
+ // {
97
+ // title: t('knownFacts.text'),
98
+ // dataIndex: 'text',
99
+ // },
100
+ // {
101
+ // title: t('createdAt'),
102
+ // dataIndex: 'creationTimestamp',
103
+ // sorter: (a: KnownFact, b: KnownFact) =>
104
+ // new Date(a.creationTimestamp ?? Date.now()).getTime() -
105
+ // new Date(b.creationTimestamp ?? Date.now()).getTime(),
106
+ // render: (creationTimestamp: Date) => (
107
+ // <div className={styles.columnCentered}>
108
+ // <span className={styles.date}>
109
+ // {creationTimestamp
110
+ // ? new Intl.DateTimeFormat('it', {
111
+ // dateStyle: 'short',
112
+ // timeStyle: 'short',
113
+ // }).format(new Date(creationTimestamp))
114
+ // : '-'}
115
+ // </span>
116
+ // </div>
117
+ // ),
118
+ // },
119
+ // {
120
+ // title: t('actions'),
121
+ // key: 'action',
122
+ // render: (_value: any, kf: KnownFact) => (
123
+ // <div className={styles.actionColumn}>
124
+ // <Button
125
+ // danger
126
+ // icon={<DeleteOutlined />}
127
+ // disabled={selectedRowKeys?.length > 0}
128
+ // title={t('delete') || 'Delete'}
129
+ // onClick={() => {
130
+ // kf.knownFactID &&
131
+ // Modal.confirm({
132
+ // title: t('knownFacts.deleteConfirmTitle'),
133
+ // content: t('knownFacts.deleteConfirmMessage'),
134
+ // okText: t('confirm'),
135
+ // cancelText: t('cancel'),
136
+ // centered: true,
137
+ // autoFocusButton: 'cancel',
138
+ // onOk: async () => {
139
+ // try {
140
+ // const response = await deleteKnownFact(
141
+ // sessionID,
142
+ // kf.knownFactID
143
+ // );
144
+ // if (response.resultCode === 0) {
145
+ // toast.success(t('knownFacts.deleteSuccess'));
146
+ // setSelectedRowKeys([]);
147
+ // fetchKnownFacts();
148
+ // } else {
149
+ // console.error(response);
150
+ // toast.error(
151
+ // t(getErrori18nKey(response.resultCode), {
152
+ // ns: 'common',
153
+ // })
154
+ // );
155
+ // }
156
+ // } catch (_e) {
157
+ // let error = _e as Error;
158
+ // toast.error(t('Error') + error.message);
159
+ // }
160
+ // },
161
+ // });
162
+ // }}
163
+ // />
164
+ // </div>
165
+ // ),
166
+ // },
167
+ // ];
168
+
169
+ return (
170
+ <Drawer
171
+ open={visible}
172
+ width="80%"
173
+ className="memori-known-facts-drawer"
174
+ onClose={() => closeDrawer()}
175
+ title={t('knownFacts.title')}
176
+ >
177
+ <p>
178
+ {t('knownFacts.description', {
179
+ memoriName: memori.name,
180
+ })}
181
+ </p>
182
+
183
+ <Spin spinning={loading}>
184
+ <div className="memori-known-facts-actions">
185
+ <Button
186
+ primary
187
+ danger
188
+ onClick={() => {
189
+ setBulkDeleteModalVisible(true);
190
+ }}
191
+ className="memori-known-facts-delete-selected"
192
+ disabled={selectedRowKeys?.length === 0}
193
+ icon={<Delete />}
194
+ loading={loading}
195
+ >
196
+ {t('selected')} ({selectedRowKeys?.length})
197
+ </Button>
198
+ <Modal
199
+ className="memori-known-facts-modal"
200
+ open={bulkDeleteModalVisible}
201
+ closable
202
+ title={
203
+ selectedRowKeys.length > 1
204
+ ? t('knownFacts.deleteSelectedConfirmTitle')
205
+ : t('knownFacts.deleteConfirmTitle')
206
+ }
207
+ description={
208
+ selectedRowKeys.length > 1
209
+ ? t('knownFacts.deleteSelectedConfirmMessage', {
210
+ number: selectedRowKeys.length,
211
+ })
212
+ : t('knownFacts.deleteConfirmMessage')
213
+ }
214
+ onClose={() => {
215
+ setBulkDeleteModalVisible(false);
216
+ }}
217
+ footer={
218
+ <>
219
+ <Button
220
+ ghost
221
+ onClick={() => {
222
+ setBulkDeleteModalVisible(false);
223
+ }}
224
+ >
225
+ {t('cancel')}
226
+ </Button>
227
+ <Button
228
+ primary
229
+ danger
230
+ onClick={async () => {
231
+ try {
232
+ const mutations = selectedRowKeys.map(key => {
233
+ let knownFactID = key as string;
234
+ return deleteKnownFact(sessionID, knownFactID);
235
+ });
236
+ Promise.all(mutations).then(responses => {
237
+ if (responses.every(r => r.resultCode === 0)) {
238
+ toast.success(t('knownFacts.deleteSuccess'));
239
+ setSelectedRowKeys([]);
240
+ fetchKnownFacts();
241
+ setBulkDeleteModalVisible(false);
242
+ } else {
243
+ let errored = responses.find(r => r.resultCode !== 0);
244
+ console.error(errored);
245
+ if (errored?.resultCode !== undefined)
246
+ toast.error(
247
+ t(getErrori18nKey(errored?.resultCode))
248
+ );
249
+ }
250
+ });
251
+ } catch (_e) {
252
+ let error = _e as Error;
253
+ toast.error(t('Error') + error.message);
254
+ }
255
+ }}
256
+ >
257
+ {t('confirm')}
258
+ </Button>
259
+ </>
260
+ }
261
+ />
262
+ </div>
263
+
264
+ {knownFactsCount > 25 && (
265
+ <nav className="memori--table--pagination">
266
+ {knownFactsCount > numberOfResults && (
267
+ <div className="memori--table--pagination--pages">
268
+ <Button
269
+ shape="circle"
270
+ disabled={pageIndex === 0}
271
+ padded={false}
272
+ title={t('previous') || 'Previous'}
273
+ icon={<ChevronLeft />}
274
+ onClick={() => {
275
+ setPageIndex(pageIndex - 1);
276
+ fetchKnownFacts(undefined, pageIndex - 1, numberOfResults);
277
+ }}
278
+ />
279
+ <span className="memori--table--pagination--pages--current">
280
+ {pageIndex + 1} /{' '}
281
+ {Math.ceil(knownFactsCount / numberOfResults)}
282
+ </span>
283
+ <Button
284
+ shape="circle"
285
+ padded={false}
286
+ title={t('next') || 'Next'}
287
+ icon={<ChevronRight />}
288
+ disabled={
289
+ (pageIndex + 1) * numberOfResults >= knownFactsCount
290
+ }
291
+ onClick={() => {
292
+ setPageIndex(pageIndex + 1);
293
+ fetchKnownFacts(undefined, 1, numberOfResults);
294
+ }}
295
+ />
296
+ </div>
297
+ )}
298
+
299
+ <Select
300
+ options={[
301
+ { label: `25 / ${t('page') || 'page'}`, value: 25 },
302
+ { label: `50 / ${t('page') || 'page'}`, value: 50 },
303
+ { label: `100 / ${t('page') || 'page'}`, value: 100 },
304
+ ]}
305
+ value={numberOfResults}
306
+ displayValue={`${numberOfResults} / ${t('page') || 'page'}`}
307
+ onChange={value => {
308
+ setNumberOfResults(value);
309
+ fetchKnownFacts(undefined, undefined, value);
310
+ }}
311
+ />
312
+ </nav>
313
+ )}
314
+ <table className="memori--table">
315
+ <thead>
316
+ <tr>
317
+ <th className="memori--table--column-centered">
318
+ <Checkbox
319
+ checked={
320
+ !!knownFacts?.length &&
321
+ selectedRowKeys?.length === knownFacts.length
322
+ }
323
+ indeterminate={
324
+ !!knownFacts?.length &&
325
+ !!selectedRowKeys?.length &&
326
+ selectedRowKeys?.length !== knownFacts?.length
327
+ }
328
+ onChange={e => {
329
+ if (e.target.checked) {
330
+ setSelectedRowKeys(knownFacts.map(kf => kf.knownFactID));
331
+ } else {
332
+ setSelectedRowKeys([]);
333
+ }
334
+ }}
335
+ />
336
+ </th>
337
+ <th>{t('knownFacts.text')}</th>
338
+ <th className="mobile-hidden">{t('createdAt')}</th>
339
+ <th className="memori--table--column-right">{t('actions')}</th>
340
+ </tr>
341
+ </thead>
342
+ <tbody>
343
+ {knownFacts.map(kf => (
344
+ <tr key={kf.knownFactID}>
345
+ <th className="memori--table--column-centered">
346
+ <Checkbox
347
+ checked={selectedRowKeys?.includes(kf.knownFactID)}
348
+ onChange={e => {
349
+ if (e.target.checked) {
350
+ setSelectedRowKeys(srk => [
351
+ ...new Set([...srk, kf.knownFactID]),
352
+ ]);
353
+ } else {
354
+ setSelectedRowKeys(
355
+ srk =>
356
+ srk.filter(
357
+ key => key !== kf.knownFactID
358
+ ) as string[]
359
+ );
360
+ }
361
+ }}
362
+ />
363
+ </th>
364
+ <td>{kf.text}</td>
365
+ <td className="mobile-hidden">
366
+ <span className="memori--table--date">
367
+ {kf.creationTimestamp
368
+ ? new Intl.DateTimeFormat('it', {
369
+ dateStyle: 'short',
370
+ timeStyle: 'short',
371
+ }).format(new Date(kf.creationTimestamp))
372
+ : '-'}
373
+ </span>
374
+ </td>
375
+ <td className="memori--table--column-right">
376
+ <div className="memori--table--action-column">
377
+ <Button
378
+ danger
379
+ ghost
380
+ shape="circle"
381
+ icon={<Delete />}
382
+ disabled={selectedRowKeys?.length > 0}
383
+ title={t('delete') || 'Delete'}
384
+ onClick={() => setDeleteModalVisibleFor(kf.knownFactID)}
385
+ />
386
+ <Modal
387
+ className="memori-known-facts-modal"
388
+ open={deleteModalVisibleFor === kf.knownFactID}
389
+ closable
390
+ title={t('knownFacts.deleteConfirmTitle')}
391
+ description={t('knownFacts.deleteConfirmMessage')}
392
+ onClose={() => {
393
+ setDeleteModalVisibleFor(undefined);
394
+ }}
395
+ footer={
396
+ <>
397
+ <Button
398
+ ghost
399
+ onClick={() => {
400
+ setDeleteModalVisibleFor(undefined);
401
+ }}
402
+ >
403
+ {t('cancel')}
404
+ </Button>
405
+ <Button
406
+ primary
407
+ danger
408
+ onClick={async () => {
409
+ try {
410
+ const response = await deleteKnownFact(
411
+ sessionID,
412
+ kf.knownFactID
413
+ );
414
+ if (response.resultCode === 0) {
415
+ toast.success(t('knownFacts.deleteSuccess'));
416
+ setSelectedRowKeys([]);
417
+ fetchKnownFacts();
418
+ setDeleteModalVisibleFor(undefined);
419
+ } else {
420
+ console.error(response);
421
+ toast.error(
422
+ t(getErrori18nKey(response.resultCode), {
423
+ ns: 'common',
424
+ })
425
+ );
426
+ }
427
+ } catch (_e) {
428
+ let error = _e as Error;
429
+ toast.error(t('Error') + error.message);
430
+ }
431
+ }}
432
+ >
433
+ {t('confirm')}
434
+ </Button>
435
+ </>
436
+ }
437
+ />
438
+ </div>
439
+ </td>
440
+ </tr>
441
+ ))}
442
+ </tbody>
443
+ </table>
444
+ </Spin>
445
+ </Drawer>
446
+ );
447
+ };
448
+
449
+ export default KnownFacts;
@@ -0,0 +1,19 @@
1
+ // Jest Snapshot v1, https://goo.gl/fbAQLP
2
+
3
+ exports[`renders KnownFacts hidden unchanged 1`] = `<div />`;
4
+
5
+ exports[`renders KnownFacts visible unchanged 1`] = `
6
+ <div>
7
+ <div
8
+ style="position: fixed; top: 1px; left: 1px; width: 1px; height: 0px; padding: 0px; margin: -1px; overflow: hidden; clip: rect(0px, 0px, 0px, 0px); white-space: nowrap; border-width: 0px; display: none;"
9
+ />
10
+ </div>
11
+ `;
12
+
13
+ exports[`renders KnownFacts with data unchanged 1`] = `
14
+ <div>
15
+ <div
16
+ style="position: fixed; top: 1px; left: 1px; width: 1px; height: 0px; padding: 0px; margin: -1px; overflow: hidden; clip: rect(0px, 0px, 0px, 0px); white-space: nowrap; border-width: 0px; display: none;"
17
+ />
18
+ </div>
19
+ `;
@@ -49,6 +49,9 @@ import Avatar, { Props as AvatarProps } from '../Avatar/Avatar';
49
49
  import ChangeMode, { Props as ChangeModeProps } from '../ChangeMode/ChangeMode';
50
50
  import Header, { Props as HeaderProps } from '../Header/Header';
51
51
  import PoweredBy from '../PoweredBy/PoweredBy';
52
+ import AgeVerificationModal from '../AgeVerificationModal/AgeVerificationModal';
53
+ import SettingsDrawer from '../SettingsDrawer/SettingsDrawer';
54
+ import KnownFacts from '../KnownFacts/KnownFacts';
52
55
 
53
56
  // Layout
54
57
  import FullPageLayout from '../layouts/FullPage';
@@ -67,8 +70,6 @@ import {
67
70
  import { anonTag } from '../../helpers/constants';
68
71
  import { getErrori18nKey } from '../../helpers/error';
69
72
  import { getGamificationLevel } from '../../helpers/statistics';
70
- import AgeVerificationModal from '../AgeVerificationModal/AgeVerificationModal';
71
- import SettingsDrawer from '../SettingsDrawer/SettingsDrawer';
72
73
 
73
74
  // Widget utilities and helpers
74
75
  const getMemoriState = (integrationId?: string): object | null => {
@@ -453,6 +454,7 @@ const MemoriWidget = ({
453
454
  useState(false);
454
455
  const [showPositionDrawer, setShowPositionDrawer] = useState(false);
455
456
  const [showSettingsDrawer, setShowSettingsDrawer] = useState(false);
457
+ const [showKnownFactsDrawer, setShowKnownFactsDrawer] = useState(false);
456
458
  const [muteSpeaker, setMuteSpeaker] = useState(false);
457
459
  const [continuousSpeech, setContinuousSpeech] = useState(false);
458
460
  const [continuousSpeechTimeout, setContinuousSpeechTimeout] = useState(2);
@@ -2592,6 +2594,7 @@ const MemoriWidget = ({
2592
2594
  position,
2593
2595
  setShowPositionDrawer,
2594
2596
  setShowSettingsDrawer,
2597
+ setShowKnownFactsDrawer,
2595
2598
  showSpeaker: !!AZURE_COGNITIVE_SERVICES_TTS_KEY,
2596
2599
  speakerMuted: muteSpeaker || speakerMuted,
2597
2600
  setSpeakerMuted: mute => {
@@ -2613,6 +2616,8 @@ const MemoriWidget = ({
2613
2616
  showReload: selectedLayout === 'TOTEM',
2614
2617
  showClear,
2615
2618
  clearHistory: () => setHistory(h => h.slice(-1)),
2619
+ loginToken,
2620
+ sessionID: sessionId,
2616
2621
  };
2617
2622
 
2618
2623
  const avatarProps: AvatarProps = {
@@ -2905,6 +2910,16 @@ const MemoriWidget = ({
2905
2910
  additionalSettings={additionalSettings}
2906
2911
  />
2907
2912
  )}
2913
+
2914
+ {showKnownFactsDrawer && sessionId && (
2915
+ <KnownFacts
2916
+ apiURL={apiUrl}
2917
+ memori={memori}
2918
+ sessionID={sessionId}
2919
+ visible={showKnownFactsDrawer}
2920
+ closeDrawer={() => setShowKnownFactsDrawer(false)}
2921
+ />
2922
+ )}
2908
2923
  </div>
2909
2924
  );
2910
2925
  };
@@ -142,7 +142,9 @@ const SettingsDrawer = ({
142
142
  </div>
143
143
  <div className="memori-settings-drawer--field">
144
144
  <Checkbox
145
- label={t('write_and_speak.hideEmissionsLabel')}
145
+ label={
146
+ t('write_and_speak.hideEmissionsLabel') || 'Hide emissions'
147
+ }
146
148
  name="hideControls"
147
149
  checked={hideEmissions}
148
150
  onChange={e => {
@@ -209,8 +209,8 @@
209
209
  }
210
210
 
211
211
  .memori--deep-thought-disclaimer .memori-tooltip .memori-tooltip--trigger svg {
212
- width: 1.25em;
213
- height: 1.25em;
212
+ width: 1.5rem;
213
+ height: 1.5rem;
214
214
  padding: 5px;
215
215
  border: 1px solid #666;
216
216
  border-radius: 50%;
@@ -0,0 +1,28 @@
1
+ import React from 'react';
2
+
3
+ const ChevronLeft = ({
4
+ className,
5
+ title,
6
+ }: {
7
+ className?: string;
8
+ title?: string;
9
+ }) => (
10
+ <svg
11
+ {...(!title ? { 'aria-hidden': 'true' } : {})}
12
+ focusable="false"
13
+ role="img"
14
+ xmlns="http://www.w3.org/2000/svg"
15
+ viewBox="0 0 24 24"
16
+ fill="none"
17
+ stroke="currentColor"
18
+ strokeLinecap="round"
19
+ strokeLinejoin="round"
20
+ strokeWidth="2"
21
+ className={className}
22
+ aria-label={title}
23
+ >
24
+ <path d="M15 18L9 12 15 6"></path>
25
+ </svg>
26
+ );
27
+
28
+ export default ChevronLeft;
@@ -0,0 +1,28 @@
1
+ import React from 'react';
2
+
3
+ const ChevronRight = ({
4
+ className,
5
+ title,
6
+ }: {
7
+ className?: string;
8
+ title?: string;
9
+ }) => (
10
+ <svg
11
+ {...(!title ? { 'aria-hidden': 'true' } : {})}
12
+ focusable="false"
13
+ role="img"
14
+ xmlns="http://www.w3.org/2000/svg"
15
+ viewBox="0 0 24 24"
16
+ fill="none"
17
+ stroke="currentColor"
18
+ strokeLinecap="round"
19
+ strokeLinejoin="round"
20
+ strokeWidth="2"
21
+ className={className}
22
+ aria-label={title}
23
+ >
24
+ <path d="M9 18L15 12 9 6"></path>
25
+ </svg>
26
+ );
27
+
28
+ export default ChevronRight;
@@ -99,6 +99,34 @@
99
99
  border-radius: var(--memori-button-radius);
100
100
  }
101
101
 
102
+ .memori-button--danger {
103
+ border-color: var(--memori-error-color);
104
+ background: rgba(0, 0, 0, 0.02);
105
+ color: var(--memori-error-color);
106
+ }
107
+
108
+ .memori-button--danger:hover,
109
+ .memori-button--danger:focus {
110
+ border-color: var(--memori-error-color);
111
+ background-color: var(--memori-error-color);
112
+ color: #fff;
113
+ }
114
+
115
+ .memori-button--danger.memori-button--ghost {
116
+ border-color: transparent;
117
+ background: none;
118
+ box-shadow: none;
119
+ color: var(--memori-error-color);
120
+ }
121
+
122
+ .memori-button--danger.memori-button--ghost:hover,
123
+ .memori-button--danger.memori-button--ghost:focus {
124
+ border-color: var(--memori-error-color);
125
+ background: rgba(0, 0, 0, 0.02);
126
+ box-shadow: 0 2px 0 rgba(0, 0, 0, 0.02), 0 4px 8px rgba(0, 0, 0, 0.04);
127
+ color: var(--memori-error-color);
128
+ }
129
+
102
130
  .memori-button--circle {
103
131
  padding: 0.75em;
104
132
  border-radius: 50%;
@@ -129,4 +157,4 @@
129
157
  .memori-button[disabled] {
130
158
  cursor: not-allowed;
131
159
  opacity: 0.6;
132
- }
160
+ }