@arbidocs/blocks 0.5.43 → 0.5.45
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/README.md +14 -0
- package/dist/agents/definitions/agentTasks.d.ts +4 -0
- package/dist/agents/definitions/index.d.ts +1 -0
- package/dist/agents/index.cjs +14 -10
- package/dist/agents/index.js +1 -1
- package/dist/calls/index.cjs +73 -696
- package/dist/calls/index.cjs.map +1 -1
- package/dist/calls/index.js +10 -666
- package/dist/calls/index.js.map +1 -1
- package/dist/{chunk-6AJJJ5HR.cjs → chunk-5R256EMF.cjs} +671 -3
- package/dist/chunk-5R256EMF.cjs.map +1 -0
- package/dist/{chunk-E3IEZMRK.cjs → chunk-ET42AFEJ.cjs} +15 -2
- package/dist/chunk-ET42AFEJ.cjs.map +1 -0
- package/dist/{chunk-FOIDBAZB.js → chunk-OQMWTEM2.js} +15 -3
- package/dist/chunk-OQMWTEM2.js.map +1 -0
- package/dist/{chunk-4U4NXFV5.js → chunk-TKTNXFAB.js} +666 -9
- package/dist/chunk-TKTNXFAB.js.map +1 -0
- package/dist/connect/index.cjs +1736 -482
- package/dist/connect/index.cjs.map +1 -1
- package/dist/connect/index.d.ts +2 -0
- package/dist/connect/index.js +1729 -479
- package/dist/connect/index.js.map +1 -1
- package/dist/connection/ConnectedFilterDropdown.d.ts +6 -0
- package/dist/connection/agents/useConnectedAgentManagement.d.ts +60 -0
- package/dist/connection/conversation/ConnectedConversation.d.ts +7 -9
- package/dist/connection/conversation/ConnectedConversationPage.d.ts +30 -0
- package/dist/connection/conversation/SemanticSearchButton.d.ts +12 -0
- package/dist/connection/files/imports/ConnectedAccountsImport.d.ts +16 -0
- package/dist/connection/files/imports/DriveImportPanel.d.ts +10 -0
- package/dist/connection/files/imports/EmailImportPanel.d.ts +21 -0
- package/dist/connection/files/imports/ImportHandoff.d.ts +24 -0
- package/dist/connection/files/imports/useDriveSyncTrigger.d.ts +11 -0
- package/dist/connection/files/imports/useEmailSyncTrigger.d.ts +11 -0
- package/dist/connection/files/imports/useImportHandoff.d.ts +20 -0
- package/dist/connection/files/index.d.ts +1 -0
- package/dist/index.cjs +14 -10
- package/dist/index.js +1 -1
- package/dist/workflow-canvas/index.cjs +2 -2
- package/dist/workflow-canvas/index.js +1 -1
- package/node_modules/@arbidocs/coedit/package.json +1 -1
- package/package.json +5 -5
- package/dist/chunk-4U4NXFV5.js.map +0 -1
- package/dist/chunk-6AJJJ5HR.cjs.map +0 -1
- package/dist/chunk-E3IEZMRK.cjs.map +0 -1
- package/dist/chunk-FOIDBAZB.js.map +0 -1
package/dist/connect/index.cjs
CHANGED
|
@@ -62,7 +62,7 @@ var chunkCG757WKY_cjs = require('../chunk-CG757WKY.cjs');
|
|
|
62
62
|
var chunkW3PSIIMN_cjs = require('../chunk-W3PSIIMN.cjs');
|
|
63
63
|
var chunkQUMUAJ2P_cjs = require('../chunk-QUMUAJ2P.cjs');
|
|
64
64
|
var chunkVZOOGA47_cjs = require('../chunk-VZOOGA47.cjs');
|
|
65
|
-
var
|
|
65
|
+
var chunk5R256EMF_cjs = require('../chunk-5R256EMF.cjs');
|
|
66
66
|
var chunkEGSSLWNZ_cjs = require('../chunk-EGSSLWNZ.cjs');
|
|
67
67
|
var chunkHDEOORSV_cjs = require('../chunk-HDEOORSV.cjs');
|
|
68
68
|
var chunkP6HVJP6Z_cjs = require('../chunk-P6HVJP6Z.cjs');
|
|
@@ -2288,6 +2288,76 @@ function ConnectedAgentCreator({
|
|
|
2288
2288
|
) })
|
|
2289
2289
|
] });
|
|
2290
2290
|
}
|
|
2291
|
+
var DEFAULT_LABELS = {
|
|
2292
|
+
addressCopied: "Agent address copied",
|
|
2293
|
+
addressCopyFailed: "Could not copy the address",
|
|
2294
|
+
deleted: (agent) => `Agent "${agent.given_name}" deleted.`,
|
|
2295
|
+
deleteFailed: (error) => `Delete failed: ${error instanceof Error ? error.message : error}`
|
|
2296
|
+
};
|
|
2297
|
+
function useConnectedAgentManagement({
|
|
2298
|
+
confirmDelete,
|
|
2299
|
+
onAssignTask,
|
|
2300
|
+
labels
|
|
2301
|
+
} = {}) {
|
|
2302
|
+
const { data: agents = [], isLoading } = react.useAgents();
|
|
2303
|
+
const deletion = react.useDeleteAgents();
|
|
2304
|
+
const { notify: notify18 } = chunkB3NYBMDR_cjs.useBlocksEnvironment();
|
|
2305
|
+
const l = { ...DEFAULT_LABELS, ...labels };
|
|
2306
|
+
const [editorOpen, setEditorOpen] = React9.useState(false);
|
|
2307
|
+
const [editing, setEditing] = React9.useState(null);
|
|
2308
|
+
const [assignFor, setAssignFor] = React9.useState(null);
|
|
2309
|
+
const onEditorOpenChange = (open) => {
|
|
2310
|
+
setEditorOpen(open);
|
|
2311
|
+
};
|
|
2312
|
+
const create4 = () => {
|
|
2313
|
+
setEditing(null);
|
|
2314
|
+
setEditorOpen(true);
|
|
2315
|
+
};
|
|
2316
|
+
const edit = (agent) => {
|
|
2317
|
+
setEditing(agent);
|
|
2318
|
+
setEditorOpen(true);
|
|
2319
|
+
};
|
|
2320
|
+
const assign = (agent) => {
|
|
2321
|
+
if (onAssignTask) onAssignTask(agent);
|
|
2322
|
+
else setAssignFor(agent);
|
|
2323
|
+
};
|
|
2324
|
+
const remove = async (agent) => {
|
|
2325
|
+
try {
|
|
2326
|
+
if (confirmDelete && !await confirmDelete(agent)) return false;
|
|
2327
|
+
await deletion.mutateAsync({ agentExtIds: [agent.external_id] });
|
|
2328
|
+
notify18(l.deleted(agent), "success");
|
|
2329
|
+
return true;
|
|
2330
|
+
} catch (error) {
|
|
2331
|
+
notify18(l.deleteFailed(error), "error");
|
|
2332
|
+
return false;
|
|
2333
|
+
}
|
|
2334
|
+
};
|
|
2335
|
+
const copyAddress = async (address) => {
|
|
2336
|
+
try {
|
|
2337
|
+
await navigator.clipboard.writeText(address);
|
|
2338
|
+
notify18(l.addressCopied, "success");
|
|
2339
|
+
} catch {
|
|
2340
|
+
if (l.addressCopyFailed !== null) notify18(l.addressCopyFailed, "error");
|
|
2341
|
+
}
|
|
2342
|
+
};
|
|
2343
|
+
return {
|
|
2344
|
+
agents,
|
|
2345
|
+
isLoading,
|
|
2346
|
+
create: create4,
|
|
2347
|
+
edit,
|
|
2348
|
+
assign,
|
|
2349
|
+
remove,
|
|
2350
|
+
copyAddress,
|
|
2351
|
+
editorProps: { open: editorOpen, onOpenChange: onEditorOpenChange, agent: editing },
|
|
2352
|
+
assignmentProps: assignFor ? {
|
|
2353
|
+
open: true,
|
|
2354
|
+
onOpenChange: (open) => {
|
|
2355
|
+
if (!open) setAssignFor(null);
|
|
2356
|
+
},
|
|
2357
|
+
initialAgentExtId: assignFor.external_id
|
|
2358
|
+
} : null
|
|
2359
|
+
};
|
|
2360
|
+
}
|
|
2291
2361
|
var RUN_KIND = {
|
|
2292
2362
|
email_documents: "Email",
|
|
2293
2363
|
annotate_documents: "AI Review",
|
|
@@ -29004,6 +29074,870 @@ function ConnectedGridView(props) {
|
|
|
29004
29074
|
);
|
|
29005
29075
|
return /* @__PURE__ */ jsxRuntime.jsx(chunkLKK52DEY_cjs.GridView, { ...props, gridState, onGridStateChange });
|
|
29006
29076
|
}
|
|
29077
|
+
function useEmailSyncTrigger() {
|
|
29078
|
+
const arbi = react.useArbi();
|
|
29079
|
+
const { notify: notify18 } = chunkB3NYBMDR_cjs.useBlocksEnvironment();
|
|
29080
|
+
const triggerSync = react.useTriggerMailboxSync();
|
|
29081
|
+
const runSync = React9.useCallback(
|
|
29082
|
+
async ({
|
|
29083
|
+
vendorKey,
|
|
29084
|
+
workspaceExtId,
|
|
29085
|
+
workspaceLabel = "the workspace"
|
|
29086
|
+
}) => {
|
|
29087
|
+
await arbi.connectors.bridgeTokens({ vendor: vendorKey });
|
|
29088
|
+
if (workspaceExtId) {
|
|
29089
|
+
await arbi.workspaces.open(workspaceExtId).catch(() => {
|
|
29090
|
+
});
|
|
29091
|
+
}
|
|
29092
|
+
triggerSync.mutate(
|
|
29093
|
+
{ vendorKey, workspaceExtId },
|
|
29094
|
+
{
|
|
29095
|
+
onSuccess: (res) => {
|
|
29096
|
+
const n = res?.estimated_count;
|
|
29097
|
+
if (n === 0) {
|
|
29098
|
+
notify18("You\u2019re up to date \u2014 no new emails to sync.", "success");
|
|
29099
|
+
} else if (n != null && n > 0) {
|
|
29100
|
+
notify18(
|
|
29101
|
+
`Fetching ${n} new email${n === 1 ? "" : "s"} to ${workspaceLabel}.`,
|
|
29102
|
+
"success"
|
|
29103
|
+
);
|
|
29104
|
+
} else {
|
|
29105
|
+
notify18("Sync started \u2014 fetching new emails\u2026", "success");
|
|
29106
|
+
}
|
|
29107
|
+
},
|
|
29108
|
+
onError: (err) => {
|
|
29109
|
+
if (react.connectorErrorStatus(err) === 425) {
|
|
29110
|
+
notify18("Still preparing your session \u2014 please try Sync now again.", "error");
|
|
29111
|
+
} else if (react.connectorErrorStatus(err) === 409) {
|
|
29112
|
+
notify18("Reconnect needed \u2014 your account needs to be re-authorized.", "error");
|
|
29113
|
+
} else if (react.connectorErrorStatus(err) === 404) {
|
|
29114
|
+
notify18("Email sync is not enabled for this connector yet.", "error");
|
|
29115
|
+
} else {
|
|
29116
|
+
notify18("Could not start sync. Please try again.", "error");
|
|
29117
|
+
}
|
|
29118
|
+
}
|
|
29119
|
+
}
|
|
29120
|
+
);
|
|
29121
|
+
},
|
|
29122
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps -- triggerSync.mutate is a stable TanStack Query reference
|
|
29123
|
+
[arbi, notify18, triggerSync.mutate]
|
|
29124
|
+
);
|
|
29125
|
+
return { runSync, isPending: triggerSync.isPending };
|
|
29126
|
+
}
|
|
29127
|
+
function useImportHandoff(running, processed) {
|
|
29128
|
+
const [lastRunCount, setLastRunCount] = React9.useState(null);
|
|
29129
|
+
const seenWhileRunning = React9.useRef(null);
|
|
29130
|
+
React9.useEffect(() => {
|
|
29131
|
+
if (running) {
|
|
29132
|
+
setLastRunCount(null);
|
|
29133
|
+
if (typeof processed === "number") seenWhileRunning.current = processed;
|
|
29134
|
+
return;
|
|
29135
|
+
}
|
|
29136
|
+
if (seenWhileRunning.current !== null) {
|
|
29137
|
+
setLastRunCount(seenWhileRunning.current);
|
|
29138
|
+
seenWhileRunning.current = null;
|
|
29139
|
+
}
|
|
29140
|
+
}, [running, processed]);
|
|
29141
|
+
return {
|
|
29142
|
+
lastRunCount,
|
|
29143
|
+
dismiss: () => setLastRunCount(null)
|
|
29144
|
+
};
|
|
29145
|
+
}
|
|
29146
|
+
function ImportHandoff({
|
|
29147
|
+
count: count2,
|
|
29148
|
+
noun,
|
|
29149
|
+
onDismiss,
|
|
29150
|
+
onViewProgress,
|
|
29151
|
+
"data-testid": testId
|
|
29152
|
+
}) {
|
|
29153
|
+
if (count2 <= 0) return null;
|
|
29154
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "mt-2 flex items-start justify-between gap-3", "data-testid": testId, children: [
|
|
29155
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "ml-[34px] text-sm leading-snug text-muted-foreground", children: [
|
|
29156
|
+
"Imported ",
|
|
29157
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "font-medium text-foreground", children: count2.toLocaleString() }),
|
|
29158
|
+
" ",
|
|
29159
|
+
count2 === 1 ? noun : `${noun}s`,
|
|
29160
|
+
" \xB7 indexing in the background"
|
|
29161
|
+
] }),
|
|
29162
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex shrink-0 items-center gap-1.5", children: [
|
|
29163
|
+
onViewProgress && /* @__PURE__ */ jsxRuntime.jsxs(
|
|
29164
|
+
ui.Button,
|
|
29165
|
+
{
|
|
29166
|
+
variant: "outline",
|
|
29167
|
+
size: "sm",
|
|
29168
|
+
className: "h-7 gap-1.5",
|
|
29169
|
+
onClick: onViewProgress,
|
|
29170
|
+
"data-testid": testId ? `${testId}-view` : void 0,
|
|
29171
|
+
children: [
|
|
29172
|
+
/* @__PURE__ */ jsxRuntime.jsx(lucideReact.ClockFading, { className: "h-3.5 w-3.5" }),
|
|
29173
|
+
"View progress"
|
|
29174
|
+
]
|
|
29175
|
+
}
|
|
29176
|
+
),
|
|
29177
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
29178
|
+
ui.Button,
|
|
29179
|
+
{
|
|
29180
|
+
variant: "ghost",
|
|
29181
|
+
size: "sm",
|
|
29182
|
+
className: "h-7 px-2 text-muted-foreground",
|
|
29183
|
+
onClick: onDismiss,
|
|
29184
|
+
"aria-label": "Dismiss import summary",
|
|
29185
|
+
"data-testid": testId ? `${testId}-dismiss` : void 0,
|
|
29186
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.X, { className: "h-4 w-4" })
|
|
29187
|
+
}
|
|
29188
|
+
)
|
|
29189
|
+
] })
|
|
29190
|
+
] });
|
|
29191
|
+
}
|
|
29192
|
+
var PROVIDER_FAMILIES = [
|
|
29193
|
+
{ key: "microsoft", label: "Microsoft", vendors: ["microsoft"] },
|
|
29194
|
+
{ key: "google", label: "Google", vendors: ["gmail"] }
|
|
29195
|
+
];
|
|
29196
|
+
function VendorGlyph({ catalog }) {
|
|
29197
|
+
return /* @__PURE__ */ jsxRuntime.jsx(chunkWALADS2S_cjs.VendorLogo, { vendorKey: catalog.vendor_key, className: "h-7 w-7" });
|
|
29198
|
+
}
|
|
29199
|
+
function mailboxProductName(catalog) {
|
|
29200
|
+
if (catalog.vendor_key === "microsoft") return "Outlook";
|
|
29201
|
+
if (catalog.vendor_key === "gmail") return "Gmail";
|
|
29202
|
+
return catalog.display_name;
|
|
29203
|
+
}
|
|
29204
|
+
function EmailProviderRow({
|
|
29205
|
+
catalog,
|
|
29206
|
+
userConnector,
|
|
29207
|
+
workspaceExtId,
|
|
29208
|
+
workspaceName,
|
|
29209
|
+
onViewProgress,
|
|
29210
|
+
onNeedsReconnectChange
|
|
29211
|
+
}) {
|
|
29212
|
+
const [settingsOpen, setSettingsOpen] = React9.useState(false);
|
|
29213
|
+
const { runSync, isPending: syncPending } = useEmailSyncTrigger();
|
|
29214
|
+
const cancelSync = react.useCancelMailboxSync();
|
|
29215
|
+
const arbi = react.useArbi();
|
|
29216
|
+
const isConnected = !!userConnector?.is_connected;
|
|
29217
|
+
const thisSync = userConnector?.syncs?.find((s) => s.workspace_ext_id === workspaceExtId);
|
|
29218
|
+
const syncingHere = isConnected && !!thisSync && thisSync.enabled;
|
|
29219
|
+
const [tokensBridged, setTokensBridged] = React9.useState(false);
|
|
29220
|
+
React9.useEffect(() => {
|
|
29221
|
+
if (!isConnected) {
|
|
29222
|
+
setTokensBridged(false);
|
|
29223
|
+
return;
|
|
29224
|
+
}
|
|
29225
|
+
let cancelled = false;
|
|
29226
|
+
void arbi.connectors.bridgeTokens({ vendor: catalog.vendor_key, autoSyncWorkspaceExtId: workspaceExtId }).finally(() => {
|
|
29227
|
+
if (!cancelled) setTokensBridged(true);
|
|
29228
|
+
});
|
|
29229
|
+
return () => {
|
|
29230
|
+
cancelled = true;
|
|
29231
|
+
};
|
|
29232
|
+
}, [isConnected, arbi, catalog.vendor_key, workspaceExtId]);
|
|
29233
|
+
const { data: mailboxFolders, error: foldersError } = react.useMailboxFolders(
|
|
29234
|
+
catalog.vendor_key,
|
|
29235
|
+
isConnected && tokensBridged
|
|
29236
|
+
);
|
|
29237
|
+
const needsReconnect = isConnected && !!foldersError;
|
|
29238
|
+
React9.useEffect(() => {
|
|
29239
|
+
onNeedsReconnectChange(catalog.vendor_key, needsReconnect);
|
|
29240
|
+
}, [needsReconnect, catalog.vendor_key, onNeedsReconnectChange]);
|
|
29241
|
+
const { data: progress, refetch: refetchProgress } = react.useMailboxSyncProgress(
|
|
29242
|
+
catalog.vendor_key,
|
|
29243
|
+
workspaceExtId,
|
|
29244
|
+
syncingHere
|
|
29245
|
+
);
|
|
29246
|
+
const running = !!progress?.running;
|
|
29247
|
+
const { lastRunCount, dismiss: dismissHandoff } = useImportHandoff(running, progress?.processed);
|
|
29248
|
+
react.useRefreshConnectorsOnRunEnd(running);
|
|
29249
|
+
const busy = syncPending;
|
|
29250
|
+
const kickProgressPolling = () => {
|
|
29251
|
+
[500, 1400, 2800].forEach((ms) => window.setTimeout(() => void refetchProgress(), ms));
|
|
29252
|
+
};
|
|
29253
|
+
const syncNow = () => {
|
|
29254
|
+
void runSync({ vendorKey: catalog.vendor_key, workspaceExtId, workspaceLabel: workspaceName });
|
|
29255
|
+
kickProgressPolling();
|
|
29256
|
+
};
|
|
29257
|
+
const stopSync = () => cancelSync.mutate(
|
|
29258
|
+
{ vendorKey: catalog.vendor_key, workspaceExtId },
|
|
29259
|
+
{ onSettled: () => void refetchProgress() }
|
|
29260
|
+
);
|
|
29261
|
+
const emailNoun = (n) => n === 1 ? "email" : "emails";
|
|
29262
|
+
const syncedCount = thisSync?.synced_count ?? 0;
|
|
29263
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
29264
|
+
chunkWALADS2S_cjs.ImportRow,
|
|
29265
|
+
{
|
|
29266
|
+
testId: `email-provider-row-${catalog.vendor_key}`,
|
|
29267
|
+
logo: /* @__PURE__ */ jsxRuntime.jsx(VendorGlyph, { catalog }),
|
|
29268
|
+
name: mailboxProductName(catalog),
|
|
29269
|
+
actions: (
|
|
29270
|
+
// Connecting AND reconnecting are owned by the family header, so a
|
|
29271
|
+
// not-connected or needs-reconnect row shows no button of its own.
|
|
29272
|
+
!isConnected || needsReconnect ? null : /* @__PURE__ */ jsxRuntime.jsx(
|
|
29273
|
+
chunkWALADS2S_cjs.ImportRunActions,
|
|
29274
|
+
{
|
|
29275
|
+
isRunning: running,
|
|
29276
|
+
isStopping: cancelSync.isPending,
|
|
29277
|
+
isBusy: busy,
|
|
29278
|
+
onImport: syncingHere ? syncNow : () => setSettingsOpen(true),
|
|
29279
|
+
onStop: stopSync,
|
|
29280
|
+
onSettings: () => setSettingsOpen(true),
|
|
29281
|
+
settingsLabel: `${mailboxProductName(catalog)} sync settings`,
|
|
29282
|
+
stopButton: { testId: `email-stop-${catalog.vendor_key}` }
|
|
29283
|
+
}
|
|
29284
|
+
)
|
|
29285
|
+
),
|
|
29286
|
+
children: [
|
|
29287
|
+
isConnected && !needsReconnect && !running && /* @__PURE__ */ jsxRuntime.jsxs(
|
|
29288
|
+
chunkWALADS2S_cjs.ImportSummary,
|
|
29289
|
+
{
|
|
29290
|
+
aside: /* @__PURE__ */ jsxRuntime.jsx(chunkWALADS2S_cjs.ImportAside, { children: thisSync && thisSync.folders.length > 0 && /* @__PURE__ */ jsxRuntime.jsx(
|
|
29291
|
+
chunkWALADS2S_cjs.FolderSummary,
|
|
29292
|
+
{
|
|
29293
|
+
names: thisSync.folders.map(
|
|
29294
|
+
(id) => mailboxFolders?.find((f) => f.id === id)?.name
|
|
29295
|
+
),
|
|
29296
|
+
testId: `email-folders-${catalog.vendor_key}`
|
|
29297
|
+
}
|
|
29298
|
+
) }),
|
|
29299
|
+
children: [
|
|
29300
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
|
|
29301
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "font-medium text-foreground", children: syncedCount.toLocaleString() }),
|
|
29302
|
+
" ",
|
|
29303
|
+
emailNoun(syncedCount),
|
|
29304
|
+
" in this workspace"
|
|
29305
|
+
] }),
|
|
29306
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { "data-testid": `email-last-sync-${catalog.vendor_key}`, children: [
|
|
29307
|
+
thisSync?.last_sync_at ? `Last synced ${ui.formatRelativeTime(thisSync.last_sync_at, { style: "compact" })}` : "Not synced yet",
|
|
29308
|
+
thisSync?.backfill_since ? ` \xB7 Backfill: since ${new Date(thisSync.backfill_since).toLocaleDateString()}` : thisSync?.backfill_window != null && ` \xB7 Backfill: ${windowLabel(thisSync.backfill_window)}`
|
|
29309
|
+
] })
|
|
29310
|
+
]
|
|
29311
|
+
}
|
|
29312
|
+
),
|
|
29313
|
+
running && /* @__PURE__ */ jsxRuntime.jsx(
|
|
29314
|
+
chunkWALADS2S_cjs.ImportProgress,
|
|
29315
|
+
{
|
|
29316
|
+
processed: progress?.processed ?? 0,
|
|
29317
|
+
total: progress?.total,
|
|
29318
|
+
noun: "emails",
|
|
29319
|
+
testId: `email-progress-${catalog.vendor_key}`
|
|
29320
|
+
}
|
|
29321
|
+
),
|
|
29322
|
+
!running && lastRunCount !== null && /* @__PURE__ */ jsxRuntime.jsx(
|
|
29323
|
+
ImportHandoff,
|
|
29324
|
+
{
|
|
29325
|
+
count: lastRunCount,
|
|
29326
|
+
noun: "email",
|
|
29327
|
+
onDismiss: dismissHandoff,
|
|
29328
|
+
onViewProgress,
|
|
29329
|
+
"data-testid": `email-handoff-${catalog.vendor_key}`
|
|
29330
|
+
}
|
|
29331
|
+
),
|
|
29332
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
29333
|
+
ConnectedMailboxSyncDialog,
|
|
29334
|
+
{
|
|
29335
|
+
catalog,
|
|
29336
|
+
userConnector,
|
|
29337
|
+
open: settingsOpen,
|
|
29338
|
+
onOpenChange: setSettingsOpen,
|
|
29339
|
+
lockedWorkspaceExtId: workspaceExtId
|
|
29340
|
+
}
|
|
29341
|
+
)
|
|
29342
|
+
]
|
|
29343
|
+
}
|
|
29344
|
+
);
|
|
29345
|
+
}
|
|
29346
|
+
function EmailImportPanel({
|
|
29347
|
+
workspaceExtId,
|
|
29348
|
+
workspaceName,
|
|
29349
|
+
onViewProgress,
|
|
29350
|
+
microsoftExtra,
|
|
29351
|
+
googleExtra
|
|
29352
|
+
}) {
|
|
29353
|
+
const arbi = react.useArbi();
|
|
29354
|
+
const { confirm, notify: notify18 } = chunkB3NYBMDR_cjs.useBlocksEnvironment();
|
|
29355
|
+
const { data: catalog = [] } = react.useConnectorCatalog();
|
|
29356
|
+
const { data: myConnectors = [] } = react.useMyConnectors();
|
|
29357
|
+
const disconnect = react.useDisconnectConnector();
|
|
29358
|
+
const isVendorVisible = react.useConnectorVendorVisibility();
|
|
29359
|
+
const [reconnectByVendor, setReconnectByVendor] = React9.useState({});
|
|
29360
|
+
const handleNeedsReconnectChange = React9.useCallback((vendorKey, needs) => {
|
|
29361
|
+
setReconnectByVendor(
|
|
29362
|
+
(prev) => prev[vendorKey] === needs ? prev : { ...prev, [vendorKey]: needs }
|
|
29363
|
+
);
|
|
29364
|
+
}, []);
|
|
29365
|
+
const mailboxCatalog = catalog.filter(
|
|
29366
|
+
(c) => react.isMailboxSyncVendor(c.vendor_key) && isVendorVisible(c.vendor_key)
|
|
29367
|
+
);
|
|
29368
|
+
const connectedByVendor = Object.fromEntries(myConnectors.map((uc) => [uc.vendor_key, uc]));
|
|
29369
|
+
const byVendor = Object.fromEntries(mailboxCatalog.map((c) => [c.vendor_key, c]));
|
|
29370
|
+
const connectFamily = async (vendorKey) => {
|
|
29371
|
+
try {
|
|
29372
|
+
window.location.href = await arbi.connectors.authorize(
|
|
29373
|
+
vendorKey,
|
|
29374
|
+
react.connectorReturnTo("accounts")
|
|
29375
|
+
);
|
|
29376
|
+
} catch {
|
|
29377
|
+
notify18("Could not start the connection. Please try again.", "error");
|
|
29378
|
+
}
|
|
29379
|
+
};
|
|
29380
|
+
const reconnectFamily = async (vendorKey) => {
|
|
29381
|
+
try {
|
|
29382
|
+
await disconnect.mutateAsync({ vendorKey });
|
|
29383
|
+
} catch {
|
|
29384
|
+
}
|
|
29385
|
+
try {
|
|
29386
|
+
window.location.href = await arbi.connectors.authorize(
|
|
29387
|
+
vendorKey,
|
|
29388
|
+
react.connectorReturnTo("accounts")
|
|
29389
|
+
);
|
|
29390
|
+
} catch {
|
|
29391
|
+
notify18("Could not start reconnection. Please try again.", "error");
|
|
29392
|
+
}
|
|
29393
|
+
};
|
|
29394
|
+
const extraByFamily = {
|
|
29395
|
+
microsoft: isVendorVisible("microsoft") ? microsoftExtra : null,
|
|
29396
|
+
google: isVendorVisible("gmail") ? googleExtra : null
|
|
29397
|
+
};
|
|
29398
|
+
const disconnectFamily = React9.useCallback(
|
|
29399
|
+
async (family, connectVendor, identity) => {
|
|
29400
|
+
const who = identity ? `${identity} will be disconnected.` : "This account will be disconnected.";
|
|
29401
|
+
const ok = await confirm({
|
|
29402
|
+
message: `${who} Documents already imported stay in the workspace, but nothing further will sync until you connect again.`,
|
|
29403
|
+
title: `Disconnect ${family.label}?`
|
|
29404
|
+
});
|
|
29405
|
+
if (!ok) return;
|
|
29406
|
+
await disconnect.mutateAsync({ vendorKey: connectVendor });
|
|
29407
|
+
if (connectVendor === "microsoft") {
|
|
29408
|
+
for (const spVendor of react.SHAREPOINT_VENDORS) {
|
|
29409
|
+
if (connectedByVendor[spVendor]) {
|
|
29410
|
+
await disconnect.mutateAsync({ vendorKey: spVendor }).catch(() => {
|
|
29411
|
+
});
|
|
29412
|
+
}
|
|
29413
|
+
}
|
|
29414
|
+
}
|
|
29415
|
+
notify18(`Disconnected ${family.label}`, "success");
|
|
29416
|
+
},
|
|
29417
|
+
[confirm, disconnect, connectedByVendor, notify18]
|
|
29418
|
+
);
|
|
29419
|
+
const groups = PROVIDER_FAMILIES.map((family) => {
|
|
29420
|
+
const entries = family.vendors.map((v) => byVendor[v]).filter(Boolean);
|
|
29421
|
+
const extra = extraByFamily[family.key] ?? null;
|
|
29422
|
+
const connectVendor = family.vendors[0];
|
|
29423
|
+
const connectUc = connectedByVendor[connectVendor];
|
|
29424
|
+
const connected = !!connectUc?.is_connected;
|
|
29425
|
+
const identity = family.vendors.map((v) => connectedByVendor[v]).find((uc) => uc?.is_connected && uc?.vendor_user_identity)?.vendor_user_identity;
|
|
29426
|
+
const mailboxNeedsReconnect = family.vendors.some((v) => reconnectByVendor[v]);
|
|
29427
|
+
const needsReconnect = connected && (react.isDriveSyncVendor(connectVendor) && !!connectUc?.drive_needs_reconsent || mailboxNeedsReconnect);
|
|
29428
|
+
return { family, entries, extra, identity, connectVendor, connected, needsReconnect };
|
|
29429
|
+
}).filter((g) => g.entries.length > 0 || g.extra);
|
|
29430
|
+
if (groups.length === 0) return null;
|
|
29431
|
+
return /* @__PURE__ */ jsxRuntime.jsx(chunkWALADS2S_cjs.ImportPanel, { "data-testid": "email-import-panel", children: groups.map(
|
|
29432
|
+
({ family, entries, extra, identity, connectVendor, connected, needsReconnect }) => /* @__PURE__ */ jsxRuntime.jsx(
|
|
29433
|
+
chunkWALADS2S_cjs.ImportFamilySection,
|
|
29434
|
+
{
|
|
29435
|
+
label: family.label,
|
|
29436
|
+
identity,
|
|
29437
|
+
action: !connected ? "connect" : needsReconnect ? "reconnect" : "disconnect",
|
|
29438
|
+
isActionPending: disconnect.isPending,
|
|
29439
|
+
onAction: () => void (!connected ? connectFamily(connectVendor) : needsReconnect ? reconnectFamily(connectVendor) : disconnectFamily(family, connectVendor, identity)),
|
|
29440
|
+
testId: `import-family-${family.key}`,
|
|
29441
|
+
actionButton: !connected ? { testId: `import-family-connect-${family.key}` } : needsReconnect ? { testId: `import-family-reconnect-${family.key}` } : { testId: `import-family-disconnect-${family.key}` },
|
|
29442
|
+
children: /* @__PURE__ */ jsxRuntime.jsxs(chunkWALADS2S_cjs.ImportList, { children: [
|
|
29443
|
+
entries.map((entry) => /* @__PURE__ */ jsxRuntime.jsx(
|
|
29444
|
+
EmailProviderRow,
|
|
29445
|
+
{
|
|
29446
|
+
catalog: entry,
|
|
29447
|
+
userConnector: connectedByVendor[entry.vendor_key],
|
|
29448
|
+
workspaceExtId,
|
|
29449
|
+
workspaceName,
|
|
29450
|
+
onViewProgress,
|
|
29451
|
+
onNeedsReconnectChange: handleNeedsReconnectChange
|
|
29452
|
+
},
|
|
29453
|
+
entry.vendor_key
|
|
29454
|
+
)),
|
|
29455
|
+
extra
|
|
29456
|
+
] })
|
|
29457
|
+
},
|
|
29458
|
+
family.key
|
|
29459
|
+
)
|
|
29460
|
+
) });
|
|
29461
|
+
}
|
|
29462
|
+
function useDriveSyncTrigger() {
|
|
29463
|
+
const arbi = react.useArbi();
|
|
29464
|
+
const { notify: notify18 } = chunkB3NYBMDR_cjs.useBlocksEnvironment();
|
|
29465
|
+
const triggerSync = react.useTriggerDriveSync();
|
|
29466
|
+
const runSync = React9.useCallback(
|
|
29467
|
+
async ({
|
|
29468
|
+
vendorKey,
|
|
29469
|
+
workspaceExtId,
|
|
29470
|
+
workspaceLabel = "the workspace"
|
|
29471
|
+
}) => {
|
|
29472
|
+
await arbi.connectors.bridgeTokens({ vendor: vendorKey });
|
|
29473
|
+
if (workspaceExtId) {
|
|
29474
|
+
await arbi.workspaces.open(workspaceExtId).catch(() => {
|
|
29475
|
+
});
|
|
29476
|
+
}
|
|
29477
|
+
triggerSync.mutate(
|
|
29478
|
+
{ vendorKey },
|
|
29479
|
+
{
|
|
29480
|
+
onSuccess: (res) => {
|
|
29481
|
+
const n = res?.estimated_count;
|
|
29482
|
+
if (n === 0) {
|
|
29483
|
+
notify18("You\u2019re up to date \u2014 no new documents to sync.", "success");
|
|
29484
|
+
} else if (n != null && n > 0) {
|
|
29485
|
+
notify18(
|
|
29486
|
+
`Fetching ${n} new document${n === 1 ? "" : "s"} to ${workspaceLabel}.`,
|
|
29487
|
+
"success"
|
|
29488
|
+
);
|
|
29489
|
+
} else {
|
|
29490
|
+
notify18("Sync started \u2014 fetching new documents\u2026", "success");
|
|
29491
|
+
}
|
|
29492
|
+
},
|
|
29493
|
+
onError: (err) => {
|
|
29494
|
+
if (react.connectorErrorStatus(err) === 425) {
|
|
29495
|
+
notify18("Still preparing your session \u2014 please try Sync now again.", "error");
|
|
29496
|
+
} else if (react.connectorErrorStatus(err) === 409) {
|
|
29497
|
+
notify18("Reconnect needed \u2014 your account needs to be re-authorized.", "error");
|
|
29498
|
+
} else if (react.connectorErrorStatus(err) === 404) {
|
|
29499
|
+
notify18("Drive sync is not enabled for this connector yet.", "error");
|
|
29500
|
+
} else {
|
|
29501
|
+
notify18("Could not start sync. Please try again.", "error");
|
|
29502
|
+
}
|
|
29503
|
+
}
|
|
29504
|
+
}
|
|
29505
|
+
);
|
|
29506
|
+
},
|
|
29507
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps -- triggerSync.mutate is a stable TanStack Query reference
|
|
29508
|
+
[arbi, notify18, triggerSync.mutate]
|
|
29509
|
+
);
|
|
29510
|
+
return { runSync, isPending: triggerSync.isPending };
|
|
29511
|
+
}
|
|
29512
|
+
var DRIVE_PRODUCT = {
|
|
29513
|
+
microsoft: { name: "OneDrive", glyph: "onedrive" },
|
|
29514
|
+
gmail: { name: "Google Drive", glyph: "googledrive" },
|
|
29515
|
+
microsoft_sharepoint: { name: "SharePoint", glyph: "sharepoint" },
|
|
29516
|
+
box: { name: "Box", glyph: "box" },
|
|
29517
|
+
dropbox: { name: "Dropbox", glyph: "dropbox" },
|
|
29518
|
+
onenote: { name: "OneNote", glyph: "onenote" },
|
|
29519
|
+
clio: { name: "Clio", glyph: "clio" }
|
|
29520
|
+
};
|
|
29521
|
+
function driveProduct(vendorKey) {
|
|
29522
|
+
return DRIVE_PRODUCT[vendorKey] ?? { name: "Drive", glyph: "onedrive" };
|
|
29523
|
+
}
|
|
29524
|
+
function VendorGlyph2({ catalog }) {
|
|
29525
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
29526
|
+
chunkWALADS2S_cjs.VendorLogo,
|
|
29527
|
+
{
|
|
29528
|
+
vendorKey: catalog.vendor_key,
|
|
29529
|
+
product: driveProduct(catalog.vendor_key).glyph,
|
|
29530
|
+
className: "h-7 w-7"
|
|
29531
|
+
}
|
|
29532
|
+
);
|
|
29533
|
+
}
|
|
29534
|
+
function OneDriveProviderRow({
|
|
29535
|
+
catalog,
|
|
29536
|
+
userConnector,
|
|
29537
|
+
workspaceExtId,
|
|
29538
|
+
workspaceName,
|
|
29539
|
+
onViewProgress
|
|
29540
|
+
}) {
|
|
29541
|
+
const [settingsOpen, setSettingsOpen] = React9.useState(false);
|
|
29542
|
+
const { runSync, isPending: syncPending } = useDriveSyncTrigger();
|
|
29543
|
+
const cancelSync = react.useCancelDriveSync();
|
|
29544
|
+
const arbi = react.useArbi();
|
|
29545
|
+
const { notify: notify18 } = chunkB3NYBMDR_cjs.useBlocksEnvironment();
|
|
29546
|
+
const isConnected = !!userConnector?.is_connected;
|
|
29547
|
+
const product = driveProduct(catalog.vendor_key);
|
|
29548
|
+
const status = userConnector?.drive_sync_status ?? null;
|
|
29549
|
+
const configuredHere = status != null && userConnector?.drive_sync_workspace_ext_id === workspaceExtId;
|
|
29550
|
+
const folderCount = userConnector?.drive_sync_folders?.length ?? 0;
|
|
29551
|
+
const needsReconsent = isConnected && !!userConnector?.drive_needs_reconsent;
|
|
29552
|
+
const [tokensBridged, setTokensBridged] = React9.useState(false);
|
|
29553
|
+
React9.useEffect(() => {
|
|
29554
|
+
if (!isConnected) {
|
|
29555
|
+
setTokensBridged(false);
|
|
29556
|
+
return;
|
|
29557
|
+
}
|
|
29558
|
+
let cancelled = false;
|
|
29559
|
+
void arbi.connectors.bridgeTokens({ vendor: catalog.vendor_key, autoSyncWorkspaceExtId: workspaceExtId }).finally(() => {
|
|
29560
|
+
if (!cancelled) setTokensBridged(true);
|
|
29561
|
+
});
|
|
29562
|
+
return () => {
|
|
29563
|
+
cancelled = true;
|
|
29564
|
+
};
|
|
29565
|
+
}, [isConnected, arbi, catalog.vendor_key, workspaceExtId]);
|
|
29566
|
+
const { error: foldersError } = react.useDriveFolders(
|
|
29567
|
+
catalog.vendor_key,
|
|
29568
|
+
isConnected && tokensBridged && !needsReconsent
|
|
29569
|
+
);
|
|
29570
|
+
const needsReconnect = needsReconsent || isConnected && react.connectorErrorStatus(foldersError) === 409;
|
|
29571
|
+
const { data: progress, refetch: refetchProgress } = react.useDriveSyncProgress(
|
|
29572
|
+
catalog.vendor_key,
|
|
29573
|
+
configuredHere && !needsReconnect
|
|
29574
|
+
);
|
|
29575
|
+
const running = !!progress?.running;
|
|
29576
|
+
const { lastRunCount, dismiss: dismissHandoff } = useImportHandoff(running, progress?.processed);
|
|
29577
|
+
react.useRefreshConnectorsOnRunEnd(running);
|
|
29578
|
+
const { data: estimate, refetch: refetchEstimate } = react.useDriveSyncEstimate(
|
|
29579
|
+
catalog.vendor_key,
|
|
29580
|
+
configuredHere && tokensBridged && !needsReconnect && !running
|
|
29581
|
+
);
|
|
29582
|
+
const lastSummaryRef = React9.useRef(null);
|
|
29583
|
+
const baselinedRef = React9.useRef(false);
|
|
29584
|
+
React9.useEffect(() => {
|
|
29585
|
+
if (progress === void 0) return;
|
|
29586
|
+
const s = progress.summary;
|
|
29587
|
+
const finishedAt = s?.finished_at ?? null;
|
|
29588
|
+
if (!baselinedRef.current) {
|
|
29589
|
+
baselinedRef.current = true;
|
|
29590
|
+
lastSummaryRef.current = finishedAt;
|
|
29591
|
+
return;
|
|
29592
|
+
}
|
|
29593
|
+
if (!s?.finished_at || lastSummaryRef.current === s.finished_at) return;
|
|
29594
|
+
lastSummaryRef.current = s.finished_at;
|
|
29595
|
+
const total = s.attempted || s.ingested;
|
|
29596
|
+
const importedMsg = `Imported ${s.ingested} of ${total} document${total === 1 ? "" : "s"} from ${product.name}.`;
|
|
29597
|
+
const skipped = s.skipped ?? [];
|
|
29598
|
+
if (skipped.length === 0) {
|
|
29599
|
+
notify18(importedMsg, "success");
|
|
29600
|
+
} else {
|
|
29601
|
+
notify18(`${importedMsg} ${skipped.length} couldn\u2019t be imported:`, "warning", {
|
|
29602
|
+
duration: 12e3,
|
|
29603
|
+
description: /* @__PURE__ */ jsxRuntime.jsx("ul", { className: "mt-1 max-h-56 space-y-0.5 overflow-y-auto pr-1 text-xs", children: skipped.map((f, i) => /* @__PURE__ */ jsxRuntime.jsxs("li", { className: "break-all", children: [
|
|
29604
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "font-medium", children: f.name }),
|
|
29605
|
+
/* @__PURE__ */ jsxRuntime.jsxs("span", { className: "text-muted-foreground", children: [
|
|
29606
|
+
" \u2014 ",
|
|
29607
|
+
f.reason
|
|
29608
|
+
] })
|
|
29609
|
+
] }, i)) })
|
|
29610
|
+
});
|
|
29611
|
+
}
|
|
29612
|
+
void refetchEstimate();
|
|
29613
|
+
}, [progress, refetchEstimate, product.name, notify18]);
|
|
29614
|
+
const pendingCount = estimate?.estimated_count;
|
|
29615
|
+
const busy = syncPending;
|
|
29616
|
+
const ownsAuth = catalog.vendor_key === "microsoft_sharepoint";
|
|
29617
|
+
const [reauthPending, setReauthPending] = React9.useState(false);
|
|
29618
|
+
const reconnectSelf = async () => {
|
|
29619
|
+
setReauthPending(true);
|
|
29620
|
+
try {
|
|
29621
|
+
window.location.href = await arbi.connectors.authorize(
|
|
29622
|
+
catalog.vendor_key,
|
|
29623
|
+
react.connectorReturnTo("accounts")
|
|
29624
|
+
);
|
|
29625
|
+
} catch {
|
|
29626
|
+
setReauthPending(false);
|
|
29627
|
+
notify18("Could not start reconnection. Please try again.", "error");
|
|
29628
|
+
}
|
|
29629
|
+
};
|
|
29630
|
+
const kickProgressPolling = () => {
|
|
29631
|
+
[500, 1400, 2800].forEach((ms) => window.setTimeout(() => void refetchProgress(), ms));
|
|
29632
|
+
};
|
|
29633
|
+
const syncNow = () => {
|
|
29634
|
+
void runSync({
|
|
29635
|
+
vendorKey: catalog.vendor_key,
|
|
29636
|
+
workspaceExtId,
|
|
29637
|
+
workspaceLabel: workspaceName
|
|
29638
|
+
});
|
|
29639
|
+
kickProgressPolling();
|
|
29640
|
+
[1500, 4e3].forEach((ms) => window.setTimeout(() => void refetchEstimate(), ms));
|
|
29641
|
+
};
|
|
29642
|
+
const stopSync = () => cancelSync.mutate(
|
|
29643
|
+
{ vendorKey: catalog.vendor_key },
|
|
29644
|
+
{ onSettled: () => void refetchProgress() }
|
|
29645
|
+
);
|
|
29646
|
+
const driveNoun = (n) => n === 1 ? "document" : "documents";
|
|
29647
|
+
const showRunActions = isConnected && !needsReconnect;
|
|
29648
|
+
const reconnectAction = ownsAuth && needsReconnect ? /* @__PURE__ */ jsxRuntime.jsx(
|
|
29649
|
+
chunkWALADS2S_cjs.ImportActionButton,
|
|
29650
|
+
{
|
|
29651
|
+
onClick: () => void reconnectSelf(),
|
|
29652
|
+
disabled: reauthPending,
|
|
29653
|
+
"data-testid": `onedrive-reconnect-${catalog.vendor_key}`,
|
|
29654
|
+
children: reauthPending ? "Reconnecting\u2026" : "Reconnect"
|
|
29655
|
+
}
|
|
29656
|
+
) : null;
|
|
29657
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
29658
|
+
chunkWALADS2S_cjs.ImportRow,
|
|
29659
|
+
{
|
|
29660
|
+
testId: `onedrive-provider-row-${catalog.vendor_key}`,
|
|
29661
|
+
logo: /* @__PURE__ */ jsxRuntime.jsx(VendorGlyph2, { catalog }),
|
|
29662
|
+
name: product.name,
|
|
29663
|
+
actions: (
|
|
29664
|
+
// OneDrive/Google Drive: connecting AND reconnecting are owned by the family header.
|
|
29665
|
+
// SharePoint (ownsAuth) is a separate grant, so its row renders its OWN Reconnect (D1).
|
|
29666
|
+
showRunActions ? (
|
|
29667
|
+
// Until folders are configured here (or when nothing new is pending), Import now
|
|
29668
|
+
// stays disabled; the gear opens the folder picker.
|
|
29669
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
29670
|
+
chunkWALADS2S_cjs.ImportRunActions,
|
|
29671
|
+
{
|
|
29672
|
+
isRunning: running,
|
|
29673
|
+
isStopping: cancelSync.isPending,
|
|
29674
|
+
isBusy: busy,
|
|
29675
|
+
importDisabled: !configuredHere || pendingCount === 0,
|
|
29676
|
+
importTitle: !configuredHere ? `Choose ${product.name} folders in settings first` : pendingCount === 0 ? "No new documents to import" : void 0,
|
|
29677
|
+
onImport: syncNow,
|
|
29678
|
+
onStop: stopSync,
|
|
29679
|
+
onSettings: () => setSettingsOpen(true),
|
|
29680
|
+
settingsLabel: `${product.name} import settings`,
|
|
29681
|
+
importButton: { testId: `onedrive-sync-${catalog.vendor_key}` },
|
|
29682
|
+
settingsButton: { testId: `onedrive-settings-${catalog.vendor_key}` },
|
|
29683
|
+
stopButton: { testId: `onedrive-stop-${catalog.vendor_key}` }
|
|
29684
|
+
}
|
|
29685
|
+
)
|
|
29686
|
+
) : reconnectAction
|
|
29687
|
+
),
|
|
29688
|
+
children: [
|
|
29689
|
+
ownsAuth && needsReconnect && /* @__PURE__ */ jsxRuntime.jsxs(chunkWALADS2S_cjs.ImportHint, { "data-testid": `onedrive-reconnect-hint-${catalog.vendor_key}`, children: [
|
|
29690
|
+
"Couldn\u2019t reach SharePoint. Click ",
|
|
29691
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "font-medium", children: "Reconnect" }),
|
|
29692
|
+
" \u2014 if it keeps happening, log out and back in to refresh the connection."
|
|
29693
|
+
] }),
|
|
29694
|
+
configuredHere && !needsReconnect && !running && /* @__PURE__ */ jsxRuntime.jsxs(
|
|
29695
|
+
chunkWALADS2S_cjs.ImportSummary,
|
|
29696
|
+
{
|
|
29697
|
+
className: "mt-2",
|
|
29698
|
+
aside: typeof pendingCount === "number" ? /* @__PURE__ */ jsxRuntime.jsx(chunkWALADS2S_cjs.ImportAside, { className: "max-w-none shrink-0", children: /* @__PURE__ */ jsxRuntime.jsx("span", { "data-testid": `drive-pending-${catalog.vendor_key}`, children: pendingCount > 0 ? `${pendingCount.toLocaleString()} new ${driveNoun(pendingCount)} to sync` : "No new documents to sync" }) }) : void 0,
|
|
29699
|
+
children: [
|
|
29700
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
|
|
29701
|
+
"Syncing ",
|
|
29702
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "font-medium text-foreground", children: folderCount }),
|
|
29703
|
+
" folder",
|
|
29704
|
+
folderCount === 1 ? "" : "s",
|
|
29705
|
+
" into this workspace"
|
|
29706
|
+
] }),
|
|
29707
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { "data-testid": `drive-last-sync-${catalog.vendor_key}`, children: userConnector?.drive_last_sync_at ? `Last synced ${ui.formatRelativeTime(userConnector.drive_last_sync_at, { style: "compact" })}` : "Not synced yet" })
|
|
29708
|
+
]
|
|
29709
|
+
}
|
|
29710
|
+
),
|
|
29711
|
+
isConnected && !needsReconnect && !running && !configuredHere && /* @__PURE__ */ jsxRuntime.jsxs(
|
|
29712
|
+
"button",
|
|
29713
|
+
{
|
|
29714
|
+
type: "button",
|
|
29715
|
+
className: "ml-[34px] mt-2 text-left text-sm leading-snug text-muted-foreground hover:text-foreground pointer-coarse:min-h-11",
|
|
29716
|
+
onClick: () => setSettingsOpen(true),
|
|
29717
|
+
"data-testid": `onedrive-choose-folders-${catalog.vendor_key}`,
|
|
29718
|
+
children: [
|
|
29719
|
+
"Choose folders in ",
|
|
29720
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "underline", children: "settings" }),
|
|
29721
|
+
" to start syncing"
|
|
29722
|
+
]
|
|
29723
|
+
}
|
|
29724
|
+
),
|
|
29725
|
+
running && /* @__PURE__ */ jsxRuntime.jsx(
|
|
29726
|
+
chunkWALADS2S_cjs.ImportProgress,
|
|
29727
|
+
{
|
|
29728
|
+
processed: progress?.processed ?? 0,
|
|
29729
|
+
total: progress?.total,
|
|
29730
|
+
noun: "documents",
|
|
29731
|
+
testId: `onedrive-progress-${catalog.vendor_key}`
|
|
29732
|
+
}
|
|
29733
|
+
),
|
|
29734
|
+
!running && lastRunCount !== null && /* @__PURE__ */ jsxRuntime.jsx(
|
|
29735
|
+
ImportHandoff,
|
|
29736
|
+
{
|
|
29737
|
+
count: lastRunCount,
|
|
29738
|
+
noun: "document",
|
|
29739
|
+
onDismiss: dismissHandoff,
|
|
29740
|
+
onViewProgress,
|
|
29741
|
+
"data-testid": `onedrive-handoff-${catalog.vendor_key}`
|
|
29742
|
+
}
|
|
29743
|
+
),
|
|
29744
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
29745
|
+
ConnectedDriveSyncDialog,
|
|
29746
|
+
{
|
|
29747
|
+
catalog,
|
|
29748
|
+
userConnector,
|
|
29749
|
+
open: settingsOpen,
|
|
29750
|
+
onOpenChange: setSettingsOpen,
|
|
29751
|
+
lockedWorkspaceExtId: workspaceExtId,
|
|
29752
|
+
onEnabled: () => void refetchEstimate()
|
|
29753
|
+
}
|
|
29754
|
+
)
|
|
29755
|
+
]
|
|
29756
|
+
}
|
|
29757
|
+
);
|
|
29758
|
+
}
|
|
29759
|
+
function SharePointEnableRow({
|
|
29760
|
+
catalog,
|
|
29761
|
+
sharePointAdminUrl
|
|
29762
|
+
}) {
|
|
29763
|
+
const arbi = react.useArbi();
|
|
29764
|
+
const { notify: notify18 } = chunkB3NYBMDR_cjs.useBlocksEnvironment();
|
|
29765
|
+
const [pending, setPending] = React9.useState(false);
|
|
29766
|
+
const product = driveProduct(catalog.vendor_key);
|
|
29767
|
+
const enable = async () => {
|
|
29768
|
+
setPending(true);
|
|
29769
|
+
try {
|
|
29770
|
+
window.location.href = await arbi.connectors.authorize(
|
|
29771
|
+
catalog.vendor_key,
|
|
29772
|
+
react.connectorReturnTo("accounts")
|
|
29773
|
+
);
|
|
29774
|
+
} catch {
|
|
29775
|
+
setPending(false);
|
|
29776
|
+
notify18("Could not start the connection. Please try again.", "error");
|
|
29777
|
+
}
|
|
29778
|
+
};
|
|
29779
|
+
const copyAdminLink = async () => {
|
|
29780
|
+
const link = sharePointAdminUrl;
|
|
29781
|
+
if (!link) return;
|
|
29782
|
+
try {
|
|
29783
|
+
await navigator.clipboard.writeText(link);
|
|
29784
|
+
notify18("Approval link copied \u2014 send it to your Microsoft admin.", "success");
|
|
29785
|
+
} catch {
|
|
29786
|
+
notify18(`Copy this link for your Microsoft admin: ${link}`, "info");
|
|
29787
|
+
}
|
|
29788
|
+
};
|
|
29789
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
29790
|
+
chunkWALADS2S_cjs.ImportRow,
|
|
29791
|
+
{
|
|
29792
|
+
testId: `onedrive-provider-row-${catalog.vendor_key}`,
|
|
29793
|
+
logo: /* @__PURE__ */ jsxRuntime.jsx(chunkWALADS2S_cjs.VendorLogo, { vendorKey: catalog.vendor_key, product: product.glyph, className: "h-7 w-7" }),
|
|
29794
|
+
name: product.name,
|
|
29795
|
+
actions: /* @__PURE__ */ jsxRuntime.jsx(
|
|
29796
|
+
chunkWALADS2S_cjs.ImportActionButton,
|
|
29797
|
+
{
|
|
29798
|
+
onClick: () => void enable(),
|
|
29799
|
+
disabled: pending,
|
|
29800
|
+
"data-testid": `onedrive-enable-${catalog.vendor_key}`,
|
|
29801
|
+
children: pending ? "Enabling\u2026" : `Enable ${product.name}`
|
|
29802
|
+
}
|
|
29803
|
+
),
|
|
29804
|
+
children: sharePointAdminUrl && /* @__PURE__ */ jsxRuntime.jsxs(chunkWALADS2S_cjs.ImportHint, { children: [
|
|
29805
|
+
"Does your organization require admin approval?",
|
|
29806
|
+
" ",
|
|
29807
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
29808
|
+
"button",
|
|
29809
|
+
{
|
|
29810
|
+
type: "button",
|
|
29811
|
+
className: "underline hover:text-foreground",
|
|
29812
|
+
onClick: () => void copyAdminLink(),
|
|
29813
|
+
"data-testid": "sharepoint-copy-admin-link",
|
|
29814
|
+
children: "Copy the approval link"
|
|
29815
|
+
}
|
|
29816
|
+
),
|
|
29817
|
+
" ",
|
|
29818
|
+
"and send it to your Microsoft admin \u2014 they won't need an ARBI account."
|
|
29819
|
+
] })
|
|
29820
|
+
}
|
|
29821
|
+
);
|
|
29822
|
+
}
|
|
29823
|
+
function DriveImportPanel({
|
|
29824
|
+
workspaceExtId,
|
|
29825
|
+
workspaceName,
|
|
29826
|
+
onViewProgress,
|
|
29827
|
+
only,
|
|
29828
|
+
sharePointAdminUrl
|
|
29829
|
+
}) {
|
|
29830
|
+
const { data: catalog = [] } = react.useConnectorCatalog();
|
|
29831
|
+
const { data: myConnectors = [] } = react.useMyConnectors();
|
|
29832
|
+
const driveCatalog = catalog.filter(
|
|
29833
|
+
(c) => react.isDriveSyncVendor(c.vendor_key) && (!only || c.vendor_key === only)
|
|
29834
|
+
);
|
|
29835
|
+
if (driveCatalog.length === 0) return null;
|
|
29836
|
+
const connectedByVendor = Object.fromEntries(myConnectors.map((uc) => [uc.vendor_key, uc]));
|
|
29837
|
+
const microsoftConnected = !!connectedByVendor["microsoft"]?.is_connected;
|
|
29838
|
+
const rows = driveCatalog.map((entry) => {
|
|
29839
|
+
const uc = connectedByVendor[entry.vendor_key];
|
|
29840
|
+
if (entry.vendor_key === "microsoft_sharepoint" && !uc) {
|
|
29841
|
+
if (microsoftConnected) {
|
|
29842
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
29843
|
+
SharePointEnableRow,
|
|
29844
|
+
{
|
|
29845
|
+
catalog: entry,
|
|
29846
|
+
sharePointAdminUrl
|
|
29847
|
+
},
|
|
29848
|
+
entry.vendor_key
|
|
29849
|
+
);
|
|
29850
|
+
}
|
|
29851
|
+
const product = driveProduct(entry.vendor_key);
|
|
29852
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
29853
|
+
chunkWALADS2S_cjs.ImportRow,
|
|
29854
|
+
{
|
|
29855
|
+
testId: `onedrive-provider-row-${entry.vendor_key}`,
|
|
29856
|
+
logo: /* @__PURE__ */ jsxRuntime.jsx(
|
|
29857
|
+
chunkWALADS2S_cjs.VendorLogo,
|
|
29858
|
+
{
|
|
29859
|
+
vendorKey: entry.vendor_key,
|
|
29860
|
+
product: product.glyph,
|
|
29861
|
+
className: "h-7 w-7"
|
|
29862
|
+
}
|
|
29863
|
+
),
|
|
29864
|
+
name: product.name
|
|
29865
|
+
},
|
|
29866
|
+
entry.vendor_key
|
|
29867
|
+
);
|
|
29868
|
+
}
|
|
29869
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
29870
|
+
OneDriveProviderRow,
|
|
29871
|
+
{
|
|
29872
|
+
catalog: entry,
|
|
29873
|
+
userConnector: uc,
|
|
29874
|
+
workspaceExtId,
|
|
29875
|
+
workspaceName,
|
|
29876
|
+
onViewProgress
|
|
29877
|
+
},
|
|
29878
|
+
entry.vendor_key
|
|
29879
|
+
);
|
|
29880
|
+
}).filter(Boolean);
|
|
29881
|
+
if (rows.length === 0) return null;
|
|
29882
|
+
return /* @__PURE__ */ jsxRuntime.jsx(chunkWALADS2S_cjs.ImportList, { "data-testid": "onedrive-import-panel", children: rows });
|
|
29883
|
+
}
|
|
29884
|
+
function useHasAccountsImport() {
|
|
29885
|
+
const isVendorVisible = react.useConnectorVendorVisibility();
|
|
29886
|
+
return isVendorVisible("microsoft") || isVendorVisible("gmail");
|
|
29887
|
+
}
|
|
29888
|
+
function ConnectedAccountsImport({
|
|
29889
|
+
workspaceExtId,
|
|
29890
|
+
workspaceName,
|
|
29891
|
+
onViewProgress,
|
|
29892
|
+
sharePointAdminUrl
|
|
29893
|
+
}) {
|
|
29894
|
+
const isVendorVisible = react.useConnectorVendorVisibility();
|
|
29895
|
+
if (!isVendorVisible("microsoft") && !isVendorVisible("gmail")) return null;
|
|
29896
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
29897
|
+
EmailImportPanel,
|
|
29898
|
+
{
|
|
29899
|
+
workspaceExtId,
|
|
29900
|
+
workspaceName,
|
|
29901
|
+
onViewProgress,
|
|
29902
|
+
microsoftExtra: (
|
|
29903
|
+
// Two drive products ride Microsoft: OneDrive (the `microsoft` grant) and SharePoint
|
|
29904
|
+
// (its own grant, behind its own visibility toggle).
|
|
29905
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "divide-y divide-border", "data-testid": "upload-source-onedrive", children: [
|
|
29906
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
29907
|
+
DriveImportPanel,
|
|
29908
|
+
{
|
|
29909
|
+
workspaceExtId,
|
|
29910
|
+
workspaceName,
|
|
29911
|
+
onViewProgress,
|
|
29912
|
+
sharePointAdminUrl,
|
|
29913
|
+
only: "microsoft"
|
|
29914
|
+
}
|
|
29915
|
+
),
|
|
29916
|
+
isVendorVisible("microsoft_sharepoint") && /* @__PURE__ */ jsxRuntime.jsx("div", { "data-testid": "upload-source-sharepoint", children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
29917
|
+
DriveImportPanel,
|
|
29918
|
+
{
|
|
29919
|
+
workspaceExtId,
|
|
29920
|
+
workspaceName,
|
|
29921
|
+
onViewProgress,
|
|
29922
|
+
sharePointAdminUrl,
|
|
29923
|
+
only: "microsoft_sharepoint"
|
|
29924
|
+
}
|
|
29925
|
+
) })
|
|
29926
|
+
] })
|
|
29927
|
+
),
|
|
29928
|
+
googleExtra: /* @__PURE__ */ jsxRuntime.jsx("div", { "data-testid": "upload-source-googledrive", children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
29929
|
+
DriveImportPanel,
|
|
29930
|
+
{
|
|
29931
|
+
workspaceExtId,
|
|
29932
|
+
workspaceName,
|
|
29933
|
+
onViewProgress,
|
|
29934
|
+
sharePointAdminUrl,
|
|
29935
|
+
only: "gmail"
|
|
29936
|
+
}
|
|
29937
|
+
) })
|
|
29938
|
+
}
|
|
29939
|
+
);
|
|
29940
|
+
}
|
|
29007
29941
|
var UNTITLED = "Untitled";
|
|
29008
29942
|
function useDatabaseCellSources(databases) {
|
|
29009
29943
|
const workspaceId = react.useArbiSessionState((state) => state.workspaceId);
|
|
@@ -34086,7 +35020,7 @@ function useConnectedThreadActivity(conversationId) {
|
|
|
34086
35020
|
step: typeof event.detail?.step === "string" ? event.detail.step : void 0,
|
|
34087
35021
|
createdAt: event.created_at,
|
|
34088
35022
|
card: callDetail ? /* @__PURE__ */ jsxRuntime.jsx(
|
|
34089
|
-
|
|
35023
|
+
chunk5R256EMF_cjs.ThreadCallLogCard,
|
|
34090
35024
|
{
|
|
34091
35025
|
detail: callDetail,
|
|
34092
35026
|
name: personName,
|
|
@@ -34094,7 +35028,7 @@ function useConnectedThreadActivity(conversationId) {
|
|
|
34094
35028
|
time: ui.formatRelativeTime(event.created_at, { style: "short" })
|
|
34095
35029
|
}
|
|
34096
35030
|
) : recordingCall ? /* @__PURE__ */ jsxRuntime.jsx(
|
|
34097
|
-
|
|
35031
|
+
chunk5R256EMF_cjs.RecordingCard,
|
|
34098
35032
|
{
|
|
34099
35033
|
callExtId: recordingCall,
|
|
34100
35034
|
recordingExtId: recordingId,
|
|
@@ -36929,7 +37863,7 @@ var MessageComponent = ({
|
|
|
36929
37863
|
const statusLabel = isFailed ? "Response failed" : isStopped ? "Stopped" : finalElapsedSeconds >= 0.05 ? `Answered in ${finalElapsedSeconds.toFixed(1)}s` : "Complete";
|
|
36930
37864
|
const timeLabel = ui.formatFriendlyDate(message.created_at || "");
|
|
36931
37865
|
const messageId = message.external_id;
|
|
36932
|
-
const transcriptRuns =
|
|
37866
|
+
const transcriptRuns = chunk5R256EMF_cjs.useTranscriptRuns();
|
|
36933
37867
|
const messageRole = isUser ? "user" : "assistant";
|
|
36934
37868
|
const menuItems = [
|
|
36935
37869
|
...isUser ? [
|
|
@@ -37137,7 +38071,7 @@ var MessageComponent = ({
|
|
|
37137
38071
|
const speakerName = speaker ? ui.getUserDisplayName(speaker) : null;
|
|
37138
38072
|
const isMe = transcriptSegment.speaker_ext_id === currentUser?.external_id;
|
|
37139
38073
|
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
37140
|
-
|
|
38074
|
+
chunk5R256EMF_cjs.TranscriptEntry,
|
|
37141
38075
|
{
|
|
37142
38076
|
speakerId: transcriptSegment.speaker_ext_id,
|
|
37143
38077
|
speakerName: isMe ? "Me" : speakerName || "Former member",
|
|
@@ -37698,6 +38632,763 @@ function ConnectedMessageList({ messages }) {
|
|
|
37698
38632
|
/* @__PURE__ */ jsxRuntime.jsx(ConnectedThreadsPreview, { open: previewOpen, onOpenChange: setPreviewOpen })
|
|
37699
38633
|
] });
|
|
37700
38634
|
}
|
|
38635
|
+
function ThreadSearch({ children, ResultsBoundary = chunkTM2D4XT4_cjs.ErrorBoundary }) {
|
|
38636
|
+
const [query, setQuery] = React9.useState("");
|
|
38637
|
+
const [submitted, setSubmitted] = React9.useState("");
|
|
38638
|
+
const selectedWorkspaceId = react.useArbiSessionState((s) => s.workspaceId);
|
|
38639
|
+
const { notify: notify18, openConversation } = chunkB3NYBMDR_cjs.useBlocksEnvironment();
|
|
38640
|
+
const search = react.useConversationSearch();
|
|
38641
|
+
const isSearching = search.isPending;
|
|
38642
|
+
const groups = React9.useMemo(
|
|
38643
|
+
() => search.isError ? [] : (search.data?.results ?? []).map((g) => ({
|
|
38644
|
+
id: g.conversation_ext_id,
|
|
38645
|
+
title: g.title,
|
|
38646
|
+
matches: g.messages.map((m) => ({
|
|
38647
|
+
id: m.message_ext_id,
|
|
38648
|
+
role: m.role,
|
|
38649
|
+
score: m.score,
|
|
38650
|
+
snippet: m.snippet
|
|
38651
|
+
}))
|
|
38652
|
+
})),
|
|
38653
|
+
[search.data, search.isError]
|
|
38654
|
+
);
|
|
38655
|
+
const handleSearch = React9.useCallback(() => {
|
|
38656
|
+
const q = query.trim();
|
|
38657
|
+
if (!q || !selectedWorkspaceId || isSearching) return;
|
|
38658
|
+
setSubmitted(q);
|
|
38659
|
+
search.mutate(
|
|
38660
|
+
{ query: q, search_mode: "hybrid", limit: 20 },
|
|
38661
|
+
{
|
|
38662
|
+
onError: (err) => {
|
|
38663
|
+
console.error("Conversation search failed", err);
|
|
38664
|
+
notify18("Conversation search failed", "error");
|
|
38665
|
+
}
|
|
38666
|
+
}
|
|
38667
|
+
);
|
|
38668
|
+
}, [query, selectedWorkspaceId, isSearching, search, notify18]);
|
|
38669
|
+
const clearSearch = React9.useCallback(() => {
|
|
38670
|
+
setQuery("");
|
|
38671
|
+
setSubmitted("");
|
|
38672
|
+
}, []);
|
|
38673
|
+
const openHit = React9.useCallback(
|
|
38674
|
+
(conversationId, messageId) => {
|
|
38675
|
+
openConversation(conversationId, messageId ? { messageId } : void 0);
|
|
38676
|
+
},
|
|
38677
|
+
[openConversation]
|
|
38678
|
+
);
|
|
38679
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
38680
|
+
chunkDWWRLKEZ_cjs.ConversationSearchView,
|
|
38681
|
+
{
|
|
38682
|
+
query,
|
|
38683
|
+
onQueryChange: setQuery,
|
|
38684
|
+
onSubmit: handleSearch,
|
|
38685
|
+
canSubmit: !!query.trim() && !!selectedWorkspaceId && !isSearching,
|
|
38686
|
+
isSearching,
|
|
38687
|
+
submittedQuery: submitted,
|
|
38688
|
+
groups,
|
|
38689
|
+
onOpenConversation: openHit,
|
|
38690
|
+
onClear: clearSearch,
|
|
38691
|
+
ResultsBoundary,
|
|
38692
|
+
children
|
|
38693
|
+
}
|
|
38694
|
+
);
|
|
38695
|
+
}
|
|
38696
|
+
var DEFAULT_THREAD_VISIBILITY = { me: null, workspace: null };
|
|
38697
|
+
var relativeTime2 = (iso) => ui.formatRelativeTime(iso, { style: "short" });
|
|
38698
|
+
var LIST_LABELS = {
|
|
38699
|
+
emptyTitle: "Nothing here yet",
|
|
38700
|
+
emptyMessage: "Use New: just type what you need, or fill in an owner and a due date. You always decide when a thread is done.",
|
|
38701
|
+
untitled: `Untitled ${ui.getEntityLabel("CONVERSATION").toLowerCase()}`,
|
|
38702
|
+
noMatches: `No ${ui.getEntityLabel("CONVERSATION", "PLURAL").toLowerCase()} match.`,
|
|
38703
|
+
selectAll: "Select all"
|
|
38704
|
+
};
|
|
38705
|
+
var RENAME_DIALOG = { testId: "rename-conversation-modal" };
|
|
38706
|
+
function useStableRecencyOrder(rows) {
|
|
38707
|
+
const orderRef = React9.useRef([]);
|
|
38708
|
+
return React9.useMemo(() => {
|
|
38709
|
+
const byRecency = [...rows].sort(
|
|
38710
|
+
(a, b) => new Date(b.updated_at || b.created_at || 0).getTime() - new Date(a.updated_at || a.created_at || 0).getTime()
|
|
38711
|
+
);
|
|
38712
|
+
const present = new Set(byRecency.map((r) => r.external_id));
|
|
38713
|
+
const known = new Set(orderRef.current);
|
|
38714
|
+
const added = byRecency.map((r) => r.external_id).filter((id) => !known.has(id));
|
|
38715
|
+
orderRef.current = [...added, ...orderRef.current.filter((id) => present.has(id))];
|
|
38716
|
+
const byId = new Map(byRecency.map((r) => [r.external_id, r]));
|
|
38717
|
+
return orderRef.current.flatMap((id) => byId.get(id) ?? []);
|
|
38718
|
+
}, [rows]);
|
|
38719
|
+
}
|
|
38720
|
+
function ConnectedThreadsPage({
|
|
38721
|
+
showHeader = true,
|
|
38722
|
+
search = false,
|
|
38723
|
+
ResultsBoundary,
|
|
38724
|
+
focusLauncher,
|
|
38725
|
+
layout = "list",
|
|
38726
|
+
workflowActions
|
|
38727
|
+
}) {
|
|
38728
|
+
const mode = layout === "inbox" ? "tasks" : "threads";
|
|
38729
|
+
const { confirm, notify: notify18, openConversation, openDocument } = chunkB3NYBMDR_cjs.useBlocksEnvironment();
|
|
38730
|
+
const { conversations: all, isLoading } = react.useConversationItems();
|
|
38731
|
+
const [doneFilter] = react.useTransientView("threads.done", "exclude");
|
|
38732
|
+
const [visibilityFilters] = react.useTransientView("threads.visibility", DEFAULT_THREAD_VISIBILITY);
|
|
38733
|
+
const [meetingFilter] = react.useTransientView("threads.meetings", null);
|
|
38734
|
+
const [topbarFilterQuery, setTopbarFilterQuery] = react.useTransientView("topbar.filter", "");
|
|
38735
|
+
const currentUserExtId = react.useArbiSession().user?.external_id;
|
|
38736
|
+
const listed = React9.useMemo(
|
|
38737
|
+
() => all.filter((c) => mode === "threads" || c.status != null),
|
|
38738
|
+
[all, mode]
|
|
38739
|
+
);
|
|
38740
|
+
const tasks = useStableRecencyOrder(listed);
|
|
38741
|
+
const updateConversation = react.useUpdateConversation();
|
|
38742
|
+
const deleteConversation = react.useDeleteConversation();
|
|
38743
|
+
const people = useTaskPeople();
|
|
38744
|
+
const renderPerson = useRenderTaskPerson();
|
|
38745
|
+
const canEditShared = react.useCanEditShared();
|
|
38746
|
+
const isWorkspaceOwner = react.useIsWorkspaceOwner();
|
|
38747
|
+
const { data: agents = [] } = react.useAgents();
|
|
38748
|
+
const { data: workflows = [] } = react.useWorkflows();
|
|
38749
|
+
const agentNames = React9.useMemo(
|
|
38750
|
+
() => Object.fromEntries(agents.map((a) => [a.external_id, a.given_name || a.email])),
|
|
38751
|
+
[agents]
|
|
38752
|
+
);
|
|
38753
|
+
const workflowNames = React9.useMemo(
|
|
38754
|
+
() => Object.fromEntries(workflows.map((w) => [w.external_id, w.name])),
|
|
38755
|
+
[workflows]
|
|
38756
|
+
);
|
|
38757
|
+
const runConversation = react.useRunConversation();
|
|
38758
|
+
const [busyId, setBusyId] = React9.useState(null);
|
|
38759
|
+
const [editorOpen, setEditorOpen] = React9.useState(false);
|
|
38760
|
+
const [editing, setEditing] = React9.useState(null);
|
|
38761
|
+
const [startOpen, setStartOpen] = React9.useState(false);
|
|
38762
|
+
const [parentForNew, setParentForNew] = React9.useState(void 0);
|
|
38763
|
+
const nameOf = (task) => task.title?.trim() || task.workflow_ext_id && workflowNames[task.workflow_ext_id] || "Untitled task";
|
|
38764
|
+
const openCreate = () => {
|
|
38765
|
+
setParentForNew(void 0);
|
|
38766
|
+
setStartOpen(true);
|
|
38767
|
+
};
|
|
38768
|
+
const openAddSubtask = (parent) => {
|
|
38769
|
+
setParentForNew(parent.external_id);
|
|
38770
|
+
setStartOpen(true);
|
|
38771
|
+
};
|
|
38772
|
+
const [renaming, setRenaming] = React9.useState(null);
|
|
38773
|
+
const [newTitle, setNewTitle] = React9.useState("");
|
|
38774
|
+
const [isExportOpen, setIsExportOpen] = React9.useState(false);
|
|
38775
|
+
const [exportRows, setExportRows] = React9.useState([]);
|
|
38776
|
+
const openEdit = (task) => {
|
|
38777
|
+
if (mode === "threads" || !task.status) {
|
|
38778
|
+
setRenaming(task);
|
|
38779
|
+
setNewTitle(task.title ?? "");
|
|
38780
|
+
return;
|
|
38781
|
+
}
|
|
38782
|
+
setEditing(task);
|
|
38783
|
+
setEditorOpen(true);
|
|
38784
|
+
};
|
|
38785
|
+
const act = async (task, action, success, failure) => {
|
|
38786
|
+
setBusyId(task.external_id);
|
|
38787
|
+
try {
|
|
38788
|
+
await action();
|
|
38789
|
+
if (success) notify18(success, "success");
|
|
38790
|
+
} catch (error) {
|
|
38791
|
+
notify18(
|
|
38792
|
+
error instanceof browser.ArbiApiError && error.detail ? `${failure}: ${error.detail}` : failure,
|
|
38793
|
+
"error"
|
|
38794
|
+
);
|
|
38795
|
+
} finally {
|
|
38796
|
+
setBusyId(null);
|
|
38797
|
+
}
|
|
38798
|
+
};
|
|
38799
|
+
const patch = (task, body) => updateConversation.mutateAsync({ conversationId: task.external_id, patch: body });
|
|
38800
|
+
const setStatus = (task, status, success) => act(task, () => patch(task, { status }), success, "Failed to update task");
|
|
38801
|
+
const handleToggleShared = (task, shouldShare) => act(
|
|
38802
|
+
task,
|
|
38803
|
+
() => patch(task, { shared: shouldShare }),
|
|
38804
|
+
shouldShare ? `Shared \u201C${nameOf(task)}\u201D with the workspace` : `Made \u201C${nameOf(task)}\u201D private`,
|
|
38805
|
+
"Failed to change who can see the task"
|
|
38806
|
+
);
|
|
38807
|
+
const handleMove = (task, parentId) => act(
|
|
38808
|
+
task,
|
|
38809
|
+
() => patch(task, { parent_conversation_ext_id: parentId }),
|
|
38810
|
+
parentId ? `Moved \u201C${nameOf(task)}\u201D` : `Moved \u201C${nameOf(task)}\u201D to the top level`,
|
|
38811
|
+
"Failed to move task"
|
|
38812
|
+
);
|
|
38813
|
+
const handleDelete = async (task) => {
|
|
38814
|
+
const subtasks = tasks.filter((t) => t.parent_conversation_ext_id === task.external_id).length;
|
|
38815
|
+
const confirmed = await confirm({
|
|
38816
|
+
message: `Delete \u201C${nameOf(task)}\u201D? This can't be undone from here.${subtasks ? ` Its ${subtasks === 1 ? "sub-task stays" : `${subtasks} sub-tasks stay`} and ${subtasks === 1 ? "moves" : "move"} to the top level.` : ""}`,
|
|
38817
|
+
title: "Delete task"
|
|
38818
|
+
});
|
|
38819
|
+
if (!confirmed) return;
|
|
38820
|
+
await act(
|
|
38821
|
+
task,
|
|
38822
|
+
() => deleteConversation.mutateAsync(task.external_id),
|
|
38823
|
+
`Deleted \u201C${nameOf(task)}\u201D`,
|
|
38824
|
+
"Failed to delete task"
|
|
38825
|
+
);
|
|
38826
|
+
};
|
|
38827
|
+
const forEach = async (rows, one, done) => {
|
|
38828
|
+
let failed = 0;
|
|
38829
|
+
for (const task of rows) {
|
|
38830
|
+
try {
|
|
38831
|
+
await one(task);
|
|
38832
|
+
} catch {
|
|
38833
|
+
failed += 1;
|
|
38834
|
+
}
|
|
38835
|
+
}
|
|
38836
|
+
notify18(
|
|
38837
|
+
failed ? `${failed} of ${rows.length} could not be changed: you may not be allowed to change them` : done,
|
|
38838
|
+
failed ? "error" : "success"
|
|
38839
|
+
);
|
|
38840
|
+
};
|
|
38841
|
+
const handleMarkDoneMany = (rows) => forEach(rows, (task) => patch(task, { status: "done" }), `Marked ${rows.length} done`);
|
|
38842
|
+
const handleDeleteMany = async (rows) => {
|
|
38843
|
+
const named = rows.slice(0, 3).map((task) => `"${nameOf(task)}"`).join(", ");
|
|
38844
|
+
const more = rows.length - 3;
|
|
38845
|
+
const confirmed = await confirm({
|
|
38846
|
+
message: `Delete ${more > 0 ? `${named} and ${more} more` : named}? This cannot be undone.`,
|
|
38847
|
+
title: `Delete ${rows.length} item${rows.length === 1 ? "" : "s"}`
|
|
38848
|
+
});
|
|
38849
|
+
if (!confirmed) return;
|
|
38850
|
+
await forEach(
|
|
38851
|
+
rows,
|
|
38852
|
+
(task) => deleteConversation.mutateAsync(task.external_id),
|
|
38853
|
+
`Deleted ${rows.length}`
|
|
38854
|
+
);
|
|
38855
|
+
};
|
|
38856
|
+
const handleSaveRename = React9.useCallback(() => {
|
|
38857
|
+
if (!renaming || !newTitle.trim()) return;
|
|
38858
|
+
updateConversation.mutate(
|
|
38859
|
+
{ conversationId: renaming.external_id, patch: { title: newTitle.trim() } },
|
|
38860
|
+
{
|
|
38861
|
+
onSuccess: () => {
|
|
38862
|
+
notify18("Conversation renamed successfully", "success");
|
|
38863
|
+
setRenaming(null);
|
|
38864
|
+
setNewTitle("");
|
|
38865
|
+
},
|
|
38866
|
+
onError: (error) => {
|
|
38867
|
+
console.error("Failed to rename conversation:", error);
|
|
38868
|
+
notify18("Failed to rename conversation", "error");
|
|
38869
|
+
}
|
|
38870
|
+
}
|
|
38871
|
+
);
|
|
38872
|
+
}, [renaming, newTitle, updateConversation, notify18]);
|
|
38873
|
+
const handleBulkShare = async (rows) => {
|
|
38874
|
+
const unshared = rows.filter((c) => !c.is_shared);
|
|
38875
|
+
if (unshared.length === 0) {
|
|
38876
|
+
await confirm({
|
|
38877
|
+
message: "All selected conversations are already shared",
|
|
38878
|
+
title: "Info",
|
|
38879
|
+
kind: "alert"
|
|
38880
|
+
});
|
|
38881
|
+
return;
|
|
38882
|
+
}
|
|
38883
|
+
const noun = ui.getEntityLabel("CONVERSATION", unshared.length > 1 ? "PLURAL" : "SINGULAR");
|
|
38884
|
+
const confirmed = await confirm({
|
|
38885
|
+
message: `Are you sure you want to share ${unshared.length} ${noun.toLowerCase()} with everyone in the current ${ui.getEntityLabel("WORKSPACE").toLowerCase()}? You can make them private again later.`,
|
|
38886
|
+
title: `Share ${ui.getEntityLabel("CONVERSATION", "PLURAL")}`
|
|
38887
|
+
});
|
|
38888
|
+
if (!confirmed) return;
|
|
38889
|
+
try {
|
|
38890
|
+
await Promise.all(
|
|
38891
|
+
unshared.map(
|
|
38892
|
+
(c) => updateConversation.mutateAsync({ conversationId: c.external_id, patch: { shared: true } })
|
|
38893
|
+
)
|
|
38894
|
+
);
|
|
38895
|
+
notify18(`${unshared.length} ${noun.toLowerCase()} shared successfully`, "success");
|
|
38896
|
+
} catch (error) {
|
|
38897
|
+
console.error("Failed to share conversations:", error);
|
|
38898
|
+
notify18("Failed to share some conversations", "error");
|
|
38899
|
+
}
|
|
38900
|
+
};
|
|
38901
|
+
const { data: workspaceDocs } = react.useDocuments();
|
|
38902
|
+
const outputsByTask = React9.useMemo(() => {
|
|
38903
|
+
const out = {};
|
|
38904
|
+
for (const [conversationId, docs] of Object.entries(
|
|
38905
|
+
chunkDWWRLKEZ_cjs.groupOutputsByConversation(workspaceDocs ?? [])
|
|
38906
|
+
)) {
|
|
38907
|
+
out[conversationId] = docs.map((d) => ({
|
|
38908
|
+
id: d.external_id,
|
|
38909
|
+
name: ui.getDocumentTitle(d, d.external_id)
|
|
38910
|
+
}));
|
|
38911
|
+
}
|
|
38912
|
+
return out;
|
|
38913
|
+
}, [workspaceDocs]);
|
|
38914
|
+
const handleOpenOutput = (documentId) => openDocument(documentId);
|
|
38915
|
+
const handleGrantAccess = (task) => act(
|
|
38916
|
+
task,
|
|
38917
|
+
() => runConversation.mutateAsync(task.external_id),
|
|
38918
|
+
`Running \u201C${nameOf(task)}\u201D`,
|
|
38919
|
+
"Failed to run task"
|
|
38920
|
+
);
|
|
38921
|
+
const threadLabels = useThreadLabels(canEditShared);
|
|
38922
|
+
const selectionActions = (selected, isCompact) => {
|
|
38923
|
+
const mine = selected.every((c) => c.created_by_ext_id === currentUserExtId);
|
|
38924
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
38925
|
+
mode === "threads" && selected.every((row2) => row2.is_owner || row2.is_shared && canEditShared) && selected.some((row2) => row2.status !== "done") && !selected.some((row2) => row2.in_progress || row2.status === "generating") && /* @__PURE__ */ jsxRuntime.jsx(
|
|
38926
|
+
chunkV4ISCZJ7_cjs.SelectionBarAction,
|
|
38927
|
+
{
|
|
38928
|
+
icon: lucideReact.CheckCheck,
|
|
38929
|
+
label: "Mark Done",
|
|
38930
|
+
onClick: () => void handleMarkDoneMany(selected),
|
|
38931
|
+
isCompact,
|
|
38932
|
+
testId: "threads-bulk-done"
|
|
38933
|
+
}
|
|
38934
|
+
),
|
|
38935
|
+
threadLabels.renderBulkLabels(selected, isCompact),
|
|
38936
|
+
mine && selected.some((c) => !c.is_shared) && /* @__PURE__ */ jsxRuntime.jsx(
|
|
38937
|
+
ui.VisibilityToggle,
|
|
38938
|
+
{
|
|
38939
|
+
items: selected,
|
|
38940
|
+
onToggle: () => void handleBulkShare(selected),
|
|
38941
|
+
disablePrivate: true,
|
|
38942
|
+
showLabel: false,
|
|
38943
|
+
tooltipInactive: "Share all with workspace members",
|
|
38944
|
+
tooltipMixed: "Share all with workspace members (some already shared)",
|
|
38945
|
+
"data-testid": "bulk-shared-toggle"
|
|
38946
|
+
}
|
|
38947
|
+
),
|
|
38948
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
38949
|
+
chunkV4ISCZJ7_cjs.SelectionBarAction,
|
|
38950
|
+
{
|
|
38951
|
+
icon: lucideReact.FolderUp,
|
|
38952
|
+
label: "Export",
|
|
38953
|
+
onClick: () => {
|
|
38954
|
+
setExportRows(selected);
|
|
38955
|
+
setIsExportOpen(true);
|
|
38956
|
+
},
|
|
38957
|
+
isCompact,
|
|
38958
|
+
tooltip: `Export the selected ${ui.getEntityLabel("CONVERSATION", "PLURAL").toLowerCase()} to another ${ui.getEntityLabel("WORKSPACE").toLowerCase()}`,
|
|
38959
|
+
testId: "export-chats-button"
|
|
38960
|
+
}
|
|
38961
|
+
),
|
|
38962
|
+
mode === "threads" && selected.every((row2) => row2.is_owner || isWorkspaceOwner) && /* @__PURE__ */ jsxRuntime.jsx(
|
|
38963
|
+
chunkV4ISCZJ7_cjs.SelectionBarAction,
|
|
38964
|
+
{
|
|
38965
|
+
icon: lucideReact.Trash2,
|
|
38966
|
+
label: "Delete",
|
|
38967
|
+
className: "text-red-text hover:bg-red-bg hover:text-red-text",
|
|
38968
|
+
onClick: () => void handleDeleteMany(selected),
|
|
38969
|
+
isCompact,
|
|
38970
|
+
testId: "threads-bulk-delete"
|
|
38971
|
+
}
|
|
38972
|
+
)
|
|
38973
|
+
] });
|
|
38974
|
+
};
|
|
38975
|
+
const page = /* @__PURE__ */ jsxRuntime.jsxs(
|
|
38976
|
+
"div",
|
|
38977
|
+
{
|
|
38978
|
+
className: "flex h-full min-h-0 flex-col",
|
|
38979
|
+
"data-testid": mode === "tasks" ? "tasks-page" : "threads-page",
|
|
38980
|
+
children: [
|
|
38981
|
+
/* @__PURE__ */ jsxRuntime.jsx("main", { className: "flex min-h-0 flex-1 flex-col bg-background", children: mode === "threads" ? /* @__PURE__ */ jsxRuntime.jsx(
|
|
38982
|
+
chunkO3MRE2HL_cjs.ConversationListView,
|
|
38983
|
+
{
|
|
38984
|
+
showHeader,
|
|
38985
|
+
conversations: tasks,
|
|
38986
|
+
doneFilter,
|
|
38987
|
+
visibilityFilters,
|
|
38988
|
+
meetingFilter,
|
|
38989
|
+
renderThread: (row2) => /* @__PURE__ */ jsxRuntime.jsx(
|
|
38990
|
+
ConversationEntity,
|
|
38991
|
+
{
|
|
38992
|
+
conversation: row2,
|
|
38993
|
+
showRePrefix: false,
|
|
38994
|
+
labelMaxWidth: "max-w-full",
|
|
38995
|
+
className: "w-full max-w-full [&_.truncate]:line-clamp-2 [&_.truncate]:whitespace-normal [&_.truncate]:break-words [&_.truncate]:text-left",
|
|
38996
|
+
"data-testid": `thread-open-${row2.external_id}`
|
|
38997
|
+
}
|
|
38998
|
+
),
|
|
38999
|
+
renderLabels: threadLabels.renderLabels,
|
|
39000
|
+
labelText: threadLabels.labelText,
|
|
39001
|
+
renderBy: (row2) => /* @__PURE__ */ jsxRuntime.jsx(
|
|
39002
|
+
chunkO3MRE2HL_cjs.ConversationTurnSpeaker,
|
|
39003
|
+
{
|
|
39004
|
+
variant: "icon",
|
|
39005
|
+
role: row2.last_message_role,
|
|
39006
|
+
actor: row2.last_message_actor,
|
|
39007
|
+
currentUserId: currentUserExtId,
|
|
39008
|
+
colorClass: row2.last_message_actor ? ui.getUserAvatarColor(row2.last_message_actor.external_id) : void 0
|
|
39009
|
+
}
|
|
39010
|
+
),
|
|
39011
|
+
renderStatus: (row2) => /* @__PURE__ */ jsxRuntime.jsx(ConversationStatusCell, { conversation: row2 }),
|
|
39012
|
+
isLoading,
|
|
39013
|
+
filterText: topbarFilterQuery ?? "",
|
|
39014
|
+
formatDate: relativeTime2,
|
|
39015
|
+
onOpen: (c) => openConversation(c.external_id),
|
|
39016
|
+
onRename: openEdit,
|
|
39017
|
+
onDelete: handleDelete,
|
|
39018
|
+
canEditShared,
|
|
39019
|
+
isWorkspaceOwner,
|
|
39020
|
+
selectionActions,
|
|
39021
|
+
footer: /* @__PURE__ */ jsxRuntime.jsx(ConnectedThreadLauncher, { autoFocus: focusLauncher })
|
|
39022
|
+
}
|
|
39023
|
+
) : /* @__PURE__ */ jsxRuntime.jsx(
|
|
39024
|
+
chunkO3MRE2HL_cjs.TaskInbox,
|
|
39025
|
+
{
|
|
39026
|
+
tasks,
|
|
39027
|
+
isLoading,
|
|
39028
|
+
...workflowActions,
|
|
39029
|
+
onCreate: openCreate,
|
|
39030
|
+
filterText: topbarFilterQuery ?? "",
|
|
39031
|
+
labels: LIST_LABELS,
|
|
39032
|
+
gridId: "conversation-list-grid-v4",
|
|
39033
|
+
onFilterTextChange: (text2) => setTopbarFilterQuery(text2),
|
|
39034
|
+
outputsByTask,
|
|
39035
|
+
onOpenActivity: (task) => openConversation(task.external_id),
|
|
39036
|
+
formatRelative: relativeTime2,
|
|
39037
|
+
onOpenOutput: handleOpenOutput,
|
|
39038
|
+
busyId,
|
|
39039
|
+
formatDate: ui.formatFriendlyDate,
|
|
39040
|
+
onOpenThread: (conversationId) => openConversation(conversationId),
|
|
39041
|
+
onMarkDone: (task) => setStatus(task, "done", `Marked \u201C${nameOf(task)}\u201D done`),
|
|
39042
|
+
onReopen: (task) => setStatus(task, "todo", `Reopened \u201C${nameOf(task)}\u201D`),
|
|
39043
|
+
people,
|
|
39044
|
+
agentNames,
|
|
39045
|
+
workflowNames,
|
|
39046
|
+
canEditShared,
|
|
39047
|
+
isWorkspaceOwner,
|
|
39048
|
+
renderPerson,
|
|
39049
|
+
onToggleShared: handleToggleShared,
|
|
39050
|
+
onEdit: openEdit,
|
|
39051
|
+
onDelete: handleDelete,
|
|
39052
|
+
onAddSubtask: openAddSubtask,
|
|
39053
|
+
onMove: handleMove,
|
|
39054
|
+
onMarkDoneMany: handleMarkDoneMany,
|
|
39055
|
+
onDeleteMany: handleDeleteMany,
|
|
39056
|
+
onGrantAccess: handleGrantAccess,
|
|
39057
|
+
selectionActions
|
|
39058
|
+
}
|
|
39059
|
+
) }),
|
|
39060
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
39061
|
+
ConnectedTaskStartDialog,
|
|
39062
|
+
{
|
|
39063
|
+
open: startOpen,
|
|
39064
|
+
onOpenChange: setStartOpen,
|
|
39065
|
+
initialParentId: parentForNew
|
|
39066
|
+
}
|
|
39067
|
+
),
|
|
39068
|
+
/* @__PURE__ */ jsxRuntime.jsx(ConnectedTaskComposer, { open: editorOpen, onOpenChange: setEditorOpen, task: editing }),
|
|
39069
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
39070
|
+
ConnectedExportDialog,
|
|
39071
|
+
{
|
|
39072
|
+
open: isExportOpen,
|
|
39073
|
+
onOpenChange: setIsExportOpen,
|
|
39074
|
+
items: exportRows.map((c) => ({ extId: c.external_id, label: nameOf(c) })),
|
|
39075
|
+
entityType: "CONVERSATION",
|
|
39076
|
+
testId: "export-chats-modal"
|
|
39077
|
+
}
|
|
39078
|
+
),
|
|
39079
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
39080
|
+
chunkFEVJA4BP_cjs.RenameDialog,
|
|
39081
|
+
{
|
|
39082
|
+
open: !!renaming,
|
|
39083
|
+
onClose: () => {
|
|
39084
|
+
setRenaming(null);
|
|
39085
|
+
setNewTitle("");
|
|
39086
|
+
},
|
|
39087
|
+
title: `Rename ${ui.getEntityLabel("CONVERSATION")}`,
|
|
39088
|
+
labels: { description: "Rename the conversation title" },
|
|
39089
|
+
fieldLabel: `${ui.getEntityLabel("CONVERSATION")} Title`,
|
|
39090
|
+
placeholder: "Enter title",
|
|
39091
|
+
value: newTitle,
|
|
39092
|
+
onChange: setNewTitle,
|
|
39093
|
+
onSave: handleSaveRename,
|
|
39094
|
+
canSave: !!newTitle.trim(),
|
|
39095
|
+
dialogTestId: RENAME_DIALOG.testId
|
|
39096
|
+
}
|
|
39097
|
+
)
|
|
39098
|
+
]
|
|
39099
|
+
}
|
|
39100
|
+
);
|
|
39101
|
+
return search ? /* @__PURE__ */ jsxRuntime.jsx(ThreadSearch, { ResultsBoundary, children: page }) : page;
|
|
39102
|
+
}
|
|
39103
|
+
function ConnectedFilterDropdown({
|
|
39104
|
+
stateKey,
|
|
39105
|
+
...props
|
|
39106
|
+
}) {
|
|
39107
|
+
const [open, setOpen] = react.useTransientView(`filter.dropdown.${stateKey}`, false);
|
|
39108
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
39109
|
+
chunkAQPZ4QMV_cjs.TriStateFilterMenu,
|
|
39110
|
+
{
|
|
39111
|
+
...props,
|
|
39112
|
+
testId: `${stateKey}-filter-button`,
|
|
39113
|
+
open,
|
|
39114
|
+
onOpenChange: setOpen
|
|
39115
|
+
}
|
|
39116
|
+
);
|
|
39117
|
+
}
|
|
39118
|
+
function SearchSparkleIcon({ className }) {
|
|
39119
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
39120
|
+
"svg",
|
|
39121
|
+
{
|
|
39122
|
+
viewBox: "0 0 24 24",
|
|
39123
|
+
fill: "none",
|
|
39124
|
+
stroke: "currentColor",
|
|
39125
|
+
strokeWidth: "2",
|
|
39126
|
+
strokeLinecap: "round",
|
|
39127
|
+
strokeLinejoin: "round",
|
|
39128
|
+
"aria-hidden": "true",
|
|
39129
|
+
className,
|
|
39130
|
+
children: [
|
|
39131
|
+
/* @__PURE__ */ jsxRuntime.jsx("circle", { cx: "10.5", cy: "10.5", r: "7.5" }),
|
|
39132
|
+
/* @__PURE__ */ jsxRuntime.jsx("path", { d: "m21 21-5.2-5.2" }),
|
|
39133
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
39134
|
+
"path",
|
|
39135
|
+
{
|
|
39136
|
+
d: "M10.5 6.8c.35 2.1 1.6 3.35 3.7 3.7-2.1.35-3.35 1.6-3.7 3.7-.35-2.1-1.6-3.35-3.7-3.7 2.1-.35 3.35-1.6 3.7-3.7Z",
|
|
39137
|
+
fill: "currentColor",
|
|
39138
|
+
strokeWidth: "1"
|
|
39139
|
+
}
|
|
39140
|
+
)
|
|
39141
|
+
]
|
|
39142
|
+
}
|
|
39143
|
+
);
|
|
39144
|
+
}
|
|
39145
|
+
function SemanticSearchButton({ active, onClick }) {
|
|
39146
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(ui.Tooltip, { children: [
|
|
39147
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.TooltipTrigger, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
39148
|
+
ui.Button,
|
|
39149
|
+
{
|
|
39150
|
+
type: "button",
|
|
39151
|
+
variant: "ghost",
|
|
39152
|
+
size: "icon",
|
|
39153
|
+
onClick,
|
|
39154
|
+
"aria-label": "Semantic search",
|
|
39155
|
+
"aria-pressed": active,
|
|
39156
|
+
"data-testid": "semantic-search-button",
|
|
39157
|
+
className: active ? "bg-muted text-primary" : "text-muted-foreground hover:text-foreground",
|
|
39158
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(SearchSparkleIcon, { className: "size-5" })
|
|
39159
|
+
}
|
|
39160
|
+
) }),
|
|
39161
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.TooltipContent, { children: /* @__PURE__ */ jsxRuntime.jsx("p", { children: "Semantic search" }) })
|
|
39162
|
+
] });
|
|
39163
|
+
}
|
|
39164
|
+
var DEFAULT_THREAD_VISIBILITY2 = { me: null, workspace: null };
|
|
39165
|
+
function ConnectedConversationPage({
|
|
39166
|
+
renderComposerAccessory,
|
|
39167
|
+
ResultsBoundary,
|
|
39168
|
+
onGoToDocuments,
|
|
39169
|
+
modelSelector,
|
|
39170
|
+
composerAccessory,
|
|
39171
|
+
composerTools,
|
|
39172
|
+
ConversationThread: ConversationThread2
|
|
39173
|
+
}) {
|
|
39174
|
+
const session = react.useArbiSessionStore();
|
|
39175
|
+
const { openFiles } = chunkB3NYBMDR_cjs.useBlocksEnvironment();
|
|
39176
|
+
React9.useEffect(() => () => session.setActiveCitationKey(null), [session]);
|
|
39177
|
+
const { isInChat, setActiveTab } = useThreadTabs();
|
|
39178
|
+
const [doneFilter, setDoneFilter] = react.useTransientView(
|
|
39179
|
+
"threads.done",
|
|
39180
|
+
"exclude"
|
|
39181
|
+
);
|
|
39182
|
+
const [visibilityFilters, setVisibilityFilters] = react.useTransientView(
|
|
39183
|
+
"threads.visibility",
|
|
39184
|
+
DEFAULT_THREAD_VISIBILITY2
|
|
39185
|
+
);
|
|
39186
|
+
const [meetingFilter, setMeetingFilter] = react.useTransientView(
|
|
39187
|
+
"threads.meetings",
|
|
39188
|
+
null
|
|
39189
|
+
);
|
|
39190
|
+
const [threadFilter, setThreadFilter] = react.useTransientView("topbar.filter", "");
|
|
39191
|
+
const { data: userSettings } = react.useUserSettings();
|
|
39192
|
+
const isDeveloper = userSettings?.developer === true;
|
|
39193
|
+
const showPaMode = userSettings?.show_pa_mode ?? false;
|
|
39194
|
+
const searchEnabled = userSettings?.show_conversation_search === true;
|
|
39195
|
+
const [semanticSearchOpen, setSemanticSearchOpen] = React9.useState(false);
|
|
39196
|
+
const handleSelectSource = (source) => {
|
|
39197
|
+
if (source === "internet") {
|
|
39198
|
+
setUrlDialogOpen(true);
|
|
39199
|
+
return;
|
|
39200
|
+
}
|
|
39201
|
+
chunkB3NYBMDR_cjs.openDialog("upload", { tab: "upload", source });
|
|
39202
|
+
};
|
|
39203
|
+
const handleGoToDocuments = () => {
|
|
39204
|
+
chunkB3NYBMDR_cjs.closeDialog("conversationDocuments");
|
|
39205
|
+
if (onGoToDocuments) onGoToDocuments();
|
|
39206
|
+
else openFiles();
|
|
39207
|
+
};
|
|
39208
|
+
const handleStatusClick = () => {
|
|
39209
|
+
chunkB3NYBMDR_cjs.openDialog("conversationDocuments");
|
|
39210
|
+
};
|
|
39211
|
+
const currentConversationId = react.useArbiSessionState((state) => state.conversationId);
|
|
39212
|
+
const { conversations: taskItems } = react.useConversationItems();
|
|
39213
|
+
const conversations = taskItems;
|
|
39214
|
+
const workspaceId = react.useArbiSessionState((state) => state.workspaceId);
|
|
39215
|
+
const { data: workspaces = [] } = react.useWorkspaces();
|
|
39216
|
+
const workspace = workspaces.find((item) => item.external_id === workspaceId);
|
|
39217
|
+
const workspaceRole = react.useWorkspaceRole();
|
|
39218
|
+
const isGuest = workspaceRole === "guest";
|
|
39219
|
+
const canUpload = workspaceRole !== null && !isGuest;
|
|
39220
|
+
const [urlDialogOpen, setUrlDialogOpen] = React9.useState(false);
|
|
39221
|
+
const [focusLauncher, setFocusLauncher] = React9.useState(false);
|
|
39222
|
+
React9.useEffect(() => {
|
|
39223
|
+
if (isInChat) setFocusLauncher(false);
|
|
39224
|
+
}, [isInChat]);
|
|
39225
|
+
const uploadUrls = useAddFromUrls({
|
|
39226
|
+
onZipFiles: (files) => chunkB3NYBMDR_cjs.openDialog("upload", { tab: "upload", files, source: "computer" })
|
|
39227
|
+
});
|
|
39228
|
+
const uploadDisabledReason = isGuest ? "Guests cannot upload documents in this workspace" : "You cannot upload to this workspace";
|
|
39229
|
+
const { data: allWorkspaceDocuments = [] } = react.useDocuments();
|
|
39230
|
+
const { data: conversationDocuments } = react.useConversationDocuments();
|
|
39231
|
+
const pinnedDocumentId = react.useArbiSessionState((state) => state.pinnedDocumentId);
|
|
39232
|
+
const pinnedRef = artifacts.parseVersionRef(pinnedDocumentId);
|
|
39233
|
+
const pinnedDocument = conversationDocuments?.find((d) => d.external_id === pinnedRef.docId) ?? allWorkspaceDocuments?.find((d) => d.external_id === pinnedRef.docId);
|
|
39234
|
+
const pinnedTitle = pinnedDocument ? `${ui.getDocumentTitle(pinnedDocument)}${pinnedRef.version ? ` (version ${pinnedRef.version})` : ""}` : null;
|
|
39235
|
+
const startNewChat = (asPaChat) => {
|
|
39236
|
+
session.clearConversationError(currentConversationId || "new");
|
|
39237
|
+
session.startNewConversation();
|
|
39238
|
+
session.openThreadTab(null);
|
|
39239
|
+
session.setPaMode(true);
|
|
39240
|
+
};
|
|
39241
|
+
const threadFilterDropdown = /* @__PURE__ */ jsxRuntime.jsx(
|
|
39242
|
+
ConnectedFilterDropdown,
|
|
39243
|
+
{
|
|
39244
|
+
stateKey: "threads",
|
|
39245
|
+
filterStates: /* @__PURE__ */ new Map([
|
|
39246
|
+
["done", doneFilter],
|
|
39247
|
+
["me", visibilityFilters.me],
|
|
39248
|
+
["workspace", visibilityFilters.workspace],
|
|
39249
|
+
["meeting", meetingFilter]
|
|
39250
|
+
]),
|
|
39251
|
+
onFiltersChange: (filters) => {
|
|
39252
|
+
setDoneFilter(filters.get("done") ?? null);
|
|
39253
|
+
setMeetingFilter(filters.get("meeting") ?? null);
|
|
39254
|
+
setVisibilityFilters({
|
|
39255
|
+
me: filters.get("me") ?? null,
|
|
39256
|
+
workspace: filters.get("workspace") ?? null
|
|
39257
|
+
});
|
|
39258
|
+
},
|
|
39259
|
+
options: [
|
|
39260
|
+
{
|
|
39261
|
+
id: "me",
|
|
39262
|
+
label: "Only Me",
|
|
39263
|
+
count: conversations.filter((thread) => !thread.is_shared).length
|
|
39264
|
+
},
|
|
39265
|
+
{
|
|
39266
|
+
id: "workspace",
|
|
39267
|
+
label: "Workspace",
|
|
39268
|
+
count: conversations.filter((thread) => thread.is_shared).length
|
|
39269
|
+
},
|
|
39270
|
+
{
|
|
39271
|
+
id: "meeting",
|
|
39272
|
+
label: "Meetings",
|
|
39273
|
+
count: conversations.filter((thread) => !!thread.meeting_call_ext_id).length
|
|
39274
|
+
},
|
|
39275
|
+
{
|
|
39276
|
+
id: "done",
|
|
39277
|
+
label: "Done",
|
|
39278
|
+
count: conversations.filter((thread) => thread.status === "done").length
|
|
39279
|
+
}
|
|
39280
|
+
],
|
|
39281
|
+
hasExternalActiveState: Boolean(threadFilter.trim()),
|
|
39282
|
+
renderChevron: true,
|
|
39283
|
+
disableHoverOpen: true,
|
|
39284
|
+
align: "start"
|
|
39285
|
+
}
|
|
39286
|
+
);
|
|
39287
|
+
const threadFilterBox = /* @__PURE__ */ jsxRuntime.jsx(
|
|
39288
|
+
chunk2EI7NCUA_cjs.FilterInput,
|
|
39289
|
+
{
|
|
39290
|
+
filter: threadFilterDropdown,
|
|
39291
|
+
borderless: true,
|
|
39292
|
+
value: threadFilter,
|
|
39293
|
+
onChange: setThreadFilter,
|
|
39294
|
+
fields: ["text"],
|
|
39295
|
+
onFieldsChange: () => {
|
|
39296
|
+
},
|
|
39297
|
+
hideFieldPicker: true,
|
|
39298
|
+
ariaLabel: "Filter threads",
|
|
39299
|
+
labels: doneFilter === "exclude" ? { placeholder: "Done hidden" } : void 0,
|
|
39300
|
+
className: "w-44 max-w-[40vw]"
|
|
39301
|
+
}
|
|
39302
|
+
);
|
|
39303
|
+
const { data: workspaceTags = [] } = react.useTags();
|
|
39304
|
+
const historyCount = chunkO3MRE2HL_cjs.filterConversationRows(
|
|
39305
|
+
conversations,
|
|
39306
|
+
threadFilter,
|
|
39307
|
+
(row2) => workspaceTags.filter((tag) => row2.label_ext_ids?.includes(tag.external_id)).map((tag) => tag.name).join(" "),
|
|
39308
|
+
doneFilter,
|
|
39309
|
+
visibilityFilters,
|
|
39310
|
+
meetingFilter
|
|
39311
|
+
).length;
|
|
39312
|
+
const historyFiltered = Boolean(threadFilter.trim()) || doneFilter !== null || meetingFilter !== null || Object.values(visibilityFilters).some(Boolean);
|
|
39313
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
39314
|
+
/* @__PURE__ */ jsxRuntime.jsxs(chunkDWWRLKEZ_cjs.ConversationRoot, { children: [
|
|
39315
|
+
/* @__PURE__ */ jsxRuntime.jsxs(chunkDWWRLKEZ_cjs.ConversationHeader, { children: [
|
|
39316
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
39317
|
+
ConnectedThreadTabs,
|
|
39318
|
+
{
|
|
39319
|
+
historyCount,
|
|
39320
|
+
historyFiltered,
|
|
39321
|
+
historyActions: threadFilterBox,
|
|
39322
|
+
rightContent: (isCompact) => /* @__PURE__ */ jsxRuntime.jsxs(chunkDWWRLKEZ_cjs.ConversationHeaderActions, { children: [
|
|
39323
|
+
searchEnabled && /* @__PURE__ */ jsxRuntime.jsx(
|
|
39324
|
+
SemanticSearchButton,
|
|
39325
|
+
{
|
|
39326
|
+
active: semanticSearchOpen && !isInChat,
|
|
39327
|
+
onClick: () => {
|
|
39328
|
+
if (isInChat) {
|
|
39329
|
+
setActiveTab("history");
|
|
39330
|
+
setSemanticSearchOpen(true);
|
|
39331
|
+
} else {
|
|
39332
|
+
setSemanticSearchOpen((open) => !open);
|
|
39333
|
+
}
|
|
39334
|
+
}
|
|
39335
|
+
}
|
|
39336
|
+
),
|
|
39337
|
+
isInChat && /* @__PURE__ */ jsxRuntime.jsx(chunk5R256EMF_cjs.ConnectedConversationCallActions, {}),
|
|
39338
|
+
isInChat && /* @__PURE__ */ jsxRuntime.jsx(
|
|
39339
|
+
chunkDWWRLKEZ_cjs.NewChatButton,
|
|
39340
|
+
{
|
|
39341
|
+
entityLabel: "Task",
|
|
39342
|
+
labels: { newEntity: () => "New Task" },
|
|
39343
|
+
isCompact,
|
|
39344
|
+
onClick: () => {
|
|
39345
|
+
setFocusLauncher(true);
|
|
39346
|
+
setActiveTab("history");
|
|
39347
|
+
}
|
|
39348
|
+
}
|
|
39349
|
+
),
|
|
39350
|
+
showPaMode && /* @__PURE__ */ jsxRuntime.jsx(chunkDWWRLKEZ_cjs.NewPaChatButton, { isCompact, onClick: () => startNewChat() })
|
|
39351
|
+
] })
|
|
39352
|
+
}
|
|
39353
|
+
),
|
|
39354
|
+
isInChat && /* @__PURE__ */ jsxRuntime.jsx(ConnectedThreadTaskBar, { conversationId: currentConversationId })
|
|
39355
|
+
] }),
|
|
39356
|
+
isInChat && /* @__PURE__ */ jsxRuntime.jsx(
|
|
39357
|
+
ConversationThread2,
|
|
39358
|
+
{
|
|
39359
|
+
modelSelector,
|
|
39360
|
+
composerAccessory: renderComposerAccessory ? renderComposerAccessory({
|
|
39361
|
+
documents: conversationDocuments || [],
|
|
39362
|
+
pinnedTitle,
|
|
39363
|
+
onStatusClick: handleStatusClick,
|
|
39364
|
+
onSelectSource: handleSelectSource,
|
|
39365
|
+
onAddFromSources: handleGoToDocuments,
|
|
39366
|
+
canUpload,
|
|
39367
|
+
uploadDisabledReason
|
|
39368
|
+
}) : composerAccessory,
|
|
39369
|
+
composerTools: composerTools !== void 0 ? composerTools : isDeveloper && /* @__PURE__ */ jsxRuntime.jsx(
|
|
39370
|
+
chunkDWWRLKEZ_cjs.ConversationSettingsButton,
|
|
39371
|
+
{
|
|
39372
|
+
label: `${ui.getEntityLabel("CONVERSATION")} Settings`,
|
|
39373
|
+
onClick: () => chunkB3NYBMDR_cjs.openDialog("conversationSettings")
|
|
39374
|
+
}
|
|
39375
|
+
)
|
|
39376
|
+
}
|
|
39377
|
+
),
|
|
39378
|
+
!isInChat && /* @__PURE__ */ jsxRuntime.jsx(chunkDWWRLKEZ_cjs.ConversationHistoryPane, { children: searchEnabled && semanticSearchOpen ? /* @__PURE__ */ jsxRuntime.jsx(ConnectedThreadsPage, { showHeader: false, search: true, ResultsBoundary }) : /* @__PURE__ */ jsxRuntime.jsx(ConnectedThreadsPage, { showHeader: false, focusLauncher }) })
|
|
39379
|
+
] }),
|
|
39380
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
39381
|
+
chunkWALADS2S_cjs.UrlInputDialog,
|
|
39382
|
+
{
|
|
39383
|
+
open: urlDialogOpen,
|
|
39384
|
+
onOpenChange: setUrlDialogOpen,
|
|
39385
|
+
onUrlsSubmit: uploadUrls,
|
|
39386
|
+
titleWorkspaceName: workspace?.name,
|
|
39387
|
+
titleIcon: workspace && /* @__PURE__ */ jsxRuntime.jsx(ConnectedWorkspaceEntity, { workspace, size: 24, variant: "icon" })
|
|
39388
|
+
}
|
|
39389
|
+
)
|
|
39390
|
+
] });
|
|
39391
|
+
}
|
|
37701
39392
|
function useStartRequestedDraft(enabled = true) {
|
|
37702
39393
|
const session = react.useArbiSessionStore();
|
|
37703
39394
|
chunkB3NYBMDR_cjs.useIntentRequest(
|
|
@@ -38288,7 +39979,7 @@ function useThreadScroll({
|
|
|
38288
39979
|
scrollToBottom
|
|
38289
39980
|
};
|
|
38290
39981
|
}
|
|
38291
|
-
function
|
|
39982
|
+
function ConversationThread({
|
|
38292
39983
|
modelSelector,
|
|
38293
39984
|
composerAccessory,
|
|
38294
39985
|
composerTools
|
|
@@ -38388,7 +40079,7 @@ function ConnectedConversation({
|
|
|
38388
40079
|
const isGuest = react.useWorkspaceRole() === "guest";
|
|
38389
40080
|
const meetingReadOnly = isGuest && !!currentTask?.meeting_call_ext_id;
|
|
38390
40081
|
const meetingCallExtId = currentTask?.meeting_call_ext_id ?? null;
|
|
38391
|
-
const threadMessages =
|
|
40082
|
+
const threadMessages = chunk5R256EMF_cjs.useMeetingThreadMessages(meetingCallExtId, messageHistory);
|
|
38392
40083
|
const [firstTurnPrompt, setFirstTurnPrompt] = React9.useState(null);
|
|
38393
40084
|
const currentUserExtId = react.useArbiSession().user?.external_id ?? "";
|
|
38394
40085
|
const pendingFirstTurn = React9.useMemo(
|
|
@@ -38436,7 +40127,7 @@ function ConnectedConversation({
|
|
|
38436
40127
|
return shownThreadMessages.slice(0, editIndex);
|
|
38437
40128
|
}, [shownThreadMessages, editingMessageId]);
|
|
38438
40129
|
const transcriptRunInfo = React9.useMemo(
|
|
38439
|
-
() =>
|
|
40130
|
+
() => chunk5R256EMF_cjs.threadTranscriptRuns(meetingCallExtId ? visibleMessages : []),
|
|
38440
40131
|
[meetingCallExtId, visibleMessages]
|
|
38441
40132
|
);
|
|
38442
40133
|
const threadLines = React9.useMemo(
|
|
@@ -38451,7 +40142,7 @@ function ConnectedConversation({
|
|
|
38451
40142
|
}),
|
|
38452
40143
|
[threadMessages]
|
|
38453
40144
|
);
|
|
38454
|
-
const provisionalSpeakers =
|
|
40145
|
+
const provisionalSpeakers = chunk5R256EMF_cjs.useProvisionalSpeakers(meetingCallExtId, threadLines);
|
|
38455
40146
|
const showProvisional = !!meetingCallExtId && meetingView !== "chat";
|
|
38456
40147
|
const latestContextUsage = React9.useMemo(() => {
|
|
38457
40148
|
const messages = messageHistory;
|
|
@@ -38590,7 +40281,7 @@ function ConnectedConversation({
|
|
|
38590
40281
|
useStartRequestedDraft();
|
|
38591
40282
|
const orphanedMessage = react.getOrphanedLastMessage(messageHistory, isGenerating, assistantMode);
|
|
38592
40283
|
return /* @__PURE__ */ jsxRuntime.jsxs(chunkDWWRLKEZ_cjs.ConversationBody, { children: [
|
|
38593
|
-
/* @__PURE__ */ jsxRuntime.jsx(chunkDWWRLKEZ_cjs.ConversationMain, { "data-testid": `conversation-${currentConversationId}`, children: threadsLoading ? /* @__PURE__ */ jsxRuntime.jsx(chunkDWWRLKEZ_cjs.ConversationLoading, {}) : messageHistory.length > 0 || isBranching ? /* @__PURE__ */ jsxRuntime.jsx(AskAgainContext.Provider, { value: handleAskAgain, children: /* @__PURE__ */ jsxRuntime.jsxs(
|
|
40284
|
+
/* @__PURE__ */ jsxRuntime.jsx(chunkDWWRLKEZ_cjs.ConversationMain, { "data-testid": `conversation-${currentConversationId}`, children: threadsLoading ? /* @__PURE__ */ jsxRuntime.jsx(chunkDWWRLKEZ_cjs.ConversationLoading, {}) : messageHistory.length > 0 || isBranching ? /* @__PURE__ */ jsxRuntime.jsx(AskAgainContext.Provider, { value: handleAskAgain, children: /* @__PURE__ */ jsxRuntime.jsxs(chunk5R256EMF_cjs.TranscriptRunsContext.Provider, { value: transcriptRunInfo, children: [
|
|
38594
40285
|
meetingCallExtId && transcriptLineCount > 0 && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex justify-center py-2", children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
38595
40286
|
chunkNXHETIOB_cjs.ConversationFilter,
|
|
38596
40287
|
{
|
|
@@ -38609,12 +40300,12 @@ function ConnectedConversation({
|
|
|
38609
40300
|
}
|
|
38610
40301
|
) }),
|
|
38611
40302
|
/* @__PURE__ */ jsxRuntime.jsx(ConnectedMessageArea, { ref: containerRef, messages: visibleMessages }),
|
|
38612
|
-
showProvisional && /* @__PURE__ */ jsxRuntime.jsx(
|
|
40303
|
+
showProvisional && /* @__PURE__ */ jsxRuntime.jsx(chunk5R256EMF_cjs.ProvisionalSpeakers, { ids: provisionalSpeakers })
|
|
38613
40304
|
] }) }) : meetingCallExtId ? (
|
|
38614
40305
|
// A meeting thread with nothing yet: call-aware, not the upload prompt.
|
|
38615
40306
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
|
|
38616
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
38617
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
40307
|
+
/* @__PURE__ */ jsxRuntime.jsx(chunk5R256EMF_cjs.CallConversationEmpty, { callExtId: meetingCallExtId }),
|
|
40308
|
+
/* @__PURE__ */ jsxRuntime.jsx(chunk5R256EMF_cjs.ProvisionalSpeakers, { ids: provisionalSpeakers })
|
|
38618
40309
|
] })
|
|
38619
40310
|
) : currentTask && currentTask.status != null ? /* @__PURE__ */ jsxRuntime.jsx(chunkO3MRE2HL_cjs.TaskEmptyState, { task: currentTask }) : pendingFirstTurn && isGenerating ? /* @__PURE__ */ jsxRuntime.jsx(ConnectedMessageArea, { ref: containerRef, messages: pendingFirstTurn }) : /* @__PURE__ */ jsxRuntime.jsx(
|
|
38620
40311
|
ConnectedConversationEmpty,
|
|
@@ -38744,6 +40435,33 @@ function ConnectedConversation({
|
|
|
38744
40435
|
slashWorkflows.launcher
|
|
38745
40436
|
] });
|
|
38746
40437
|
}
|
|
40438
|
+
function ConnectedConversation({
|
|
40439
|
+
layout = "thread",
|
|
40440
|
+
page,
|
|
40441
|
+
conversationId,
|
|
40442
|
+
...props
|
|
40443
|
+
}) {
|
|
40444
|
+
const session = react.useArbiSessionStore();
|
|
40445
|
+
React9.useEffect(() => {
|
|
40446
|
+
if (conversationId === void 0) return;
|
|
40447
|
+
if (layout === "page") {
|
|
40448
|
+
const tabId = conversationId ?? "new";
|
|
40449
|
+
if (session.getState().activeThreadTabId !== tabId) session.openThreadTab(conversationId);
|
|
40450
|
+
} else if (session.getState().conversationId !== conversationId) {
|
|
40451
|
+
session.setConversationId(conversationId);
|
|
40452
|
+
}
|
|
40453
|
+
}, [conversationId, layout, session]);
|
|
40454
|
+
return layout === "page" ? /* @__PURE__ */ jsxRuntime.jsx(
|
|
40455
|
+
ConnectedConversationPage,
|
|
40456
|
+
{
|
|
40457
|
+
...page,
|
|
40458
|
+
modelSelector: props.modelSelector,
|
|
40459
|
+
composerAccessory: props.composerAccessory,
|
|
40460
|
+
composerTools: props.composerTools,
|
|
40461
|
+
ConversationThread
|
|
40462
|
+
}
|
|
40463
|
+
) : /* @__PURE__ */ jsxRuntime.jsx(ConversationThread, { ...props });
|
|
40464
|
+
}
|
|
38747
40465
|
function ConnectedCompactConversation() {
|
|
38748
40466
|
const containerRef = React9.useRef(null);
|
|
38749
40467
|
const inputRef = React9.useRef(null);
|
|
@@ -41506,474 +43224,6 @@ function ConnectedAccountAccessBadge() {
|
|
|
41506
43224
|
/* @__PURE__ */ jsxRuntime.jsx(ui.PopoverContent, { className: "max-w-xs text-sm", align: "end", children: explanation })
|
|
41507
43225
|
] });
|
|
41508
43226
|
}
|
|
41509
|
-
function ThreadSearch({ children, ResultsBoundary = chunkTM2D4XT4_cjs.ErrorBoundary }) {
|
|
41510
|
-
const [query, setQuery] = React9.useState("");
|
|
41511
|
-
const [submitted, setSubmitted] = React9.useState("");
|
|
41512
|
-
const selectedWorkspaceId = react.useArbiSessionState((s) => s.workspaceId);
|
|
41513
|
-
const { notify: notify18, openConversation } = chunkB3NYBMDR_cjs.useBlocksEnvironment();
|
|
41514
|
-
const search = react.useConversationSearch();
|
|
41515
|
-
const isSearching = search.isPending;
|
|
41516
|
-
const groups = React9.useMemo(
|
|
41517
|
-
() => search.isError ? [] : (search.data?.results ?? []).map((g) => ({
|
|
41518
|
-
id: g.conversation_ext_id,
|
|
41519
|
-
title: g.title,
|
|
41520
|
-
matches: g.messages.map((m) => ({
|
|
41521
|
-
id: m.message_ext_id,
|
|
41522
|
-
role: m.role,
|
|
41523
|
-
score: m.score,
|
|
41524
|
-
snippet: m.snippet
|
|
41525
|
-
}))
|
|
41526
|
-
})),
|
|
41527
|
-
[search.data, search.isError]
|
|
41528
|
-
);
|
|
41529
|
-
const handleSearch = React9.useCallback(() => {
|
|
41530
|
-
const q = query.trim();
|
|
41531
|
-
if (!q || !selectedWorkspaceId || isSearching) return;
|
|
41532
|
-
setSubmitted(q);
|
|
41533
|
-
search.mutate(
|
|
41534
|
-
{ query: q, search_mode: "hybrid", limit: 20 },
|
|
41535
|
-
{
|
|
41536
|
-
onError: (err) => {
|
|
41537
|
-
console.error("Conversation search failed", err);
|
|
41538
|
-
notify18("Conversation search failed", "error");
|
|
41539
|
-
}
|
|
41540
|
-
}
|
|
41541
|
-
);
|
|
41542
|
-
}, [query, selectedWorkspaceId, isSearching, search, notify18]);
|
|
41543
|
-
const clearSearch = React9.useCallback(() => {
|
|
41544
|
-
setQuery("");
|
|
41545
|
-
setSubmitted("");
|
|
41546
|
-
}, []);
|
|
41547
|
-
const openHit = React9.useCallback(
|
|
41548
|
-
(conversationId, messageId) => {
|
|
41549
|
-
openConversation(conversationId, messageId ? { messageId } : void 0);
|
|
41550
|
-
},
|
|
41551
|
-
[openConversation]
|
|
41552
|
-
);
|
|
41553
|
-
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
41554
|
-
chunkDWWRLKEZ_cjs.ConversationSearchView,
|
|
41555
|
-
{
|
|
41556
|
-
query,
|
|
41557
|
-
onQueryChange: setQuery,
|
|
41558
|
-
onSubmit: handleSearch,
|
|
41559
|
-
canSubmit: !!query.trim() && !!selectedWorkspaceId && !isSearching,
|
|
41560
|
-
isSearching,
|
|
41561
|
-
submittedQuery: submitted,
|
|
41562
|
-
groups,
|
|
41563
|
-
onOpenConversation: openHit,
|
|
41564
|
-
onClear: clearSearch,
|
|
41565
|
-
ResultsBoundary,
|
|
41566
|
-
children
|
|
41567
|
-
}
|
|
41568
|
-
);
|
|
41569
|
-
}
|
|
41570
|
-
var DEFAULT_THREAD_VISIBILITY = { me: null, workspace: null };
|
|
41571
|
-
var relativeTime2 = (iso) => ui.formatRelativeTime(iso, { style: "short" });
|
|
41572
|
-
var LIST_LABELS = {
|
|
41573
|
-
emptyTitle: "Nothing here yet",
|
|
41574
|
-
emptyMessage: "Use New: just type what you need, or fill in an owner and a due date. You always decide when a thread is done.",
|
|
41575
|
-
untitled: `Untitled ${ui.getEntityLabel("CONVERSATION").toLowerCase()}`,
|
|
41576
|
-
noMatches: `No ${ui.getEntityLabel("CONVERSATION", "PLURAL").toLowerCase()} match.`,
|
|
41577
|
-
selectAll: "Select all"
|
|
41578
|
-
};
|
|
41579
|
-
var RENAME_DIALOG = { testId: "rename-conversation-modal" };
|
|
41580
|
-
function useStableRecencyOrder(rows) {
|
|
41581
|
-
const orderRef = React9.useRef([]);
|
|
41582
|
-
return React9.useMemo(() => {
|
|
41583
|
-
const byRecency = [...rows].sort(
|
|
41584
|
-
(a, b) => new Date(b.updated_at || b.created_at || 0).getTime() - new Date(a.updated_at || a.created_at || 0).getTime()
|
|
41585
|
-
);
|
|
41586
|
-
const present = new Set(byRecency.map((r) => r.external_id));
|
|
41587
|
-
const known = new Set(orderRef.current);
|
|
41588
|
-
const added = byRecency.map((r) => r.external_id).filter((id) => !known.has(id));
|
|
41589
|
-
orderRef.current = [...added, ...orderRef.current.filter((id) => present.has(id))];
|
|
41590
|
-
const byId = new Map(byRecency.map((r) => [r.external_id, r]));
|
|
41591
|
-
return orderRef.current.flatMap((id) => byId.get(id) ?? []);
|
|
41592
|
-
}, [rows]);
|
|
41593
|
-
}
|
|
41594
|
-
function ConnectedThreadsPage({
|
|
41595
|
-
showHeader = true,
|
|
41596
|
-
search = false,
|
|
41597
|
-
ResultsBoundary,
|
|
41598
|
-
focusLauncher,
|
|
41599
|
-
layout = "list",
|
|
41600
|
-
workflowActions
|
|
41601
|
-
}) {
|
|
41602
|
-
const mode = layout === "inbox" ? "tasks" : "threads";
|
|
41603
|
-
const { confirm, notify: notify18, openConversation, openDocument } = chunkB3NYBMDR_cjs.useBlocksEnvironment();
|
|
41604
|
-
const { conversations: all, isLoading } = react.useConversationItems();
|
|
41605
|
-
const [doneFilter] = react.useTransientView("threads.done", "exclude");
|
|
41606
|
-
const [visibilityFilters] = react.useTransientView("threads.visibility", DEFAULT_THREAD_VISIBILITY);
|
|
41607
|
-
const [meetingFilter] = react.useTransientView("threads.meetings", null);
|
|
41608
|
-
const [topbarFilterQuery, setTopbarFilterQuery] = react.useTransientView("topbar.filter", "");
|
|
41609
|
-
const currentUserExtId = react.useArbiSession().user?.external_id;
|
|
41610
|
-
const listed = React9.useMemo(
|
|
41611
|
-
() => all.filter((c) => mode === "threads" || c.status != null),
|
|
41612
|
-
[all, mode]
|
|
41613
|
-
);
|
|
41614
|
-
const tasks = useStableRecencyOrder(listed);
|
|
41615
|
-
const updateConversation = react.useUpdateConversation();
|
|
41616
|
-
const deleteConversation = react.useDeleteConversation();
|
|
41617
|
-
const people = useTaskPeople();
|
|
41618
|
-
const renderPerson = useRenderTaskPerson();
|
|
41619
|
-
const canEditShared = react.useCanEditShared();
|
|
41620
|
-
const isWorkspaceOwner = react.useIsWorkspaceOwner();
|
|
41621
|
-
const { data: agents = [] } = react.useAgents();
|
|
41622
|
-
const { data: workflows = [] } = react.useWorkflows();
|
|
41623
|
-
const agentNames = React9.useMemo(
|
|
41624
|
-
() => Object.fromEntries(agents.map((a) => [a.external_id, a.given_name || a.email])),
|
|
41625
|
-
[agents]
|
|
41626
|
-
);
|
|
41627
|
-
const workflowNames = React9.useMemo(
|
|
41628
|
-
() => Object.fromEntries(workflows.map((w) => [w.external_id, w.name])),
|
|
41629
|
-
[workflows]
|
|
41630
|
-
);
|
|
41631
|
-
const runConversation = react.useRunConversation();
|
|
41632
|
-
const [busyId, setBusyId] = React9.useState(null);
|
|
41633
|
-
const [editorOpen, setEditorOpen] = React9.useState(false);
|
|
41634
|
-
const [editing, setEditing] = React9.useState(null);
|
|
41635
|
-
const [startOpen, setStartOpen] = React9.useState(false);
|
|
41636
|
-
const [parentForNew, setParentForNew] = React9.useState(void 0);
|
|
41637
|
-
const nameOf = (task) => task.title?.trim() || task.workflow_ext_id && workflowNames[task.workflow_ext_id] || "Untitled task";
|
|
41638
|
-
const openCreate = () => {
|
|
41639
|
-
setParentForNew(void 0);
|
|
41640
|
-
setStartOpen(true);
|
|
41641
|
-
};
|
|
41642
|
-
const openAddSubtask = (parent) => {
|
|
41643
|
-
setParentForNew(parent.external_id);
|
|
41644
|
-
setStartOpen(true);
|
|
41645
|
-
};
|
|
41646
|
-
const [renaming, setRenaming] = React9.useState(null);
|
|
41647
|
-
const [newTitle, setNewTitle] = React9.useState("");
|
|
41648
|
-
const [isExportOpen, setIsExportOpen] = React9.useState(false);
|
|
41649
|
-
const [exportRows, setExportRows] = React9.useState([]);
|
|
41650
|
-
const openEdit = (task) => {
|
|
41651
|
-
if (mode === "threads" || !task.status) {
|
|
41652
|
-
setRenaming(task);
|
|
41653
|
-
setNewTitle(task.title ?? "");
|
|
41654
|
-
return;
|
|
41655
|
-
}
|
|
41656
|
-
setEditing(task);
|
|
41657
|
-
setEditorOpen(true);
|
|
41658
|
-
};
|
|
41659
|
-
const act = async (task, action, success, failure) => {
|
|
41660
|
-
setBusyId(task.external_id);
|
|
41661
|
-
try {
|
|
41662
|
-
await action();
|
|
41663
|
-
if (success) notify18(success, "success");
|
|
41664
|
-
} catch (error) {
|
|
41665
|
-
notify18(
|
|
41666
|
-
error instanceof browser.ArbiApiError && error.detail ? `${failure}: ${error.detail}` : failure,
|
|
41667
|
-
"error"
|
|
41668
|
-
);
|
|
41669
|
-
} finally {
|
|
41670
|
-
setBusyId(null);
|
|
41671
|
-
}
|
|
41672
|
-
};
|
|
41673
|
-
const patch = (task, body) => updateConversation.mutateAsync({ conversationId: task.external_id, patch: body });
|
|
41674
|
-
const setStatus = (task, status, success) => act(task, () => patch(task, { status }), success, "Failed to update task");
|
|
41675
|
-
const handleToggleShared = (task, shouldShare) => act(
|
|
41676
|
-
task,
|
|
41677
|
-
() => patch(task, { shared: shouldShare }),
|
|
41678
|
-
shouldShare ? `Shared \u201C${nameOf(task)}\u201D with the workspace` : `Made \u201C${nameOf(task)}\u201D private`,
|
|
41679
|
-
"Failed to change who can see the task"
|
|
41680
|
-
);
|
|
41681
|
-
const handleMove = (task, parentId) => act(
|
|
41682
|
-
task,
|
|
41683
|
-
() => patch(task, { parent_conversation_ext_id: parentId }),
|
|
41684
|
-
parentId ? `Moved \u201C${nameOf(task)}\u201D` : `Moved \u201C${nameOf(task)}\u201D to the top level`,
|
|
41685
|
-
"Failed to move task"
|
|
41686
|
-
);
|
|
41687
|
-
const handleDelete = async (task) => {
|
|
41688
|
-
const subtasks = tasks.filter((t) => t.parent_conversation_ext_id === task.external_id).length;
|
|
41689
|
-
const confirmed = await confirm({
|
|
41690
|
-
message: `Delete \u201C${nameOf(task)}\u201D? This can't be undone from here.${subtasks ? ` Its ${subtasks === 1 ? "sub-task stays" : `${subtasks} sub-tasks stay`} and ${subtasks === 1 ? "moves" : "move"} to the top level.` : ""}`,
|
|
41691
|
-
title: "Delete task"
|
|
41692
|
-
});
|
|
41693
|
-
if (!confirmed) return;
|
|
41694
|
-
await act(
|
|
41695
|
-
task,
|
|
41696
|
-
() => deleteConversation.mutateAsync(task.external_id),
|
|
41697
|
-
`Deleted \u201C${nameOf(task)}\u201D`,
|
|
41698
|
-
"Failed to delete task"
|
|
41699
|
-
);
|
|
41700
|
-
};
|
|
41701
|
-
const forEach = async (rows, one, done) => {
|
|
41702
|
-
let failed = 0;
|
|
41703
|
-
for (const task of rows) {
|
|
41704
|
-
try {
|
|
41705
|
-
await one(task);
|
|
41706
|
-
} catch {
|
|
41707
|
-
failed += 1;
|
|
41708
|
-
}
|
|
41709
|
-
}
|
|
41710
|
-
notify18(
|
|
41711
|
-
failed ? `${failed} of ${rows.length} could not be changed: you may not be allowed to change them` : done,
|
|
41712
|
-
failed ? "error" : "success"
|
|
41713
|
-
);
|
|
41714
|
-
};
|
|
41715
|
-
const handleMarkDoneMany = (rows) => forEach(rows, (task) => patch(task, { status: "done" }), `Marked ${rows.length} done`);
|
|
41716
|
-
const handleDeleteMany = async (rows) => {
|
|
41717
|
-
const named = rows.slice(0, 3).map((task) => `"${nameOf(task)}"`).join(", ");
|
|
41718
|
-
const more = rows.length - 3;
|
|
41719
|
-
const confirmed = await confirm({
|
|
41720
|
-
message: `Delete ${more > 0 ? `${named} and ${more} more` : named}? This cannot be undone.`,
|
|
41721
|
-
title: `Delete ${rows.length} item${rows.length === 1 ? "" : "s"}`
|
|
41722
|
-
});
|
|
41723
|
-
if (!confirmed) return;
|
|
41724
|
-
await forEach(
|
|
41725
|
-
rows,
|
|
41726
|
-
(task) => deleteConversation.mutateAsync(task.external_id),
|
|
41727
|
-
`Deleted ${rows.length}`
|
|
41728
|
-
);
|
|
41729
|
-
};
|
|
41730
|
-
const handleSaveRename = React9.useCallback(() => {
|
|
41731
|
-
if (!renaming || !newTitle.trim()) return;
|
|
41732
|
-
updateConversation.mutate(
|
|
41733
|
-
{ conversationId: renaming.external_id, patch: { title: newTitle.trim() } },
|
|
41734
|
-
{
|
|
41735
|
-
onSuccess: () => {
|
|
41736
|
-
notify18("Conversation renamed successfully", "success");
|
|
41737
|
-
setRenaming(null);
|
|
41738
|
-
setNewTitle("");
|
|
41739
|
-
},
|
|
41740
|
-
onError: (error) => {
|
|
41741
|
-
console.error("Failed to rename conversation:", error);
|
|
41742
|
-
notify18("Failed to rename conversation", "error");
|
|
41743
|
-
}
|
|
41744
|
-
}
|
|
41745
|
-
);
|
|
41746
|
-
}, [renaming, newTitle, updateConversation, notify18]);
|
|
41747
|
-
const handleBulkShare = async (rows) => {
|
|
41748
|
-
const unshared = rows.filter((c) => !c.is_shared);
|
|
41749
|
-
if (unshared.length === 0) {
|
|
41750
|
-
await confirm({
|
|
41751
|
-
message: "All selected conversations are already shared",
|
|
41752
|
-
title: "Info",
|
|
41753
|
-
kind: "alert"
|
|
41754
|
-
});
|
|
41755
|
-
return;
|
|
41756
|
-
}
|
|
41757
|
-
const noun = ui.getEntityLabel("CONVERSATION", unshared.length > 1 ? "PLURAL" : "SINGULAR");
|
|
41758
|
-
const confirmed = await confirm({
|
|
41759
|
-
message: `Are you sure you want to share ${unshared.length} ${noun.toLowerCase()} with everyone in the current ${ui.getEntityLabel("WORKSPACE").toLowerCase()}? You can make them private again later.`,
|
|
41760
|
-
title: `Share ${ui.getEntityLabel("CONVERSATION", "PLURAL")}`
|
|
41761
|
-
});
|
|
41762
|
-
if (!confirmed) return;
|
|
41763
|
-
try {
|
|
41764
|
-
await Promise.all(
|
|
41765
|
-
unshared.map(
|
|
41766
|
-
(c) => updateConversation.mutateAsync({ conversationId: c.external_id, patch: { shared: true } })
|
|
41767
|
-
)
|
|
41768
|
-
);
|
|
41769
|
-
notify18(`${unshared.length} ${noun.toLowerCase()} shared successfully`, "success");
|
|
41770
|
-
} catch (error) {
|
|
41771
|
-
console.error("Failed to share conversations:", error);
|
|
41772
|
-
notify18("Failed to share some conversations", "error");
|
|
41773
|
-
}
|
|
41774
|
-
};
|
|
41775
|
-
const { data: workspaceDocs } = react.useDocuments();
|
|
41776
|
-
const outputsByTask = React9.useMemo(() => {
|
|
41777
|
-
const out = {};
|
|
41778
|
-
for (const [conversationId, docs] of Object.entries(
|
|
41779
|
-
chunkDWWRLKEZ_cjs.groupOutputsByConversation(workspaceDocs ?? [])
|
|
41780
|
-
)) {
|
|
41781
|
-
out[conversationId] = docs.map((d) => ({
|
|
41782
|
-
id: d.external_id,
|
|
41783
|
-
name: ui.getDocumentTitle(d, d.external_id)
|
|
41784
|
-
}));
|
|
41785
|
-
}
|
|
41786
|
-
return out;
|
|
41787
|
-
}, [workspaceDocs]);
|
|
41788
|
-
const handleOpenOutput = (documentId) => openDocument(documentId);
|
|
41789
|
-
const handleGrantAccess = (task) => act(
|
|
41790
|
-
task,
|
|
41791
|
-
() => runConversation.mutateAsync(task.external_id),
|
|
41792
|
-
`Running \u201C${nameOf(task)}\u201D`,
|
|
41793
|
-
"Failed to run task"
|
|
41794
|
-
);
|
|
41795
|
-
const threadLabels = useThreadLabels(canEditShared);
|
|
41796
|
-
const selectionActions = (selected, isCompact) => {
|
|
41797
|
-
const mine = selected.every((c) => c.created_by_ext_id === currentUserExtId);
|
|
41798
|
-
return /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
41799
|
-
mode === "threads" && selected.every((row2) => row2.is_owner || row2.is_shared && canEditShared) && selected.some((row2) => row2.status !== "done") && !selected.some((row2) => row2.in_progress || row2.status === "generating") && /* @__PURE__ */ jsxRuntime.jsx(
|
|
41800
|
-
chunkV4ISCZJ7_cjs.SelectionBarAction,
|
|
41801
|
-
{
|
|
41802
|
-
icon: lucideReact.CheckCheck,
|
|
41803
|
-
label: "Mark Done",
|
|
41804
|
-
onClick: () => void handleMarkDoneMany(selected),
|
|
41805
|
-
isCompact,
|
|
41806
|
-
testId: "threads-bulk-done"
|
|
41807
|
-
}
|
|
41808
|
-
),
|
|
41809
|
-
threadLabels.renderBulkLabels(selected, isCompact),
|
|
41810
|
-
mine && selected.some((c) => !c.is_shared) && /* @__PURE__ */ jsxRuntime.jsx(
|
|
41811
|
-
ui.VisibilityToggle,
|
|
41812
|
-
{
|
|
41813
|
-
items: selected,
|
|
41814
|
-
onToggle: () => void handleBulkShare(selected),
|
|
41815
|
-
disablePrivate: true,
|
|
41816
|
-
showLabel: false,
|
|
41817
|
-
tooltipInactive: "Share all with workspace members",
|
|
41818
|
-
tooltipMixed: "Share all with workspace members (some already shared)",
|
|
41819
|
-
"data-testid": "bulk-shared-toggle"
|
|
41820
|
-
}
|
|
41821
|
-
),
|
|
41822
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
41823
|
-
chunkV4ISCZJ7_cjs.SelectionBarAction,
|
|
41824
|
-
{
|
|
41825
|
-
icon: lucideReact.FolderUp,
|
|
41826
|
-
label: "Export",
|
|
41827
|
-
onClick: () => {
|
|
41828
|
-
setExportRows(selected);
|
|
41829
|
-
setIsExportOpen(true);
|
|
41830
|
-
},
|
|
41831
|
-
isCompact,
|
|
41832
|
-
tooltip: `Export the selected ${ui.getEntityLabel("CONVERSATION", "PLURAL").toLowerCase()} to another ${ui.getEntityLabel("WORKSPACE").toLowerCase()}`,
|
|
41833
|
-
testId: "export-chats-button"
|
|
41834
|
-
}
|
|
41835
|
-
),
|
|
41836
|
-
mode === "threads" && selected.every((row2) => row2.is_owner || isWorkspaceOwner) && /* @__PURE__ */ jsxRuntime.jsx(
|
|
41837
|
-
chunkV4ISCZJ7_cjs.SelectionBarAction,
|
|
41838
|
-
{
|
|
41839
|
-
icon: lucideReact.Trash2,
|
|
41840
|
-
label: "Delete",
|
|
41841
|
-
className: "text-red-text hover:bg-red-bg hover:text-red-text",
|
|
41842
|
-
onClick: () => void handleDeleteMany(selected),
|
|
41843
|
-
isCompact,
|
|
41844
|
-
testId: "threads-bulk-delete"
|
|
41845
|
-
}
|
|
41846
|
-
)
|
|
41847
|
-
] });
|
|
41848
|
-
};
|
|
41849
|
-
const page = /* @__PURE__ */ jsxRuntime.jsxs(
|
|
41850
|
-
"div",
|
|
41851
|
-
{
|
|
41852
|
-
className: "flex h-full min-h-0 flex-col",
|
|
41853
|
-
"data-testid": mode === "tasks" ? "tasks-page" : "threads-page",
|
|
41854
|
-
children: [
|
|
41855
|
-
/* @__PURE__ */ jsxRuntime.jsx("main", { className: "flex min-h-0 flex-1 flex-col bg-background", children: mode === "threads" ? /* @__PURE__ */ jsxRuntime.jsx(
|
|
41856
|
-
chunkO3MRE2HL_cjs.ConversationListView,
|
|
41857
|
-
{
|
|
41858
|
-
showHeader,
|
|
41859
|
-
conversations: tasks,
|
|
41860
|
-
doneFilter,
|
|
41861
|
-
visibilityFilters,
|
|
41862
|
-
meetingFilter,
|
|
41863
|
-
renderThread: (row2) => /* @__PURE__ */ jsxRuntime.jsx(
|
|
41864
|
-
ConversationEntity,
|
|
41865
|
-
{
|
|
41866
|
-
conversation: row2,
|
|
41867
|
-
showRePrefix: false,
|
|
41868
|
-
labelMaxWidth: "max-w-full",
|
|
41869
|
-
className: "w-full max-w-full [&_.truncate]:line-clamp-2 [&_.truncate]:whitespace-normal [&_.truncate]:break-words [&_.truncate]:text-left",
|
|
41870
|
-
"data-testid": `thread-open-${row2.external_id}`
|
|
41871
|
-
}
|
|
41872
|
-
),
|
|
41873
|
-
renderLabels: threadLabels.renderLabels,
|
|
41874
|
-
labelText: threadLabels.labelText,
|
|
41875
|
-
renderBy: (row2) => /* @__PURE__ */ jsxRuntime.jsx(
|
|
41876
|
-
chunkO3MRE2HL_cjs.ConversationTurnSpeaker,
|
|
41877
|
-
{
|
|
41878
|
-
variant: "icon",
|
|
41879
|
-
role: row2.last_message_role,
|
|
41880
|
-
actor: row2.last_message_actor,
|
|
41881
|
-
currentUserId: currentUserExtId,
|
|
41882
|
-
colorClass: row2.last_message_actor ? ui.getUserAvatarColor(row2.last_message_actor.external_id) : void 0
|
|
41883
|
-
}
|
|
41884
|
-
),
|
|
41885
|
-
renderStatus: (row2) => /* @__PURE__ */ jsxRuntime.jsx(ConversationStatusCell, { conversation: row2 }),
|
|
41886
|
-
isLoading,
|
|
41887
|
-
filterText: topbarFilterQuery ?? "",
|
|
41888
|
-
formatDate: relativeTime2,
|
|
41889
|
-
onOpen: (c) => openConversation(c.external_id),
|
|
41890
|
-
onRename: openEdit,
|
|
41891
|
-
onDelete: handleDelete,
|
|
41892
|
-
canEditShared,
|
|
41893
|
-
isWorkspaceOwner,
|
|
41894
|
-
selectionActions,
|
|
41895
|
-
footer: /* @__PURE__ */ jsxRuntime.jsx(ConnectedThreadLauncher, { autoFocus: focusLauncher })
|
|
41896
|
-
}
|
|
41897
|
-
) : /* @__PURE__ */ jsxRuntime.jsx(
|
|
41898
|
-
chunkO3MRE2HL_cjs.TaskInbox,
|
|
41899
|
-
{
|
|
41900
|
-
tasks,
|
|
41901
|
-
isLoading,
|
|
41902
|
-
...workflowActions,
|
|
41903
|
-
onCreate: openCreate,
|
|
41904
|
-
filterText: topbarFilterQuery ?? "",
|
|
41905
|
-
labels: LIST_LABELS,
|
|
41906
|
-
gridId: "conversation-list-grid-v4",
|
|
41907
|
-
onFilterTextChange: (text2) => setTopbarFilterQuery(text2),
|
|
41908
|
-
outputsByTask,
|
|
41909
|
-
onOpenActivity: (task) => openConversation(task.external_id),
|
|
41910
|
-
formatRelative: relativeTime2,
|
|
41911
|
-
onOpenOutput: handleOpenOutput,
|
|
41912
|
-
busyId,
|
|
41913
|
-
formatDate: ui.formatFriendlyDate,
|
|
41914
|
-
onOpenThread: (conversationId) => openConversation(conversationId),
|
|
41915
|
-
onMarkDone: (task) => setStatus(task, "done", `Marked \u201C${nameOf(task)}\u201D done`),
|
|
41916
|
-
onReopen: (task) => setStatus(task, "todo", `Reopened \u201C${nameOf(task)}\u201D`),
|
|
41917
|
-
people,
|
|
41918
|
-
agentNames,
|
|
41919
|
-
workflowNames,
|
|
41920
|
-
canEditShared,
|
|
41921
|
-
isWorkspaceOwner,
|
|
41922
|
-
renderPerson,
|
|
41923
|
-
onToggleShared: handleToggleShared,
|
|
41924
|
-
onEdit: openEdit,
|
|
41925
|
-
onDelete: handleDelete,
|
|
41926
|
-
onAddSubtask: openAddSubtask,
|
|
41927
|
-
onMove: handleMove,
|
|
41928
|
-
onMarkDoneMany: handleMarkDoneMany,
|
|
41929
|
-
onDeleteMany: handleDeleteMany,
|
|
41930
|
-
onGrantAccess: handleGrantAccess,
|
|
41931
|
-
selectionActions
|
|
41932
|
-
}
|
|
41933
|
-
) }),
|
|
41934
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
41935
|
-
ConnectedTaskStartDialog,
|
|
41936
|
-
{
|
|
41937
|
-
open: startOpen,
|
|
41938
|
-
onOpenChange: setStartOpen,
|
|
41939
|
-
initialParentId: parentForNew
|
|
41940
|
-
}
|
|
41941
|
-
),
|
|
41942
|
-
/* @__PURE__ */ jsxRuntime.jsx(ConnectedTaskComposer, { open: editorOpen, onOpenChange: setEditorOpen, task: editing }),
|
|
41943
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
41944
|
-
ConnectedExportDialog,
|
|
41945
|
-
{
|
|
41946
|
-
open: isExportOpen,
|
|
41947
|
-
onOpenChange: setIsExportOpen,
|
|
41948
|
-
items: exportRows.map((c) => ({ extId: c.external_id, label: nameOf(c) })),
|
|
41949
|
-
entityType: "CONVERSATION",
|
|
41950
|
-
testId: "export-chats-modal"
|
|
41951
|
-
}
|
|
41952
|
-
),
|
|
41953
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
41954
|
-
chunkFEVJA4BP_cjs.RenameDialog,
|
|
41955
|
-
{
|
|
41956
|
-
open: !!renaming,
|
|
41957
|
-
onClose: () => {
|
|
41958
|
-
setRenaming(null);
|
|
41959
|
-
setNewTitle("");
|
|
41960
|
-
},
|
|
41961
|
-
title: `Rename ${ui.getEntityLabel("CONVERSATION")}`,
|
|
41962
|
-
labels: { description: "Rename the conversation title" },
|
|
41963
|
-
fieldLabel: `${ui.getEntityLabel("CONVERSATION")} Title`,
|
|
41964
|
-
placeholder: "Enter title",
|
|
41965
|
-
value: newTitle,
|
|
41966
|
-
onChange: setNewTitle,
|
|
41967
|
-
onSave: handleSaveRename,
|
|
41968
|
-
canSave: !!newTitle.trim(),
|
|
41969
|
-
dialogTestId: RENAME_DIALOG.testId
|
|
41970
|
-
}
|
|
41971
|
-
)
|
|
41972
|
-
]
|
|
41973
|
-
}
|
|
41974
|
-
);
|
|
41975
|
-
return search ? /* @__PURE__ */ jsxRuntime.jsx(ThreadSearch, { ResultsBoundary, children: page }) : page;
|
|
41976
|
-
}
|
|
41977
43227
|
function useSessionPanelMode(panelId, defaultMode = "docked", isOpen = true) {
|
|
41978
43228
|
const panelModes = react.useArbiSessionState((s) => s.shell.panels.modes);
|
|
41979
43229
|
const setPanelModeStore = react.useArbiSessionStore().setPanelMode;
|
|
@@ -42375,7 +43625,7 @@ Object.defineProperty(exports, "useViewerStreamingDocument", {
|
|
|
42375
43625
|
});
|
|
42376
43626
|
Object.defineProperty(exports, "useMeetingThreadMessages", {
|
|
42377
43627
|
enumerable: true,
|
|
42378
|
-
get: function () { return
|
|
43628
|
+
get: function () { return chunk5R256EMF_cjs.useMeetingThreadMessages; }
|
|
42379
43629
|
});
|
|
42380
43630
|
Object.defineProperty(exports, "isListedDocument", {
|
|
42381
43631
|
enumerable: true,
|
|
@@ -42446,6 +43696,7 @@ exports.ChatAttachmentList = ChatAttachmentList;
|
|
|
42446
43696
|
exports.ConnectedAccountAccessBadge = ConnectedAccountAccessBadge;
|
|
42447
43697
|
exports.ConnectedAccountCluster = ConnectedAccountCluster;
|
|
42448
43698
|
exports.ConnectedAccountSettings = ConnectedAccountSettings;
|
|
43699
|
+
exports.ConnectedAccountsImport = ConnectedAccountsImport;
|
|
42449
43700
|
exports.ConnectedAddContacts = ConnectedAddContacts;
|
|
42450
43701
|
exports.ConnectedAgentChat = ConnectedAgentChat;
|
|
42451
43702
|
exports.ConnectedAgentChatPanel = ConnectedAgentChatPanel;
|
|
@@ -42483,6 +43734,7 @@ exports.ConnectedFieldsManager = ConnectedFieldsManager;
|
|
|
42483
43734
|
exports.ConnectedFilesBulkActions = ConnectedFilesBulkActions;
|
|
42484
43735
|
exports.ConnectedFilesExplorer = ConnectedFilesExplorer;
|
|
42485
43736
|
exports.ConnectedFilesPage = ConnectedFilesPage;
|
|
43737
|
+
exports.ConnectedFilterDropdown = ConnectedFilterDropdown;
|
|
42486
43738
|
exports.ConnectedForgotPassword = ConnectedForgotPassword;
|
|
42487
43739
|
exports.ConnectedGlobalDialogs = ConnectedGlobalDialogs;
|
|
42488
43740
|
exports.ConnectedGrantWorkspaceAccessDialog = ConnectedGrantWorkspaceAccessDialog;
|
|
@@ -42727,6 +43979,7 @@ exports.useAuthPages = useAuthPages;
|
|
|
42727
43979
|
exports.useAutoRefreshPendingProjects = useAutoRefreshPendingProjects;
|
|
42728
43980
|
exports.useBatchCompleteToasts = useBatchCompleteToasts;
|
|
42729
43981
|
exports.useChatMessageToasts = useChatMessageToasts;
|
|
43982
|
+
exports.useConnectedAgentManagement = useConnectedAgentManagement;
|
|
42730
43983
|
exports.useConnectedCalendarCalls = useConnectedCalendarCalls;
|
|
42731
43984
|
exports.useConnectedNotificationBell = useConnectedNotificationBell;
|
|
42732
43985
|
exports.useConnectedShellWorkspaces = useConnectedShellWorkspaces;
|
|
@@ -42745,6 +43998,7 @@ exports.useFilesDialogs = useFilesDialogs;
|
|
|
42745
43998
|
exports.useFilesGridStates = useFilesGridStates;
|
|
42746
43999
|
exports.useFilesPrefs = useFilesPrefs;
|
|
42747
44000
|
exports.useFilesStore = useFilesStore;
|
|
44001
|
+
exports.useHasAccountsImport = useHasAccountsImport;
|
|
42748
44002
|
exports.useLaunchWorkflow = useLaunchWorkflow;
|
|
42749
44003
|
exports.useMemberLookup = useMemberLookup;
|
|
42750
44004
|
exports.useMessengerRows = useMessengerRows;
|