@memori.ai/memori-react 8.41.2 → 8.41.4
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 +23 -0
- 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 +16 -11
- package/dist/components/ChatBubble/ChatBubble.js.map +1 -1
- package/dist/components/MemoriWidget/MemoriWidget.js +121 -84
- package/dist/components/MemoriWidget/MemoriWidget.js.map +1 -1
- package/dist/components/UploadButton/UploadDocuments/UploadDocuments.js +79 -52
- package/dist/components/UploadButton/UploadDocuments/UploadDocuments.js.map +1 -1
- package/dist/helpers/constants.d.ts +1 -1
- package/dist/helpers/constants.js +0 -1
- package/dist/helpers/constants.js.map +1 -1
- package/dist/helpers/utils.d.ts +1 -1
- package/dist/version.d.ts +1 -1
- package/dist/version.js +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 +16 -11
- package/esm/components/ChatBubble/ChatBubble.js.map +1 -1
- package/esm/components/MemoriWidget/MemoriWidget.js +121 -84
- package/esm/components/MemoriWidget/MemoriWidget.js.map +1 -1
- package/esm/components/UploadButton/UploadDocuments/UploadDocuments.js +79 -52
- package/esm/components/UploadButton/UploadDocuments/UploadDocuments.js.map +1 -1
- package/esm/helpers/constants.d.ts +1 -1
- package/esm/helpers/constants.js +0 -1
- package/esm/helpers/constants.js.map +1 -1
- package/esm/helpers/utils.d.ts +1 -1
- package/esm/version.d.ts +1 -1
- package/esm/version.js +1 -1
- package/package.json +1 -1
- package/src/components/Avatar/Avatar.test.tsx +27 -0
- 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 +63 -0
- package/src/components/ChatBubble/ChatBubble.tsx +28 -3
- package/src/components/MemoriWidget/MemoriWidget.tsx +110 -68
- package/src/components/UploadButton/UploadDocuments/UploadDocuments.tsx +103 -55
- package/src/components/UploadButton/__snapshots__/UploadButton.test.tsx.snap +2 -2
- package/src/components/layouts/layouts.stories.tsx +6 -13
- package/src/helpers/constants.ts +0 -1
- package/src/helpers/utils.test.ts +1 -1
- package/src/version.ts +1 -1
|
@@ -125,6 +125,20 @@ const getMemoriState = (integrationId?: string): object | null => {
|
|
|
125
125
|
};
|
|
126
126
|
};
|
|
127
127
|
|
|
128
|
+
/** Unified login token resolution: React state > ref > call-site override > props. */
|
|
129
|
+
const resolveLoginTokenValue = (
|
|
130
|
+
loginToken: string | undefined,
|
|
131
|
+
userTokenRef: string | undefined,
|
|
132
|
+
callAdditionalInfoLoginToken: string | undefined,
|
|
133
|
+
additionalInfoLoginToken: string | undefined,
|
|
134
|
+
authTokenProp: string | undefined
|
|
135
|
+
): string | undefined =>
|
|
136
|
+
loginToken ??
|
|
137
|
+
userTokenRef ??
|
|
138
|
+
callAdditionalInfoLoginToken ??
|
|
139
|
+
additionalInfoLoginToken ??
|
|
140
|
+
authTokenProp;
|
|
141
|
+
|
|
128
142
|
/** Place spec with all nulls for postEnterTextAsync when position is not set or user chose "I don't want to provide my position". */
|
|
129
143
|
const NULL_PLACE_SPEC = {
|
|
130
144
|
placeName: null,
|
|
@@ -377,7 +391,6 @@ window.typeBatchMessages = typeBatchMessages;
|
|
|
377
391
|
let audioContext: IAudioContext;
|
|
378
392
|
|
|
379
393
|
let memoriPassword: string | undefined;
|
|
380
|
-
let userToken: string | undefined;
|
|
381
394
|
|
|
382
395
|
export interface LayoutProps {
|
|
383
396
|
Header?: typeof Header;
|
|
@@ -559,32 +572,78 @@ const MemoriWidget = ({
|
|
|
559
572
|
const [loginToken, setLoginToken] = useState<string | undefined>(
|
|
560
573
|
additionalInfo?.loginToken ?? authToken
|
|
561
574
|
);
|
|
575
|
+
const userTokenRef = useRef<string | undefined>(
|
|
576
|
+
additionalInfo?.loginToken ?? authToken
|
|
577
|
+
);
|
|
578
|
+
const prevPropsLoginTokenRef = useRef<string | undefined>(
|
|
579
|
+
additionalInfo?.loginToken ?? authToken
|
|
580
|
+
);
|
|
581
|
+
|
|
562
582
|
const [user, setUser] = useState<User | undefined>({
|
|
563
583
|
avatarURL: typeof userAvatar === 'string' ? userAvatar : undefined,
|
|
564
584
|
} as User);
|
|
585
|
+
|
|
586
|
+
const resolveLoginToken = useCallback(
|
|
587
|
+
(callAdditionalInfoLoginToken?: string) =>
|
|
588
|
+
resolveLoginTokenValue(
|
|
589
|
+
loginToken,
|
|
590
|
+
userTokenRef.current,
|
|
591
|
+
callAdditionalInfoLoginToken,
|
|
592
|
+
additionalInfo?.loginToken,
|
|
593
|
+
authToken
|
|
594
|
+
),
|
|
595
|
+
[loginToken, additionalInfo?.loginToken, authToken]
|
|
596
|
+
);
|
|
597
|
+
|
|
598
|
+
// Sync loginToken when props change (including explicit removal from parent)
|
|
565
599
|
useEffect(() => {
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
) {
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
|
|
578
|
-
if (!birthDate && user.birthDate) {
|
|
579
|
-
setBirthDate(user.birthDate);
|
|
580
|
-
setLocalConfig('birthDate', user.birthDate);
|
|
581
|
-
}
|
|
582
|
-
} else {
|
|
583
|
-
removeLocalConfig('loginToken');
|
|
584
|
-
}
|
|
585
|
-
});
|
|
600
|
+
const incomingToken = additionalInfo?.loginToken ?? authToken;
|
|
601
|
+
const prevPropsToken = prevPropsLoginTokenRef.current;
|
|
602
|
+
prevPropsLoginTokenRef.current = incomingToken;
|
|
603
|
+
|
|
604
|
+
if (incomingToken !== prevPropsToken) {
|
|
605
|
+
setLoginToken(incomingToken);
|
|
606
|
+
userTokenRef.current = incomingToken;
|
|
607
|
+
if (!incomingToken) {
|
|
608
|
+
removeLocalConfig('loginToken');
|
|
609
|
+
setUser(undefined);
|
|
610
|
+
}
|
|
586
611
|
}
|
|
587
|
-
}, [loginToken,
|
|
612
|
+
}, [additionalInfo?.loginToken, authToken]);
|
|
613
|
+
|
|
614
|
+
useEffect(() => {
|
|
615
|
+
if (!loginToken || !(showLogin || memori.requireLoginToken)) {
|
|
616
|
+
return;
|
|
617
|
+
}
|
|
618
|
+
|
|
619
|
+
let cancelled = false;
|
|
620
|
+
|
|
621
|
+
client.backend
|
|
622
|
+
.pwlGetCurrentUser(loginToken)
|
|
623
|
+
.then(({ user: fetchedUser, resultCode }) => {
|
|
624
|
+
if (cancelled) return;
|
|
625
|
+
|
|
626
|
+
if (fetchedUser && resultCode === 0) {
|
|
627
|
+
setUser(fetchedUser);
|
|
628
|
+
setLocalConfig('loginToken', loginToken);
|
|
629
|
+
userTokenRef.current = loginToken;
|
|
630
|
+
|
|
631
|
+
if (!birthDate && fetchedUser.birthDate) {
|
|
632
|
+
setBirthDate(fetchedUser.birthDate);
|
|
633
|
+
setLocalConfig('birthDate', fetchedUser.birthDate);
|
|
634
|
+
}
|
|
635
|
+
} else {
|
|
636
|
+
setLoginToken(undefined);
|
|
637
|
+
userTokenRef.current = undefined;
|
|
638
|
+
setUser(undefined);
|
|
639
|
+
removeLocalConfig('loginToken');
|
|
640
|
+
}
|
|
641
|
+
});
|
|
642
|
+
|
|
643
|
+
return () => {
|
|
644
|
+
cancelled = true;
|
|
645
|
+
};
|
|
646
|
+
}, [loginToken, showLogin, memori.requireLoginToken]);
|
|
588
647
|
const [showLoginDrawer, setShowLoginDrawer] = useState(false);
|
|
589
648
|
|
|
590
649
|
const [clickedStart, setClickedStart] = useState(false);
|
|
@@ -764,7 +823,7 @@ const MemoriWidget = ({
|
|
|
764
823
|
|
|
765
824
|
if (!additionalInfo?.loginToken && !authToken) {
|
|
766
825
|
setLoginToken(getLocalConfig<typeof loginToken>('loginToken', undefined));
|
|
767
|
-
|
|
826
|
+
userTokenRef.current = getLocalConfig<typeof loginToken>('loginToken', undefined);
|
|
768
827
|
|
|
769
828
|
setBirthDate(getLocalConfig<string | undefined>('birthDate', undefined));
|
|
770
829
|
}
|
|
@@ -1391,12 +1450,7 @@ const MemoriWidget = ({
|
|
|
1391
1450
|
pin: params.pin ?? personification?.pin,
|
|
1392
1451
|
additionalInfo: {
|
|
1393
1452
|
...(params.additionalInfo || additionalInfo || {}),
|
|
1394
|
-
loginToken:
|
|
1395
|
-
userToken ??
|
|
1396
|
-
loginToken ??
|
|
1397
|
-
params.additionalInfo?.loginToken ??
|
|
1398
|
-
additionalInfo?.loginToken ??
|
|
1399
|
-
authToken,
|
|
1453
|
+
loginToken: resolveLoginToken(params.additionalInfo?.loginToken),
|
|
1400
1454
|
language: (
|
|
1401
1455
|
userLang ??
|
|
1402
1456
|
memori.culture?.split('-')?.[0] ??
|
|
@@ -1558,12 +1612,7 @@ const MemoriWidget = ({
|
|
|
1558
1612
|
birthDate: userBirthDate,
|
|
1559
1613
|
additionalInfo: {
|
|
1560
1614
|
...(additionalInfoProp || additionalInfo || {}),
|
|
1561
|
-
loginToken:
|
|
1562
|
-
userToken ??
|
|
1563
|
-
loginToken ??
|
|
1564
|
-
additionalInfoProp?.loginToken ??
|
|
1565
|
-
additionalInfo?.loginToken ??
|
|
1566
|
-
authToken,
|
|
1615
|
+
loginToken: resolveLoginToken(additionalInfoProp?.loginToken),
|
|
1567
1616
|
language: (
|
|
1568
1617
|
userLang ??
|
|
1569
1618
|
memori.culture?.split('-')?.[0] ??
|
|
@@ -1845,11 +1894,7 @@ const MemoriWidget = ({
|
|
|
1845
1894
|
birthDate: birthDate || storageBirthDate || undefined,
|
|
1846
1895
|
additionalInfo: {
|
|
1847
1896
|
...(additionalInfo || {}),
|
|
1848
|
-
loginToken:
|
|
1849
|
-
userToken ??
|
|
1850
|
-
loginToken ??
|
|
1851
|
-
additionalInfo?.loginToken ??
|
|
1852
|
-
authToken,
|
|
1897
|
+
loginToken: resolveLoginToken(),
|
|
1853
1898
|
language: (
|
|
1854
1899
|
userLang ??
|
|
1855
1900
|
memori.culture?.split('-')?.[0] ??
|
|
@@ -2732,11 +2777,7 @@ const MemoriWidget = ({
|
|
|
2732
2777
|
birthDate: birth,
|
|
2733
2778
|
additionalInfo: {
|
|
2734
2779
|
...(additionalInfo || {}),
|
|
2735
|
-
loginToken:
|
|
2736
|
-
userToken ??
|
|
2737
|
-
loginToken ??
|
|
2738
|
-
additionalInfo?.loginToken ??
|
|
2739
|
-
authToken,
|
|
2780
|
+
loginToken: resolveLoginToken(),
|
|
2740
2781
|
language: (
|
|
2741
2782
|
userLang ??
|
|
2742
2783
|
memori.culture?.split('-')?.[0] ??
|
|
@@ -3112,29 +3153,31 @@ const MemoriWidget = ({
|
|
|
3112
3153
|
return;
|
|
3113
3154
|
}
|
|
3114
3155
|
|
|
3156
|
+
const propsToken = additionalInfo?.loginToken ?? authToken;
|
|
3157
|
+
const initialDomToken = targetNode.getAttribute('authtoken') || undefined;
|
|
3158
|
+
if (initialDomToken && !propsToken) {
|
|
3159
|
+
setLoginToken(initialDomToken);
|
|
3160
|
+
userTokenRef.current = initialDomToken;
|
|
3161
|
+
}
|
|
3162
|
+
|
|
3163
|
+
const applyAuthTokenFromElement = (element: Element) => {
|
|
3164
|
+
const clientNode =
|
|
3165
|
+
element.nodeName === 'MEMORI-CLIENT'
|
|
3166
|
+
? element
|
|
3167
|
+
: element.closest('memori-client') ?? element.parentElement;
|
|
3168
|
+
const token = clientNode?.getAttribute('authtoken') || undefined;
|
|
3169
|
+
setLoginToken(token);
|
|
3170
|
+
userTokenRef.current = token;
|
|
3171
|
+
};
|
|
3172
|
+
|
|
3115
3173
|
const config = { attributes: true, childList: false, subtree: false };
|
|
3116
|
-
const callback: MutationCallback =
|
|
3174
|
+
const callback: MutationCallback = mutationList => {
|
|
3117
3175
|
for (const mutation of mutationList) {
|
|
3118
3176
|
if (
|
|
3119
3177
|
mutation.type === 'attributes' &&
|
|
3120
3178
|
mutation.attributeName?.toLowerCase() === 'authtoken'
|
|
3121
3179
|
) {
|
|
3122
|
-
|
|
3123
|
-
setLoginToken(
|
|
3124
|
-
// @ts-ignore
|
|
3125
|
-
mutation.target.getAttribute('authtoken') || undefined
|
|
3126
|
-
);
|
|
3127
|
-
// @ts-ignore
|
|
3128
|
-
userToken = mutation.target.getAttribute('authtoken') || undefined;
|
|
3129
|
-
} else {
|
|
3130
|
-
// @ts-ignore
|
|
3131
|
-
setLoginToken(
|
|
3132
|
-
mutation.target?.parentElement?.getAttribute('authtoken') ||
|
|
3133
|
-
undefined
|
|
3134
|
-
);
|
|
3135
|
-
// @ts-ignore
|
|
3136
|
-
userToken = mutation.target.getAttribute('authtoken') || undefined;
|
|
3137
|
-
}
|
|
3180
|
+
applyAuthTokenFromElement(mutation.target as Element);
|
|
3138
3181
|
}
|
|
3139
3182
|
}
|
|
3140
3183
|
};
|
|
@@ -3144,7 +3187,7 @@ const MemoriWidget = ({
|
|
|
3144
3187
|
return () => {
|
|
3145
3188
|
observer.disconnect();
|
|
3146
3189
|
};
|
|
3147
|
-
}, []);
|
|
3190
|
+
}, [memori.name, memori.memoriID, additionalInfo?.loginToken, authToken]);
|
|
3148
3191
|
|
|
3149
3192
|
/**
|
|
3150
3193
|
* Experts references
|
|
@@ -3306,7 +3349,7 @@ const MemoriWidget = ({
|
|
|
3306
3349
|
setShowLoginDrawer(false);
|
|
3307
3350
|
setUser(undefined);
|
|
3308
3351
|
setLoginToken(undefined);
|
|
3309
|
-
|
|
3352
|
+
userTokenRef.current = undefined;
|
|
3310
3353
|
removeLocalConfig('loginToken');
|
|
3311
3354
|
});
|
|
3312
3355
|
},
|
|
@@ -3379,8 +3422,7 @@ const MemoriWidget = ({
|
|
|
3379
3422
|
showTypingText:
|
|
3380
3423
|
showTypingText ?? integrationConfig?.showTypingText ?? false,
|
|
3381
3424
|
history: showFullHistory ? history : history.slice(-2),
|
|
3382
|
-
authToken:
|
|
3383
|
-
loginToken ?? userToken ?? additionalInfo?.loginToken ?? authToken,
|
|
3425
|
+
authToken: resolveLoginToken(),
|
|
3384
3426
|
dialogState: currentDialogState,
|
|
3385
3427
|
pushMessage,
|
|
3386
3428
|
simulateUserPrompt,
|
|
@@ -3770,7 +3812,7 @@ const MemoriWidget = ({
|
|
|
3770
3812
|
setShowLoginDrawer(false);
|
|
3771
3813
|
setUser(user);
|
|
3772
3814
|
setLoginToken(token);
|
|
3773
|
-
|
|
3815
|
+
userTokenRef.current = token;
|
|
3774
3816
|
setLocalConfig('loginToken', token);
|
|
3775
3817
|
// Push a message with initial status to show status message when a new session is created after login
|
|
3776
3818
|
if (
|
|
@@ -3811,7 +3853,7 @@ const MemoriWidget = ({
|
|
|
3811
3853
|
setShowLoginDrawer(false);
|
|
3812
3854
|
setUser(undefined);
|
|
3813
3855
|
setLoginToken(undefined);
|
|
3814
|
-
|
|
3856
|
+
userTokenRef.current = undefined;
|
|
3815
3857
|
removeLocalConfig('loginToken');
|
|
3816
3858
|
});
|
|
3817
3859
|
}}
|
|
@@ -167,64 +167,101 @@ const UploadDocuments: React.FC<UploadDocumentsProps> = ({
|
|
|
167
167
|
}
|
|
168
168
|
};
|
|
169
169
|
|
|
170
|
-
const
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
170
|
+
const loadXLSXLibrary = async (): Promise<void> => {
|
|
171
|
+
if (window.XLSX) return;
|
|
172
|
+
|
|
173
|
+
await new Promise((resolve, reject) => {
|
|
174
|
+
const script = document.createElement('script');
|
|
175
|
+
script.src = XLSX_URL;
|
|
176
|
+
script.onload = resolve;
|
|
177
|
+
script.onerror = reject;
|
|
178
|
+
document.head.appendChild(script);
|
|
179
|
+
});
|
|
180
|
+
};
|
|
181
181
|
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
182
|
+
const readXLSXWorkbook = async (file: File) => {
|
|
183
|
+
await loadXLSXLibrary();
|
|
184
|
+
|
|
185
|
+
const arrayBuffer = await file.arrayBuffer();
|
|
186
|
+
return window.XLSX.read(arrayBuffer, {
|
|
187
|
+
type: 'array',
|
|
188
|
+
cellFormula: true,
|
|
189
|
+
cellNF: true,
|
|
190
|
+
cellText: true,
|
|
191
|
+
cellDates: true,
|
|
192
|
+
});
|
|
193
|
+
};
|
|
194
|
+
|
|
195
|
+
const formatXLSXWorkbookForDisplay = (workbook: {
|
|
196
|
+
SheetNames: string[];
|
|
197
|
+
Sheets: Record<string, unknown>;
|
|
198
|
+
}): string => {
|
|
199
|
+
let text = '';
|
|
200
|
+
|
|
201
|
+
for (const sheetName of workbook.SheetNames) {
|
|
202
|
+
const worksheet = workbook.Sheets[sheetName];
|
|
203
|
+
const data = window.XLSX.utils.sheet_to_json(worksheet, {
|
|
204
|
+
header: 1,
|
|
205
|
+
raw: false,
|
|
189
206
|
});
|
|
190
207
|
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
header: 1,
|
|
196
|
-
raw: false,
|
|
208
|
+
const colWidths = data.reduce((widths: number[], row: any[]) => {
|
|
209
|
+
row.forEach((cell, i) => {
|
|
210
|
+
const cellWidth = (cell || '').toString().length;
|
|
211
|
+
widths[i] = Math.max(widths[i] || 0, cellWidth);
|
|
197
212
|
});
|
|
213
|
+
return widths;
|
|
214
|
+
}, []);
|
|
215
|
+
|
|
216
|
+
const formattedText = data.map((row: any[]) => {
|
|
217
|
+
return row
|
|
218
|
+
.map((cell, i) => {
|
|
219
|
+
const cellStr = (cell || '').toString();
|
|
220
|
+
return cellStr.padEnd(colWidths[i] + 2);
|
|
221
|
+
})
|
|
222
|
+
.join('|')
|
|
223
|
+
.trim();
|
|
224
|
+
});
|
|
198
225
|
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
}, []);
|
|
206
|
-
|
|
207
|
-
const formattedText = data.map((row: any[]) => {
|
|
208
|
-
return row
|
|
209
|
-
.map((cell, i) => {
|
|
210
|
-
const cellStr = (cell || '').toString();
|
|
211
|
-
return cellStr.padEnd(colWidths[i] + 2);
|
|
212
|
-
})
|
|
213
|
-
.join('|')
|
|
214
|
-
.trim();
|
|
215
|
-
});
|
|
226
|
+
if (formattedText.length > 0) {
|
|
227
|
+
const separator = colWidths
|
|
228
|
+
.map((w: number) => '-'.repeat(w + 2))
|
|
229
|
+
.join('+');
|
|
230
|
+
formattedText.splice(1, 0, separator);
|
|
231
|
+
}
|
|
216
232
|
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
}
|
|
233
|
+
text += `Sheet: ${sheetName}\n${formattedText.join('\n')}\n\n`;
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
return text;
|
|
237
|
+
};
|
|
223
238
|
|
|
224
|
-
|
|
239
|
+
const formatXLSXWorkbookAsCsv = (workbook: {
|
|
240
|
+
SheetNames: string[];
|
|
241
|
+
Sheets: Record<string, unknown>;
|
|
242
|
+
}): string => {
|
|
243
|
+
let text = '';
|
|
244
|
+
|
|
245
|
+
for (const sheetName of workbook.SheetNames) {
|
|
246
|
+
const worksheet = workbook.Sheets[sheetName];
|
|
247
|
+
const csv = window.XLSX.utils.sheet_to_csv(worksheet, { raw: false });
|
|
248
|
+
if (csv.trim()) {
|
|
249
|
+
text += `Sheet: ${sheetName}\n${csv}\n\n`;
|
|
225
250
|
}
|
|
251
|
+
}
|
|
226
252
|
|
|
227
|
-
|
|
253
|
+
return text;
|
|
254
|
+
};
|
|
255
|
+
|
|
256
|
+
const extractTextFromXLSX = async (
|
|
257
|
+
file: File
|
|
258
|
+
): Promise<{ display: string; asset: string }> => {
|
|
259
|
+
try {
|
|
260
|
+
const workbook = await readXLSXWorkbook(file);
|
|
261
|
+
return {
|
|
262
|
+
display: formatXLSXWorkbookForDisplay(workbook),
|
|
263
|
+
asset: formatXLSXWorkbookAsCsv(workbook),
|
|
264
|
+
};
|
|
228
265
|
} catch (error) {
|
|
229
266
|
console.error('XLSX extraction failed:', error);
|
|
230
267
|
throw new Error(
|
|
@@ -237,7 +274,11 @@ const UploadDocuments: React.FC<UploadDocumentsProps> = ({
|
|
|
237
274
|
|
|
238
275
|
const processDocumentFile = async (
|
|
239
276
|
file: File
|
|
240
|
-
): Promise<{
|
|
277
|
+
): Promise<{
|
|
278
|
+
text: string | null;
|
|
279
|
+
textForAsset?: string;
|
|
280
|
+
uploadAsOriginal?: boolean;
|
|
281
|
+
}> => {
|
|
241
282
|
if (isOfficeNativeFilename(file.name)) {
|
|
242
283
|
return { text: null, uploadAsOriginal: true };
|
|
243
284
|
}
|
|
@@ -245,16 +286,19 @@ const UploadDocuments: React.FC<UploadDocumentsProps> = ({
|
|
|
245
286
|
const ext = file.name.split('.').pop()?.toLowerCase() || '';
|
|
246
287
|
try {
|
|
247
288
|
let text: string | null = null;
|
|
289
|
+
let textForAsset: string | undefined;
|
|
248
290
|
|
|
249
291
|
if (ext === 'pdf') {
|
|
250
292
|
text = await extractTextFromPDF(file);
|
|
251
293
|
} else if (['txt', 'md', 'json', 'csv', 'html'].includes(ext)) {
|
|
252
294
|
text = await file.text();
|
|
253
295
|
} else if (ext === 'xlsx') {
|
|
254
|
-
|
|
296
|
+
const extracted = await extractTextFromXLSX(file);
|
|
297
|
+
text = extracted.display;
|
|
298
|
+
textForAsset = extracted.asset;
|
|
255
299
|
}
|
|
256
300
|
|
|
257
|
-
return { text };
|
|
301
|
+
return { text, textForAsset };
|
|
258
302
|
} catch (error) {
|
|
259
303
|
console.error('Document processing failed:', error);
|
|
260
304
|
throw new Error(
|
|
@@ -370,7 +414,8 @@ const UploadDocuments: React.FC<UploadDocumentsProps> = ({
|
|
|
370
414
|
const fileId = Math.random().toString(36).substr(2, 9);
|
|
371
415
|
|
|
372
416
|
try {
|
|
373
|
-
const { text, uploadAsOriginal } =
|
|
417
|
+
const { text, textForAsset, uploadAsOriginal } =
|
|
418
|
+
await processDocumentFile(file);
|
|
374
419
|
|
|
375
420
|
if (uploadAsOriginal) {
|
|
376
421
|
// Office native format: upload the original file as asset, no text extraction
|
|
@@ -403,7 +448,8 @@ const UploadDocuments: React.FC<UploadDocumentsProps> = ({
|
|
|
403
448
|
});
|
|
404
449
|
} else if (text) {
|
|
405
450
|
const baseName = file.name.replace(/\.[^/.]+$/, '') || file.name;
|
|
406
|
-
const
|
|
451
|
+
const assetText = textForAsset ?? text;
|
|
452
|
+
const textFile = new File([assetText], `${baseName}.txt`, {
|
|
407
453
|
type: 'text/plain',
|
|
408
454
|
});
|
|
409
455
|
|
|
@@ -468,7 +514,9 @@ const UploadDocuments: React.FC<UploadDocumentsProps> = ({
|
|
|
468
514
|
<input
|
|
469
515
|
ref={documentInputRef}
|
|
470
516
|
type="file"
|
|
471
|
-
accept={`.pdf,.txt,.md,.json,.xlsx,.csv,.html,${officeNativeExtensions.join(
|
|
517
|
+
accept={`.pdf,.txt,.md,.json,.xlsx,.csv,.html,${officeNativeExtensions.join(
|
|
518
|
+
','
|
|
519
|
+
)}`}
|
|
472
520
|
multiple
|
|
473
521
|
className="memori--upload-file-input"
|
|
474
522
|
onChange={handleDocumentUpload}
|
|
@@ -6,7 +6,7 @@ exports[`renders UploadButton unchanged 1`] = `
|
|
|
6
6
|
class="memori--unified-upload-wrapper"
|
|
7
7
|
>
|
|
8
8
|
<input
|
|
9
|
-
accept=".jpg,.jpeg,.png,.pdf,.txt,.json,.xlsx,.csv,.md,.html,.doc,.docx,.dotx,.
|
|
9
|
+
accept=".jpg,.jpeg,.png,.pdf,.txt,.json,.xlsx,.csv,.md,.html,.doc,.docx,.dotx,.xltx,.potx"
|
|
10
10
|
class="memori--upload-file-input"
|
|
11
11
|
multiple=""
|
|
12
12
|
style="display: none;"
|
|
@@ -52,7 +52,7 @@ exports[`renders UploadButton unchanged 1`] = `
|
|
|
52
52
|
class="memori--document-upload-wrapper"
|
|
53
53
|
>
|
|
54
54
|
<input
|
|
55
|
-
accept=".pdf,.txt,.md,.json,.xlsx,.csv,.html,.doc,.docx,.dotx,.
|
|
55
|
+
accept=".pdf,.txt,.md,.json,.xlsx,.csv,.html,.doc,.docx,.dotx,.xltx,.potx"
|
|
56
56
|
class="memori--upload-file-input"
|
|
57
57
|
multiple=""
|
|
58
58
|
type="file"
|
|
@@ -32,25 +32,18 @@ const Template: Story<Props> = args => (
|
|
|
32
32
|
|
|
33
33
|
const DefaultLayout = Template.bind({});
|
|
34
34
|
DefaultLayout.args = {
|
|
35
|
-
memoriName: '
|
|
36
|
-
ownerUserName: '
|
|
37
|
-
memoriID: '
|
|
35
|
+
memoriName: 'prova-sharepoint',
|
|
36
|
+
ownerUserName: 'Andrea-Patini',
|
|
37
|
+
memoriID: '019f129c-a5a3-74d3-b0c8-b7794437bb23',
|
|
38
38
|
ownerUserID: '91dbc9ba-b684-4fbe-9828-b5980af6cda9',
|
|
39
39
|
tenantID: 'aisuru-staging.aclambda.online',
|
|
40
40
|
engineURL: 'https://engine-staging.memori.ai/memori/v2',
|
|
41
41
|
apiURL: 'https://backend-staging.memori.ai/api/v2',
|
|
42
|
-
|
|
42
|
+
baseURL: 'https://aisuru-staging.aclambda.online',
|
|
43
|
+
layout: 'TOTEM',
|
|
43
44
|
uiLang: 'IT',
|
|
44
45
|
spokenLang: 'IT',
|
|
45
|
-
integrationID: '
|
|
46
|
-
autoStart: true,
|
|
47
|
-
sessionID: '' as string | undefined,
|
|
48
|
-
showUpload: true,
|
|
49
|
-
showReasoning: false,
|
|
50
|
-
showLogin: true,
|
|
51
|
-
multilingual: true,
|
|
52
|
-
avatar3dHidden: true,
|
|
53
|
-
showMessageConsumption: true,
|
|
46
|
+
integrationID: '019f1896-730d-7e19-9a88-6413f485247b',
|
|
54
47
|
};
|
|
55
48
|
|
|
56
49
|
export const Default = Template.bind({});
|
package/src/helpers/constants.ts
CHANGED
|
@@ -177,7 +177,7 @@ describe('utils/attachment helpers', () => {
|
|
|
177
177
|
it('detects office native filenames', () => {
|
|
178
178
|
expect(isOfficeNativeFilename('report.doc')).toBe(true);
|
|
179
179
|
expect(isOfficeNativeFilename('report.docx')).toBe(true);
|
|
180
|
-
expect(isOfficeNativeFilename('budget.xls')).toBe(
|
|
180
|
+
expect(isOfficeNativeFilename('budget.xls')).toBe(false);
|
|
181
181
|
expect(isOfficeNativeFilename('template.XLTX')).toBe(true);
|
|
182
182
|
expect(isOfficeNativeFilename('slides.potx')).toBe(true);
|
|
183
183
|
expect(isOfficeNativeFilename('notes.pdf')).toBe(false);
|
package/src/version.ts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
// This file is auto-generated. Do not edit manually.
|
|
2
|
-
export const version = '8.41.
|
|
2
|
+
export const version = '8.41.4';
|