@anakin824/prdg-chat-ui 0.2.1 → 0.3.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/dist/index.css +134 -56
- package/dist/index.css.map +1 -1
- package/dist/index.d.mts +27 -4
- package/dist/index.d.ts +27 -4
- package/dist/index.js +90 -29
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +90 -29
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
package/dist/index.mjs
CHANGED
|
@@ -324,18 +324,51 @@ function ChatNatsBridge({ natsWsUrl, natsToken, onConnectedChange }) {
|
|
|
324
324
|
|
|
325
325
|
// src/chat/provider/ChatProvider.tsx
|
|
326
326
|
var defaultTheme = {
|
|
327
|
-
primary: "#
|
|
328
|
-
bubbleSent: "#
|
|
329
|
-
bubbleReceived: "#
|
|
327
|
+
primary: "#7c3aed",
|
|
328
|
+
bubbleSent: "#7c3aed",
|
|
329
|
+
bubbleReceived: "#e5e7eb",
|
|
330
330
|
textOnSent: "#ffffff",
|
|
331
|
-
textOnReceived: "#
|
|
332
|
-
radius: "
|
|
331
|
+
textOnReceived: "#111827",
|
|
332
|
+
radius: "12px",
|
|
333
333
|
fontFamily: "system-ui, -apple-system, sans-serif",
|
|
334
|
-
surface: "#
|
|
335
|
-
border: "#
|
|
336
|
-
mutedFill: "rgba(
|
|
337
|
-
composerShadow: "0 2px
|
|
334
|
+
surface: "#ffffff",
|
|
335
|
+
border: "#e5e7eb",
|
|
336
|
+
mutedFill: "rgba(17, 24, 39, 0.06)",
|
|
337
|
+
composerShadow: "0 1px 2px rgba(15, 23, 42, 0.05), 0 2px 8px rgba(15, 23, 42, 0.06)"
|
|
338
338
|
};
|
|
339
|
+
var THEME_TO_CSS_VAR = {
|
|
340
|
+
primary: "--chat-primary",
|
|
341
|
+
bubbleSent: "--chat-bubble-sent",
|
|
342
|
+
bubbleReceived: "--chat-bubble-received",
|
|
343
|
+
textOnSent: "--chat-text-on-sent",
|
|
344
|
+
textOnReceived: "--chat-text-on-received",
|
|
345
|
+
surface: "--chat-surface",
|
|
346
|
+
border: "--chat-border",
|
|
347
|
+
mutedFill: "--chat-muted-fill",
|
|
348
|
+
composerShadow: "--chat-composer-shadow"
|
|
349
|
+
};
|
|
350
|
+
function buildThemeColorOverrideCss(themeOverride) {
|
|
351
|
+
if (!themeOverride) return "";
|
|
352
|
+
const parts = [];
|
|
353
|
+
Object.keys(THEME_TO_CSS_VAR).forEach((k) => {
|
|
354
|
+
const v = themeOverride[k];
|
|
355
|
+
const cssName = THEME_TO_CSS_VAR[k];
|
|
356
|
+
if (cssName && typeof v === "string" && v.trim() !== "") {
|
|
357
|
+
parts.push(`${cssName}: ${v};`);
|
|
358
|
+
}
|
|
359
|
+
});
|
|
360
|
+
if (parts.length === 0) return "";
|
|
361
|
+
const body = parts.join(" ");
|
|
362
|
+
return `
|
|
363
|
+
html:not(.dark) [data-chat-root]:not([data-chat-appearance="dark"]),
|
|
364
|
+
[data-chat-root][data-chat-appearance="light"] {
|
|
365
|
+
${body}
|
|
366
|
+
}
|
|
367
|
+
html.dark [data-chat-root]:not([data-chat-appearance="light"]),
|
|
368
|
+
[data-chat-root][data-chat-appearance="dark"] {
|
|
369
|
+
${body}
|
|
370
|
+
}`;
|
|
371
|
+
}
|
|
339
372
|
function ChatProvider({
|
|
340
373
|
apiUrl,
|
|
341
374
|
token,
|
|
@@ -350,9 +383,12 @@ function ChatProvider({
|
|
|
350
383
|
natsWsUrl,
|
|
351
384
|
natsToken,
|
|
352
385
|
debug: debugProp,
|
|
386
|
+
userIdentityMode = "external",
|
|
387
|
+
appearance = "auto",
|
|
353
388
|
children
|
|
354
389
|
}) {
|
|
355
390
|
const debug = resolveChatDebug(debugProp);
|
|
391
|
+
const externalIdentity = userIdentityMode === "external";
|
|
356
392
|
const queryClient = useMemo(
|
|
357
393
|
() => new QueryClient({
|
|
358
394
|
defaultOptions: {
|
|
@@ -375,7 +411,9 @@ function ChatProvider({
|
|
|
375
411
|
() => new ChatAPI(apiUrl.replace(/\/$/, ""), () => tokenRef.current, handleAuthError),
|
|
376
412
|
[apiUrl, handleAuthError]
|
|
377
413
|
);
|
|
378
|
-
const [resolvedUserId, setResolvedUserId] = useState(
|
|
414
|
+
const [resolvedUserId, setResolvedUserId] = useState(
|
|
415
|
+
() => externalIdentity ? null : userIdProp ?? null
|
|
416
|
+
);
|
|
379
417
|
const [resolvedTenantId, setResolvedTenantId] = useState(tenantIdProp ?? null);
|
|
380
418
|
const [resolvedConduitlyTenantId, setResolvedConduitlyTenantId] = useState(
|
|
381
419
|
conduitlyTenantIdProp
|
|
@@ -385,17 +423,23 @@ function ChatProvider({
|
|
|
385
423
|
chatDebugLog(debug, "ChatProvider: session inputs", {
|
|
386
424
|
apiUrl: apiUrl.replace(/\/$/, ""),
|
|
387
425
|
hasToken: Boolean(token?.trim?.()),
|
|
426
|
+
userIdentityMode,
|
|
388
427
|
userIdProp: userIdProp ?? null,
|
|
389
428
|
tenantIdProp: tenantIdProp ?? null,
|
|
390
429
|
conduitlyTenantIdProp: conduitlyTenantIdProp ?? null
|
|
391
430
|
});
|
|
392
|
-
}, [debug, apiUrl, token, userIdProp, tenantIdProp, conduitlyTenantIdProp]);
|
|
431
|
+
}, [debug, apiUrl, token, userIdentityMode, userIdProp, tenantIdProp, conduitlyTenantIdProp]);
|
|
393
432
|
useEffect(() => {
|
|
394
433
|
setMeError(null);
|
|
395
|
-
if (userIdProp) setResolvedUserId(userIdProp);
|
|
396
|
-
if (tenantIdProp) setResolvedTenantId(tenantIdProp);
|
|
397
434
|
if (conduitlyTenantIdProp) setResolvedConduitlyTenantId(conduitlyTenantIdProp);
|
|
398
|
-
if (
|
|
435
|
+
if (!externalIdentity) {
|
|
436
|
+
if (userIdProp) setResolvedUserId(userIdProp);
|
|
437
|
+
if (tenantIdProp) setResolvedTenantId(tenantIdProp);
|
|
438
|
+
} else {
|
|
439
|
+
if (tenantIdProp) setResolvedTenantId(tenantIdProp);
|
|
440
|
+
}
|
|
441
|
+
const skipMe = !externalIdentity && Boolean(userIdProp && tenantIdProp);
|
|
442
|
+
if (skipMe) {
|
|
399
443
|
chatDebugLog(debug, "identity: using userId + tenantId props (skipping GET /me)", {
|
|
400
444
|
userId: userIdProp,
|
|
401
445
|
tenantId: tenantIdProp
|
|
@@ -403,6 +447,8 @@ function ChatProvider({
|
|
|
403
447
|
return;
|
|
404
448
|
}
|
|
405
449
|
chatDebugLog(debug, "identity: fetching GET /me \u2026", {
|
|
450
|
+
userIdentityMode,
|
|
451
|
+
externalIdentity,
|
|
406
452
|
missingUserId: !userIdProp,
|
|
407
453
|
missingTenantId: !tenantIdProp
|
|
408
454
|
});
|
|
@@ -416,8 +462,22 @@ function ChatProvider({
|
|
|
416
462
|
ext_user_id: me.ext_user_id ?? null,
|
|
417
463
|
conduitly_tenant_id: me.conduitly_tenant_id ?? null
|
|
418
464
|
});
|
|
419
|
-
if (
|
|
420
|
-
|
|
465
|
+
if (externalIdentity) {
|
|
466
|
+
setResolvedUserId(me.id);
|
|
467
|
+
if (!tenantIdProp) setResolvedTenantId(me.tenant_id);
|
|
468
|
+
const ext = me.ext_user_id?.trim();
|
|
469
|
+
const passed = userIdProp?.trim();
|
|
470
|
+
if (passed && ext && passed.toLowerCase() !== ext.toLowerCase()) {
|
|
471
|
+
chatDebugWarn(
|
|
472
|
+
debug,
|
|
473
|
+
"userIdentityMode=external: `userId` prop does not match GET /me ext_user_id (using JWT user from /me)",
|
|
474
|
+
{ userIdProp: passed, me_ext_user_id: ext, internal_id: me.id }
|
|
475
|
+
);
|
|
476
|
+
}
|
|
477
|
+
} else {
|
|
478
|
+
if (!userIdProp) setResolvedUserId(me.id);
|
|
479
|
+
if (!tenantIdProp) setResolvedTenantId(me.tenant_id);
|
|
480
|
+
}
|
|
421
481
|
if (!conduitlyTenantIdProp && me.conduitly_tenant_id) {
|
|
422
482
|
setResolvedConduitlyTenantId(me.conduitly_tenant_id);
|
|
423
483
|
}
|
|
@@ -428,26 +488,19 @@ function ChatProvider({
|
|
|
428
488
|
return () => {
|
|
429
489
|
cancelled = true;
|
|
430
490
|
};
|
|
431
|
-
}, [api, token, userIdProp, tenantIdProp, conduitlyTenantIdProp, debug]);
|
|
491
|
+
}, [api, token, userIdProp, tenantIdProp, conduitlyTenantIdProp, debug, externalIdentity, userIdentityMode]);
|
|
432
492
|
const userId = resolvedUserId ?? "";
|
|
433
493
|
const tenantId = resolvedTenantId ?? "";
|
|
434
494
|
const mergedTheme = useMemo(() => ({ ...defaultTheme, ...theme }), [theme]);
|
|
435
495
|
const styleTag = useMemo(() => {
|
|
436
496
|
const t = mergedTheme;
|
|
437
|
-
|
|
438
|
-
--chat-primary: ${t.primary};
|
|
439
|
-
--chat-bubble-sent: ${t.bubbleSent};
|
|
440
|
-
--chat-bubble-received: ${t.bubbleReceived};
|
|
441
|
-
--chat-text-on-sent: ${t.textOnSent};
|
|
442
|
-
--chat-text-on-received: ${t.textOnReceived};
|
|
497
|
+
let css = `[data-chat-root] {
|
|
443
498
|
--chat-radius: ${t.radius};
|
|
444
499
|
--chat-font-family: ${t.fontFamily};
|
|
445
|
-
--chat-surface: ${t.surface};
|
|
446
|
-
--chat-border: ${t.border};
|
|
447
|
-
--chat-muted-fill: ${t.mutedFill};
|
|
448
|
-
${t.composerShadow ? `--chat-composer-shadow: ${t.composerShadow};` : ""}
|
|
449
500
|
}`;
|
|
450
|
-
|
|
501
|
+
css += buildThemeColorOverrideCss(theme);
|
|
502
|
+
return css;
|
|
503
|
+
}, [mergedTheme, theme]);
|
|
451
504
|
const [natsConnected, setNatsConnected] = useState(false);
|
|
452
505
|
const natsUrl = natsWsUrl?.trim() ?? "";
|
|
453
506
|
const wsConnected = Boolean(natsUrl) && natsConnected;
|
|
@@ -532,7 +585,15 @@ function ChatProvider({
|
|
|
532
585
|
}
|
|
533
586
|
return null;
|
|
534
587
|
}
|
|
535
|
-
return /* @__PURE__ */ React.createElement(QueryClientProvider, { client: queryClient }, /* @__PURE__ */ React.createElement(ChatContext.Provider, { value }, /* @__PURE__ */ React.createElement("div", { style: layoutStyle }, natsUrl ? /* @__PURE__ */ React.createElement(ChatNatsBridge, { natsWsUrl: natsUrl, natsToken, onConnectedChange: setNatsConnected }) : null, /* @__PURE__ */ React.createElement("style", { dangerouslySetInnerHTML: { __html: styleTag } }), /* @__PURE__ */ React.createElement(
|
|
588
|
+
return /* @__PURE__ */ React.createElement(QueryClientProvider, { client: queryClient }, /* @__PURE__ */ React.createElement(ChatContext.Provider, { value }, /* @__PURE__ */ React.createElement("div", { style: layoutStyle }, natsUrl ? /* @__PURE__ */ React.createElement(ChatNatsBridge, { natsWsUrl: natsUrl, natsToken, onConnectedChange: setNatsConnected }) : null, /* @__PURE__ */ React.createElement("style", { dangerouslySetInnerHTML: { __html: styleTag } }), /* @__PURE__ */ React.createElement(
|
|
589
|
+
"div",
|
|
590
|
+
{
|
|
591
|
+
"data-chat-root": true,
|
|
592
|
+
"data-chat-appearance": appearance === "auto" ? void 0 : appearance,
|
|
593
|
+
style: { ...layoutStyle, flex: 1 }
|
|
594
|
+
},
|
|
595
|
+
children
|
|
596
|
+
))));
|
|
536
597
|
}
|
|
537
598
|
function useChatActions() {
|
|
538
599
|
const { api } = useChat();
|