@memori.ai/memori-react 6.3.1 → 6.4.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 (86) hide show
  1. package/CHANGELOG.md +24 -0
  2. package/dist/components/Chat/Chat.js +1 -1
  3. package/dist/components/Chat/Chat.js.map +1 -1
  4. package/dist/components/ChatBubble/ChatBubble.css +16 -6
  5. package/dist/components/ChatBubble/ChatBubble.d.ts +2 -0
  6. package/dist/components/ChatBubble/ChatBubble.js +15 -7
  7. package/dist/components/ChatBubble/ChatBubble.js.map +1 -1
  8. package/dist/components/Header/Header.css +7 -1
  9. package/dist/components/KnownFacts/KnownFacts.js.map +1 -1
  10. package/dist/components/MemoriWidget/MemoriWidget.js +67 -2
  11. package/dist/components/MemoriWidget/MemoriWidget.js.map +1 -1
  12. package/dist/components/Snippet/Snippet.d.ts +3 -1
  13. package/dist/components/Snippet/Snippet.js +3 -3
  14. package/dist/components/Snippet/Snippet.js.map +1 -1
  15. package/dist/components/WhyThisAnswer/WhyThisAnswer.css +73 -0
  16. package/dist/components/WhyThisAnswer/WhyThisAnswer.d.ts +11 -0
  17. package/dist/components/WhyThisAnswer/WhyThisAnswer.js +62 -0
  18. package/dist/components/WhyThisAnswer/WhyThisAnswer.js.map +1 -0
  19. package/dist/components/icons/QuestionHelp.d.ts +5 -0
  20. package/dist/components/icons/QuestionHelp.js +6 -0
  21. package/dist/components/icons/QuestionHelp.js.map +1 -0
  22. package/dist/components/ui/Expandable.css +15 -0
  23. package/dist/components/ui/Expandable.d.ts +13 -0
  24. package/dist/components/ui/Expandable.js +44 -0
  25. package/dist/components/ui/Expandable.js.map +1 -0
  26. package/dist/components/ui/Table.css +2 -2
  27. package/dist/locales/en.json +3 -0
  28. package/dist/locales/it.json +3 -0
  29. package/dist/styles.css +5 -2
  30. package/esm/components/Chat/Chat.js +1 -1
  31. package/esm/components/Chat/Chat.js.map +1 -1
  32. package/esm/components/ChatBubble/ChatBubble.css +16 -6
  33. package/esm/components/ChatBubble/ChatBubble.d.ts +2 -0
  34. package/esm/components/ChatBubble/ChatBubble.js +11 -3
  35. package/esm/components/ChatBubble/ChatBubble.js.map +1 -1
  36. package/esm/components/Header/Header.css +7 -1
  37. package/esm/components/KnownFacts/KnownFacts.js.map +1 -1
  38. package/esm/components/MemoriWidget/MemoriWidget.js +67 -2
  39. package/esm/components/MemoriWidget/MemoriWidget.js.map +1 -1
  40. package/esm/components/Snippet/Snippet.d.ts +3 -1
  41. package/esm/components/Snippet/Snippet.js +3 -3
  42. package/esm/components/Snippet/Snippet.js.map +1 -1
  43. package/esm/components/WhyThisAnswer/WhyThisAnswer.css +73 -0
  44. package/esm/components/WhyThisAnswer/WhyThisAnswer.d.ts +11 -0
  45. package/esm/components/WhyThisAnswer/WhyThisAnswer.js +59 -0
  46. package/esm/components/WhyThisAnswer/WhyThisAnswer.js.map +1 -0
  47. package/esm/components/icons/QuestionHelp.d.ts +5 -0
  48. package/esm/components/icons/QuestionHelp.js +4 -0
  49. package/esm/components/icons/QuestionHelp.js.map +1 -0
  50. package/esm/components/ui/Expandable.css +15 -0
  51. package/esm/components/ui/Expandable.d.ts +13 -0
  52. package/esm/components/ui/Expandable.js +41 -0
  53. package/esm/components/ui/Expandable.js.map +1 -0
  54. package/esm/components/ui/Table.css +2 -2
  55. package/esm/locales/en.json +3 -0
  56. package/esm/locales/it.json +3 -0
  57. package/esm/styles.css +5 -2
  58. package/package.json +2 -2
  59. package/src/components/Chat/Chat.tsx +1 -0
  60. package/src/components/ChatBubble/ChatBubble.css +16 -6
  61. package/src/components/ChatBubble/ChatBubble.test.tsx +10 -1
  62. package/src/components/ChatBubble/ChatBubble.tsx +37 -7
  63. package/src/components/ChatBubble/__snapshots__/ChatBubble.test.tsx.snap +2 -2
  64. package/src/components/Header/Header.css +7 -1
  65. package/src/components/KnownFacts/KnownFacts.tsx +0 -78
  66. package/src/components/MemoriWidget/MemoriWidget.tsx +71 -2
  67. package/src/components/Snippet/Snippet.stories.tsx +16 -0
  68. package/src/components/Snippet/Snippet.test.tsx +30 -0
  69. package/src/components/Snippet/Snippet.tsx +20 -10
  70. package/src/components/Snippet/__snapshots__/Snippet.test.tsx.snap +168 -0
  71. package/src/components/WhyThisAnswer/WhyThisAnswer.css +73 -0
  72. package/src/components/WhyThisAnswer/WhyThisAnswer.stories.tsx +136 -0
  73. package/src/components/WhyThisAnswer/WhyThisAnswer.test.tsx +124 -0
  74. package/src/components/WhyThisAnswer/WhyThisAnswer.tsx +151 -0
  75. package/src/components/WhyThisAnswer/__snapshots__/WhyThisAnswer.test.tsx.snap +13 -0
  76. package/src/components/icons/QuestionHelp.tsx +30 -0
  77. package/src/components/ui/Expandable.css +15 -0
  78. package/src/components/ui/Expandable.stories.tsx +53 -0
  79. package/src/components/ui/Expandable.test.tsx +107 -0
  80. package/src/components/ui/Expandable.tsx +97 -0
  81. package/src/components/ui/Table.css +2 -2
  82. package/src/components/ui/__snapshots__/Expandable.test.tsx.snap +159 -0
  83. package/src/locales/en.json +3 -0
  84. package/src/locales/it.json +3 -0
  85. package/src/mocks/data.ts +58 -0
  86. package/src/styles.css +5 -2
