@arbidocs/blocks 0.4.106 → 0.4.108
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/bin/arbidocs-render-take.mjs +27 -0
- package/dist/NativeDocxEditor-UAZUKZ77.js +10 -0
- package/dist/NativeDocxEditor-UAZUKZ77.js.map +1 -0
- package/dist/NativeDocxEditor-YX7B7OFH.cjs +31 -0
- package/dist/NativeDocxEditor-YX7B7OFH.cjs.map +1 -0
- package/dist/{chunk-W2RTZOK3.js → chunk-A2MN2ZLX.js} +1750 -1779
- package/dist/chunk-A2MN2ZLX.js.map +1 -0
- package/dist/{chunk-3R6XBYL7.cjs → chunk-DTBSGG36.cjs} +7 -2
- package/dist/chunk-DTBSGG36.cjs.map +1 -0
- package/dist/{chunk-4GFB5U3K.js → chunk-EGDWNEAG.js} +4 -3
- package/dist/chunk-EGDWNEAG.js.map +1 -0
- package/dist/chunk-GYAUJ4KT.js +71 -0
- package/dist/chunk-GYAUJ4KT.js.map +1 -0
- package/dist/{chunk-PIT2YZCK.js → chunk-JQVPGMLU.js} +3 -3
- package/dist/{chunk-PIT2YZCK.js.map → chunk-JQVPGMLU.js.map} +1 -1
- package/dist/{chunk-LGX6UFYG.js → chunk-P2KPDPFF.js} +8 -3
- package/dist/chunk-P2KPDPFF.js.map +1 -0
- package/dist/{chunk-ZWWN4CUL.cjs → chunk-QT6EGMAJ.cjs} +1748 -1778
- package/dist/chunk-QT6EGMAJ.cjs.map +1 -0
- package/dist/chunk-S24XEVPS.cjs +73 -0
- package/dist/chunk-S24XEVPS.cjs.map +1 -0
- package/dist/{chunk-TP3FAP5J.cjs → chunk-TTXK62YI.cjs} +5 -5
- package/dist/{chunk-TP3FAP5J.cjs.map → chunk-TTXK62YI.cjs.map} +1 -1
- package/dist/{chunk-7LLLQUM7.cjs → chunk-ZYSY4L5L.cjs} +6 -5
- package/dist/chunk-ZYSY4L5L.cjs.map +1 -0
- package/dist/collaboration/index.cjs +15 -15
- package/dist/collaboration/index.js +1 -1
- package/dist/collaboration/mail/MailMessageView.d.ts +3 -1
- package/dist/connect/docx.cjs +7 -6
- package/dist/connect/docx.cjs.map +1 -1
- package/dist/connect/docx.js +5 -4
- package/dist/connect/docx.js.map +1 -1
- package/dist/connect/index.cjs +368 -52
- package/dist/connect/index.cjs.map +1 -1
- package/dist/connect/index.js +356 -41
- package/dist/connect/index.js.map +1 -1
- package/dist/connection/mail/ConnectedMailComposer.d.ts +12 -2
- package/dist/connection/mail/ConnectedMailMessage.d.ts +19 -0
- package/dist/connection/mail/ConnectedMailbox.d.ts +7 -3
- package/dist/connection/mail/MailComposerForm.d.ts +12 -2
- package/dist/connection/mail/index.d.ts +2 -1
- package/dist/connection/mail/types.d.ts +15 -0
- package/dist/connection/mail/useWordBody.d.ts +48 -0
- package/dist/docx/NativeDocxEditor.d.ts +9 -1
- package/dist/docx/index.cjs +51 -50
- package/dist/docx/index.cjs.map +1 -1
- package/dist/docx/index.js +4 -3
- package/dist/docx/index.js.map +1 -1
- package/dist/docx/template/HouseTemplate.d.ts +5 -0
- package/dist/index.cjs +15 -15
- package/dist/index.js +1 -1
- package/dist/record/index.cjs +307 -66
- package/dist/record/index.cjs.map +1 -1
- package/dist/record/index.d.ts +145 -26
- package/dist/record/index.js +301 -67
- package/dist/record/index.js.map +1 -1
- package/node_modules/@arbidocs/coedit/package.json +1 -1
- package/package.json +8 -5
- package/record/render-overlays.mjs +152 -0
- package/record/render-take.py +985 -0
- package/src/docx/styles.css +22 -0
- package/dist/chunk-3R6XBYL7.cjs.map +0 -1
- package/dist/chunk-4GFB5U3K.js.map +0 -1
- package/dist/chunk-7LLLQUM7.cjs.map +0 -1
- package/dist/chunk-LGX6UFYG.js.map +0 -1
- package/dist/chunk-W2RTZOK3.js.map +0 -1
- package/dist/chunk-ZWWN4CUL.cjs.map +0 -1
package/dist/connect/index.js
CHANGED
|
@@ -2,11 +2,12 @@
|
|
|
2
2
|
import { SettingsSection, ProfileCard, AvatarPicker, IdentityVerificationCard, IdentityVerificationDialog, RequireVerified, SettingsCard, SettingsActionRow, PasswordChangeDialog, EMAIL_NOTIFICATION_KEYS, EMAIL_NOTIFICATION_CATEGORIES, NotificationCategoryList, toNotificationCategories, toActiveSessionViews, SettingsRow, ActiveSessionsDialog, LogoutDialog, toLogoutSessionViews, SettingsDangerZone, DeleteAccountDialog, toDeleteBlockerViews } from '../chunk-W7NZRZ54.js';
|
|
3
3
|
import { useWorkspaceDocs } from '../chunk-XQDM6T6C.js';
|
|
4
4
|
export { ConnectedAssistantDock, redlineStats, textToArtifact, toRedlineMarkdown, useConnectedAiTask, useConnectedChat, useSemanticSearch, useWorkspaceDocs } from '../chunk-XQDM6T6C.js';
|
|
5
|
-
import { ConnectedNativeDocxEditor } from '../chunk-
|
|
5
|
+
import { ConnectedNativeDocxEditor } from '../chunk-EGDWNEAG.js';
|
|
6
6
|
import { ConnectionProvider, useConnection } from '../chunk-OYMWV45N.js';
|
|
7
7
|
export { ConnectionProvider, SESSION_EXPIRED_MESSAGE, isAuthenticated, useConnection } from '../chunk-OYMWV45N.js';
|
|
8
8
|
import { SignDocumentDialog } from '../chunk-2YOVK524.js';
|
|
9
|
-
import '../chunk-
|
|
9
|
+
import '../chunk-GYAUJ4KT.js';
|
|
10
|
+
import '../chunk-A2MN2ZLX.js';
|
|
10
11
|
import '../chunk-HFZ45FD3.js';
|
|
11
12
|
import { FilesFilterBar, FolderFilterButton, FolderPickerRow } from '../chunk-7RJTEWYM.js';
|
|
12
13
|
import { WorkspaceActivityList, WorkspaceNotificationMenu, ThreadFollowMenuItem, ThreadFollowButton, TagTable, tagTableDocx } from '../chunk-S55VDTX3.js';
|
|
@@ -27,7 +28,7 @@ import '../chunk-HOXKR26S.js';
|
|
|
27
28
|
import '../chunk-AA3PT6KR.js';
|
|
28
29
|
import '../chunk-NPLYHR2E.js';
|
|
29
30
|
import { initials } from '../chunk-OXF2IFXG.js';
|
|
30
|
-
import { PlainMailBodyEditor, draftMailCompose, emptyMailCompose, MailGrid, MailMessageView,
|
|
31
|
+
import { PlainMailBodyEditor, draftMailCompose, replyMailCompose, emptyMailCompose, MailGrid, MailMessageView, MailDocumentPicker, parseMailRecipients } from '../chunk-P2KPDPFF.js';
|
|
31
32
|
import { ModalScaffold } from '../chunk-TX2ZICS7.js';
|
|
32
33
|
import '../chunk-ZPLG7QYF.js';
|
|
33
34
|
import '../chunk-SLSBJRWW.js';
|
|
@@ -35,7 +36,7 @@ import '../chunk-7F6CBP3Z.js';
|
|
|
35
36
|
import '../chunk-VUNV25KB.js';
|
|
36
37
|
import { lazy, useState, useMemo, Suspense, useEffect, useRef, useCallback, useLayoutEffect } from 'react';
|
|
37
38
|
import { QueryClient, QueryClientProvider, useQueryClient, useQuery } from '@tanstack/react-query';
|
|
38
|
-
import { ArbiProvider, useConversations, useRunConversation, useWorkspaceActivity, useWorkspaceUsers, useWorkspaceNotificationLevel, useFollowThread, useUploadSkillFiles, ArtifactCanvas, useArbiChat, useArbi, useDocuments, useTagKindSchema, useTags, useSetTagValues, useUpdateTagKindSchema, useInvalidateTagData, useWorkspaces, useShellWorkspaces, useProfile, useUpdateProfile, useRequestEmailChange, useConfirmEmailChange, useNameEditor, useAvatarCrop, useEmailChange, ImageCropModal, useIdentityVerification, usePasswordChange, usePasswordChangeForm, useNotificationPreferences, useSessions, useCurrentSessionId, useTerminateSession, useLogoutAllSessions, useDeleteAccount, useDeleteAccountFlow, useArbiWebSocket, notify, useWorkNotifications, mailDraftIdFromContent, useMailClient, defaultMailAlias, useClaimNativeAlias, useMailOnline, useConnectMailAccount, useDisconnectMailAccount, useMailPolicy, useMailAccounts, useMailUnlock, useMailFolders, useMailMessages, useMailDraftCompose,
|
|
39
|
+
import { ArbiProvider, useConversations, useRunConversation, useWorkspaceActivity, useWorkspaceUsers, useWorkspaceNotificationLevel, useFollowThread, useUploadSkillFiles, ArtifactCanvas, useArbiChat, useArbi, useDocuments, useTagKindSchema, useTags, useSetTagValues, useUpdateTagKindSchema, useInvalidateTagData, useWorkspaces, useShellWorkspaces, useProfile, useUpdateProfile, useRequestEmailChange, useConfirmEmailChange, useNameEditor, useAvatarCrop, useEmailChange, ImageCropModal, useIdentityVerification, usePasswordChange, usePasswordChangeForm, useNotificationPreferences, useSessions, useCurrentSessionId, useTerminateSession, useLogoutAllSessions, useDeleteAccount, useDeleteAccountFlow, useArbiWebSocket, notify, useWorkNotifications, mailDraftIdFromContent, useMailClient, defaultMailAlias, useClaimNativeAlias, useMailOnline, useConnectMailAccount, useDisconnectMailAccount, useMailPolicy, useMailAccounts, useMailUnlock, useMailFolders, useMailMessages, useMailDraftCompose, useMailMessage, useMailCache, MailOfflineUnavailableError, accountPath, useAgentSession, useStartAgentSession, useCloseAgentSession, isAliasTakenError, nextAliasSuggestion, aliasTakenMessage, mailJson, ArbiWebSocketProvider, useCreateWork, useActOnStep, useConversationActivity, useConversationThreads, fileAttachment, useMailProjects, useSaveMailDraft, useSendMail, useMailDraftReplaced, AiAnswer, useMailDraftEditor } from '@arbidocs/react';
|
|
39
40
|
import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
|
|
40
41
|
import { Button, Label, Input, Dialog, DialogContent, DialogTitle, DialogDescription, Tooltip, TooltipTrigger, TooltipContent, cn } from '@arbidocs/react/ui';
|
|
41
42
|
import { useStreamedArtifact } from '@arbidocs/react/artifacts';
|
|
@@ -43,6 +44,7 @@ import { ExternalLink, UserCircle, KeyRound, Radio, Mail, Settings, Plus, ArrowL
|
|
|
43
44
|
import { useOptionalDocumentTools, fetchDocumentPdf, DocumentToolsProvider } from '@arbidocs/react/document-tools';
|
|
44
45
|
import { useNotify } from '@arbidocs/react/shell';
|
|
45
46
|
import { bytesToBase64 } from '@arbidocs/client';
|
|
47
|
+
import { createPortal } from 'react-dom';
|
|
46
48
|
|
|
47
49
|
function ConnectionBoundWebSocket({ children }) {
|
|
48
50
|
const { status } = useConnection();
|
|
@@ -2063,11 +2065,96 @@ function ConnectedMailAccounts({
|
|
|
2063
2065
|
}
|
|
2064
2066
|
);
|
|
2065
2067
|
}
|
|
2068
|
+
var sessionRooms = /* @__PURE__ */ new Map();
|
|
2069
|
+
function useWordBody({
|
|
2070
|
+
word,
|
|
2071
|
+
client,
|
|
2072
|
+
initial,
|
|
2073
|
+
sessionKey,
|
|
2074
|
+
roomId: givenRoomId,
|
|
2075
|
+
onBodyChange
|
|
2076
|
+
}) {
|
|
2077
|
+
const [documentKey] = useState(
|
|
2078
|
+
() => `mail-${sessionKey ?? initial.draft_id ?? crypto.randomUUID()}`
|
|
2079
|
+
);
|
|
2080
|
+
const roomRef = useRef(sessionRooms.get(documentKey) ?? givenRoomId);
|
|
2081
|
+
const [roomId, setRoomId] = useState(roomRef.current);
|
|
2082
|
+
const [project, setProject] = useState();
|
|
2083
|
+
const stateRef = useRef(null);
|
|
2084
|
+
const changed = useRef(onBodyChange);
|
|
2085
|
+
useEffect(() => {
|
|
2086
|
+
changed.current = onBodyChange;
|
|
2087
|
+
});
|
|
2088
|
+
const opening = useRef(null);
|
|
2089
|
+
const adapter = useMemo(
|
|
2090
|
+
() => ({
|
|
2091
|
+
...word.adapter,
|
|
2092
|
+
open: async () => {
|
|
2093
|
+
if (!roomRef.current && opening.current) return opening.current;
|
|
2094
|
+
const request = client.openDraftEditor(
|
|
2095
|
+
roomRef.current ? { roomId: roomRef.current } : { draftId: initial.draft_id ?? void 0, text: initial.text, html: initial.html }
|
|
2096
|
+
);
|
|
2097
|
+
if (!roomRef.current) opening.current = request;
|
|
2098
|
+
try {
|
|
2099
|
+
const session = await request;
|
|
2100
|
+
roomRef.current = session.room_id;
|
|
2101
|
+
sessionRooms.set(documentKey, session.room_id);
|
|
2102
|
+
setRoomId(session.room_id);
|
|
2103
|
+
setProject(session.project ?? null);
|
|
2104
|
+
return session;
|
|
2105
|
+
} finally {
|
|
2106
|
+
opening.current = null;
|
|
2107
|
+
}
|
|
2108
|
+
},
|
|
2109
|
+
save: async () => {
|
|
2110
|
+
throw new Error("Save the draft from the composer");
|
|
2111
|
+
},
|
|
2112
|
+
onDirtyChange: (dirty) => {
|
|
2113
|
+
if (dirty) changed.current();
|
|
2114
|
+
}
|
|
2115
|
+
}),
|
|
2116
|
+
// The editor keeps its adapter for the session; the seed matters only when it first opens.
|
|
2117
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
2118
|
+
[word.adapter, client, documentKey]
|
|
2119
|
+
);
|
|
2120
|
+
useEffect(() => {
|
|
2121
|
+
if (!roomId) return;
|
|
2122
|
+
return word.onRoomOpened?.(roomId) || void 0;
|
|
2123
|
+
}, [roomId, word]);
|
|
2124
|
+
const editor = useMailDraftEditor();
|
|
2125
|
+
const state = () => stateRef.current?.() ?? null;
|
|
2126
|
+
return {
|
|
2127
|
+
adapter,
|
|
2128
|
+
documentKey,
|
|
2129
|
+
stateRef,
|
|
2130
|
+
ready: !!roomId,
|
|
2131
|
+
save: (compose) => editor.save(roomRef.current, compose, state()),
|
|
2132
|
+
send: async (compose) => {
|
|
2133
|
+
const result = await editor.send(roomRef.current, compose, state());
|
|
2134
|
+
sessionRooms.delete(documentKey);
|
|
2135
|
+
return result;
|
|
2136
|
+
},
|
|
2137
|
+
body: (final) => editor.body(roomRef.current, final, state()),
|
|
2138
|
+
project,
|
|
2139
|
+
chooseProject: async (projectExtId) => {
|
|
2140
|
+
setProject(await editor.setProject(roomRef.current, projectExtId));
|
|
2141
|
+
}
|
|
2142
|
+
};
|
|
2143
|
+
}
|
|
2066
2144
|
var MailBodyEditor = lazy(
|
|
2067
2145
|
() => import('../MailBodyEditor-5PIQLYVY.js').catch(() => ({
|
|
2068
2146
|
default: PlainMailBodyEditor
|
|
2069
2147
|
}))
|
|
2070
2148
|
);
|
|
2149
|
+
var NativeDocxEditor = lazy(
|
|
2150
|
+
() => import('../NativeDocxEditor-UAZUKZ77.js').then((m) => ({ default: m.NativeDocxEditor }))
|
|
2151
|
+
);
|
|
2152
|
+
var NO_WORD = {
|
|
2153
|
+
adapter: {
|
|
2154
|
+
request: () => Promise.reject(new Error("No Word editor")),
|
|
2155
|
+
loadFonts: () => Promise.reject(new Error("No Word editor"))
|
|
2156
|
+
}
|
|
2157
|
+
};
|
|
2071
2158
|
function MailComposerForm({
|
|
2072
2159
|
account,
|
|
2073
2160
|
initial,
|
|
@@ -2076,13 +2163,18 @@ function MailComposerForm({
|
|
|
2076
2163
|
drafts,
|
|
2077
2164
|
onClose,
|
|
2078
2165
|
onOpenDraft,
|
|
2166
|
+
onReload,
|
|
2079
2167
|
onChange,
|
|
2080
2168
|
embedded = false,
|
|
2081
2169
|
closeRequestRef,
|
|
2082
2170
|
localDraftId: initialLocalDraftId,
|
|
2083
2171
|
offline,
|
|
2084
2172
|
documents,
|
|
2085
|
-
notify: notify3
|
|
2173
|
+
notify: notify3,
|
|
2174
|
+
word,
|
|
2175
|
+
sessionKey,
|
|
2176
|
+
roomId,
|
|
2177
|
+
headerSlot
|
|
2086
2178
|
}) {
|
|
2087
2179
|
const { client } = useMailClient();
|
|
2088
2180
|
const [to, setTo] = useState(initial.to.map((r) => r.email).join("; "));
|
|
@@ -2099,7 +2191,26 @@ function MailComposerForm({
|
|
|
2099
2191
|
const [dirty, setDirty] = useState(false);
|
|
2100
2192
|
const [attaching, setAttaching] = useState(false);
|
|
2101
2193
|
const [saved, setSaved] = useState(false);
|
|
2194
|
+
const [replacedBy, setReplacedBy] = useState();
|
|
2102
2195
|
const isOnline = useMailOnline();
|
|
2196
|
+
const [usesWord] = useState(
|
|
2197
|
+
() => !!word && !!client.openDraftEditor && account?.provider === "native" && isOnline && !initialLocalDraftId
|
|
2198
|
+
);
|
|
2199
|
+
const [bodyChanged, setBodyChanged] = useState(false);
|
|
2200
|
+
const [wordPending, setWordPending] = useState(false);
|
|
2201
|
+
const projects = useMailProjects({ enabled: usesWord });
|
|
2202
|
+
const wordBody = useWordBody({
|
|
2203
|
+
word: word ?? NO_WORD,
|
|
2204
|
+
client,
|
|
2205
|
+
initial,
|
|
2206
|
+
sessionKey,
|
|
2207
|
+
roomId,
|
|
2208
|
+
onBodyChange: () => {
|
|
2209
|
+
setBodyChanged(true);
|
|
2210
|
+
setSaved(false);
|
|
2211
|
+
setDirty(true);
|
|
2212
|
+
}
|
|
2213
|
+
});
|
|
2103
2214
|
const [localDraftId, setLocalDraftId] = useState(initialLocalDraftId);
|
|
2104
2215
|
const [savedLocally, setSavedLocally] = useState(false);
|
|
2105
2216
|
const [secure, setSecure] = useState(initial.secure_delivery ?? false);
|
|
@@ -2143,27 +2254,46 @@ function MailComposerForm({
|
|
|
2143
2254
|
const send = useSendMail(
|
|
2144
2255
|
offline && { keep: queueInOutbox, isNetworkFailure: offline.isNetworkFailure }
|
|
2145
2256
|
);
|
|
2146
|
-
const
|
|
2147
|
-
|
|
2148
|
-
|
|
2149
|
-
|
|
2150
|
-
|
|
2151
|
-
|
|
2152
|
-
if ("onDevice" in result) {
|
|
2153
|
-
setSavedLocally(true);
|
|
2154
|
-
return;
|
|
2155
|
-
}
|
|
2156
|
-
setSavedLocally(false);
|
|
2157
|
-
setDraftId(result.id);
|
|
2158
|
-
if (localDraftId) {
|
|
2159
|
-
void offline?.deleteDraft(localDraftId);
|
|
2160
|
-
setLocalDraftId(void 0);
|
|
2161
|
-
}
|
|
2162
|
-
},
|
|
2163
|
-
onError: (err) => setError(err.message)
|
|
2257
|
+
const onSaved = (result) => {
|
|
2258
|
+
setSaved(true);
|
|
2259
|
+
setDirty(false);
|
|
2260
|
+
if ("onDevice" in result) {
|
|
2261
|
+
setSavedLocally(true);
|
|
2262
|
+
return;
|
|
2164
2263
|
}
|
|
2165
|
-
|
|
2166
|
-
|
|
2264
|
+
setSavedLocally(false);
|
|
2265
|
+
setDraftId(result.id);
|
|
2266
|
+
setReplacedBy(void 0);
|
|
2267
|
+
if (localDraftId) {
|
|
2268
|
+
void offline?.deleteDraft(localDraftId);
|
|
2269
|
+
setLocalDraftId(void 0);
|
|
2270
|
+
}
|
|
2271
|
+
};
|
|
2272
|
+
const saveDraft = () => {
|
|
2273
|
+
if (usesWord) {
|
|
2274
|
+
if (!wordBody.ready) return setError("The editor is still opening");
|
|
2275
|
+
setWordPending(true);
|
|
2276
|
+
void wordBody.save(body()).then(
|
|
2277
|
+
(result) => {
|
|
2278
|
+
onSaved(result);
|
|
2279
|
+
setBodyChanged(false);
|
|
2280
|
+
},
|
|
2281
|
+
(err) => setError(err.message)
|
|
2282
|
+
).finally(() => setWordPending(false));
|
|
2283
|
+
return;
|
|
2284
|
+
}
|
|
2285
|
+
save.mutate(
|
|
2286
|
+
{ accountId: account.id, compose: body() },
|
|
2287
|
+
{ onSuccess: onSaved, onError: (err) => setError(err.message) }
|
|
2288
|
+
);
|
|
2289
|
+
};
|
|
2290
|
+
useMailDraftReplaced(draftId, (newId) => {
|
|
2291
|
+
if (save.isPending || wordPending) return;
|
|
2292
|
+
setDraftId(newId);
|
|
2293
|
+
if (!dirty && onReload) onReload(newId);
|
|
2294
|
+
else setReplacedBy(newId);
|
|
2295
|
+
});
|
|
2296
|
+
const sendMessage = async () => {
|
|
2167
2297
|
let value = attemptedPayload.current;
|
|
2168
2298
|
if (value === null) {
|
|
2169
2299
|
value = body();
|
|
@@ -2172,18 +2302,41 @@ function MailComposerForm({
|
|
|
2172
2302
|
if (problem) return setError(problem);
|
|
2173
2303
|
if (!(offline && !isOnline)) attemptedPayload.current = value;
|
|
2174
2304
|
}
|
|
2305
|
+
if (usesWord) {
|
|
2306
|
+
if (!wordBody.ready) return setError("The editor is still opening");
|
|
2307
|
+
const refused = (err) => {
|
|
2308
|
+
setError(err.message);
|
|
2309
|
+
if (err.status === 409) attemptedPayload.current = null;
|
|
2310
|
+
};
|
|
2311
|
+
setWordPending(true);
|
|
2312
|
+
try {
|
|
2313
|
+
if (!secure) {
|
|
2314
|
+
await wordBody.send({ ...value, request_id: requestId.current });
|
|
2315
|
+
notify3("Email queued for delivery", "success");
|
|
2316
|
+
onClose();
|
|
2317
|
+
return;
|
|
2318
|
+
}
|
|
2319
|
+
value = { ...value, ...await wordBody.body(true) };
|
|
2320
|
+
attemptedPayload.current = value;
|
|
2321
|
+
} catch (err) {
|
|
2322
|
+
return refused(err);
|
|
2323
|
+
} finally {
|
|
2324
|
+
setWordPending(false);
|
|
2325
|
+
}
|
|
2326
|
+
}
|
|
2175
2327
|
const sending = account;
|
|
2328
|
+
const message = value;
|
|
2176
2329
|
send.mutate(
|
|
2177
2330
|
{
|
|
2178
2331
|
accountId: account.id,
|
|
2179
|
-
compose:
|
|
2332
|
+
compose: message,
|
|
2180
2333
|
requestId: requestId.current,
|
|
2181
2334
|
// Secure delivery prepares its encrypted payload once.
|
|
2182
2335
|
secure: secure ? async () => {
|
|
2183
2336
|
if (sending?.provider !== "native" || !client.prepareSecureMail)
|
|
2184
2337
|
throw new Error("Choose your native inbox to send securely");
|
|
2185
2338
|
securePayload.current ??= await client.prepareSecureMail(
|
|
2186
|
-
|
|
2339
|
+
message,
|
|
2187
2340
|
sending,
|
|
2188
2341
|
requestId.current
|
|
2189
2342
|
);
|
|
@@ -2207,7 +2360,7 @@ function MailComposerForm({
|
|
|
2207
2360
|
}
|
|
2208
2361
|
);
|
|
2209
2362
|
};
|
|
2210
|
-
const busy = attaching || save.isPending || send.isPending;
|
|
2363
|
+
const busy = attaching || save.isPending || send.isPending || wordPending;
|
|
2211
2364
|
const locked = busy || attemptedPayload.current !== null;
|
|
2212
2365
|
const addFiles = async (files) => {
|
|
2213
2366
|
if (!files) return;
|
|
@@ -2246,7 +2399,7 @@ function MailComposerForm({
|
|
|
2246
2399
|
};
|
|
2247
2400
|
const close = () => {
|
|
2248
2401
|
if (busy) return;
|
|
2249
|
-
if (!saved && (dirty || !draftId) && (text || subject || to || cc || bcc || attachments.length) && !window.confirm("Close this message without saving your latest changes?"))
|
|
2402
|
+
if (!saved && (dirty || !draftId) && (text || subject || to || cc || bcc || attachments.length || bodyChanged) && !window.confirm("Close this message without saving your latest changes?"))
|
|
2250
2403
|
return;
|
|
2251
2404
|
onClose();
|
|
2252
2405
|
};
|
|
@@ -2256,6 +2409,30 @@ function MailComposerForm({
|
|
|
2256
2409
|
useEffect(() => {
|
|
2257
2410
|
onChange?.(body());
|
|
2258
2411
|
}, [to, cc, bcc, subject, text, html, attachments, draftId, secure]);
|
|
2412
|
+
const billTo = wordBody.project && /* @__PURE__ */ jsxs(
|
|
2413
|
+
"label",
|
|
2414
|
+
{
|
|
2415
|
+
className: "flex items-center gap-1 text-xs text-muted-foreground",
|
|
2416
|
+
title: "ARBI's work on this email is billed to this project",
|
|
2417
|
+
children: [
|
|
2418
|
+
"Billed to",
|
|
2419
|
+
/* @__PURE__ */ jsx(
|
|
2420
|
+
"select",
|
|
2421
|
+
{
|
|
2422
|
+
"aria-label": "Bill to",
|
|
2423
|
+
className: "max-w-[12rem] truncate rounded bg-transparent py-0.5 text-foreground hover:bg-muted/60 focus:bg-muted/60 focus:outline-none",
|
|
2424
|
+
value: wordBody.project.external_id,
|
|
2425
|
+
disabled: busy,
|
|
2426
|
+
onChange: (e) => {
|
|
2427
|
+
const chosen = projects.data?.find((p) => p.external_id === e.target.value);
|
|
2428
|
+
void wordBody.chooseProject(chosen && !chosen.personal ? chosen.external_id : null).catch((err) => setError(err.message));
|
|
2429
|
+
},
|
|
2430
|
+
children: (projects.data ?? [wordBody.project]).map((p) => /* @__PURE__ */ jsx("option", { value: p.external_id, children: p.personal ? `${p.name} (personal)` : p.name }, p.external_id))
|
|
2431
|
+
}
|
|
2432
|
+
)
|
|
2433
|
+
]
|
|
2434
|
+
}
|
|
2435
|
+
);
|
|
2259
2436
|
const form = /* @__PURE__ */ jsxs(
|
|
2260
2437
|
"form",
|
|
2261
2438
|
{
|
|
@@ -2271,7 +2448,7 @@ function MailComposerForm({
|
|
|
2271
2448
|
onSubmit: (e) => {
|
|
2272
2449
|
e.preventDefault();
|
|
2273
2450
|
setError("");
|
|
2274
|
-
sendMessage();
|
|
2451
|
+
void sendMessage();
|
|
2275
2452
|
},
|
|
2276
2453
|
className: embedded ? "flex h-full min-h-0 w-full flex-col bg-background" : "flex max-h-[95dvh] w-full max-w-3xl flex-col rounded-xl border bg-background shadow-2xl",
|
|
2277
2454
|
children: [
|
|
@@ -2289,7 +2466,7 @@ function MailComposerForm({
|
|
|
2289
2466
|
}
|
|
2290
2467
|
)
|
|
2291
2468
|
] }),
|
|
2292
|
-
/* @__PURE__ */ jsxs("div", { className: "min-h-0 flex-1 overflow-auto px-5 py-3", children: [
|
|
2469
|
+
/* @__PURE__ */ jsxs("div", { className: "flex min-h-0 flex-1 flex-col overflow-auto px-5 py-3", children: [
|
|
2293
2470
|
sameSubjectDraft && /* @__PURE__ */ jsxs(
|
|
2294
2471
|
"div",
|
|
2295
2472
|
{
|
|
@@ -2310,10 +2487,36 @@ function MailComposerForm({
|
|
|
2310
2487
|
]
|
|
2311
2488
|
}
|
|
2312
2489
|
),
|
|
2490
|
+
replacedBy && /* @__PURE__ */ jsxs(
|
|
2491
|
+
"div",
|
|
2492
|
+
{
|
|
2493
|
+
role: "status",
|
|
2494
|
+
className: "mb-3 flex items-center justify-between gap-3 rounded-md bg-muted/40 px-3 py-2 text-xs text-muted-foreground",
|
|
2495
|
+
children: [
|
|
2496
|
+
"This draft was changed elsewhere (by ARBI or in another tab). Saving keeps your version.",
|
|
2497
|
+
onReload && /* @__PURE__ */ jsx(
|
|
2498
|
+
Button,
|
|
2499
|
+
{
|
|
2500
|
+
type: "button",
|
|
2501
|
+
variant: "ghost",
|
|
2502
|
+
className: "h-7 shrink-0 text-xs",
|
|
2503
|
+
disabled: busy,
|
|
2504
|
+
onClick: () => {
|
|
2505
|
+
if (window.confirm("Discard your unsaved changes and load the changed draft?"))
|
|
2506
|
+
onReload(replacedBy);
|
|
2507
|
+
},
|
|
2508
|
+
children: "Load changes"
|
|
2509
|
+
}
|
|
2510
|
+
)
|
|
2511
|
+
]
|
|
2512
|
+
}
|
|
2513
|
+
),
|
|
2313
2514
|
/* @__PURE__ */ jsxs("p", { className: "mb-2 flex items-center gap-3 border-b border-border/60 pb-3 text-xs text-muted-foreground", children: [
|
|
2314
2515
|
/* @__PURE__ */ jsx("span", { className: "w-14 shrink-0", children: "From" }),
|
|
2315
2516
|
/* @__PURE__ */ jsx("span", { className: "rounded bg-muted/50 px-2 py-1 text-foreground", children: account?.email ?? "Connect a mailbox to send" })
|
|
2316
2517
|
] }),
|
|
2518
|
+
usesWord && wordBody.project && !headerSlot && /* @__PURE__ */ jsx("p", { className: "mb-2", children: billTo }),
|
|
2519
|
+
usesWord && wordBody.project && headerSlot && createPortal(billTo, headerSlot),
|
|
2317
2520
|
[
|
|
2318
2521
|
["To", to, setTo],
|
|
2319
2522
|
["Cc", cc, setCc],
|
|
@@ -2386,7 +2589,24 @@ function MailComposerForm({
|
|
|
2386
2589
|
}
|
|
2387
2590
|
)
|
|
2388
2591
|
] }),
|
|
2389
|
-
/* @__PURE__ */ jsx(Suspense, { fallback: /* @__PURE__ */ jsx("p", { className: "py-4 text-sm text-muted-foreground", children: "Loading editor\u2026" }), children: /* @__PURE__ */ jsx(
|
|
2592
|
+
/* @__PURE__ */ jsx(Suspense, { fallback: /* @__PURE__ */ jsx("p", { className: "py-4 text-sm text-muted-foreground", children: "Loading editor\u2026" }), children: usesWord ? /* @__PURE__ */ jsx(
|
|
2593
|
+
"div",
|
|
2594
|
+
{
|
|
2595
|
+
className: "-mx-5 -mb-3 flex min-h-[22rem] flex-1 flex-col border-t border-border/60",
|
|
2596
|
+
"data-testid": "mail-word-body",
|
|
2597
|
+
onSubmit: (event) => event.stopPropagation(),
|
|
2598
|
+
children: /* @__PURE__ */ jsx(
|
|
2599
|
+
NativeDocxEditor,
|
|
2600
|
+
{
|
|
2601
|
+
compact: true,
|
|
2602
|
+
adapter: wordBody.adapter,
|
|
2603
|
+
documentId: wordBody.documentKey,
|
|
2604
|
+
title: "Email",
|
|
2605
|
+
stateRef: wordBody.stateRef
|
|
2606
|
+
}
|
|
2607
|
+
)
|
|
2608
|
+
}
|
|
2609
|
+
) : /* @__PURE__ */ jsx(
|
|
2390
2610
|
MailBodyEditor,
|
|
2391
2611
|
{
|
|
2392
2612
|
text,
|
|
@@ -2553,6 +2773,7 @@ function ConnectedMailComposer({
|
|
|
2553
2773
|
drafts: draftsProp,
|
|
2554
2774
|
notify: notify3 = defaultMailNotify,
|
|
2555
2775
|
offline,
|
|
2776
|
+
replyTo,
|
|
2556
2777
|
...rest
|
|
2557
2778
|
}) {
|
|
2558
2779
|
const { client } = useMailClient();
|
|
@@ -2567,9 +2788,11 @@ function ConnectedMailComposer({
|
|
|
2567
2788
|
const draftsList = useMailMessages(account, draftsFolderId, "", null, {
|
|
2568
2789
|
enabled: !draftsProp && ready
|
|
2569
2790
|
});
|
|
2791
|
+
const [reloaded, setReloaded] = useState();
|
|
2792
|
+
const openId = reloaded ?? draftId;
|
|
2570
2793
|
const draft = useMailDraftCompose(
|
|
2571
2794
|
account,
|
|
2572
|
-
|
|
2795
|
+
openId,
|
|
2573
2796
|
async (from, id) => {
|
|
2574
2797
|
const message = await client.getMessage(from, id);
|
|
2575
2798
|
return draftMailCompose(
|
|
@@ -2580,14 +2803,20 @@ function ConnectedMailComposer({
|
|
|
2580
2803
|
})
|
|
2581
2804
|
);
|
|
2582
2805
|
},
|
|
2583
|
-
{ enabled: !initial && ready }
|
|
2584
|
-
);
|
|
2585
|
-
const start = useMemo(
|
|
2586
|
-
() => initial ?? (draftId ? draft.data : emptyMailCompose()),
|
|
2587
|
-
[initial, draftId, draft.data]
|
|
2806
|
+
{ enabled: (!initial || !!reloaded) && ready }
|
|
2588
2807
|
);
|
|
2808
|
+
const original = useMailMessage(account, replyTo, { enabled: !!replyTo && ready });
|
|
2809
|
+
const start = useMemo(() => {
|
|
2810
|
+
if (replyTo)
|
|
2811
|
+
return original.data && account ? {
|
|
2812
|
+
...replyMailCompose(original.data, { account, folderRole: "inbox" }),
|
|
2813
|
+
text: "",
|
|
2814
|
+
html: ""
|
|
2815
|
+
} : void 0;
|
|
2816
|
+
return reloaded ? draft.data : initial ?? (openId ? draft.data : emptyMailCompose());
|
|
2817
|
+
}, [replyTo, original.data, account, reloaded, initial, openId, draft.data]);
|
|
2589
2818
|
if (!start)
|
|
2590
|
-
return draft.error ? /* @__PURE__ */ jsx("p", { role: "alert", className: "p-4 text-sm text-destructive", children: draft.error.message }) : /* @__PURE__ */ jsx("p", { className: "p-4 text-sm text-muted-foreground", children: "Loading draft\u2026" });
|
|
2819
|
+
return draft.error ?? original.error ? /* @__PURE__ */ jsx("p", { role: "alert", className: "p-4 text-sm text-destructive", children: (draft.error ?? original.error)?.message }) : /* @__PURE__ */ jsx("p", { className: "p-4 text-sm text-muted-foreground", children: "Loading draft\u2026" });
|
|
2591
2820
|
return /* @__PURE__ */ jsx(
|
|
2592
2821
|
MailComposerForm,
|
|
2593
2822
|
{
|
|
@@ -2598,9 +2827,10 @@ function ConnectedMailComposer({
|
|
|
2598
2827
|
drafts: draftsProp ?? draftsList.data?.messages ?? [],
|
|
2599
2828
|
notify: notify3,
|
|
2600
2829
|
offline,
|
|
2830
|
+
onReload: setReloaded,
|
|
2601
2831
|
...rest
|
|
2602
2832
|
},
|
|
2603
|
-
`${account?.id}-${
|
|
2833
|
+
`${account?.id}-${openId ?? ""}`
|
|
2604
2834
|
);
|
|
2605
2835
|
}
|
|
2606
2836
|
function ConnectedMailSetup({
|
|
@@ -2780,6 +3010,8 @@ function ConnectedMailbox({
|
|
|
2780
3010
|
offline,
|
|
2781
3011
|
documents,
|
|
2782
3012
|
saveToWorkspace,
|
|
3013
|
+
word,
|
|
3014
|
+
onReplyWithArbi,
|
|
2783
3015
|
renderInvite,
|
|
2784
3016
|
renderPanel = SidePanel,
|
|
2785
3017
|
onViewerOpenChange,
|
|
@@ -2809,6 +3041,7 @@ function ConnectedMailbox({
|
|
|
2809
3041
|
const [compose, setCompose] = useState(null);
|
|
2810
3042
|
const [composeLocalDraftId, setComposeLocalDraftId] = useState();
|
|
2811
3043
|
const [composeSession, setComposeSession] = useState(0);
|
|
3044
|
+
const [mailboxKey] = useState(() => crypto.randomUUID());
|
|
2812
3045
|
const openCompose = (value, localDraftId) => {
|
|
2813
3046
|
setComposeSession((n) => n + 1);
|
|
2814
3047
|
setComposeLocalDraftId(localDraftId);
|
|
@@ -3231,6 +3464,8 @@ function ConnectedMailbox({
|
|
|
3231
3464
|
offline,
|
|
3232
3465
|
documents,
|
|
3233
3466
|
notify: notify3,
|
|
3467
|
+
word,
|
|
3468
|
+
sessionKey: `${mailboxKey}-${composeSession}`,
|
|
3234
3469
|
onChange: setCompose,
|
|
3235
3470
|
closeRequestRef: composeClose,
|
|
3236
3471
|
onClose: () => {
|
|
@@ -3265,6 +3500,7 @@ function ConnectedMailbox({
|
|
|
3265
3500
|
onBack: () => setSelected(null),
|
|
3266
3501
|
onEditDraft: () => void editDraft(),
|
|
3267
3502
|
onReply: (forward, all) => void reply(forward, all),
|
|
3503
|
+
onReplyWithArbi: onReplyWithArbi && account.provider === "native" ? () => onReplyWithArbi(message, account) : void 0,
|
|
3268
3504
|
onUpdate: (body) => void update(body),
|
|
3269
3505
|
onDownloadAttachment: (a) => void downloadAttachment(a),
|
|
3270
3506
|
onDownloadOriginal: () => void download(
|
|
@@ -3320,6 +3556,85 @@ function ConnectedMailbox({
|
|
|
3320
3556
|
)
|
|
3321
3557
|
] });
|
|
3322
3558
|
}
|
|
3559
|
+
function ConnectedMailMessage({
|
|
3560
|
+
messageId,
|
|
3561
|
+
mailbox = "native",
|
|
3562
|
+
folderRole = "inbox",
|
|
3563
|
+
onClose,
|
|
3564
|
+
onCompose,
|
|
3565
|
+
onReplyWithArbi
|
|
3566
|
+
}) {
|
|
3567
|
+
const { client } = useMailClient();
|
|
3568
|
+
const isOnline = useMailOnline();
|
|
3569
|
+
const cache = useMailCache();
|
|
3570
|
+
const accounts = useMailAccounts();
|
|
3571
|
+
const account = resolveMailbox(accounts.data, mailbox);
|
|
3572
|
+
const unlock = useMailUnlock(account);
|
|
3573
|
+
const detail = useMailMessage(account, messageId, { enabled: !!unlock.data || !isOnline });
|
|
3574
|
+
const [error, setError] = useState("");
|
|
3575
|
+
const message = detail.data;
|
|
3576
|
+
if (!account || !message)
|
|
3577
|
+
return /* @__PURE__ */ jsx("p", { role: detail.error ? "alert" : "status", className: "p-4 text-sm text-muted-foreground", children: detail.error?.message ?? "Loading message\u2026" });
|
|
3578
|
+
const update = async (body) => {
|
|
3579
|
+
try {
|
|
3580
|
+
await mailJson(
|
|
3581
|
+
client.fetch,
|
|
3582
|
+
`${accountPath(account.id)}/messages/${encodeURIComponent(message.id)}`,
|
|
3583
|
+
{
|
|
3584
|
+
method: "PATCH",
|
|
3585
|
+
body: JSON.stringify(body)
|
|
3586
|
+
}
|
|
3587
|
+
);
|
|
3588
|
+
await cache.refreshAll();
|
|
3589
|
+
if (body.folder_id || body.action) onClose();
|
|
3590
|
+
} catch (e) {
|
|
3591
|
+
setError(e instanceof Error ? e.message : "Could not update message");
|
|
3592
|
+
}
|
|
3593
|
+
};
|
|
3594
|
+
const download = async (path, name) => {
|
|
3595
|
+
try {
|
|
3596
|
+
saveFile(await (await client.fetch(path)).blob(), name);
|
|
3597
|
+
} catch (e) {
|
|
3598
|
+
setError(e instanceof Error ? e.message : "Download failed");
|
|
3599
|
+
}
|
|
3600
|
+
};
|
|
3601
|
+
const reply = async (forward = false, all = false) => {
|
|
3602
|
+
try {
|
|
3603
|
+
const attachments = forward ? await hydrateMailAttachments(client, account, message.id, message.attachments, {
|
|
3604
|
+
isOnline
|
|
3605
|
+
}) : [];
|
|
3606
|
+
onCompose(replyMailCompose(message, { account, folderRole, forward, all, attachments }));
|
|
3607
|
+
} catch (e) {
|
|
3608
|
+
setError(e instanceof Error ? e.message : "Could not prepare forwarded attachments");
|
|
3609
|
+
}
|
|
3610
|
+
};
|
|
3611
|
+
return /* @__PURE__ */ jsxs("div", { className: "flex h-full min-h-0 flex-col", children: [
|
|
3612
|
+
error && /* @__PURE__ */ jsx("p", { role: "alert", className: "px-4 pt-3 text-sm text-destructive", children: error }),
|
|
3613
|
+
/* @__PURE__ */ jsx(
|
|
3614
|
+
MailMessageView,
|
|
3615
|
+
{
|
|
3616
|
+
account,
|
|
3617
|
+
message,
|
|
3618
|
+
folderRole,
|
|
3619
|
+
folders: void 0,
|
|
3620
|
+
isOnline,
|
|
3621
|
+
loading: detail.isFetching,
|
|
3622
|
+
onBack: onClose,
|
|
3623
|
+
onEditDraft: () => void hydrateMailAttachments(client, account, message.id, message.attachments, {
|
|
3624
|
+
isOnline
|
|
3625
|
+
}).then((attachments) => onCompose(draftMailCompose(message, attachments))).catch((e) => setError(e.message)),
|
|
3626
|
+
onReply: (forward, all) => void reply(forward, all),
|
|
3627
|
+
onReplyWithArbi: onReplyWithArbi && account.provider === "native" ? () => onReplyWithArbi(message, account) : void 0,
|
|
3628
|
+
onUpdate: (body) => void update(body),
|
|
3629
|
+
onDownloadAttachment: (a) => void download(attachmentPath(account.id, message.id, a.id), a.name),
|
|
3630
|
+
onDownloadOriginal: () => void download(
|
|
3631
|
+
`${accountPath(account.id)}/messages/${message.id}/original`,
|
|
3632
|
+
"original.eml"
|
|
3633
|
+
)
|
|
3634
|
+
}
|
|
3635
|
+
)
|
|
3636
|
+
] });
|
|
3637
|
+
}
|
|
3323
3638
|
function ActiveChat({ agentId, workspaceId }) {
|
|
3324
3639
|
const chat = useArbiChat({ agentId, workspaceId });
|
|
3325
3640
|
return /* @__PURE__ */ jsx(
|
|
@@ -3383,6 +3698,6 @@ function ConnectedAgentChatPanel({
|
|
|
3383
3698
|
] });
|
|
3384
3699
|
}
|
|
3385
3700
|
|
|
3386
|
-
export { ArbiAppProvider, ConnectedAgentChatPanel, ConnectedDangerZone, ConnectedIdentityVerification, ConnectedLogoutDialog, ConnectedMailAccounts, ConnectedMailComposer, ConnectedMailSetup, ConnectedMailbox, ConnectedNotificationPreferences, ConnectedProfileCard, ConnectedRequireVerified, ConnectedSecuritySection, ConnectedSessionsRow, ConnectedSkillUpload, ConnectedTagTable, ConnectedTaskAccessRequest, ConnectedThreadFollow, ConnectedWorkflowRunner, ConnectedWorkspaceActivity, ConnectedWorkspaceNotificationMenu, DEFAULT_CONNECTED_WORKFLOW_RUNNER_LABELS, StreamedArtifact, WorkflowRunThread, defaultMailNotify, defaultUnmetPasswordRequirement, resolveMailbox, useConnectedDocxNotifications, useConnectedShellWorkspaces, useConnectedWorkNotifications };
|
|
3701
|
+
export { ArbiAppProvider, ConnectedAgentChatPanel, ConnectedDangerZone, ConnectedIdentityVerification, ConnectedLogoutDialog, ConnectedMailAccounts, ConnectedMailComposer, ConnectedMailMessage, ConnectedMailSetup, ConnectedMailbox, ConnectedNotificationPreferences, ConnectedProfileCard, ConnectedRequireVerified, ConnectedSecuritySection, ConnectedSessionsRow, ConnectedSkillUpload, ConnectedTagTable, ConnectedTaskAccessRequest, ConnectedThreadFollow, ConnectedWorkflowRunner, ConnectedWorkspaceActivity, ConnectedWorkspaceNotificationMenu, DEFAULT_CONNECTED_WORKFLOW_RUNNER_LABELS, StreamedArtifact, WorkflowRunThread, defaultMailNotify, defaultUnmetPasswordRequirement, resolveMailbox, useConnectedDocxNotifications, useConnectedShellWorkspaces, useConnectedWorkNotifications };
|
|
3387
3702
|
//# sourceMappingURL=index.js.map
|
|
3388
3703
|
//# sourceMappingURL=index.js.map
|