@memori.ai/memori-react 8.15.0 → 8.16.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 (166) hide show
  1. package/CHANGELOG.md +33 -0
  2. package/dist/components/Chat/Chat.css +2 -1
  3. package/dist/components/Chat/Chat.js +17 -17
  4. package/dist/components/Chat/Chat.js.map +1 -1
  5. package/dist/components/ChatBubble/ChatBubble.css +1 -1
  6. package/dist/components/ContentPreviewModal/ContentPreviewModal.css +114 -0
  7. package/dist/components/ContentPreviewModal/ContentPreviewModal.d.ts +14 -0
  8. package/dist/components/ContentPreviewModal/ContentPreviewModal.js +18 -0
  9. package/dist/components/ContentPreviewModal/ContentPreviewModal.js.map +1 -0
  10. package/dist/components/ContentPreviewModal/index.d.ts +2 -0
  11. package/dist/components/ContentPreviewModal/index.js +9 -0
  12. package/dist/components/ContentPreviewModal/index.js.map +1 -0
  13. package/dist/components/FilePreview/FilePreview.css +1 -1
  14. package/dist/components/FilePreview/FilePreview.js +43 -13
  15. package/dist/components/FilePreview/FilePreview.js.map +1 -1
  16. package/dist/components/MediaWidget/DocumentCard.d.ts +3 -0
  17. package/dist/components/MediaWidget/DocumentCard.js +9 -0
  18. package/dist/components/MediaWidget/DocumentCard.js.map +1 -0
  19. package/dist/components/MediaWidget/MediaItemWidget.css +946 -19
  20. package/dist/components/MediaWidget/MediaItemWidget.d.ts +5 -36
  21. package/dist/components/MediaWidget/MediaItemWidget.js +295 -198
  22. package/dist/components/MediaWidget/MediaItemWidget.js.map +1 -1
  23. package/dist/components/MediaWidget/MediaItemWidget.types.d.ts +62 -0
  24. package/dist/components/MediaWidget/MediaItemWidget.types.js +3 -0
  25. package/dist/components/MediaWidget/MediaItemWidget.types.js.map +1 -0
  26. package/dist/components/MediaWidget/MediaItemWidget.utils.d.ts +23 -0
  27. package/dist/components/MediaWidget/MediaItemWidget.utils.js +162 -0
  28. package/dist/components/MediaWidget/MediaItemWidget.utils.js.map +1 -0
  29. package/dist/components/MediaWidget/MediaPreviewModal.d.ts +15 -0
  30. package/dist/components/MediaWidget/MediaPreviewModal.js +162 -0
  31. package/dist/components/MediaWidget/MediaPreviewModal.js.map +1 -0
  32. package/dist/components/MediaWidget/MediaWidget.js +1 -2
  33. package/dist/components/MediaWidget/MediaWidget.js.map +1 -1
  34. package/dist/components/Snippet/Snippet.css +64 -33
  35. package/dist/components/Snippet/Snippet.js +17 -4
  36. package/dist/components/Snippet/Snippet.js.map +1 -1
  37. package/dist/components/StartPanel/StartPanel.js +1 -2
  38. package/dist/components/StartPanel/StartPanel.js.map +1 -1
  39. package/dist/components/UploadButton/UploadButton.css +0 -5
  40. package/dist/components/layouts/WebsiteAssistant.js +8 -8
  41. package/dist/components/layouts/WebsiteAssistant.js.map +1 -1
  42. package/dist/components/layouts/chat.css +1 -1
  43. package/dist/components/layouts/website-assistant.css +405 -197
  44. package/dist/helpers/constants.js +0 -7
  45. package/dist/helpers/constants.js.map +1 -1
  46. package/dist/helpers/utils.d.ts +1 -0
  47. package/dist/helpers/utils.js +3 -1
  48. package/dist/helpers/utils.js.map +1 -1
  49. package/dist/index.js +50 -6
  50. package/dist/index.js.map +1 -1
  51. package/dist/styles.css +0 -2
  52. package/dist/version.d.ts +1 -0
  53. package/dist/version.js +5 -0
  54. package/dist/version.js.map +1 -0
  55. package/esm/components/Chat/Chat.css +2 -1
  56. package/esm/components/Chat/Chat.js +17 -17
  57. package/esm/components/Chat/Chat.js.map +1 -1
  58. package/esm/components/ChatBubble/ChatBubble.css +1 -1
  59. package/esm/components/ContentPreviewModal/ContentPreviewModal.css +114 -0
  60. package/esm/components/ContentPreviewModal/ContentPreviewModal.d.ts +14 -0
  61. package/esm/components/ContentPreviewModal/ContentPreviewModal.js +15 -0
  62. package/esm/components/ContentPreviewModal/ContentPreviewModal.js.map +1 -0
  63. package/esm/components/ContentPreviewModal/index.d.ts +2 -0
  64. package/esm/components/ContentPreviewModal/index.js +2 -0
  65. package/esm/components/ContentPreviewModal/index.js.map +1 -0
  66. package/esm/components/FilePreview/FilePreview.css +1 -1
  67. package/esm/components/FilePreview/FilePreview.js +44 -14
  68. package/esm/components/FilePreview/FilePreview.js.map +1 -1
  69. package/esm/components/MediaWidget/DocumentCard.d.ts +3 -0
  70. package/esm/components/MediaWidget/DocumentCard.js +5 -0
  71. package/esm/components/MediaWidget/DocumentCard.js.map +1 -0
  72. package/esm/components/MediaWidget/MediaItemWidget.css +946 -19
  73. package/esm/components/MediaWidget/MediaItemWidget.d.ts +5 -36
  74. package/esm/components/MediaWidget/MediaItemWidget.js +296 -197
  75. package/esm/components/MediaWidget/MediaItemWidget.js.map +1 -1
  76. package/esm/components/MediaWidget/MediaItemWidget.types.d.ts +62 -0
  77. package/esm/components/MediaWidget/MediaItemWidget.types.js +2 -0
  78. package/esm/components/MediaWidget/MediaItemWidget.types.js.map +1 -0
  79. package/esm/components/MediaWidget/MediaItemWidget.utils.d.ts +23 -0
  80. package/esm/components/MediaWidget/MediaItemWidget.utils.js +149 -0
  81. package/esm/components/MediaWidget/MediaItemWidget.utils.js.map +1 -0
  82. package/esm/components/MediaWidget/MediaPreviewModal.d.ts +15 -0
  83. package/esm/components/MediaWidget/MediaPreviewModal.js +157 -0
  84. package/esm/components/MediaWidget/MediaPreviewModal.js.map +1 -0
  85. package/esm/components/MediaWidget/MediaWidget.js +1 -2
  86. package/esm/components/MediaWidget/MediaWidget.js.map +1 -1
  87. package/esm/components/Snippet/Snippet.css +64 -33
  88. package/esm/components/Snippet/Snippet.js +18 -5
  89. package/esm/components/Snippet/Snippet.js.map +1 -1
  90. package/esm/components/StartPanel/StartPanel.js +1 -2
  91. package/esm/components/StartPanel/StartPanel.js.map +1 -1
  92. package/esm/components/UploadButton/UploadButton.css +0 -5
  93. package/esm/components/layouts/WebsiteAssistant.js +8 -8
  94. package/esm/components/layouts/WebsiteAssistant.js.map +1 -1
  95. package/esm/components/layouts/chat.css +1 -1
  96. package/esm/components/layouts/website-assistant.css +405 -197
  97. package/esm/helpers/constants.js +0 -7
  98. package/esm/helpers/constants.js.map +1 -1
  99. package/esm/helpers/utils.d.ts +1 -0
  100. package/esm/helpers/utils.js +1 -0
  101. package/esm/helpers/utils.js.map +1 -1
  102. package/esm/index.js +50 -6
  103. package/esm/index.js.map +1 -1
  104. package/esm/styles.css +0 -2
  105. package/esm/version.d.ts +1 -0
  106. package/esm/version.js +2 -0
  107. package/esm/version.js.map +1 -0
  108. package/package.json +5 -3
  109. package/src/components/Chat/Chat.css +2 -1
  110. package/src/components/Chat/Chat.stories.tsx +124 -0
  111. package/src/components/Chat/Chat.tsx +72 -71
  112. package/src/components/Chat/__snapshots__/Chat.test.tsx.snap +567 -1034
  113. package/src/components/ChatBubble/ChatBubble.css +1 -1
  114. package/src/components/ContentPreviewModal/ContentPreviewModal.css +114 -0
  115. package/src/components/ContentPreviewModal/ContentPreviewModal.tsx +69 -0
  116. package/src/components/ContentPreviewModal/index.ts +2 -0
  117. package/src/components/FilePreview/FilePreview.css +1 -1
  118. package/src/components/FilePreview/FilePreview.tsx +60 -37
  119. package/src/components/FilePreview/__snapshots__/FilePreview.test.tsx.snap +15 -105
  120. package/src/components/MediaWidget/DocumentCard.test.tsx +45 -0
  121. package/src/components/MediaWidget/DocumentCard.tsx +19 -0
  122. package/src/components/MediaWidget/MediaItemWidget.css +946 -19
  123. package/src/components/MediaWidget/MediaItemWidget.test.tsx +89 -1
  124. package/src/components/MediaWidget/MediaItemWidget.tsx +734 -461
  125. package/src/components/MediaWidget/MediaItemWidget.types.ts +65 -0
  126. package/src/components/MediaWidget/MediaItemWidget.utils.test.ts +324 -0
  127. package/src/components/MediaWidget/MediaItemWidget.utils.ts +194 -0
  128. package/src/components/MediaWidget/MediaPreviewModal.test.tsx +271 -0
  129. package/src/components/MediaWidget/MediaPreviewModal.tsx +423 -0
  130. package/src/components/MediaWidget/MediaWidget.stories.tsx +193 -0
  131. package/src/components/MediaWidget/MediaWidget.tsx +2 -4
  132. package/src/components/MediaWidget/__snapshots__/DocumentCard.test.tsx.snap +24 -0
  133. package/src/components/MediaWidget/__snapshots__/MediaItemWidget.test.tsx.snap +162 -170
  134. package/src/components/MediaWidget/__snapshots__/MediaWidget.test.tsx.snap +21 -63
  135. package/src/components/Snippet/Snippet.css +64 -33
  136. package/src/components/Snippet/Snippet.tsx +30 -21
  137. package/src/components/Snippet/__snapshots__/Snippet.test.tsx.snap +314 -297
  138. package/src/components/StartPanel/StartPanel.tsx +0 -9
  139. package/src/components/StartPanel/__snapshots__/StartPanel.test.tsx.snap +12 -636
  140. package/src/components/UploadButton/UploadButton.css +0 -5
  141. package/src/components/layouts/WebsiteAssistant.tsx +66 -62
  142. package/src/components/layouts/__snapshots__/Chat.test.tsx.snap +1 -53
  143. package/src/components/layouts/__snapshots__/FullPage.test.tsx.snap +2 -106
  144. package/src/components/layouts/__snapshots__/HiddenChat.test.tsx.snap +1 -53
  145. package/src/components/layouts/__snapshots__/Totem.test.tsx.snap +1 -53
  146. package/src/components/layouts/__snapshots__/WebsiteAssistant.test.tsx.snap +32 -33
  147. package/src/components/layouts/__snapshots__/ZoomedFullBody.test.tsx.snap +1 -53
  148. package/src/components/layouts/chat.css +1 -1
  149. package/src/components/layouts/layouts.stories.tsx +68 -0
  150. package/src/components/layouts/website-assistant.css +405 -197
  151. package/src/helpers/constants.ts +0 -7
  152. package/src/helpers/utils.ts +4 -0
  153. package/src/index.test.tsx +8 -0
  154. package/src/index.tsx +55 -5
  155. package/src/styles.css +0 -2
  156. package/src/version.ts +2 -0
  157. package/src/components/AttachmentLinkModal/AttachmentLinkModal.css +0 -68
  158. package/src/components/AttachmentLinkModal/AttachmentLinkModal.stories.tsx +0 -32
  159. package/src/components/AttachmentLinkModal/AttachmentLinkModal.test.tsx +0 -10
  160. package/src/components/AttachmentLinkModal/AttachmentLinkModal.tsx +0 -131
  161. package/src/components/AttachmentLinkModal/__snapshots__/AttachmentLinkModal.test.tsx.snap +0 -9
  162. package/src/components/MediaWidget/LinkItemWidget.css +0 -46
  163. package/src/components/MediaWidget/LinkItemWidget.stories.tsx +0 -61
  164. package/src/components/MediaWidget/LinkItemWidget.test.tsx +0 -33
  165. package/src/components/MediaWidget/LinkItemWidget.tsx +0 -204
  166. package/src/components/MediaWidget/__snapshots__/LinkItemWidget.test.tsx.snap +0 -253