@@ -0,0 +1,41 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { useEffect, useRef, useState } from 'react';
3
+ import Button from './Button';
4
+ import cx from 'classnames';
5
+ import { useTranslation } from 'react-i18next';
6
+ const Expandable = ({ rows, className, innerClassName, btnClassName, defaultExpanded = false, expandSymbol = () => '...', collapseSymbol = (lang) => lang === 'it' ? 'Mostra meno' : 'Show less', children, }) => {
7
+ const { i18n } = useTranslation();
8
+ const lang = i18n.language;
9
+ const collapseSymbolText = collapseSymbol(lang);
10
+ const expandSymbolText = expandSymbol(lang);
11
+ const [expanded, setExpanded] = useState(defaultExpanded);
12
+ const [needsExpanding, setNeedsExpanding] = useState(false);
13
+ const [rowHeight, setRowHeight] = useState(16);
14
+ const ref = useRef(null);
15
+ useEffect(() => {
16
+ if (ref.current) {
17
+ let height = ref.current.getBoundingClientRect().height;
18
+ let computedStyle = getComputedStyle(ref.current);
19
+ let elLineHeight = computedStyle.lineHeight;
20
+ let lineHeight = elLineHeight === 'normal' || !(elLineHeight === null || elLineHeight === void 0 ? void 0 : elLineHeight.length)
21
+ ? 1.2 * parseInt(computedStyle.fontSize, 10)
22
+ : parseInt(elLineHeight, 10);
23
+ console.table({
24
+ rows,
25
+ lineHeight,
26
+ height,
27
+ maxHeight: rows * lineHeight,
28
+ needsExpanding: height > rows * lineHeight,
29
+ });
30
+ setRowHeight(lineHeight);
31
+ if (height && height > rows * lineHeight) {
32
+ setNeedsExpanding(true);
33
+ }
34
+ }
35
+ }, [rows, ref.current]);
36
+ return (_jsxs("div", { className: cx('memori-expandable', className), children: [_jsx("div", { ref: ref, className: cx('memori-expandable--inner', innerClassName), style: {
37
+ maxHeight: expanded || !needsExpanding ? '9999px' : `${rowHeight * rows}px`,
38
+ }, children: children }), needsExpanding && !expanded && (_jsx(Button, { ghost: true, padded: false, className: btnClassName, onClick: () => setExpanded(true), children: expandSymbolText })), needsExpanding && expanded && (_jsx(Button, { ghost: true, padded: false, className: btnClassName, onClick: () => setExpanded(false), children: collapseSymbolText }))] }));
39
+ };
40
+ export default Expandable;
41
+ //# sourceMappingURL=Expandable.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Expandable.js","sourceRoot":"","sources":["../../../src/components/ui/Expandable.tsx"],"names":[],"mappings":"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"}
@@ -1,6 +1,6 @@
1
1
  table.memori--table {
2
2
  --memori-table-spacing: 1rem;
3
- --memori-table-border-color: hsl(205, 20%, 94%);
3
+ --memori-table-border-color: rgb(237, 240, 243);
4
4
  --memori-table-bg-color: rgb(246, 248, 249);
5
5
 
6
6
  margin: 1rem 0;
@@ -110,4 +110,4 @@ table.memori--table td.memori--table--column-right {
110
110
 
111
111
  .memori--table--date {
112
112
  white-space: nowrap;
113
- }
113
+ }
@@ -33,6 +33,7 @@
33
33
  "showTranslatedText": "Show translation",
34
34
  "exactPosition": "Exact position",
35
35
  "uncertain": "Uncertain",
36
+ "question": "Question",
36
37
  "nothingFound": "Nothing found",
37
38
  "venue": "Venue",
38
39
  "searchVenue": "Search venue...",
@@ -42,6 +43,8 @@
42
43
  "memoriBlockedReasonExceedChats": "because it has exceeded the monthly threshold of allowed chats.",
43
44
  "memoriBlockedGiverHelper": "You can still manage it as administrator, but other users will not be able to interact with it.",
44
45
  "generatedByAI": "Answer generated by AI, may occasionally generate incorrect informations",
46
+ "whyThisAnswer": "Why this answer?",
47
+ "whyThisAnswerHelper": "This answer was generated automatically by an artificial intelligence based on these verified contents.",
45
48
  "completionsEnabled": "Advanced AI, can respond with automatically generated answers that may sometimes contain incorrect information",
46
49
  "completionProviderDown": "This Twin is integrated with a generative AI from {{provider}}, but it is currently unavailable. Try again later.",
47
50
  "completionProviderFallbackName": "an external provider",
@@ -33,6 +33,7 @@
33
33
  "showTranslatedText": "Mostra traduzione",
34
34
  "exactPosition": "Posizione esatta",
35
35
  "uncertain": "Incertezza",
36
+ "question": "Domanda",
36
37
  "nothingFound": "Nessun risultato",
37
38
  "venue": "Luogo",
38
39
  "searchVenue": "Cerca luogo...",
@@ -42,6 +43,8 @@
42
43
  "memoriBlockedReasonExceedChats": "perchè ha superato la soglia mensile di chat ammesse.",
43
44
  "memoriBlockedGiverHelper": "Puoi sempre gestirlo in qualità di amministratore, ma altri utenti non potranno interrogarlo.",
44
45
  "generatedByAI": "Risposta generata da IA, può talvolta generare informazioni non corrette",
46
+ "whyThisAnswer": "Perché questa risposta?",
47
+ "whyThisAnswerHelper": "Questa risposta è stata generata automaticamente da un'intelligenza artificiale sulla base di questi contenuti verificati.",
45
48
  "completionsEnabled": "IA evoluta, può rispondere con risposte generate automaticamente che talvolta potrebbero contenere informazioni non corrette",
46
49
  "completionProviderDown": "Questo Twin è integrato con una IA generativa di {{provider}}, ma al momento non è disponibile. Riprova più tardi.",
47
50
  "completionProviderFallbackName": "un provider esterno",
package/esm/styles.css CHANGED
@@ -7,6 +7,7 @@
7
7
  @import url('./components/ui/Tooltip.css');
8
8
  @import url('./components/ui/Select.css');
9
9
  @import url('./components/ui/Table.css');
10
+ @import url('./components/ui/Expandable.css');
10
11
 
11
12
  @import url('./components/CompletionProviderStatus/CompletionProviderStatus.css');
12
13
  @import url('./components/PoweredBy/PoweredBy.css');
@@ -41,6 +42,7 @@
41
42
  @import url('./components/KnownFacts/KnownFacts.css');
42
43
  @import url('./components/LoginDrawer/LoginDrawer.css');
43
44
  @import url('./components/VenueWidget/VenueWidget.css');
45
+ @import url('./components/WhyThisAnswer/WhyThisAnswer.css');
44
46
  @import url('./components/MemoriWidget/MemoriWidget.css');
45
47
 
46
48
  @import url('https://fonts.bunny.net/css?family=lexend-deca:200,400,700');
@@ -76,11 +78,12 @@ body.sb-show-main #root,
76
78
  --memori-chat-bubble-bg: #fff;
77
79
  --memori-chat-user-bubble-bg: var(--memori-primary);
78
80
  --memori-text-color: #000;
81
+ --memori-border-radius: 5px;
79
82
  --memori-button-bg: #fff;
80
83
  --memori-button-text: #000;
81
84
  --memori-button-padding: 0.5rem 1.5rem;
82
85
  --memori-button-border-color: #d9d9d9;
83
- --memori-button-radius: 5px;
86
+ --memori-button-radius: var(--memori-border-radius);
84
87
  --memori-button-box-shadow: 0 2px 0 rgba(0, 0, 0, 0.02);
85
88
  --memori-blur-background: 0px;
86
89
  --memori-drawer--width: 80%;
@@ -99,4 +102,4 @@ body.sb-show-main #root,
99
102
  .mobile-hidden {
100
103
  display: none;
101
104
  }
102
- }
105
+ }
package/package.json CHANGED
@@ -1,5 +1,5 @@
1
1
  {
2
- "version": "6.3.1",
2
+ "version": "6.4.0",
3
3
  "name": "@memori.ai/memori-react",
4
4
  "author": "Memori Srl",
5
5
  "main": "dist/index.js",
@@ -291,7 +291,7 @@
291
291
  },
