@ai-matrx/messaging 0.13.1 → 0.15.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +59 -0
- package/README.md +5 -1
- package/dist/index.cjs +59 -18
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +37 -9
- package/dist/index.d.ts +37 -9
- package/dist/index.js +59 -18
- package/dist/index.js.map +1 -1
- package/dist/react.cjs +121 -33
- package/dist/react.cjs.map +1 -1
- package/dist/react.d.cts +47 -10
- package/dist/react.d.ts +47 -10
- package/dist/react.js +121 -33
- package/dist/react.js.map +1 -1
- package/package.json +4 -3
package/dist/react.cjs
CHANGED
|
@@ -869,7 +869,7 @@ function projectMessage(row, fallbackOrganizationId) {
|
|
|
869
869
|
id: requiredStr(row, "id", operation),
|
|
870
870
|
conversationId: requiredStr(row, "conversation_id", operation),
|
|
871
871
|
senderId: requiredStr(row, "sender_id", operation),
|
|
872
|
-
organizationId: str(row, "organization_id") ?? fallbackOrganizationId,
|
|
872
|
+
organizationId: str(row, "organization_id") ?? fallbackOrganizationId ?? "",
|
|
873
873
|
content: typeof row["content"] === "string" ? row["content"] : "",
|
|
874
874
|
kind: MESSAGE_KINDS.has(kindRaw) ? kindRaw : "text",
|
|
875
875
|
// A row read from the DB is at least `sent`. `sending`/`failed` are outbox
|
|
@@ -917,7 +917,7 @@ function projectConversationSummary(row, viewerId, fallbackOrganizationId) {
|
|
|
917
917
|
groupName,
|
|
918
918
|
groupImageUrl,
|
|
919
919
|
createdBy: createdBy === null ? null : createdBy,
|
|
920
|
-
organizationId: str(row, "organization_id") ?? fallbackOrganizationId,
|
|
920
|
+
organizationId: str(row, "organization_id") ?? fallbackOrganizationId ?? "",
|
|
921
921
|
createdAt,
|
|
922
922
|
updatedAt,
|
|
923
923
|
metadata: jsonObject(row["metadata"])
|
|
@@ -983,6 +983,7 @@ function createMessagingStore() {
|
|
|
983
983
|
let threads = /* @__PURE__ */ new Map();
|
|
984
984
|
let activeConversationId = null;
|
|
985
985
|
let conversationReadFailures = /* @__PURE__ */ new Map();
|
|
986
|
+
let conversationsLoadError = null;
|
|
986
987
|
const listeners = /* @__PURE__ */ new Set();
|
|
987
988
|
let cached = null;
|
|
988
989
|
function snapshot() {
|
|
@@ -996,7 +997,8 @@ function createMessagingStore() {
|
|
|
996
997
|
totalUnreadConversations: conversations.filter((item) => item.unreadCount > 0).length,
|
|
997
998
|
archiveFilter,
|
|
998
999
|
archivedCount,
|
|
999
|
-
conversationReadFailures
|
|
1000
|
+
conversationReadFailures,
|
|
1001
|
+
conversationsLoadError
|
|
1000
1002
|
};
|
|
1001
1003
|
return cached;
|
|
1002
1004
|
}
|
|
@@ -1041,6 +1043,12 @@ function createMessagingStore() {
|
|
|
1041
1043
|
conversations = normalizeConversations(items);
|
|
1042
1044
|
hasMoreConversations = hasMore;
|
|
1043
1045
|
hasLoadedConversations = true;
|
|
1046
|
+
conversationsLoadError = null;
|
|
1047
|
+
emit();
|
|
1048
|
+
},
|
|
1049
|
+
setConversationsLoadError(message) {
|
|
1050
|
+
if (message === conversationsLoadError) return;
|
|
1051
|
+
conversationsLoadError = message;
|
|
1044
1052
|
emit();
|
|
1045
1053
|
},
|
|
1046
1054
|
setArchiveFilter(next) {
|
|
@@ -1250,7 +1258,11 @@ function createMessagingEngine(options) {
|
|
|
1250
1258
|
optimisticMessage({
|
|
1251
1259
|
conversationId: entry.draft.conversationId,
|
|
1252
1260
|
senderId: identity.userId,
|
|
1253
|
-
|
|
1261
|
+
// Client-only until the confirmed row replaces it: the active
|
|
1262
|
+
// organization, else the conversation's own.
|
|
1263
|
+
organizationId: identity.organizationId ?? store.snapshot().conversations.find(
|
|
1264
|
+
(item) => item.conversation.id === entry.draft.conversationId
|
|
1265
|
+
)?.conversation.organizationId ?? "",
|
|
1254
1266
|
content: entry.draft.content,
|
|
1255
1267
|
clientMessageId: entry.clientMessageId,
|
|
1256
1268
|
...entry.draft.kind !== void 0 ? { kind: entry.draft.kind } : {},
|
|
@@ -1269,10 +1281,20 @@ function createMessagingEngine(options) {
|
|
|
1269
1281
|
}
|
|
1270
1282
|
async function reloadInbox() {
|
|
1271
1283
|
if (disposed) return;
|
|
1272
|
-
|
|
1273
|
-
|
|
1274
|
-
|
|
1275
|
-
|
|
1284
|
+
let page;
|
|
1285
|
+
try {
|
|
1286
|
+
page = await repository.listConversations({
|
|
1287
|
+
limit: conversationPageSize,
|
|
1288
|
+
archived: store.snapshot().archiveFilter
|
|
1289
|
+
});
|
|
1290
|
+
} catch (error) {
|
|
1291
|
+
if (!disposed) {
|
|
1292
|
+
store.setConversationsLoadError(
|
|
1293
|
+
error instanceof Error ? error.message : typeof error === "string" ? error : "The conversation list could not be read."
|
|
1294
|
+
);
|
|
1295
|
+
}
|
|
1296
|
+
throw error;
|
|
1297
|
+
}
|
|
1276
1298
|
if (disposed) return;
|
|
1277
1299
|
conversationCursor = page.nextCursor;
|
|
1278
1300
|
store.setConversations(page.items, page.hasMore);
|
|
@@ -1357,6 +1379,13 @@ function createMessagingEngine(options) {
|
|
|
1357
1379
|
}
|
|
1358
1380
|
});
|
|
1359
1381
|
},
|
|
1382
|
+
async refreshInbox() {
|
|
1383
|
+
try {
|
|
1384
|
+
await reloadInbox();
|
|
1385
|
+
} catch (error) {
|
|
1386
|
+
reportError(error, "inboxRefresh");
|
|
1387
|
+
}
|
|
1388
|
+
},
|
|
1360
1389
|
async setArchiveFilter(next) {
|
|
1361
1390
|
if (next === store.snapshot().archiveFilter) return;
|
|
1362
1391
|
store.setArchiveFilter(next);
|
|
@@ -1739,12 +1768,15 @@ var RPCS = {
|
|
|
1739
1768
|
};
|
|
1740
1769
|
var MESSAGE_COLUMNS = "id,conversation_id,sender_id,organization_id,content,message_type,status,reply_to_id,client_message_id,action_data,media_url,media_thumbnail_url,media_metadata,created_at,edited_at,deleted_at,deleted_for_everyone,metadata";
|
|
1741
1770
|
var CONVERSATION_COLUMNS = "id,type,group_name,group_image_url,created_by,organization_id,created_at,updated_at,metadata";
|
|
1771
|
+
function optionalOrg(organizationId) {
|
|
1772
|
+
return typeof organizationId === "string" && organizationId.length > 0 ? organizationId : null;
|
|
1773
|
+
}
|
|
1742
1774
|
function requireOrg(organizationId, operation) {
|
|
1743
|
-
if (
|
|
1775
|
+
if (organizationId === null) {
|
|
1744
1776
|
throw new MessagingError(
|
|
1745
|
-
"
|
|
1746
|
-
`${operation}: no
|
|
1747
|
-
"
|
|
1777
|
+
"organization-required",
|
|
1778
|
+
`${operation}: no organization selected`,
|
|
1779
|
+
"A new conversation is filed under one organization. Ask the person to choose one, then pass it as organizationId on <MessagingProvider>. Reading and replying to existing conversations never needs it."
|
|
1748
1780
|
);
|
|
1749
1781
|
}
|
|
1750
1782
|
return organizationId;
|
|
@@ -1756,7 +1788,7 @@ function sleep(ms) {
|
|
|
1756
1788
|
return new Promise((resolve) => setTimeout(resolve, jittered));
|
|
1757
1789
|
}
|
|
1758
1790
|
function createMessagingRepository(options) {
|
|
1759
|
-
const org =
|
|
1791
|
+
const org = optionalOrg(options.organizationId);
|
|
1760
1792
|
const handedIn = options.identity;
|
|
1761
1793
|
if (handedIn !== void 0 && handedIn !== null && handedIn.userId !== void 0) {
|
|
1762
1794
|
options.onDiagnostic?.(
|
|
@@ -1826,6 +1858,11 @@ function createMessagingRepository(options) {
|
|
|
1826
1858
|
});
|
|
1827
1859
|
return found;
|
|
1828
1860
|
}
|
|
1861
|
+
async function organizationOfExisting(conversationId) {
|
|
1862
|
+
if (org !== null) return org;
|
|
1863
|
+
const conversation = await repository.getConversation(conversationId);
|
|
1864
|
+
return conversation.organizationId;
|
|
1865
|
+
}
|
|
1829
1866
|
const repository = {
|
|
1830
1867
|
organizationId: org,
|
|
1831
1868
|
actingUserId,
|
|
@@ -1958,6 +1995,7 @@ function createMessagingRepository(options) {
|
|
|
1958
1995
|
},
|
|
1959
1996
|
async getOrCreateDirectConversation(otherUserId) {
|
|
1960
1997
|
const operation = "getOrCreateDirectConversation";
|
|
1998
|
+
const destination = requireOrg(org, operation);
|
|
1961
1999
|
const me = await actingUser(operation);
|
|
1962
2000
|
const id = await withSessionRetry(
|
|
1963
2001
|
operation,
|
|
@@ -1969,7 +2007,7 @@ function createMessagingRepository(options) {
|
|
|
1969
2007
|
// not a preference.
|
|
1970
2008
|
p_user1_id: me,
|
|
1971
2009
|
p_user2_id: otherUserId,
|
|
1972
|
-
p_organization_id:
|
|
2010
|
+
p_organization_id: destination
|
|
1973
2011
|
},
|
|
1974
2012
|
operation
|
|
1975
2013
|
)
|
|
@@ -1981,13 +2019,14 @@ function createMessagingRepository(options) {
|
|
|
1981
2019
|
},
|
|
1982
2020
|
async createGroupConversation({ name, memberIds }) {
|
|
1983
2021
|
const operation = "createGroupConversation";
|
|
2022
|
+
const destination = requireOrg(org, operation);
|
|
1984
2023
|
const me = await actingUser(operation);
|
|
1985
2024
|
const { data, error } = await withSessionRetry(
|
|
1986
2025
|
operation,
|
|
1987
2026
|
async () => db().from(TABLES.conversations).insert({
|
|
1988
2027
|
type: "group",
|
|
1989
2028
|
group_name: name,
|
|
1990
|
-
organization_id:
|
|
2029
|
+
organization_id: destination,
|
|
1991
2030
|
created_by: me
|
|
1992
2031
|
}).select("id").single()
|
|
1993
2032
|
);
|
|
@@ -2002,7 +2041,7 @@ function createMessagingRepository(options) {
|
|
|
2002
2041
|
conversation_id: conversationId,
|
|
2003
2042
|
user_id: userId,
|
|
2004
2043
|
role: userId === me ? "owner" : "member",
|
|
2005
|
-
organization_id:
|
|
2044
|
+
organization_id: destination,
|
|
2006
2045
|
created_by: me
|
|
2007
2046
|
}))
|
|
2008
2047
|
);
|
|
@@ -2012,10 +2051,11 @@ function createMessagingRepository(options) {
|
|
|
2012
2051
|
async insertMessage(draft, clientMessageId) {
|
|
2013
2052
|
const operation = "insertMessage";
|
|
2014
2053
|
const me = await actingUser(operation);
|
|
2054
|
+
const destination = await organizationOfExisting(draft.conversationId);
|
|
2015
2055
|
const { data, error } = await db().from(TABLES.messages).insert({
|
|
2016
2056
|
conversation_id: draft.conversationId,
|
|
2017
2057
|
sender_id: me,
|
|
2018
|
-
organization_id:
|
|
2058
|
+
organization_id: destination,
|
|
2019
2059
|
created_by: me,
|
|
2020
2060
|
content: draft.content,
|
|
2021
2061
|
message_type: draft.kind ?? "text",
|
|
@@ -2076,12 +2116,13 @@ function createMessagingRepository(options) {
|
|
|
2076
2116
|
async addMembers(conversationId, memberIds) {
|
|
2077
2117
|
const operation = "addMembers";
|
|
2078
2118
|
const me = await actingUser(operation);
|
|
2119
|
+
const destination = await organizationOfExisting(conversationId);
|
|
2079
2120
|
const { error } = await db().from(TABLES.participants).insert(
|
|
2080
2121
|
memberIds.map((userId) => ({
|
|
2081
2122
|
conversation_id: conversationId,
|
|
2082
2123
|
user_id: userId,
|
|
2083
2124
|
role: "member",
|
|
2084
|
-
organization_id:
|
|
2125
|
+
organization_id: destination,
|
|
2085
2126
|
created_by: me
|
|
2086
2127
|
}))
|
|
2087
2128
|
);
|
|
@@ -2192,7 +2233,7 @@ function MessagingProvider(props) {
|
|
|
2192
2233
|
}, [strayUserId]);
|
|
2193
2234
|
const session = useSessionUserId(client, props.onDiagnostic);
|
|
2194
2235
|
const userId = session.snapshot.userId;
|
|
2195
|
-
const ready = client != null && userId !== null
|
|
2236
|
+
const ready = client != null && userId !== null;
|
|
2196
2237
|
const hostProvidesRealtime = (0, import_react2.useIsRealtimeProviderMounted)();
|
|
2197
2238
|
const runtime = /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
2198
2239
|
MessagingRuntime,
|
|
@@ -2228,12 +2269,13 @@ function MessagingRuntime(props) {
|
|
|
2228
2269
|
actionRegistry.register(handler);
|
|
2229
2270
|
});
|
|
2230
2271
|
}, [actionRegistry, handlers]);
|
|
2231
|
-
const ready = client != null && manager !== null && sessionIdentity !== null && userId !== null
|
|
2272
|
+
const ready = client != null && manager !== null && sessionIdentity !== null && userId !== null;
|
|
2273
|
+
const activeOrganizationId = typeof organizationId === "string" && organizationId.length > 0 ? organizationId : null;
|
|
2232
2274
|
const engine = (0, import_react.useMemo)(() => {
|
|
2233
2275
|
if (!ready || manager === null || sessionIdentity === null || userId === null) return null;
|
|
2234
2276
|
const identity = {
|
|
2235
2277
|
userId,
|
|
2236
|
-
organizationId
|
|
2278
|
+
organizationId: activeOrganizationId
|
|
2237
2279
|
};
|
|
2238
2280
|
const report = (event) => {
|
|
2239
2281
|
(diagnosticRef.current ?? defaultDiagnostics)(event);
|
|
@@ -2244,7 +2286,7 @@ function MessagingRuntime(props) {
|
|
|
2244
2286
|
// supabase-shape.ts); everything below this line works against the rich
|
|
2245
2287
|
// contract, which `supabase-shape.test.ts` proves a real client honors.
|
|
2246
2288
|
client,
|
|
2247
|
-
organizationId,
|
|
2289
|
+
organizationId: activeOrganizationId,
|
|
2248
2290
|
// THE SAME READER the render loop above uses. Two readers would be two
|
|
2249
2291
|
// answers during the tick an account switch takes.
|
|
2250
2292
|
sessionIdentity,
|
|
@@ -2277,14 +2319,14 @@ function MessagingRuntime(props) {
|
|
|
2277
2319
|
}
|
|
2278
2320
|
});
|
|
2279
2321
|
return built;
|
|
2280
|
-
}, [ready, manager, sessionIdentity, userId,
|
|
2322
|
+
}, [ready, manager, sessionIdentity, userId, activeOrganizationId]);
|
|
2281
2323
|
(0, import_react.useEffect)(() => {
|
|
2282
2324
|
if (engine === null) return void 0;
|
|
2283
2325
|
void engine.start().catch((error) => {
|
|
2284
2326
|
(diagnosticRef.current ?? defaultDiagnostics)({
|
|
2285
2327
|
level: "error",
|
|
2286
2328
|
message: `Messaging failed to start: ${String(error?.message ?? error)}`,
|
|
2287
|
-
remedy: "Check the signed-in session
|
|
2329
|
+
remedy: "Check the signed-in session, then reload the surface."
|
|
2288
2330
|
});
|
|
2289
2331
|
});
|
|
2290
2332
|
return () => {
|
|
@@ -2298,9 +2340,10 @@ function MessagingRuntime(props) {
|
|
|
2298
2340
|
const sourceFeature = props.sourceFeature;
|
|
2299
2341
|
const ai = (0, import_react.useMemo)(() => {
|
|
2300
2342
|
if (transport === void 0 || agents === void 0 || !ready) return null;
|
|
2343
|
+
if (activeOrganizationId === null) return null;
|
|
2301
2344
|
return createMessagingAi({
|
|
2302
2345
|
transport,
|
|
2303
|
-
organizationId,
|
|
2346
|
+
organizationId: activeOrganizationId,
|
|
2304
2347
|
agents,
|
|
2305
2348
|
...maxTranscriptMessages !== void 0 ? { maxTranscriptMessages } : {},
|
|
2306
2349
|
...sourceApp !== void 0 ? { sourceApp } : {},
|
|
@@ -2310,7 +2353,7 @@ function MessagingRuntime(props) {
|
|
|
2310
2353
|
transport,
|
|
2311
2354
|
agents,
|
|
2312
2355
|
ready,
|
|
2313
|
-
|
|
2356
|
+
activeOrganizationId,
|
|
2314
2357
|
maxTranscriptMessages,
|
|
2315
2358
|
sourceApp,
|
|
2316
2359
|
sourceFeature
|
|
@@ -2361,7 +2404,7 @@ function useRequiredMessagingHost() {
|
|
|
2361
2404
|
const host = useMessagingHost();
|
|
2362
2405
|
if (host === null) {
|
|
2363
2406
|
throw new Error(
|
|
2364
|
-
"[@ai-matrx/messaging] No messaging host. Wrap this tree in <MessagingProvider client={supabase}
|
|
2407
|
+
"[@ai-matrx/messaging] No messaging host. Wrap this tree in <MessagingProvider client={supabase} organizationId={orgId}> and render it only once auth has resolved."
|
|
2365
2408
|
);
|
|
2366
2409
|
}
|
|
2367
2410
|
return host;
|
|
@@ -2486,7 +2529,11 @@ function useConversations() {
|
|
|
2486
2529
|
hasMore: snapshot?.hasMoreConversations ?? false,
|
|
2487
2530
|
// "Not loaded yet" is a FACT from the store, never a guess. Showing
|
|
2488
2531
|
// "No conversations yet" before the first read is a screen telling a lie.
|
|
2489
|
-
isInitialLoading: snapshot === null || !snapshot.hasLoadedConversations,
|
|
2532
|
+
isInitialLoading: snapshot === null || !snapshot.hasLoadedConversations && snapshot.conversationsLoadError === null,
|
|
2533
|
+
loadError: snapshot?.conversationsLoadError ?? null,
|
|
2534
|
+
retry: () => {
|
|
2535
|
+
void host?.engine.refreshInbox();
|
|
2536
|
+
},
|
|
2490
2537
|
totalUnreadConversations: snapshot?.totalUnreadConversations ?? 0,
|
|
2491
2538
|
loadMore: () => {
|
|
2492
2539
|
void host?.engine.loadMoreConversations();
|
|
@@ -2751,7 +2798,8 @@ function useMessageAction(message) {
|
|
|
2751
2798
|
const context = {
|
|
2752
2799
|
messageId: message.id,
|
|
2753
2800
|
actorId: host.identity.userId,
|
|
2754
|
-
|
|
2801
|
+
// The active organization, else the organization the message lives in.
|
|
2802
|
+
organizationId: host.identity.organizationId ?? message.organizationId,
|
|
2755
2803
|
choice
|
|
2756
2804
|
};
|
|
2757
2805
|
host.actions.execute(action, context).then(setReceipt).catch((cause) => {
|
|
@@ -3067,6 +3115,7 @@ function EmptyState(props) {
|
|
|
3067
3115
|
}
|
|
3068
3116
|
|
|
3069
3117
|
// src/react/components.tsx
|
|
3118
|
+
var import_design_system = require("@ai-matrx/design-system");
|
|
3070
3119
|
var import_jsx_runtime4 = require("react/jsx-runtime");
|
|
3071
3120
|
var AI_LABELS = {
|
|
3072
3121
|
catchUp: "Catch me up",
|
|
@@ -3084,7 +3133,9 @@ function ConversationList(props) {
|
|
|
3084
3133
|
activeConversationId,
|
|
3085
3134
|
archiveFilter,
|
|
3086
3135
|
setArchiveFilter,
|
|
3087
|
-
archivedCount
|
|
3136
|
+
archivedCount,
|
|
3137
|
+
loadError,
|
|
3138
|
+
retry
|
|
3088
3139
|
} = useConversations();
|
|
3089
3140
|
const RowChrome = useMessagingHost()?.wrapConversationRow ?? null;
|
|
3090
3141
|
const [query, setQuery] = (0, import_react5.useState)("");
|
|
@@ -3149,7 +3200,20 @@ function ConversationList(props) {
|
|
|
3149
3200
|
}
|
|
3150
3201
|
) }) : null,
|
|
3151
3202
|
/* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { className: "mx-msg__scroll", children: [
|
|
3152
|
-
isInitialLoading ? /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(ConversationSkeleton, {}) : visible.length === 0 ?
|
|
3203
|
+
isInitialLoading ? /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(ConversationSkeleton, {}) : loadError !== null && visible.length === 0 ? (
|
|
3204
|
+
// A failed read resolves to the failure — never a skeleton forever,
|
|
3205
|
+
// never "No conversations yet" (RC-B12 round 11). ErrorBox is the
|
|
3206
|
+
// design-system error slot: the host fills it with its menu.
|
|
3207
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
|
|
3208
|
+
ReadFailureBox,
|
|
3209
|
+
{
|
|
3210
|
+
title: "Couldn't load your conversations",
|
|
3211
|
+
message: loadError,
|
|
3212
|
+
operation: "List your conversations",
|
|
3213
|
+
onRetry: retry
|
|
3214
|
+
}
|
|
3215
|
+
)
|
|
3216
|
+
) : visible.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
|
|
3153
3217
|
EmptyState,
|
|
3154
3218
|
{
|
|
3155
3219
|
title: query.length > 0 ? "No matches" : showingArchive ? "No archived conversations" : "No conversations yet",
|
|
@@ -3326,10 +3390,11 @@ function ConversationView(props) {
|
|
|
3326
3390
|
body: "It doesn't exist, or you aren't a member of it."
|
|
3327
3391
|
}
|
|
3328
3392
|
) : conversation.error !== null && messages.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
|
|
3329
|
-
|
|
3393
|
+
ReadFailureBox,
|
|
3330
3394
|
{
|
|
3331
3395
|
title: "Couldn't load this conversation",
|
|
3332
|
-
|
|
3396
|
+
message: conversation.error.message || "Check your connection, then open it again.",
|
|
3397
|
+
operation: "Open this conversation"
|
|
3333
3398
|
}
|
|
3334
3399
|
) : messages.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(EmptyState, { title: "No messages yet", body: "Say something to get started." }) : /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { className: "mx-msg__messages", children: [
|
|
3335
3400
|
conversation.hasMoreOlder ? /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
|
|
@@ -3660,4 +3725,27 @@ function MessagingInbox(props) {
|
|
|
3660
3725
|
}
|
|
3661
3726
|
);
|
|
3662
3727
|
}
|
|
3728
|
+
function ReadFailureBox({
|
|
3729
|
+
title,
|
|
3730
|
+
message,
|
|
3731
|
+
operation,
|
|
3732
|
+
onRetry
|
|
3733
|
+
}) {
|
|
3734
|
+
return /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { className: "mx-msg__empty", role: "alert", children: [
|
|
3735
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
|
|
3736
|
+
import_design_system.ErrorBox,
|
|
3737
|
+
{
|
|
3738
|
+
as: "div",
|
|
3739
|
+
title,
|
|
3740
|
+
message,
|
|
3741
|
+
operation,
|
|
3742
|
+
origin: "messaging",
|
|
3743
|
+
style: { color: "var(--mx-msg-danger)", fontWeight: 600 },
|
|
3744
|
+
children: title
|
|
3745
|
+
}
|
|
3746
|
+
),
|
|
3747
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)("p", { children: message }),
|
|
3748
|
+
onRetry ? /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("button", { type: "button", className: "mx-msg__button mx-msg__button--ghost", onClick: onRetry, children: "Try again" }) : null
|
|
3749
|
+
] });
|
|
3750
|
+
}
|
|
3663
3751
|
//# sourceMappingURL=react.cjs.map
|