@@ -65,13 +65,6 @@ export const allowedMediaTypes = [
65
65
  export const anonTag = '👤';
66
66
 
67
67
  export const prismSyntaxLangs = [
68
- {
69
- name: 'text',
70
- lang: 'text',
71
- mimeType: 'text/plain',
72
- monacoLang: 'plaintext',
73
- executable: true,
74
- },
75
68
  {
76
69
  name: 'javascript/jsx',
77
70
  lang: 'jsx',
@@ -246,6 +246,10 @@ export const stripHTML = (text: string) => {
246
246
  return el.textContent || '';
247
247
  };
248
248
 
249
+ /** Ensures all <a> tags in HTML open in a new tab (target="_blank" rel="noopener noreferrer"). */
250
+ export const withLinksOpenInNewTab = (html: string): string =>
251
+ html.replace(/<a\s+/gi, '<a target="_blank" rel="noopener noreferrer" ');
252
+
249
253
  export const escapeHTML = (text: string) => {
250
254
  const el = document.createElement('textarea');
251
255
  el.textContent = text;
@@ -3,6 +3,14 @@ import { render } from '@testing-library/react';
3
3
  import { memori, tenant, integration } from './mocks/data';
4
4
  import Memori from './index';
5
5
 
6
+ // Mock fetch for API calls
7
+ globalThis.fetch = jest.fn(() =>
8
+ Promise.resolve({
9
+ ok: true,
10
+ json: () => Promise.resolve({}),
11
+ })
12
+ ) as jest.Mock;
13
+
6
14
  // Mock matchMedia for tests
7
15
  Object.defineProperty(window, 'matchMedia', {
8
16
  writable: true,
package/src/index.tsx CHANGED
@@ -23,6 +23,8 @@ import { useTranslation } from 'react-i18next';
23
23
  import I18nWrapper from './I18nWrapper';
24
24
  import { ArtifactProvider } from './components/MemoriArtifactSystem/context/ArtifactContext';
25
25
 
26
+ import { version } from './version';
27
+
26
28
  export interface Props {
27
29
  memoriName?: string | null;
28
30
  memoriID?: string | null;
@@ -257,9 +259,7 @@ const Memori: React.FC<Props> = ({
257
259
  const config = { attributes: true, childList: false, subtree: false };
258
260
  const callback: MutationCallback = (mutationList, _observer) => {
259
261
  for (const mutation of mutationList) {
260
- if (
261
- mutation.type === 'attributes'
262
- ) {
262
+ if (mutation.type === 'attributes') {
263
263
  const target =
264
264
  mutation.target.nodeName === 'MEMORI-CLIENT'
265
265
  ? mutation.target
@@ -340,7 +340,12 @@ const Memori: React.FC<Props> = ({
340
340
  | undefined,
341
341
  showLogin: memori?.enableDeepThought,
342
342
  memoriLang: memori?.culture?.split('-')?.[0],
343
- autoStart: layout === 'HIDDEN_CHAT',
343
+ autoStart:
344
+ layout === 'HIDDEN_CHAT'
345
+ ? true
346
+ : layout === 'WEBSITE_ASSISTANT'
347
+ ? false
348
+ : autoStart,
344
349
  }
345
350
  : {
346
351
  ...(tag && pin ? { personification: { tag, pin } } : {}),
@@ -362,7 +367,9 @@ const Memori: React.FC<Props> = ({
362
367
  initialQuestion ??
363
368
  (layoutIntegrationConfig.initialQuestion as string | undefined),
364
369
  autoStart:
365
- autoStart !== undefined
370
+ layout === 'WEBSITE_ASSISTANT'
371
+ ? false
372
+ : autoStart !== undefined
366
373
  ? autoStart
367
374
  : layout === 'HIDDEN_CHAT'
368
375
  ? true
@@ -373,6 +380,49 @@ const Memori: React.FC<Props> = ({
373
380
  memoriLang: spokenLang ?? memori?.culture?.split('-')?.[0],
374
381
  };
375
382
 
383
+ const [pulseSent, setPulseSent] = useState(false);
384
+
385
+ const sendPulse = useCallback(() => {
386
+ if ((memori?.memoriID || memoriID) && !pulseSent) {
387
+ let origin = window?.location.origin;
388
+
389
+ if (
390
+ !origin ||
391
+ origin.includes('localhost') ||
392
+ origin.includes('memori-ai.github.io')
393
+ ) {
394
+ setPulseSent(true);
395
+ return;
396
+ }
397
+
398
+ setPulseSent(true);
399
+ fetch('https://pulse.aisuru.com/post', {
400
+ method: 'POST',
401
+ headers: {
402
+ 'Content-Type': 'application/json',
403
+ },
404
+ body: JSON.stringify({
405
+ pulse: {
406
+ clientType: __WEBCOMPONENT__
407
+ ? 'memori-webcomponent'
408
+ : 'memori-react',
409
+ clientVersion: `v${version}`,
410
+ userAgent: navigator.userAgent,
411
+ language: navigator.language,
412
+ timezone: Intl.DateTimeFormat().resolvedOptions().timeZone,
413
+ memoriID: memori?.memoriID ?? memoriID,
414
+ tenant: tenantID,
415
+ referrer: origin,
416
+ },
417
+ }),
418
+ });
419
+ }
420
+ }, [memori?.memoriID, memoriID, tenantID, __WEBCOMPONENT__, pulseSent]);
421
+
422
+ useEffect(() => {
423
+ sendPulse();
424
+ }, [sendPulse]);
425
+
376
426
  return (
377
427
  <I18nWrapper>
378
428
  <VisemeProvider>
package/src/styles.css CHANGED
@@ -16,7 +16,6 @@
16
16
 
17
17
  @import url('./components/CompletionProviderStatus/CompletionProviderStatus.css');
18
18
  @import url('./components/PoweredBy/PoweredBy.css');
19
- @import url('./components/AttachmentLinkModal/AttachmentLinkModal.css');
20
19
  @import url('./components/Auth/Auth.css');
21
20
  @import url('./components/Avatar/Avatar.css');
22
21
  @import url('./components/Avatar/AvatarView/AvatarComponent/positionControls/positionControls.css');
@@ -36,7 +35,6 @@
36
35
  @import url('./components/FeedbackButtons/FeedbackButtons.css');
37
36
  @import url('./components/Header/Header.css');
38
37
  @import url('./components/icons/loading.css');
39
- @import url('./components/MediaWidget/LinkItemWidget.css');
40
38
  @import url('./components/MediaWidget/MediaItemWidget.css');
41
39
  @import url('./components/MediaWidget/MediaWidget.css');
42
40
  @import url('./components/SendOnEnterMenu/SendOnEnterMenu.css');
package/src/version.ts ADDED
@@ -0,0 +1,2 @@
1
+ // This file is auto-generated. Do not edit manually.
2
+ export const version = '8.16.0';
@@ -1,68 +0,0 @@
1
- .attachment-link-modal,
2
- .attachment-link-modal * {
3
- box-sizing: border-box;
4
- }
5
-
6
- .attachment-link-modal--label {
7
- display: inline-block;
8
- margin-top: 1rem;
9
- margin-bottom: 0.5rem;
10
- }
11
-
12
- .attachment-link-modal--centered {
13
- display: flex;
14
- align-items: center;
15
- justify-content: center;
16
- }
17
-
18
- .attachment-link-modal--input {
19
- width: 100%;
20
- padding: 0.5rem 0.75rem;
21
- border: 1px solid #d9d9d9;
22
- border-radius: 4px;
23
- margin-bottom: 1rem;
24
- background: #fff;
25
- box-shadow: 0 2px 8px rgba(0, 0, 0, 0.15);
26
- }
27
-
28
- .attachment-link-modal--row {
29
- display: flex;
30
- align-items: center;
31
- justify-content: space-between;
32
- }
33
-
34
- .attachment-link-modal--column {
35
- display: flex;
36
- width: 50%;
37
- flex-direction: column;
38
- padding: 0.5rem;
39
- margin-right: 1rem;
40
- }
41
-
42
- .attachment-link-modal--column + .attachment-link-modal--column {
43
- margin-right: 0;
44
- margin-left: 1rem;
45
- }
46
-
47
- @media (max-width: 768px) {
48
- .attachment-link-modal--row {
49
- flex-direction: column;
50
- }
51
-
52
- .attachment-link-modal--column {
53
- width: 100%;
54
- margin-right: 0;
55
- margin-bottom: 1rem;
56
- margin-left: 0;
57
- }
58
- .attachment-link-modal--column + .attachment-link-modal--column {
59
- margin-left: 0;
60
- }
61
- }
62
-
63
- .attachment-link-modal a.memori-link-item--link {
64
- display: inline-block;
65
- width: 100%;
66
- max-width: 400px;
67
- margin: 0.5rem 1rem;
68
- }
@@ -1,32 +0,0 @@
1
- import React from 'react';
2
- import { Meta, Story } from '@storybook/react';
3
- import I18nWrapper from '../../I18nWrapper';
4
- import AttachmentLinkModal, { Props } from './AttachmentLinkModal';
5
-
6
- import './AttachmentLinkModal.css';
7
-
8
- const meta: Meta = {
9
- title: 'AttachmentLinkModal',
10
- component: AttachmentLinkModal,
11
- parameters: {
12
- controls: { expanded: true },
13
- layout: 'fullscreen',
14
- },
15
- };
16
-
17
- export default meta;
18
-
19
- const Template: Story<Props> = args => (
20
- <I18nWrapper>
21
- <AttachmentLinkModal {...args} />
22
- </I18nWrapper>
23
- );
24
-
25
- // By passing using the Args format for exported stories, you can control the props for a component for reuse in a test
26
- // https://storybook.js.org/docs/react/workflows/unit-testing
27
- export const Default = Template.bind({});
28
- Default.args = {
29
- visible: true,
30
- onCancel: () => {},
31
- onOk: () => {},
32
- };
@@ -1,10 +0,0 @@
1
- import React from 'react';
2
- import { render } from '@testing-library/react';
3
- import AttachmentLinkModal from './AttachmentLinkModal';
4
-
5
- it('renders AttachmentLinkModal unchanged', () => {
6
- const { container } = render(
7
- <AttachmentLinkModal visible onCancel={() => {}} onOk={() => {}} />
8
- );
9
- expect(container).toMatchSnapshot();
10
- });
@@ -1,131 +0,0 @@
1
- import React, { useState } from 'react';
2
- import { useTranslation } from 'react-i18next';
3
- import { RenderLinkItem } from '../MediaWidget/LinkItemWidget';
4
- import Button from '../ui/Button';
5
- import Modal from '../ui/Modal';
6
-
7
- export interface Props {
8
- visible: boolean;
9
- onCancel?: () => void;
10
- onOk: ({ url, title }: { url: string; title: string }) => void;
11
- apiURL?: string;
12
- }
13
-
14
- const AttachmentLinkModal = ({ visible, onCancel, onOk }: Props) => {
15
- const { t } = useTranslation();
16
- const [newLink, setNewLink] = useState<{ url: string; title: string }>({
17
- url: '',
18
- title: '',
19
- });
20
-
21
- const onKeyPress = (e: React.KeyboardEvent<HTMLInputElement>) => {
22
- if (e.key === 'Enter') {
23
- if (newLink?.url.length === 0 || newLink?.title.length === 0) return;
24
-
25
- let saveButton = document.getElementById(
26
- 'save-link-button'
27
- ) as HTMLButtonElement | null;
28
-
29
- if (saveButton) {
30
- saveButton.click();
31
- }
32
- }
33
- };
34
-
35
- return (
36
- <Modal
37
- open={visible}
38
- title={t('media.addLinkLabel')}
39
- className="attachment-link-modal"
40
- closable
41
- width="100%"
42
- widthMd="80%"
43
- onClose={() => {
44
- if (onCancel) onCancel();
45
- }}
46
- footer={
47
- <>
48
- <Button onClick={onCancel}>{t('cancel')}</Button>
49
- <Button
50
- id="save-link-button"
51
- primary
52
- onClick={() => {
53
- if (newLink?.url.length === 0 || newLink?.title.length === 0)
54
- return;
55
- onOk(newLink);
56
- setNewLink({ url: '', title: '' });
57
- }}
58
- disabled={newLink?.url.length === 0 || newLink?.title.length === 0}
59
- >
60
- {t('confirm')}
61
- </Button>
62
- </>
63
- }
64
- >
65
- <div className="attachment-link-modal--row">
66
- <div className="attachment-link-modal--column">
67
- <label
68
- htmlFor="new-link-url"
69
- className="attachment-link-modal--label"
70
- >
71
- {t('media.linkKey')}:
72
- </label>
73
- <input
74
- type="url"
75
- className="attachment-link-modal--input "
76
- onChange={e => {
77
- let value =
78
- e.target.value.startsWith('http') || e.target.value.length === 0
79
- ? e.target.value
80
- : `https://${e.target.value}`;
81
- setNewLink(l => ({ title: l?.title ?? '', url: value }));
82
- }}
83
- placeholder="https://memori.ai/..."
84
- value={newLink?.url}
85
- name="url"
86
- onKeyDown={onKeyPress}
87
- />
88
- <label
89
- htmlFor="new-link-title"
90
- className="attachment-link-modal--label"
91
- >
92
- {t('media.linkValue')}:
93
- </label>
94
- <input
95
- type="text"
96
- className="attachment-link-modal--input "
97
- onChange={e =>
98
- setNewLink(l => ({ url: l?.url ?? '', title: e.target.value }))
99
- }
100
- value={newLink?.title}
101
- name="title"
102
- onKeyDown={onKeyPress}
103
- />
104
- </div>
105
- <div className="attachment-link-modal--column">
106
- <div className="attachment-link-modal--centered">
107
- <RenderLinkItem
108
- key={newLink?.url ?? ''}
109
- item={{
110
- title: newLink?.title ?? '',
111
- url: newLink?.url ?? '',
112
- mediumID: '',
113
- mimeType: 'text/html',
114
- }}
115
- onLinkPreviewInfo={data => {
116
- if (!newLink?.title?.length) {
117
- setNewLink(l => ({
118
- ...l,
119
- title: data?.title ?? '',
120
- }));
121
- }
122
- }}
123
- />
124
- </div>
125
- </div>
126
- </div>
127
- </Modal>
128
- );
129
- };
130
-
131
- export default AttachmentLinkModal;
@@ -1,9 +0,0 @@
1
- // Jest Snapshot v1, https://goo.gl/fbAQLP
2
-
3
- exports[`renders AttachmentLinkModal unchanged 1`] = `
4
- <div>
5
- <div
6
- 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;"
7
- />
8
- </div>
9
- `;
@@ -1,46 +0,0 @@
1
- .memori-link-items--grid {
2
- display: grid;
3
- padding: 1rem;
4
- grid-auto-flow: dense;
5
- grid-gap: 1rem;
6
- grid-template-columns: repeat(auto-fill, minmax(150px, 1fr));
7
- }
8
-
9
- /* Allineamento link per messaggi dell'utente */
10
- .memori-link-items--grid.memori-link-items--user {
11
- direction: rtl;
12
- }
13
-
14
- /* Allineamento link per messaggi dell'agente */
15
- .memori-link-items--grid.memori-link-items--agent {
16
- direction: ltr;
17
- }
18
-
19
- .memori-link-item--card {
20
- height: 100%;
21
- margin-bottom: 1rem;
22
- }
23
-
24
- .memori-link-item--card .memori-card--cover {
25
- height: auto;
26
- text-align: center;
27
- }
28
-
29
- .memori-link-item--card .memori-card--cover img {
30
- min-width: 100%;
31
- min-height: 100%;
32
- object-fit: contain;
33
- }
34
-
35
- a.memori-link-item--link {
36
- text-decoration: none;
37
- }
38
-
39
- .memori-link-item--card-cover-icon {
40
- padding: 1rem;
41
- }
42
-
43
- .memori-link-item--icon {
44
- width: 50%;
45
- height: 50%;
46
- }
@@ -1,61 +0,0 @@
1
- import React from 'react';
2
- import { Meta, Story } from '@storybook/react';
3
- import I18nWrapper from '../../I18nWrapper';
4
- import LinkItemWidget, { Props } from './LinkItemWidget';
5
-
6
- import './LinkItemWidget.css';
7
-
8
- const meta: Meta = {
9
- title: 'Media Widget/Link',
10
- component: LinkItemWidget,
11
- argTypes: {},
12
- parameters: {
13
- controls: { expanded: true },
14
- },
15
- };
16
-
17
- export default meta;
18
-
19
- const Template: Story<Props> = args => (
20
- <I18nWrapper>
21
- <LinkItemWidget {...args} />
22
- </I18nWrapper>
23
- );
24
-
25
- // By passing using the Args format for exported stories, you can control the props for a component for reuse in a test
26
- // https://storybook.js.org/docs/react/workflows/unit-testing
27
- export const Default = Template.bind({});
28
- Default.args = {
29
- items: [
30
- {
31
- mediumID: '95226d7e-7bae-465e-8b80-995587bb5971',
32
- mimeType: 'text/html',
33
- title: 'Memori Srl',
34
- url: 'https://memori.ai/en',
35
- },
36
- {
37
- mediumID: '95226d7e-7bae-465e-8b80-995587bb5971',
38
- mimeType: 'text/html',
39
- title: 'AIsuru',
40
- url: 'https://www.aisuru.com/en',
41
- },
42
- {
43
- mediumID: '95226d7e-7bae-465e-8b80-995587bb5971',
44
- mimeType: 'text/html',
45
- title: 'Introducing Plone Remix | Vimeo',
46
- url: 'https://vimeo.com/766468314',
47
- },
48
- {
49
- mediumID: '95226d7e-7bae-465e-8b80-995587bb5971',
50
- mimeType: 'text/html',
51
- title: 'A sustainable web: is it possible? - Nicola Zambello | YouTube',
52
- url: 'https://www.youtube.com/watch?v=feH26j3rBz8',
53
- },
54
- {
55
- mediumID: '95226d7e-7bae-465e-8b80-995587bb5971',
56
- mimeType: 'text/html',
57
- title: 'Memori backend API',
58
- url: 'https://backend.memori.ai',
59
- },
60
- ],
61
- };
@@ -1,33 +0,0 @@
1
- import React from 'react';
2
- import { Medium } from '@memori.ai/memori-api-client/dist/types';
3
- import { render } from '@testing-library/react';
4
- import LinkItemWidget from './LinkItemWidget';
5
-
6
- const linkMedium: Medium = {
7
- mediumID: '95226d7e-7bae-465e-8b80-995587bb5971',
8
- mimeType: 'text/html',
9
- title: 'Memori Srl',
10
- url: 'https://memori.ai/en',
11
- };
12
-
13
- it('renders LinkItemWidget unchanged', () => {
14
- const { container } = render(<LinkItemWidget items={[linkMedium]} />);
15
- expect(container).toMatchSnapshot();
16
- });
17
-
18
- it('renders LinkItemWidget unchanged with no media', () => {
19
- const { container } = render(<LinkItemWidget items={[]} />);
20
- expect(container).toMatchSnapshot();
21
- });
22
-
23
- it('renders LinkItemWidget unchanged with baseUrl', () => {
24
- const { container } = render(<LinkItemWidget items={[linkMedium]} />);
25
- expect(container).toMatchSnapshot();
26
- });
27
-
28
- it('renders LinkItemWidget unchanged with description oneline', () => {
29
- const { container } = render(
30
- <LinkItemWidget items={[linkMedium]} descriptionOneLine />
31
- );
32
- expect(container).toMatchSnapshot();
33
- });