292
292
  "dependencies": {
293
293
  "@headlessui/react": "1.7.4",
294
- "@memori.ai/memori-api-client": "^4.1.0",
294
+ "@memori.ai/memori-api-client": "^4.1.2",
295
295
  "@react-three/drei": "8.20.2",
296
296
  "@react-three/fiber": "7.0.25",
297
297
  "classnames": "2.3.2",
@@ -202,6 +202,7 @@ const Chat: React.FC<Props> = ({
202
202
  tenant={tenant}
203
203
  baseUrl={baseUrl}
204
204
  apiUrl={apiUrl}
205
+ sessionID={sessionID}
205
206
  simulateUserPrompt={simulateUserPrompt}
206
207
  showAIicon={showAIicon}
207
208
  showFeedback={
@@ -146,17 +146,22 @@
146
146
  margin-left: auto;
147
147
  }
148
148
 
149
- .memori-chat--bubble.memori-chat--with-addon .memori-chat--bubble-ai-icon {
149
+ .memori-chat--bubble.memori-chat--with-addon .memori-chat--bubble-action-icon {
150
150
  display: flex;
151
151
  justify-content: flex-end;
152
- padding: 3px;
152
+ padding: 0;
153
153
  text-align: right;
154
154
  }
155
155
 
156
- .memori-chat--bubble.memori-chat--with-addon .memori-chat--bubble-ai-icon svg {
156
+ .memori-chat--bubble.memori-chat--with-addon .memori-chat--bubble-action-icon.memori-chat--bubble-action-icon--ai {
157
+ padding: 3px;
158
+ }
159
+
160
+ .memori-chat--bubble.memori-chat--with-addon .memori-chat--bubble-action-icon svg {
157
161
  overflow: visible;
158
- width: 0.85rem;
159
- height: 0.85rem;
162
+ width: 1rem;
163
+ height: 1rem;
164
+ color: #000;
160
165
  }
161
166
 
162
167
  .memori-chat--bubble-addon .memori-chat--feedback {
@@ -180,6 +185,11 @@
180
185
  height: 0.9rem;
181
186
  }
182
187
 
188
+ .memori-chat--bubble.memori-chat--with-addon .memori-chat--bubble-action-icon.memori-chat--bubble-action-icon--ai svg {
189
+ width: 0.85rem;
190
+ height: 0.85rem;
191
+ }
192
+
183
193
  .memori-chat--bubble-addon-separator {
184
194
  width: 1px;
185
195
  height: 1.5em;
@@ -260,4 +270,4 @@
260
270
  30% {
261
271
  transform: translateY(-10px);
262
272
  }
263
- }
273
+ }
@@ -1,13 +1,14 @@
1
1
  import React from 'react';
2
2
  import { render } from '@testing-library/react';
3
3
  import ChatBubble from './ChatBubble';
4
- import { memori, tenant } from '../../mocks/data';
4
+ import { memori, tenant, sessionID } from '../../mocks/data';
5
5
 
6
6
  it('renders ChatBubble unchanged', () => {
7
7
  const { container } = render(
8
8
  <ChatBubble
9
9
  memori={memori}
10
10
  tenant={tenant}
11
+ sessionID={sessionID}
11
12
  message={{
12
13
  fromUser: false,
13
14
  text: 'Proin libero ante, dignissim sit amet turpis a, pretium condimentum dolor.',
@@ -25,6 +26,7 @@ it('renders ChatBubble with initial msg unchanged', () => {
25
26
  <ChatBubble
26
27
  memori={memori}
27
28
  tenant={tenant}
29
+ sessionID={sessionID}
28
30
  message={{
29
31
  fromUser: false,
30
32
  text: 'Proin libero ante, dignissim sit amet turpis a, pretium condimentum dolor.',
@@ -42,6 +44,7 @@ it('renders ChatBubble with user msg unchanged', () => {
42
44
  <ChatBubble
43
45
  memori={memori}
44
46
  tenant={tenant}
47
+ sessionID={sessionID}
45
48
  message={{
46
49
  fromUser: true,
47
50
  text: 'Proin libero ante, dignissim sit amet turpis a, pretium condimentum dolor.',
@@ -59,6 +62,7 @@ it('renders ChatBubble with msg generated by AI unchanged', () => {
59
62
  <ChatBubble
60
63
  memori={memori}
61
64
  tenant={tenant}
65
+ sessionID={sessionID}
62
66
  message={{
63
67
  fromUser: true,
64
68
  text: 'Proin libero ante, dignissim sit amet turpis a, pretium condimentum dolor.',
@@ -80,6 +84,7 @@ it('renders ChatBubble with msg from BoE expert unchanged', () => {
80
84
  enableBoardOfExperts: true,
81
85
  }}
82
86
  tenant={tenant}
87
+ sessionID={sessionID}
83
88
  apiUrl="https://backend.memori.ai"
84
89
  experts={[
85
90
  {
@@ -109,6 +114,7 @@ it('renders ChatBubble from user with avatar unchanged', () => {
109
114
  <ChatBubble
110
115
  memori={memori}
111
116
  tenant={tenant}
117
+ sessionID={sessionID}
112
118
  user={{ avatarURL: 'https://picsum.photos/200' }}
113
119
  message={{
114
120
  fromUser: true,
@@ -127,6 +133,7 @@ it('renders ChatBubble from user with custom avatar unchanged', () => {
127
133
  <ChatBubble
128
134
  memori={memori}
129
135
  tenant={tenant}
136
+ sessionID={sessionID}
130
137
  userAvatar="https://picsum.photos/200"
131
138
  message={{
132
139
  fromUser: true,
@@ -145,6 +152,7 @@ it('renders ChatBubble from user with avatar as react element unchanged', () =>
145
152
  <ChatBubble
146
153
  memori={memori}
147
154
  tenant={tenant}
155
+ sessionID={sessionID}
148
156
  user={{ avatarURL: 'https://picsum.photos/200' }}
149
157
  userAvatar={<span>USER</span>}
150
158
  message={{
@@ -164,6 +172,7 @@ it('renders ChatBubble with markdown unchanged', () => {
164
172
  <ChatBubble
165
173
  memori={memori}
166
174
  tenant={tenant}
175
+ sessionID={sessionID}
167
176
  message={{
168
177
  fromUser: false,
169
178
  text: '## Test\n\nEcco tutte le possibili personalizzazioni che puoi applicare:\n\n- **Colletto**:\n - Girocollo\n - Scollo a V\n\n- **Manica**:\n - Manica Lunga\n - Manica Corta\n\n- **Taglia**:\n - XS\n - S\n - M\n - L\n - XL\n - XXL\n - 3XL\n\n- **Posizione Stampa**:\n - Fronte Petto\n - Retro Schiena\n - Fronte DX\n - Fronte SX\n\n- **Generazione Immagine**:\n - Prompt generazione immagine\n\nSeleziona le personalizzazioni che desideri applicare.\n\n[Vedi altro](https://memori.ai)',
@@ -1,4 +1,4 @@
1
- import React from 'react';
1
+ import React, { useState } from 'react';
2
2
  import cx from 'classnames';
3
3
  import {
4
4
  ExpertReference,
@@ -18,14 +18,19 @@ import { useTranslation } from 'react-i18next';
18
18
  import { marked } from 'marked';
19
19
  import { sanitize } from 'dompurify';
20
20
  import { cleanUrl } from '../../helpers/utils';
21
+ import Button from '../ui/Button';
22
+ import QuestionHelp from '../icons/QuestionHelp';
23
+ import WhyThisAnswer from '../WhyThisAnswer/WhyThisAnswer';
21
24
 
22
25
  export interface Props {
23
26
  message: Message;
24
27
  memori: Memori;
28
+ sessionID: string;
25
29
  tenant?: Tenant;
26
30
  baseUrl?: string;
27
31
  apiUrl?: string;
28
32
  showFeedback?: boolean;
33
+ showWhyThisAnswer?: boolean;
29
34
  simulateUserPrompt?: (msg: string) => void;
30
35
  showAIicon?: boolean;
31
36
  isFirst?: boolean;
@@ -61,7 +66,9 @@ const ChatBubble: React.FC<Props> = ({
61
66
  tenant,
62
67
  baseUrl,
63
68
  apiUrl,
69
+ sessionID,
64
70
  showFeedback,
71
+ showWhyThisAnswer = true,
65
72
  simulateUserPrompt,
66
73
  showAIicon = true,
67
74
  isFirst = false,
@@ -70,6 +77,7 @@ const ChatBubble: React.FC<Props> = ({
70
77
  experts,
71
78
  }) => {
72
79
  const { t } = useTranslation();
80
+ const [showingWhyThisAnswer, setShowingWhyThisAnswer] = useState(false);
73
81
 
74
82
  const renderedText = sanitize(
75
83
  (marked.parse(message.translatedText || message.text) as string)
@@ -187,11 +195,6 @@ const ChatBubble: React.FC<Props> = ({
187
195
  message.fromUser ? '30' : '-30'
188
196
  }`}
189
197
  >
190
- {/*(message.translatedText || message.text)
191
- .split(/\r\n|\r|\n/)
192
- .map((row, index) => (
193
- <p key={index}>{row}</p>
194
- ))*/}
195
198
  <div dangerouslySetInnerHTML={{ __html: renderedText }} />
196
199
  {((message.generatedByAI && showAIicon) ||
197
200
  (showFeedback && simulateUserPrompt)) && (
@@ -211,13 +214,30 @@ const ChatBubble: React.FC<Props> = ({
211
214
  <Tooltip
212
215
  align="left"
213
216
  content={t('generatedByAI')}
214
- className="memori-chat--bubble-ai-icon"
217
+ className="memori-chat--bubble-action-icon memori-chat--bubble-action-icon--ai"
215
218
  >
216
219
  <span>
217
220
  <AI title={t('generatedByAI') || undefined} />
218
221
  </span>
219
222
  </Tooltip>
220
223
  )}
224
+
225
+ {!message.fromUser &&
226
+ message.questionAnswered &&
227
+ apiUrl &&
228
+ showWhyThisAnswer && (
229
+ <Button
230
+ ghost
231
+ shape="circle"
232
+ title={t('whyThisAnswer') || undefined}
233
+ className="memori-chat--bubble-action-icon"
234
+ onClick={() => setShowingWhyThisAnswer(true)}
235
+ disabled={showingWhyThisAnswer}
236
+ icon={
237
+ <QuestionHelp title={t('whyThisAnswer') || undefined} />
238
+ }
239
+ />
240
+ )}
221
241
  </div>
222
242
  )}
223
243
  </Transition.Child>
@@ -284,6 +304,16 @@ const ChatBubble: React.FC<Props> = ({
284
304
  </>
285
305
  )}
286
306
  </Transition>
307
+
308
+ {showingWhyThisAnswer && apiUrl && (
309
+ <WhyThisAnswer
310
+ visible={showingWhyThisAnswer}
311
+ message={message}
312
+ closeDrawer={() => setShowingWhyThisAnswer(false)}
313
+ apiURL={apiUrl}
314
+ sessionID={sessionID}
315
+ />
316
+ )}
287
317
  </>
288
318
  );
289
319
  };
@@ -339,7 +339,7 @@ exports[`renders ChatBubble with msg from BoE expert unchanged 1`] = `
339
339
  class="memori-chat--bubble-addon"
340
340
  >
341
341
  <div
342
- class="memori-tooltip memori-tooltip--align-left memori-chat--bubble-ai-icon"
342
+ class="memori-tooltip memori-tooltip--align-left memori-chat--bubble-action-icon memori-chat--bubble-action-icon--ai"
343
343
  >
344
344
  <div
345
345
  class="memori-tooltip--content"
@@ -421,7 +421,7 @@ exports[`renders ChatBubble with msg generated by AI unchanged 1`] = `
421
421
  class="memori-chat--bubble-addon"
422
422
  >
423
423
  <div
424
- class="memori-tooltip memori-tooltip--align-left memori-chat--bubble-ai-icon"
424
+ class="memori-tooltip memori-tooltip--align-left memori-chat--bubble-action-icon memori-chat--bubble-action-icon--ai"
425
425
  >
426
426
  <div
427
427
  class="memori-tooltip--content"
@@ -63,6 +63,12 @@
63
63
  white-space: nowrap;
64
64
  }
65
65
 
66
+ @media (max-width: 768px) {
67
+ .memori-header--position .memori-header--position-placeName {
68
+ display: none;
69
+ }
70
+ }
71
+
66
72
  .memori-header--position .memori-header--button {
67
73
  margin-right: 0.5rem;
68
74
  margin-left: 0.5rem;
@@ -76,4 +82,4 @@
76
82
 
77
83
  .memori-header .memori-header--button--position {
78
84
  margin-right: 0.25rem;
79
- }
85
+ }
@@ -87,84 +87,6 @@ const KnownFacts = ({
87
87
  const [selectedRowKeys, setSelectedRowKeys] = useState<(string | number)[]>(
88
88
  []
89
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
90
 
169
91
  return (
170
92
  <Drawer
@@ -688,6 +688,13 @@ const MemoriWidget = ({
688
688
  emitter: currentState.emitter,
689
689
  media: currentState.media,
690
690
  fromUser: false,
691
+ questionAnswered: msg,
692
+ contextVars: currentState.contextVars,
693
+ date: currentState.currentDate,
694
+ placeName: currentState.currentPlaceName,
695
+ placeLatitude: currentState.currentLatitude,
696
+ placeLongitude: currentState.currentLongitude,
697
+ placeUncertaintyKm: currentState.currentUncertaintyKm,
691
698
  });
692
699
  speak(emission);
693
700
  }
@@ -717,6 +724,13 @@ const MemoriWidget = ({
717
724
  emitter: currentState.emitter,
718
725
  media: currentState.media,
719
726
  fromUser: false,
727
+ questionAnswered: msg,
728
+ contextVars: currentState.contextVars,
729
+ date: currentState.currentDate,
730
+ placeName: currentState.currentPlaceName,
731
+ placeLatitude: currentState.currentLatitude,
732
+ placeLongitude: currentState.currentLongitude,
733
+ placeUncertaintyKm: currentState.currentUncertaintyKm,
720
734
  });
721
735
  speak(emission);
722
736
  }
@@ -736,7 +750,7 @@ const MemoriWidget = ({
736
750
  !instruct &&
737
751
  isMultilanguageEnabled
738
752
  ) {
739
- translateDialogState(currentState, userLang).then(ts => {
753
+ translateDialogState(currentState, userLang, msg).then(ts => {
740
754
  if (ts.emission) {
741
755
  speak(ts.emission);
742
756
  }
@@ -753,7 +767,14 @@ const MemoriWidget = ({
753
767
  emitter: currentState.emitter,
754
768
  media: currentState.media,
755
769
  fromUser: false,
770
+ questionAnswered: msg,
756
771
  generatedByAI: !!currentState.completion,
772
+ contextVars: currentState.contextVars,
773
+ date: currentState.currentDate,
774
+ placeName: currentState.currentPlaceName,
775
+ placeLatitude: currentState.currentLatitude,
776
+ placeLongitude: currentState.currentLongitude,
777
+ placeUncertaintyKm: currentState.currentUncertaintyKm,
757
778
  });
758
779
  speak(emission);
759
780
  }
@@ -794,7 +815,11 @@ const MemoriWidget = ({
794
815
  /**
795
816
  * Traduzioni istantanee
796
817
  */
797
- const translateDialogState = async (state: DialogState, userLang: string) => {
818
+ const translateDialogState = async (
819
+ state: DialogState,
820
+ userLang: string,
821
+ msg?: string
822
+ ) => {
798
823
  const emission = state.emission ?? currentDialogState?.emission;
799
824
 
800
825
  let translatedState = { ...state };
@@ -813,6 +838,13 @@ const MemoriWidget = ({
813
838
  emitter: state.emitter,
814
839
  media: state.media,
815
840
  fromUser: false,
841
+ questionAnswered: msg,
842
+ contextVars: state.contextVars,
843
+ date: state.currentDate,
844
+ placeName: state.currentPlaceName,
845
+ placeLatitude: state.currentLatitude,
846
+ placeLongitude: state.currentLongitude,
847
+ placeUncertaintyKm: state.currentUncertaintyKm,
816
848
  };
817
849
  }
818
850
  } else {
@@ -853,7 +885,14 @@ const MemoriWidget = ({
853
885
  emitter: state.emitter,
854
886
  media: state.media,
855
887
  fromUser: false,
888
+ questionAnswered: msg,
856
889
  generatedByAI: !!state.completion,
890
+ contextVars: state.contextVars,
891
+ date: state.currentDate,
892
+ placeName: state.currentPlaceName,
893
+ placeLatitude: state.currentLatitude,
894
+ placeLongitude: state.currentLongitude,
895
+ placeUncertaintyKm: state.currentUncertaintyKm,
857
896
  };
858
897
  }
859
898
 
@@ -1086,6 +1125,12 @@ const MemoriWidget = ({
1086
1125
  media: currentState.media,
1087
1126
  fromUser: false,
1088
1127
  initial: true,
1128
+ contextVars: currentState.contextVars,
1129
+ date: currentState.currentDate,
1130
+ placeName: currentState.currentPlaceName,
1131
+ placeLatitude: currentState.currentLatitude,
1132
+ placeLongitude: currentState.currentLongitude,
1133
+ placeUncertaintyKm: currentState.currentUncertaintyKm,
1089
1134
  },
1090
1135
  ])
1091
1136
  : pushMessage({
@@ -1094,6 +1139,12 @@ const MemoriWidget = ({
1094
1139
  media: currentState.media,
1095
1140
  fromUser: false,
1096
1141
  initial: true,
1142
+ contextVars: currentState.contextVars,
1143
+ date: currentState.currentDate,
1144
+ placeName: currentState.currentPlaceName,
1145
+ placeLatitude: currentState.currentLatitude,
1146
+ placeLongitude: currentState.currentLongitude,
1147
+ placeUncertaintyKm: currentState.currentUncertaintyKm,
1097
1148
  });
1098
1149
  }
1099
1150
  }
@@ -1373,6 +1424,12 @@ const MemoriWidget = ({
1373
1424
  media: currentState.media,
1374
1425
  fromUser: false,
1375
1426
  generatedByAI: !!currentState.completion,
1427
+ contextVars: currentState.contextVars,
1428
+ date: currentState.currentDate,
1429
+ placeName: currentState.currentPlaceName,
1430
+ placeLatitude: currentState.currentLatitude,
1431
+ placeLongitude: currentState.currentLongitude,
1432
+ placeUncertaintyKm: currentState.currentUncertaintyKm,
1376
1433
  });
1377
1434
  speak(emission);
1378
1435
  setCurrentDialogState({
@@ -2263,6 +2320,12 @@ const MemoriWidget = ({
2263
2320
  emitter: currentState.emitter,
2264
2321
  media: currentState.media,
2265
2322
  fromUser: false,
2323
+ contextVars: currentState.contextVars,
2324
+ date: currentState.currentDate,
2325
+ placeName: currentState.currentPlaceName,
2326
+ placeLatitude: currentState.currentLatitude,
2327
+ placeLongitude: currentState.currentLongitude,
2328
+ placeUncertaintyKm: currentState.currentUncertaintyKm,
2266
2329
  });
2267
2330
  }
2268
2331
  } else {
@@ -2277,6 +2340,12 @@ const MemoriWidget = ({
2277
2340
  emitter: currentState.emitter,
2278
2341
  media: currentState.media,
2279
2342
  fromUser: false,
2343
+ contextVars: currentState.contextVars,
2344
+ date: currentState.currentDate,
2345
+ placeName: currentState.currentPlaceName,
2346
+ placeLatitude: currentState.currentLatitude,
2347
+ placeLongitude: currentState.currentLongitude,
2348
+ placeUncertaintyKm: currentState.currentUncertaintyKm,
2280
2349
  });
2281
2350
  }
2282
2351
  }