@memori.ai/memori-react 9.0.0-alpha.4 → 9.0.0-alpha.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +62 -0
- package/dist/components/AgeVerificationModal/AgeVerificationModal.js +5 -2
- package/dist/components/AgeVerificationModal/AgeVerificationModal.js.map +1 -1
- package/dist/components/Avatar/Avatar.js +5 -10
- package/dist/components/Avatar/Avatar.js.map +1 -1
- package/dist/components/Avatar/AvatarView/AvatarComponent/components/FullbodyAvatar/fullbodyAvatar.js +8 -1
- package/dist/components/Avatar/AvatarView/AvatarComponent/components/FullbodyAvatar/fullbodyAvatar.js.map +1 -1
- package/dist/components/Avatar/AvatarView/AvatarComponent/components/controllers/MorphTargetController.js +1 -1
- package/dist/components/Avatar/AvatarView/AvatarComponent/components/controllers/MorphTargetController.js.map +1 -1
- package/dist/components/Avatar/AvatarView/AvatarComponent/constants.d.ts +2 -0
- package/dist/components/Avatar/AvatarView/AvatarComponent/constants.js +14 -5
- package/dist/components/Avatar/AvatarView/AvatarComponent/constants.js.map +1 -1
- package/dist/components/ChatBubble/ChatBubble.js +22 -16
- package/dist/components/ChatBubble/ChatBubble.js.map +1 -1
- package/dist/components/CompletionProviderStatus/CompletionProviderStatus.js +6 -3
- package/dist/components/CompletionProviderStatus/CompletionProviderStatus.js.map +1 -1
- package/dist/components/DateSelector/DateSelector.d.ts +2 -1
- package/dist/components/DateSelector/DateSelector.js +17 -7
- package/dist/components/DateSelector/DateSelector.js.map +1 -1
- package/dist/components/FilePreview/FilePreview.js +22 -5
- package/dist/components/FilePreview/FilePreview.js.map +1 -1
- package/dist/components/Header/ChatConsumptionDropdown.js +1 -1
- package/dist/components/Header/ChatConsumptionDropdown.js.map +1 -1
- package/dist/components/Header/Header.css +2 -1
- package/dist/components/Header/Header.js +1 -1
- package/dist/components/Header/Header.js.map +1 -1
- package/dist/components/MediaWidget/MediaItemWidget.js +14 -12
- package/dist/components/MediaWidget/MediaItemWidget.js.map +1 -1
- package/dist/components/MediaWidget/MediaItemWidget.utils.d.ts +3 -2
- package/dist/components/MediaWidget/MediaItemWidget.utils.js +28 -6
- package/dist/components/MediaWidget/MediaItemWidget.utils.js.map +1 -1
- package/dist/components/MediaWidget/MediaPreviewModal.js +6 -7
- package/dist/components/MediaWidget/MediaPreviewModal.js.map +1 -1
- package/dist/components/MemoriArtifactSystem/components/ArtifactActions/styles.css +5 -4
- package/dist/components/MemoriArtifactSystem/components/ArtifactDrawer/ArtifactDrawer.css +90 -38
- package/dist/components/MemoriArtifactSystem/components/ArtifactDrawer/ArtifactDrawer.d.ts +1 -0
- package/dist/components/MemoriArtifactSystem/components/ArtifactDrawer/ArtifactDrawer.js +14 -9
- package/dist/components/MemoriArtifactSystem/components/ArtifactDrawer/ArtifactDrawer.js.map +1 -1
- package/dist/components/MemoriArtifactSystem/components/ArtifactHandler/ArtifactHandler.js +2 -2
- package/dist/components/MemoriArtifactSystem/components/ArtifactHandler/ArtifactHandler.js.map +1 -1
- package/dist/components/MemoriWidget/MemoriWidget.js +632 -280
- package/dist/components/MemoriWidget/MemoriWidget.js.map +1 -1
- package/dist/components/StartPanel/StartPanel.js +10 -5
- package/dist/components/StartPanel/StartPanel.js.map +1 -1
- package/dist/components/UploadButton/UploadButton.js +21 -5
- package/dist/components/UploadButton/UploadButton.js.map +1 -1
- package/dist/components/UploadButton/UploadDocuments/UploadDocuments.js +123 -59
- package/dist/components/UploadButton/UploadDocuments/UploadDocuments.js.map +1 -1
- package/dist/components/layouts/Chat.js +25 -30
- package/dist/components/layouts/Chat.js.map +1 -1
- package/dist/components/layouts/FullPage.js +5 -8
- package/dist/components/layouts/FullPage.js.map +1 -1
- package/dist/components/layouts/HiddenChat.js +2 -1
- package/dist/components/layouts/HiddenChat.js.map +1 -1
- package/dist/components/layouts/WebsiteAssistant/WebsiteAssistant.js +5 -1
- package/dist/components/layouts/WebsiteAssistant/WebsiteAssistant.js.map +1 -1
- package/dist/components/layouts/WebsiteAssistant/website-assistant.css +3 -4
- package/dist/components/layouts/ZoomedFullBody.js +4 -7
- package/dist/components/layouts/ZoomedFullBody.js.map +1 -1
- package/dist/components/layouts/chat.css +19 -31
- package/dist/components/layouts/fullpage.css +52 -19
- package/dist/components/layouts/zoomed-full-body.css +40 -1
- package/dist/helpers/constants.d.ts +3 -0
- package/dist/helpers/constants.js +27 -1
- package/dist/helpers/constants.js.map +1 -1
- package/dist/helpers/credits.d.ts +5 -2
- package/dist/helpers/credits.js +5 -1
- package/dist/helpers/credits.js.map +1 -1
- package/dist/helpers/message.d.ts +1 -1
- package/dist/helpers/message.js +4 -4
- package/dist/helpers/message.js.map +1 -1
- package/dist/helpers/nats/getNatsConfig.d.ts +9 -0
- package/dist/helpers/nats/getNatsConfig.js +65 -0
- package/dist/helpers/nats/getNatsConfig.js.map +1 -0
- package/dist/helpers/nats/isSessionExpiredError.d.ts +3 -0
- package/dist/helpers/nats/isSessionExpiredError.js +36 -0
- package/dist/helpers/nats/isSessionExpiredError.js.map +1 -0
- package/dist/helpers/nats/useNats.d.ts +12 -0
- package/dist/helpers/nats/useNats.js +75 -0
- package/dist/helpers/nats/useNats.js.map +1 -0
- package/dist/helpers/nats/useNatsSession.d.ts +28 -0
- package/dist/helpers/nats/useNatsSession.js +212 -0
- package/dist/helpers/nats/useNatsSession.js.map +1 -0
- package/dist/helpers/usePressTooltip.d.ts +13 -0
- package/dist/helpers/usePressTooltip.js +23 -0
- package/dist/helpers/usePressTooltip.js.map +1 -0
- package/dist/helpers/utils.d.ts +21 -0
- package/dist/helpers/utils.js +75 -4
- package/dist/helpers/utils.js.map +1 -1
- package/dist/locales/de.json +1 -0
- package/dist/locales/en.json +1 -0
- package/dist/locales/es.json +1 -0
- package/dist/locales/fr.json +1 -0
- package/dist/locales/it.json +1 -0
- package/dist/styles.css +1 -1
- package/dist/types/integration.d.ts +3 -0
- package/dist/types/integration.js +16 -0
- package/dist/types/integration.js.map +1 -0
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/esm/components/AgeVerificationModal/AgeVerificationModal.js +5 -2
- package/esm/components/AgeVerificationModal/AgeVerificationModal.js.map +1 -1
- package/esm/components/Avatar/Avatar.js +5 -10
- package/esm/components/Avatar/Avatar.js.map +1 -1
- package/esm/components/Avatar/AvatarView/AvatarComponent/components/FullbodyAvatar/fullbodyAvatar.js +9 -2
- package/esm/components/Avatar/AvatarView/AvatarComponent/components/FullbodyAvatar/fullbodyAvatar.js.map +1 -1
- package/esm/components/Avatar/AvatarView/AvatarComponent/components/controllers/MorphTargetController.js +2 -2
- package/esm/components/Avatar/AvatarView/AvatarComponent/components/controllers/MorphTargetController.js.map +1 -1
- package/esm/components/Avatar/AvatarView/AvatarComponent/constants.d.ts +2 -0
- package/esm/components/Avatar/AvatarView/AvatarComponent/constants.js +13 -4
- package/esm/components/Avatar/AvatarView/AvatarComponent/constants.js.map +1 -1
- package/esm/components/ChatBubble/ChatBubble.js +22 -16
- package/esm/components/ChatBubble/ChatBubble.js.map +1 -1
- package/esm/components/CompletionProviderStatus/CompletionProviderStatus.js +6 -3
- package/esm/components/CompletionProviderStatus/CompletionProviderStatus.js.map +1 -1
- package/esm/components/DateSelector/DateSelector.d.ts +2 -1
- package/esm/components/DateSelector/DateSelector.js +17 -7
- package/esm/components/DateSelector/DateSelector.js.map +1 -1
- package/esm/components/FilePreview/FilePreview.js +24 -7
- package/esm/components/FilePreview/FilePreview.js.map +1 -1
- package/esm/components/Header/ChatConsumptionDropdown.js +1 -1
- package/esm/components/Header/ChatConsumptionDropdown.js.map +1 -1
- package/esm/components/Header/Header.css +2 -1
- package/esm/components/Header/Header.js +1 -1
- package/esm/components/Header/Header.js.map +1 -1
- package/esm/components/MediaWidget/MediaItemWidget.js +16 -14
- package/esm/components/MediaWidget/MediaItemWidget.js.map +1 -1
- package/esm/components/MediaWidget/MediaItemWidget.utils.d.ts +3 -2
- package/esm/components/MediaWidget/MediaItemWidget.utils.js +27 -6
- package/esm/components/MediaWidget/MediaItemWidget.utils.js.map +1 -1
- package/esm/components/MediaWidget/MediaPreviewModal.js +6 -7
- package/esm/components/MediaWidget/MediaPreviewModal.js.map +1 -1
- package/esm/components/MemoriArtifactSystem/components/ArtifactActions/styles.css +5 -4
- package/esm/components/MemoriArtifactSystem/components/ArtifactDrawer/ArtifactDrawer.css +90 -38
- package/esm/components/MemoriArtifactSystem/components/ArtifactDrawer/ArtifactDrawer.d.ts +1 -0
- package/esm/components/MemoriArtifactSystem/components/ArtifactDrawer/ArtifactDrawer.js +14 -9
- package/esm/components/MemoriArtifactSystem/components/ArtifactDrawer/ArtifactDrawer.js.map +1 -1
- package/esm/components/MemoriArtifactSystem/components/ArtifactHandler/ArtifactHandler.js +2 -2
- package/esm/components/MemoriArtifactSystem/components/ArtifactHandler/ArtifactHandler.js.map +1 -1
- package/esm/components/MemoriWidget/MemoriWidget.js +632 -280
- package/esm/components/MemoriWidget/MemoriWidget.js.map +1 -1
- package/esm/components/StartPanel/StartPanel.js +10 -5
- package/esm/components/StartPanel/StartPanel.js.map +1 -1
- package/esm/components/UploadButton/UploadButton.js +21 -5
- package/esm/components/UploadButton/UploadButton.js.map +1 -1
- package/esm/components/UploadButton/UploadDocuments/UploadDocuments.js +123 -59
- package/esm/components/UploadButton/UploadDocuments/UploadDocuments.js.map +1 -1
- package/esm/components/layouts/Chat.js +25 -30
- package/esm/components/layouts/Chat.js.map +1 -1
- package/esm/components/layouts/FullPage.js +5 -8
- package/esm/components/layouts/FullPage.js.map +1 -1
- package/esm/components/layouts/HiddenChat.js +2 -1
- package/esm/components/layouts/HiddenChat.js.map +1 -1
- package/esm/components/layouts/WebsiteAssistant/WebsiteAssistant.js +5 -1
- package/esm/components/layouts/WebsiteAssistant/WebsiteAssistant.js.map +1 -1
- package/esm/components/layouts/WebsiteAssistant/website-assistant.css +3 -4
- package/esm/components/layouts/ZoomedFullBody.js +4 -7
- package/esm/components/layouts/ZoomedFullBody.js.map +1 -1
- package/esm/components/layouts/chat.css +19 -31
- package/esm/components/layouts/fullpage.css +52 -19
- package/esm/components/layouts/zoomed-full-body.css +40 -1
- package/esm/helpers/constants.d.ts +3 -0
- package/esm/helpers/constants.js +26 -0
- package/esm/helpers/constants.js.map +1 -1
- package/esm/helpers/credits.d.ts +5 -2
- package/esm/helpers/credits.js +5 -1
- package/esm/helpers/credits.js.map +1 -1
- package/esm/helpers/message.d.ts +1 -1
- package/esm/helpers/message.js +2 -2
- package/esm/helpers/message.js.map +1 -1
- package/esm/helpers/nats/getNatsConfig.d.ts +9 -0
- package/esm/helpers/nats/getNatsConfig.js +61 -0
- package/esm/helpers/nats/getNatsConfig.js.map +1 -0
- package/esm/helpers/nats/isSessionExpiredError.d.ts +3 -0
- package/esm/helpers/nats/isSessionExpiredError.js +32 -0
- package/esm/helpers/nats/isSessionExpiredError.js.map +1 -0
- package/esm/helpers/nats/useNats.d.ts +12 -0
- package/esm/helpers/nats/useNats.js +72 -0
- package/esm/helpers/nats/useNats.js.map +1 -0
- package/esm/helpers/nats/useNatsSession.d.ts +28 -0
- package/esm/helpers/nats/useNatsSession.js +208 -0
- package/esm/helpers/nats/useNatsSession.js.map +1 -0
- package/esm/helpers/usePressTooltip.d.ts +13 -0
- package/esm/helpers/usePressTooltip.js +20 -0
- package/esm/helpers/usePressTooltip.js.map +1 -0
- package/esm/helpers/utils.d.ts +21 -0
- package/esm/helpers/utils.js +68 -3
- package/esm/helpers/utils.js.map +1 -1
- package/esm/locales/de.json +1 -0
- package/esm/locales/en.json +1 -0
- package/esm/locales/es.json +1 -0
- package/esm/locales/fr.json +1 -0
- package/esm/locales/it.json +1 -0
- package/esm/styles.css +1 -1
- package/esm/types/integration.d.ts +3 -0
- package/esm/types/integration.js +11 -0
- package/esm/types/integration.js.map +1 -0
- package/esm/version.d.ts +1 -1
- package/esm/version.js +1 -1
- package/package.json +6 -4
- package/src/components/AgeVerificationModal/AgeVerificationModal.tsx +6 -1
- package/src/components/Avatar/Avatar.stories.tsx +45 -28
- package/src/components/Avatar/Avatar.test.tsx +54 -0
- package/src/components/Avatar/Avatar.tsx +8 -12
- package/src/components/Avatar/AvatarView/AvatarComponent/components/FullbodyAvatar/fullbodyAvatar.tsx +12 -5
- package/src/components/Avatar/AvatarView/AvatarComponent/components/controllers/MorphTargetController.ts +2 -1
- package/src/components/Avatar/AvatarView/AvatarComponent/constants.ts +16 -4
- package/src/components/Avatar/__snapshots__/Avatar.test.tsx.snap +164 -0
- package/src/components/ChatBubble/ChatBubble.tsx +41 -12
- package/src/components/CompletionProviderStatus/CompletionProviderStatus.tsx +8 -4
- package/src/components/DateSelector/DateSelector.stories.tsx +11 -2
- package/src/components/DateSelector/DateSelector.tsx +28 -9
- package/src/components/FilePreview/FilePreview.tsx +28 -7
- package/src/components/Header/ChatConsumptionDropdown.tsx +5 -1
- package/src/components/Header/Header.css +2 -1
- package/src/components/Header/Header.tsx +1 -0
- package/src/components/MediaWidget/MediaItemWidget.tsx +26 -13
- package/src/components/MediaWidget/MediaItemWidget.utils.test.ts +45 -2
- package/src/components/MediaWidget/MediaItemWidget.utils.ts +39 -6
- package/src/components/MediaWidget/MediaPreviewModal.tsx +9 -7
- package/src/components/MemoriArtifactSystem/ArtifactDrawer.stories.tsx +218 -2252
- package/src/components/MemoriArtifactSystem/components/ArtifactActions/styles.css +5 -4
- package/src/components/MemoriArtifactSystem/components/ArtifactDrawer/ArtifactDrawer.css +90 -38
- package/src/components/MemoriArtifactSystem/components/ArtifactDrawer/ArtifactDrawer.tsx +31 -14
- package/src/components/MemoriArtifactSystem/components/ArtifactHandler/ArtifactHandler.tsx +4 -3
- package/src/components/MemoriWidget/MemoriWidget.tsx +785 -331
- package/src/components/StartPanel/StartPanel.stories.tsx +22 -0
- package/src/components/StartPanel/StartPanel.test.tsx +64 -1
- package/src/components/StartPanel/StartPanel.tsx +26 -3
- package/src/components/StartPanel/__snapshots__/StartPanel.test.tsx.snap +261 -0
- package/src/components/UploadButton/UploadButton.tsx +30 -11
- package/src/components/UploadButton/UploadDocuments/UploadDocuments.tsx +148 -61
- package/src/components/UploadButton/__snapshots__/UploadButton.test.tsx.snap +2 -2
- package/src/components/layouts/Chat.tsx +16 -19
- package/src/components/layouts/FullPage.tsx +32 -25
- package/src/components/layouts/HiddenChat.tsx +4 -0
- package/src/components/layouts/WebsiteAssistant/WebsiteAssistant.tsx +8 -0
- package/src/components/layouts/WebsiteAssistant/website-assistant.css +3 -4
- package/src/components/layouts/ZoomedFullBody.tsx +30 -24
- package/src/components/layouts/__snapshots__/Chat.test.tsx.snap +6 -3
- package/src/components/layouts/__snapshots__/FullPage.test.tsx.snap +824 -810
- package/src/components/layouts/__snapshots__/ZoomedFullBody.test.tsx.snap +280 -273
- package/src/components/layouts/chat.css +19 -31
- package/src/components/layouts/fullpage.css +52 -19
- package/src/components/layouts/layouts.stories.tsx +131 -12
- package/src/components/layouts/zoomed-full-body.css +40 -1
- package/src/helpers/constants.ts +32 -1
- package/src/helpers/credits.ts +16 -1
- package/src/helpers/message.test.ts +28 -1
- package/src/helpers/message.ts +4 -4
- package/src/helpers/nats/getNatsConfig.ts +145 -0
- package/src/helpers/nats/isSessionExpiredError.test.ts +38 -0
- package/src/helpers/nats/isSessionExpiredError.ts +51 -0
- package/src/helpers/nats/useNats.ts +124 -0
- package/src/helpers/nats/useNatsSession.ts +394 -0
- package/src/helpers/usePressTooltip.ts +29 -0
- package/src/helpers/utils.test.ts +162 -0
- package/src/helpers/utils.ts +108 -3
- package/src/index.stories.tsx +32 -0
- package/src/locales/de.json +1 -0
- package/src/locales/en.json +1 -0
- package/src/locales/es.json +1 -0
- package/src/locales/fr.json +1 -0
- package/src/locales/it.json +1 -0
- package/src/styles.css +4 -7
- package/src/types/integration.test.ts +32 -0
- package/src/types/integration.ts +31 -0
- package/src/version.ts +1 -1
|
@@ -33,17 +33,21 @@ const PROVIDER_CONFIGS: Record<string, ProviderConfig> = {
|
|
|
33
33
|
statusPage: 'https://status.mistral-data.com/',
|
|
34
34
|
apiComponentName: ['Mistral'],
|
|
35
35
|
},
|
|
36
|
+
// Use status.claude.com directly: status.anthropic.com 302-redirects and
|
|
37
|
+
// browsers block the redirected response (missing CORS on the redirect).
|
|
36
38
|
Anthropic: {
|
|
37
|
-
statusUrl: 'https://status.
|
|
38
|
-
statusPage: 'https://status.
|
|
39
|
-
apiComponentName: [
|
|
39
|
+
statusUrl: 'https://status.claude.com/api/v2/summary.json',
|
|
40
|
+
statusPage: 'https://status.claude.com/',
|
|
41
|
+
apiComponentName: [
|
|
42
|
+
'Claude API (api.anthropic.com)',
|
|
43
|
+
'api.anthropic.com',
|
|
44
|
+
],
|
|
40
45
|
},
|
|
41
46
|
};
|
|
42
47
|
|
|
43
48
|
// Modified to handle fetch errors, different component names, and check incidents
|
|
44
49
|
const fetchProviderStatus = async (config: ProviderConfig): Promise<Status> => {
|
|
45
50
|
try {
|
|
46
|
-
// Use cross-fetch instead of native fetch
|
|
47
51
|
const response = await fetch(config.statusUrl);
|
|
48
52
|
if (!response.ok) {
|
|
49
53
|
console.warn(`Status API returned ${response.status}`);
|
|
@@ -25,14 +25,23 @@ const Template: Story<Props> = args => (
|
|
|
25
25
|
// https://storybook.js.org/docs/react/workflows/unit-testing
|
|
26
26
|
export const Default = Template.bind({});
|
|
27
27
|
Default.args = {
|
|
28
|
-
defaultDate:
|
|
28
|
+
defaultDate: '1990-06-15',
|
|
29
|
+
minAge: 18,
|
|
30
|
+
onChange: console.log,
|
|
31
|
+
disabled: false,
|
|
32
|
+
};
|
|
33
|
+
|
|
34
|
+
export const MinAge14 = Template.bind({});
|
|
35
|
+
MinAge14.args = {
|
|
36
|
+
minAge: 14,
|
|
29
37
|
onChange: console.log,
|
|
30
38
|
disabled: false,
|
|
31
39
|
};
|
|
32
40
|
|
|
33
41
|
export const Disabled = Template.bind({});
|
|
34
42
|
Disabled.args = {
|
|
35
|
-
defaultDate:
|
|
43
|
+
defaultDate: '1990-06-15',
|
|
44
|
+
minAge: 18,
|
|
36
45
|
onChange: () => {},
|
|
37
46
|
disabled: true,
|
|
38
47
|
};
|
|
@@ -5,16 +5,23 @@ import { useTranslation } from 'react-i18next';
|
|
|
5
5
|
export interface Props {
|
|
6
6
|
defaultDate?: string | Date;
|
|
7
7
|
disabled?: boolean;
|
|
8
|
+
/** Minimum age; latest selectable birth date is today minus this many years. */
|
|
9
|
+
minAge?: number;
|
|
8
10
|
onChange: (date: DateTime | undefined) => void;
|
|
9
11
|
}
|
|
10
12
|
|
|
11
13
|
const DateSelector = memo(
|
|
12
|
-
({ defaultDate, onChange, disabled = false }: Props) => {
|
|
14
|
+
({ defaultDate, onChange, disabled = false, minAge = 18 }: Props) => {
|
|
13
15
|
const { t } = useTranslation();
|
|
14
16
|
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
17
|
+
const maxDate = useMemo(
|
|
18
|
+
() => DateTime.now().minus({ years: minAge }).startOf('day'),
|
|
19
|
+
[minAge]
|
|
20
|
+
);
|
|
21
|
+
const minDate = useMemo(
|
|
22
|
+
() => DateTime.fromObject({ year: 1900, month: 1, day: 1 }),
|
|
23
|
+
[]
|
|
24
|
+
);
|
|
18
25
|
|
|
19
26
|
// State for individual fields as strings to allow empty values
|
|
20
27
|
const [day, setDay] = useState<string>('');
|
|
@@ -54,10 +61,22 @@ const DateSelector = memo(
|
|
|
54
61
|
return () => window.removeEventListener('resize', checkMobile);
|
|
55
62
|
}, []);
|
|
56
63
|
|
|
64
|
+
// Avoid re-running when parent passes an unstable onChange (inline arrow).
|
|
65
|
+
const onChangeRef = useRef(onChange);
|
|
66
|
+
onChangeRef.current = onChange;
|
|
67
|
+
const lastEmittedRef = useRef<string | null | undefined>(undefined);
|
|
68
|
+
|
|
57
69
|
// Validate and propagate changes
|
|
58
70
|
useEffect(() => {
|
|
71
|
+
const emit = (next: DateTime | undefined) => {
|
|
72
|
+
const key = next?.isValid ? next.toISODate() : null;
|
|
73
|
+
if (key === lastEmittedRef.current) return;
|
|
74
|
+
lastEmittedRef.current = key;
|
|
75
|
+
onChangeRef.current(next);
|
|
76
|
+
};
|
|
77
|
+
|
|
59
78
|
if (!day || !month || !year) {
|
|
60
|
-
|
|
79
|
+
emit(undefined);
|
|
61
80
|
return;
|
|
62
81
|
}
|
|
63
82
|
|
|
@@ -66,7 +85,7 @@ const DateSelector = memo(
|
|
|
66
85
|
const y = parseInt(year);
|
|
67
86
|
|
|
68
87
|
if (isNaN(d) || isNaN(m) || isNaN(y)) {
|
|
69
|
-
|
|
88
|
+
emit(undefined);
|
|
70
89
|
return;
|
|
71
90
|
}
|
|
72
91
|
|
|
@@ -75,11 +94,11 @@ const DateSelector = memo(
|
|
|
75
94
|
// Basic validation: check if it's a valid date (e.g. not Feb 30)
|
|
76
95
|
// and within range.
|
|
77
96
|
if (newDate.isValid && newDate >= minDate && newDate <= maxDate) {
|
|
78
|
-
|
|
97
|
+
emit(newDate);
|
|
79
98
|
} else {
|
|
80
|
-
|
|
99
|
+
emit(undefined);
|
|
81
100
|
}
|
|
82
|
-
}, [day, month, year,
|
|
101
|
+
}, [day, month, year, minDate, maxDate]);
|
|
83
102
|
|
|
84
103
|
// Handle mobile native input change
|
|
85
104
|
const handleMobileChange = (e: ChangeEvent<HTMLInputElement>) => {
|
|
@@ -3,8 +3,13 @@ import { File, X } from 'lucide-react';
|
|
|
3
3
|
import { Button } from '@memori.ai/ui';
|
|
4
4
|
import ContentPreviewModal from '../ContentPreviewModal';
|
|
5
5
|
import Snippet from '../Snippet/Snippet';
|
|
6
|
-
import {
|
|
7
|
-
|
|
6
|
+
import {
|
|
7
|
+
stripHTML,
|
|
8
|
+
stripDocumentAttachmentTags,
|
|
9
|
+
isOfficeNativeFilename,
|
|
10
|
+
getDocumentAttachmentAssetUrl,
|
|
11
|
+
} from '../../helpers/utils';
|
|
12
|
+
import { getDocumentBadgeLabel } from '../MediaWidget/MediaItemWidget.utils';
|
|
8
13
|
import { useTranslation } from 'react-i18next';
|
|
9
14
|
|
|
10
15
|
type FilePreviewProps = {
|
|
@@ -60,6 +65,15 @@ const FilePreview = ({
|
|
|
60
65
|
return 'CSV';
|
|
61
66
|
case 'html':
|
|
62
67
|
return 'HTML';
|
|
68
|
+
case 'doc':
|
|
69
|
+
case 'docx':
|
|
70
|
+
case 'dotx':
|
|
71
|
+
return 'Word';
|
|
72
|
+
case 'xls':
|
|
73
|
+
case 'xltx':
|
|
74
|
+
return 'Excel';
|
|
75
|
+
case 'potx':
|
|
76
|
+
return 'PowerPoint';
|
|
63
77
|
case 'jpg':
|
|
64
78
|
case 'jpeg':
|
|
65
79
|
return 'JPEG';
|
|
@@ -111,9 +125,7 @@ const FilePreview = ({
|
|
|
111
125
|
if (isHtmlFile(file)) {
|
|
112
126
|
let htmlContent = content;
|
|
113
127
|
if (htmlContent.includes('<') || htmlContent.includes('"')) {
|
|
114
|
-
|
|
115
|
-
div.innerHTML = htmlContent;
|
|
116
|
-
htmlContent = div.textContent || div.innerText || htmlContent;
|
|
128
|
+
htmlContent = stripHTML(htmlContent) || htmlContent;
|
|
117
129
|
}
|
|
118
130
|
htmlContent = stripDocumentAttachmentTags(htmlContent);
|
|
119
131
|
return htmlContent;
|
|
@@ -169,7 +181,16 @@ const FilePreview = ({
|
|
|
169
181
|
<button
|
|
170
182
|
type="button"
|
|
171
183
|
className="memori--preview-item-trigger"
|
|
172
|
-
onClick={() =>
|
|
184
|
+
onClick={() => {
|
|
185
|
+
if (isOfficeNativeFilename(file.name || '')) {
|
|
186
|
+
const url = getDocumentAttachmentAssetUrl(file);
|
|
187
|
+
if (url) {
|
|
188
|
+
window.open(url, '_blank', 'noopener,noreferrer');
|
|
189
|
+
}
|
|
190
|
+
} else {
|
|
191
|
+
setSelectedFile(file);
|
|
192
|
+
}
|
|
193
|
+
}}
|
|
173
194
|
aria-label={file.name}
|
|
174
195
|
>
|
|
175
196
|
{isImageContent(file.content, file.type) ? (
|
|
@@ -184,7 +205,7 @@ const FilePreview = ({
|
|
|
184
205
|
<span className="memori--preview-filename">{file.name}</span>
|
|
185
206
|
<span className="memori--preview-filetype">
|
|
186
207
|
{file.mimeType
|
|
187
|
-
?
|
|
208
|
+
? getDocumentBadgeLabel(file.mimeType, file.name)
|
|
188
209
|
: getFileType(file.name, file.type)}
|
|
189
210
|
</span>
|
|
190
211
|
</div>
|
|
@@ -285,7 +285,11 @@ const ChatConsumptionDropdown: React.FC<ChatConsumptionDropdownProps> = ({
|
|
|
285
285
|
{...triggerButtonProps}
|
|
286
286
|
variant={triggerVariant}
|
|
287
287
|
shape="default"
|
|
288
|
-
className=
|
|
288
|
+
className={cx(
|
|
289
|
+
'memori-header--button memori-header--button--sustainability',
|
|
290
|
+
open && 'memori-button--active',
|
|
291
|
+
triggerButtonProps.className
|
|
292
|
+
)}
|
|
289
293
|
aria-label={triggerLabel}
|
|
290
294
|
title={triggerLabel}
|
|
291
295
|
icon={
|
|
@@ -11,7 +11,10 @@ import React, {
|
|
|
11
11
|
import { getResourceUrl } from '../../helpers/media';
|
|
12
12
|
import {
|
|
13
13
|
withLinksOpenInNewTab,
|
|
14
|
+
stripHTML,
|
|
14
15
|
stripDocumentAttachmentTags,
|
|
16
|
+
isAssetOnlyDocumentAttachment,
|
|
17
|
+
getDocumentAttachmentAssetUrl,
|
|
15
18
|
} from '../../helpers/utils';
|
|
16
19
|
import { getTranslation } from '../../helpers/translations';
|
|
17
20
|
import { prismSyntaxLangs } from '../../helpers/constants';
|
|
@@ -32,7 +35,7 @@ import type {
|
|
|
32
35
|
import {
|
|
33
36
|
formatBytes,
|
|
34
37
|
getFileExtensionFromUrl,
|
|
35
|
-
|
|
38
|
+
getDocumentBadgeLabel,
|
|
36
39
|
countLines,
|
|
37
40
|
shouldUseDarkFileCard,
|
|
38
41
|
fetchLinkPreview,
|
|
@@ -268,7 +271,7 @@ export const RenderMediaItem = memo(function RenderMediaItem({
|
|
|
268
271
|
) : (
|
|
269
272
|
<DocumentCard
|
|
270
273
|
title={medium.title || 'File'}
|
|
271
|
-
badge={
|
|
274
|
+
badge={getDocumentBadgeLabel(medium.mimeType, medium.title)}
|
|
272
275
|
meta={(() => {
|
|
273
276
|
const size = getContentSize(medium);
|
|
274
277
|
return size != null && size > 0 ? formatBytes(size) : null;
|
|
@@ -284,7 +287,7 @@ export const RenderMediaItem = memo(function RenderMediaItem({
|
|
|
284
287
|
return (
|
|
285
288
|
<DocumentCard
|
|
286
289
|
title={medium.title || 'File'}
|
|
287
|
-
badge={
|
|
290
|
+
badge={getDocumentBadgeLabel(medium.mimeType, medium.title)}
|
|
288
291
|
meta={(() => {
|
|
289
292
|
const size = getContentSize(medium);
|
|
290
293
|
return size != null && size > 0 ? formatBytes(size) : null;
|
|
@@ -298,7 +301,7 @@ export const RenderMediaItem = memo(function RenderMediaItem({
|
|
|
298
301
|
return (
|
|
299
302
|
<DocumentCard
|
|
300
303
|
title={medium.title || 'File'}
|
|
301
|
-
badge={
|
|
304
|
+
badge={getDocumentBadgeLabel(medium.mimeType, medium.title)}
|
|
302
305
|
meta={(() => {
|
|
303
306
|
const size = getContentSize(medium);
|
|
304
307
|
return size != null && size > 0 ? formatBytes(size) : null;
|
|
@@ -324,8 +327,11 @@ export const RenderMediaItem = memo(function RenderMediaItem({
|
|
|
324
327
|
|
|
325
328
|
// Extension and file detection helpers
|
|
326
329
|
const fileExtensionFromUrl = getFileExtensionFromUrl(normURL || item.url);
|
|
327
|
-
const
|
|
328
|
-
|
|
330
|
+
const fileExtension = getDocumentBadgeLabel(
|
|
331
|
+
item.mimeType,
|
|
332
|
+
item.title,
|
|
333
|
+
normURL || item.url
|
|
334
|
+
);
|
|
329
335
|
const isFile = shouldUseDarkFileCard(
|
|
330
336
|
item,
|
|
331
337
|
fileExtensionFromUrl,
|
|
@@ -355,8 +361,16 @@ export const RenderMediaItem = memo(function RenderMediaItem({
|
|
|
355
361
|
const metaParts = [lineText, sizeText].filter(Boolean);
|
|
356
362
|
const metaLine = metaParts.length > 0 ? metaParts.join(' · ') : null;
|
|
357
363
|
|
|
364
|
+
// Asset-only attachments (e.g. Office native files) open via URL, not modal
|
|
365
|
+
const isAssetOnlyAttachment = isAssetOnlyDocumentAttachment(item);
|
|
366
|
+
|
|
358
367
|
// Document attachments and attached files should open in modal, not as links
|
|
359
|
-
if (
|
|
368
|
+
if (
|
|
369
|
+
(isDocumentAttachment || isAttachedFile) &&
|
|
370
|
+
item.mediumID &&
|
|
371
|
+
_onClick &&
|
|
372
|
+
!isAssetOnlyAttachment
|
|
373
|
+
) {
|
|
360
374
|
return (
|
|
361
375
|
<div
|
|
362
376
|
onClick={() => _onClick(item)}
|
|
@@ -395,16 +409,17 @@ export const RenderMediaItem = memo(function RenderMediaItem({
|
|
|
395
409
|
|
|
396
410
|
// Build href: open in new tab (never modal). Use URL, or blob for content-only items.
|
|
397
411
|
const getFileCardHref = (): string => {
|
|
398
|
-
|
|
412
|
+
const assetUrl = getDocumentAttachmentAssetUrl(item);
|
|
413
|
+
if (assetUrl) {
|
|
399
414
|
return (
|
|
400
415
|
getResourceUrl({
|
|
401
|
-
resourceURI:
|
|
416
|
+
resourceURI: assetUrl,
|
|
402
417
|
sessionID,
|
|
403
418
|
tenantID,
|
|
404
419
|
baseURL,
|
|
405
420
|
apiURL,
|
|
406
421
|
}) ||
|
|
407
|
-
|
|
422
|
+
assetUrl ||
|
|
408
423
|
'#'
|
|
409
424
|
);
|
|
410
425
|
}
|
|
@@ -416,9 +431,7 @@ export const RenderMediaItem = memo(function RenderMediaItem({
|
|
|
416
431
|
htmlContent.includes('<document_attachment')
|
|
417
432
|
) {
|
|
418
433
|
if (htmlContent.includes('<') || htmlContent.includes('"')) {
|
|
419
|
-
|
|
420
|
-
div.innerHTML = htmlContent;
|
|
421
|
-
htmlContent = div.textContent || div.innerText || htmlContent;
|
|
434
|
+
htmlContent = stripHTML(htmlContent) || htmlContent;
|
|
422
435
|
}
|
|
423
436
|
htmlContent = stripDocumentAttachmentTags(htmlContent);
|
|
424
437
|
}
|
|
@@ -2,6 +2,7 @@ import {
|
|
|
2
2
|
formatBytes,
|
|
3
3
|
getFileExtensionFromUrl,
|
|
4
4
|
getFileExtensionFromMime,
|
|
5
|
+
getDocumentBadgeLabel,
|
|
5
6
|
countLines,
|
|
6
7
|
shouldUseDarkFileCard,
|
|
7
8
|
fetchLinkPreview,
|
|
@@ -57,8 +58,25 @@ describe('MediaItemWidget.utils', () => {
|
|
|
57
58
|
expect(getFileExtensionFromMime('text/html')).toBe('HTML');
|
|
58
59
|
expect(getFileExtensionFromMime('text/plain')).toBe('TXT');
|
|
59
60
|
expect(getFileExtensionFromMime('application/json')).toBe('JSON');
|
|
60
|
-
expect(getFileExtensionFromMime('application/vnd.ms-excel')).toBe('
|
|
61
|
-
expect(
|
|
61
|
+
expect(getFileExtensionFromMime('application/vnd.ms-excel')).toBe('Excel');
|
|
62
|
+
expect(
|
|
63
|
+
getFileExtensionFromMime(
|
|
64
|
+
'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'
|
|
65
|
+
)
|
|
66
|
+
).toBe('Excel');
|
|
67
|
+
});
|
|
68
|
+
|
|
69
|
+
it('maps office mime types with parameters to short labels', () => {
|
|
70
|
+
expect(
|
|
71
|
+
getFileExtensionFromMime(
|
|
72
|
+
'application/vnd.openxmlformats-officedocument.wordprocessingml.document; charset=binary'
|
|
73
|
+
)
|
|
74
|
+
).toBe('Word');
|
|
75
|
+
expect(
|
|
76
|
+
getFileExtensionFromMime(
|
|
77
|
+
'application/vnd.openxmlformats-officedocument.spreadsheetml.template'
|
|
78
|
+
)
|
|
79
|
+
).toBe('Excel');
|
|
62
80
|
});
|
|
63
81
|
|
|
64
82
|
it('uses subtype when not in MIME_TO_EXT map', () => {
|
|
@@ -71,6 +89,31 @@ describe('MediaItemWidget.utils', () => {
|
|
|
71
89
|
});
|
|
72
90
|
});
|
|
73
91
|
|
|
92
|
+
describe('getDocumentBadgeLabel', () => {
|
|
93
|
+
it('prefers URL extension, then filename, then mime type', () => {
|
|
94
|
+
expect(
|
|
95
|
+
getDocumentBadgeLabel(
|
|
96
|
+
'application/pdf',
|
|
97
|
+
'report.docx',
|
|
98
|
+
'https://example.com/file.pdf'
|
|
99
|
+
)
|
|
100
|
+
).toBe('PDF');
|
|
101
|
+
expect(
|
|
102
|
+
getDocumentBadgeLabel(
|
|
103
|
+
'application/vnd.openxmlformats-officedocument.wordprocessingml.document',
|
|
104
|
+
'report.docx',
|
|
105
|
+
'https://example.com/asset/123'
|
|
106
|
+
)
|
|
107
|
+
).toBe('Word');
|
|
108
|
+
expect(
|
|
109
|
+
getDocumentBadgeLabel(
|
|
110
|
+
'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
|
|
111
|
+
'budget.xlsx'
|
|
112
|
+
)
|
|
113
|
+
).toBe('Excel');
|
|
114
|
+
});
|
|
115
|
+
});
|
|
116
|
+
|
|
74
117
|
describe('countLines', () => {
|
|
75
118
|
it('returns 0 for undefined or empty', () => {
|
|
76
119
|
expect(countLines(undefined)).toBe(0);
|
|
@@ -1,4 +1,8 @@
|
|
|
1
1
|
import type { Medium } from '@memori.ai/memori-api-client/dist/types';
|
|
2
|
+
import {
|
|
3
|
+
officeExtensionShortLabels,
|
|
4
|
+
officeMimeShortLabels,
|
|
5
|
+
} from '../../helpers/constants';
|
|
2
6
|
import type { LinkPreviewInfo } from './MediaItemWidget.types';
|
|
3
7
|
|
|
4
8
|
export const FILE_EXTENSIONS_DARK_CARD = [
|
|
@@ -7,6 +11,7 @@ export const FILE_EXTENSIONS_DARK_CARD = [
|
|
|
7
11
|
'PDF',
|
|
8
12
|
'DOC',
|
|
9
13
|
'DOCX',
|
|
14
|
+
'DOTX',
|
|
10
15
|
'XLS',
|
|
11
16
|
'XLSX',
|
|
12
17
|
'JSON',
|
|
@@ -22,6 +27,7 @@ export const FILE_MIME_TYPES_DARK_CARD = [
|
|
|
22
27
|
'application/pdf',
|
|
23
28
|
'application/msword',
|
|
24
29
|
'application/vnd.openxmlformats-officedocument.wordprocessingml.document',
|
|
30
|
+
'application/vnd.openxmlformats-officedocument.wordprocessingml.template',
|
|
25
31
|
'application/vnd.ms-excel',
|
|
26
32
|
'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
|
|
27
33
|
'text/html',
|
|
@@ -54,11 +60,6 @@ export const IMAGE_MIME_TYPES = [
|
|
|
54
60
|
|
|
55
61
|
const MIME_TO_EXT: Record<string, string> = {
|
|
56
62
|
'application/pdf': 'PDF',
|
|
57
|
-
'application/msword': 'DOC',
|
|
58
|
-
'application/vnd.openxmlformats-officedocument.wordprocessingml.document':
|
|
59
|
-
'DOCX',
|
|
60
|
-
'application/vnd.ms-excel': 'XLS',
|
|
61
|
-
'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet': 'XLSX',
|
|
62
63
|
'text/html': 'HTML',
|
|
63
64
|
'text/plain': 'TXT',
|
|
64
65
|
'text/css': 'CSS',
|
|
@@ -87,14 +88,46 @@ export function getFileExtensionFromUrl(
|
|
|
87
88
|
return match ? match[1].toUpperCase() : null;
|
|
88
89
|
}
|
|
89
90
|
|
|
91
|
+
function normalizeMimeType(mimeType: string): string {
|
|
92
|
+
return mimeType.split(';')[0].trim();
|
|
93
|
+
}
|
|
94
|
+
|
|
90
95
|
export function getFileExtensionFromMime(mimeType: string): string {
|
|
96
|
+
const normalized = normalizeMimeType(mimeType);
|
|
97
|
+
const normalizedLower = normalized.toLowerCase();
|
|
98
|
+
|
|
99
|
+
const officeLabel =
|
|
100
|
+
officeMimeShortLabels[normalized] ||
|
|
101
|
+
officeMimeShortLabels[normalizedLower];
|
|
102
|
+
if (officeLabel) return officeLabel;
|
|
103
|
+
|
|
91
104
|
return (
|
|
105
|
+
MIME_TO_EXT[normalized] ||
|
|
106
|
+
MIME_TO_EXT[normalizedLower] ||
|
|
92
107
|
MIME_TO_EXT[mimeType] ||
|
|
93
|
-
|
|
108
|
+
normalized.split('/')[1]?.toUpperCase() ||
|
|
94
109
|
'FILE'
|
|
95
110
|
);
|
|
96
111
|
}
|
|
97
112
|
|
|
113
|
+
export function getDocumentBadgeLabel(
|
|
114
|
+
mimeType: string,
|
|
115
|
+
filename?: string | null,
|
|
116
|
+
url?: string | null
|
|
117
|
+
): string {
|
|
118
|
+
const fromUrl = getFileExtensionFromUrl(url || undefined);
|
|
119
|
+
if (fromUrl) {
|
|
120
|
+
return officeExtensionShortLabels[fromUrl] || fromUrl;
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
const fromFilename = getFileExtensionFromUrl(filename || undefined);
|
|
124
|
+
if (fromFilename) {
|
|
125
|
+
return officeExtensionShortLabels[fromFilename] || fromFilename;
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
return getFileExtensionFromMime(mimeType);
|
|
129
|
+
}
|
|
130
|
+
|
|
98
131
|
export function countLines(content: string | undefined): number {
|
|
99
132
|
if (!content) return 0;
|
|
100
133
|
return content.split(/\r\n|\r|\n/).length;
|
|
@@ -70,6 +70,8 @@ const MIME_MARKDOWN = 'text/markdown';
|
|
|
70
70
|
const MIME_WORD_DOC = 'application/msword';
|
|
71
71
|
const MIME_WORD_DOCX =
|
|
72
72
|
'application/vnd.openxmlformats-officedocument.wordprocessingml.document';
|
|
73
|
+
const MIME_WORD_DOTX =
|
|
74
|
+
'application/vnd.openxmlformats-officedocument.wordprocessingml.template';
|
|
73
75
|
|
|
74
76
|
const VIDEO_MIME_TYPES = [
|
|
75
77
|
'video/mp4',
|
|
@@ -99,7 +101,11 @@ function isAudio(mimeType: string): boolean {
|
|
|
99
101
|
}
|
|
100
102
|
|
|
101
103
|
function isWordDoc(mimeType: string): boolean {
|
|
102
|
-
return
|
|
104
|
+
return (
|
|
105
|
+
mimeType === MIME_WORD_DOC ||
|
|
106
|
+
mimeType === MIME_WORD_DOCX ||
|
|
107
|
+
mimeType === MIME_WORD_DOTX
|
|
108
|
+
);
|
|
103
109
|
}
|
|
104
110
|
|
|
105
111
|
// Document attachments (PDF, XLSX, TXT, CSV, etc.) are extracted as text, not binary.
|
|
@@ -268,9 +274,7 @@ export function MediaPreviewModal({
|
|
|
268
274
|
// HTML document attachment: display HTML content in a code-like format
|
|
269
275
|
let htmlContent = medium.content || '';
|
|
270
276
|
if (htmlContent.includes('<') || htmlContent.includes('"')) {
|
|
271
|
-
|
|
272
|
-
div.innerHTML = htmlContent;
|
|
273
|
-
htmlContent = div.textContent || div.innerText || htmlContent;
|
|
277
|
+
htmlContent = stripHTML(htmlContent) || htmlContent;
|
|
274
278
|
} else {
|
|
275
279
|
htmlContent = stripDocumentAttachmentTags(htmlContent);
|
|
276
280
|
}
|
|
@@ -290,9 +294,7 @@ export function MediaPreviewModal({
|
|
|
290
294
|
// Other document attachments: render as plain text
|
|
291
295
|
let displayContent = medium.content;
|
|
292
296
|
if (displayContent.includes('<') || displayContent.includes('"')) {
|
|
293
|
-
|
|
294
|
-
div.innerHTML = displayContent;
|
|
295
|
-
displayContent = div.textContent || div.innerText || displayContent;
|
|
297
|
+
displayContent = stripHTML(displayContent) || displayContent;
|
|
296
298
|
} else {
|
|
297
299
|
displayContent = stripDocumentAttachmentTags(displayContent);
|
|
298
300
|
}
|