organify-ui 0.3.23 → 0.3.24
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.
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import { cn, TooltipProvider, Tooltip, TooltipTrigger, TooltipContent, ScrollArea, Skeleton, Avatar, AvatarFallback, Drawer, DrawerContent, DrawerHeader, DrawerTitle, DrawerDescription, DrawerFooter, Badge,
|
|
1
|
+
import { cn, TooltipProvider, Tooltip, TooltipTrigger, TooltipContent, ScrollArea, Skeleton, useOrganifyApi, useOrganify, Avatar, AvatarImage, AvatarFallback, Drawer, DrawerContent, DrawerHeader, DrawerTitle, DrawerDescription, DrawerFooter, Badge, useOrganifyUser, useOrganifyWorkspace, useOrganifyGql } from './chunk-276ZWKXB.js';
|
|
2
2
|
import { OrgPlus, OrgSearch, OrgComment, OrgClose, OrgEdit, OrgTeam, OrgGlobe, OrgLock, OrgCheckCircle, OrgError, OrgWarning, OrgInfo, OrgChevronDown, OrgChevronRight, OrgDoor, OrgTrash, OrgCheck, OrgFolder, OrgChevronLeft } from './chunk-MZKEDV5W.js';
|
|
3
3
|
import * as React6 from 'react';
|
|
4
|
-
import React6__default, { useState,
|
|
4
|
+
import React6__default, { useState, useEffect, useCallback } from 'react';
|
|
5
5
|
import { Slot } from '@radix-ui/react-slot';
|
|
6
6
|
import { cva } from 'class-variance-authority';
|
|
7
7
|
import { jsxs, jsx, Fragment } from 'react/jsx-runtime';
|
|
@@ -399,6 +399,236 @@ function ChatSidebar({
|
|
|
399
399
|
] }) }) })
|
|
400
400
|
] });
|
|
401
401
|
}
|
|
402
|
+
var _cache = /* @__PURE__ */ new Map();
|
|
403
|
+
var _inflight = /* @__PURE__ */ new Map();
|
|
404
|
+
var _pendingBatch = /* @__PURE__ */ new Set();
|
|
405
|
+
var _batchTimer = null;
|
|
406
|
+
var _batchResolvers = /* @__PURE__ */ new Map();
|
|
407
|
+
function _flushBatch(gatewayUrl) {
|
|
408
|
+
const ids = Array.from(_pendingBatch);
|
|
409
|
+
_pendingBatch.clear();
|
|
410
|
+
_batchTimer = null;
|
|
411
|
+
if (ids.length === 0) return;
|
|
412
|
+
const p = fetch(`${gatewayUrl}/api/users/profiles/batch`, {
|
|
413
|
+
method: "POST",
|
|
414
|
+
headers: { "Content-Type": "application/json" },
|
|
415
|
+
credentials: "include",
|
|
416
|
+
body: JSON.stringify({ ids })
|
|
417
|
+
}).then((r) => r.ok ? r.json() : null).catch(() => null).then((body) => {
|
|
418
|
+
const results = !body ? [] : Array.isArray(body) ? body : Array.isArray(body.data) ? body.data : [];
|
|
419
|
+
const byId = /* @__PURE__ */ new Map();
|
|
420
|
+
for (const u of results) {
|
|
421
|
+
byId.set(String(u.id), u);
|
|
422
|
+
}
|
|
423
|
+
for (const id of ids) {
|
|
424
|
+
const user = byId.get(id) ?? null;
|
|
425
|
+
_cache.set(id, user);
|
|
426
|
+
_inflight.delete(id);
|
|
427
|
+
const resolvers = _batchResolvers.get(id) ?? [];
|
|
428
|
+
_batchResolvers.delete(id);
|
|
429
|
+
for (const resolve of resolvers) resolve(user);
|
|
430
|
+
}
|
|
431
|
+
});
|
|
432
|
+
for (const id of ids) {
|
|
433
|
+
if (!_batchResolvers.has(id)) _batchResolvers.set(id, []);
|
|
434
|
+
_inflight.set(id, p.then(() => _cache.get(id) ?? null));
|
|
435
|
+
}
|
|
436
|
+
}
|
|
437
|
+
function resolveUser(userId, gatewayUrl) {
|
|
438
|
+
if (_cache.has(userId)) {
|
|
439
|
+
return Promise.resolve(_cache.get(userId));
|
|
440
|
+
}
|
|
441
|
+
if (_inflight.has(userId)) {
|
|
442
|
+
return _inflight.get(userId);
|
|
443
|
+
}
|
|
444
|
+
_pendingBatch.add(userId);
|
|
445
|
+
if (!_batchResolvers.has(userId)) _batchResolvers.set(userId, []);
|
|
446
|
+
if (!_batchTimer) {
|
|
447
|
+
_batchTimer = setTimeout(() => _flushBatch(gatewayUrl), 0);
|
|
448
|
+
}
|
|
449
|
+
const p = new Promise((resolve) => {
|
|
450
|
+
_batchResolvers.get(userId).push(resolve);
|
|
451
|
+
});
|
|
452
|
+
_inflight.set(userId, p);
|
|
453
|
+
return p;
|
|
454
|
+
}
|
|
455
|
+
function invalidateUserCache(userId) {
|
|
456
|
+
_cache.delete(userId);
|
|
457
|
+
_inflight.delete(userId);
|
|
458
|
+
}
|
|
459
|
+
function seedUserCache(users) {
|
|
460
|
+
for (const u of users) {
|
|
461
|
+
_cache.set(String(u.id), u);
|
|
462
|
+
}
|
|
463
|
+
}
|
|
464
|
+
function useResolvedUser(userId) {
|
|
465
|
+
const api = useOrganifyApi();
|
|
466
|
+
const { user: currentUser } = useOrganify();
|
|
467
|
+
const key = userId != null ? String(userId) : void 0;
|
|
468
|
+
if (currentUser?.id != null) {
|
|
469
|
+
const ck = String(currentUser.id);
|
|
470
|
+
if (!_cache.has(ck)) {
|
|
471
|
+
_cache.set(ck, {
|
|
472
|
+
id: currentUser.id,
|
|
473
|
+
name: currentUser.name ?? "",
|
|
474
|
+
avatarUrl: currentUser.avatarUrl ?? void 0
|
|
475
|
+
});
|
|
476
|
+
}
|
|
477
|
+
}
|
|
478
|
+
const [user, setUser] = useState(() => {
|
|
479
|
+
if (!key) return void 0;
|
|
480
|
+
return _cache.has(key) ? _cache.get(key) : void 0;
|
|
481
|
+
});
|
|
482
|
+
useEffect(() => {
|
|
483
|
+
if (!key || !api.gatewayUrl) return;
|
|
484
|
+
let cancelled = false;
|
|
485
|
+
if (_cache.has(key)) {
|
|
486
|
+
setUser(_cache.get(key) ?? null);
|
|
487
|
+
return;
|
|
488
|
+
}
|
|
489
|
+
resolveUser(key, api.gatewayUrl).then((u) => {
|
|
490
|
+
if (!cancelled) setUser(u);
|
|
491
|
+
});
|
|
492
|
+
return () => {
|
|
493
|
+
cancelled = true;
|
|
494
|
+
};
|
|
495
|
+
}, [key, api.gatewayUrl]);
|
|
496
|
+
useEffect(() => {
|
|
497
|
+
if (!key || !currentUser?.id) return;
|
|
498
|
+
if (String(currentUser.id) === key) {
|
|
499
|
+
setUser(_cache.get(key) ?? null);
|
|
500
|
+
}
|
|
501
|
+
}, [key, currentUser]);
|
|
502
|
+
return user;
|
|
503
|
+
}
|
|
504
|
+
function getInitials(name) {
|
|
505
|
+
return name.split(/\s+/).filter(Boolean).slice(0, 2).map((w) => w[0].toUpperCase()).join("");
|
|
506
|
+
}
|
|
507
|
+
function nameToGradient(name) {
|
|
508
|
+
let hash = 0;
|
|
509
|
+
for (let i = 0; i < name.length; i++) {
|
|
510
|
+
hash = name.charCodeAt(i) + ((hash << 5) - hash);
|
|
511
|
+
}
|
|
512
|
+
const gradients = [
|
|
513
|
+
"from-violet-500 to-purple-600",
|
|
514
|
+
"from-blue-500 to-cyan-500",
|
|
515
|
+
"from-emerald-500 to-teal-500",
|
|
516
|
+
"from-orange-500 to-amber-500",
|
|
517
|
+
"from-rose-500 to-pink-500",
|
|
518
|
+
"from-indigo-500 to-blue-600",
|
|
519
|
+
"from-fuchsia-500 to-purple-500",
|
|
520
|
+
"from-teal-500 to-green-500"
|
|
521
|
+
];
|
|
522
|
+
return gradients[Math.abs(hash) % gradients.length];
|
|
523
|
+
}
|
|
524
|
+
function UserAvatar({
|
|
525
|
+
userId,
|
|
526
|
+
name: nameProp,
|
|
527
|
+
src: srcProp,
|
|
528
|
+
email,
|
|
529
|
+
role,
|
|
530
|
+
showHoverInfo = true,
|
|
531
|
+
fallback,
|
|
532
|
+
extraInfo,
|
|
533
|
+
onClick,
|
|
534
|
+
className,
|
|
535
|
+
size = "default",
|
|
536
|
+
shape = "circle",
|
|
537
|
+
status,
|
|
538
|
+
...props
|
|
539
|
+
}) {
|
|
540
|
+
const resolved = useResolvedUser(!nameProp && userId != null ? userId : null);
|
|
541
|
+
const name = nameProp ?? resolved?.name ?? "\u2026";
|
|
542
|
+
const src = srcProp ?? resolved?.avatarUrl ?? void 0;
|
|
543
|
+
const isLoading = !nameProp && userId != null && resolved === void 0;
|
|
544
|
+
const initials = getInitials(name);
|
|
545
|
+
const gradient = nameToGradient(name || "unknown");
|
|
546
|
+
const avatarElement = /* @__PURE__ */ jsxs(
|
|
547
|
+
Avatar,
|
|
548
|
+
{
|
|
549
|
+
size,
|
|
550
|
+
shape,
|
|
551
|
+
status,
|
|
552
|
+
gradient,
|
|
553
|
+
className: cn(
|
|
554
|
+
onClick && "cursor-pointer",
|
|
555
|
+
isLoading && "animate-pulse opacity-60",
|
|
556
|
+
className
|
|
557
|
+
),
|
|
558
|
+
onClick,
|
|
559
|
+
...props,
|
|
560
|
+
children: [
|
|
561
|
+
src ? /* @__PURE__ */ jsx(AvatarImage, { src, alt: name }) : null,
|
|
562
|
+
/* @__PURE__ */ jsx(
|
|
563
|
+
AvatarFallback,
|
|
564
|
+
{
|
|
565
|
+
className: cn(
|
|
566
|
+
"bg-gradient-to-br text-white font-semibold",
|
|
567
|
+
gradient,
|
|
568
|
+
size === "sm" && "text-xs",
|
|
569
|
+
size === "default" && "text-sm",
|
|
570
|
+
size === "lg" && "text-lg",
|
|
571
|
+
size === "xl" && "text-xl"
|
|
572
|
+
),
|
|
573
|
+
children: fallback ?? initials
|
|
574
|
+
}
|
|
575
|
+
)
|
|
576
|
+
]
|
|
577
|
+
}
|
|
578
|
+
);
|
|
579
|
+
if (!showHoverInfo) return avatarElement;
|
|
580
|
+
return /* @__PURE__ */ jsx(TooltipProvider, { delayDuration: 300, children: /* @__PURE__ */ jsxs(Tooltip, { children: [
|
|
581
|
+
/* @__PURE__ */ jsx(TooltipTrigger, { asChild: true, children: avatarElement }),
|
|
582
|
+
/* @__PURE__ */ jsxs(
|
|
583
|
+
TooltipContent,
|
|
584
|
+
{
|
|
585
|
+
side: "top",
|
|
586
|
+
className: cn(
|
|
587
|
+
"flex items-center gap-3 rounded-xl border border-theme-subtle",
|
|
588
|
+
"bg-card-surface/95 px-4 py-3 shadow-glass-xl backdrop-blur-2xl",
|
|
589
|
+
"max-w-xs"
|
|
590
|
+
),
|
|
591
|
+
children: [
|
|
592
|
+
/* @__PURE__ */ jsxs(Avatar, { size: "sm", shape, gradient, children: [
|
|
593
|
+
src ? /* @__PURE__ */ jsx(AvatarImage, { src, alt: name }) : null,
|
|
594
|
+
/* @__PURE__ */ jsx(AvatarFallback, { className: cn("bg-gradient-to-br text-white text-xs font-semibold", gradient), children: initials })
|
|
595
|
+
] }),
|
|
596
|
+
/* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-0.5 min-w-0", children: [
|
|
597
|
+
/* @__PURE__ */ jsx("span", { className: "text-sm font-semibold text-white truncate", children: name }),
|
|
598
|
+
email && /* @__PURE__ */ jsx("span", { className: "text-xs text-theme-muted truncate", children: email }),
|
|
599
|
+
role && /* @__PURE__ */ jsx("span", { className: "text-xs text-primary-light/80 capitalize", children: role.toLowerCase() }),
|
|
600
|
+
extraInfo?.map((info) => /* @__PURE__ */ jsxs("span", { className: "text-xs text-theme-muted", children: [
|
|
601
|
+
info.label,
|
|
602
|
+
": ",
|
|
603
|
+
info.value
|
|
604
|
+
] }, info.label))
|
|
605
|
+
] })
|
|
606
|
+
]
|
|
607
|
+
}
|
|
608
|
+
)
|
|
609
|
+
] }) });
|
|
610
|
+
}
|
|
611
|
+
UserAvatar.displayName = "UserAvatar";
|
|
612
|
+
function UserDisplayName({
|
|
613
|
+
userId,
|
|
614
|
+
name: nameProp,
|
|
615
|
+
loadingFallback = "\u2026",
|
|
616
|
+
className,
|
|
617
|
+
style
|
|
618
|
+
}) {
|
|
619
|
+
const resolved = useResolvedUser(!nameProp && userId != null ? userId : null);
|
|
620
|
+
const isLoading = !nameProp && userId != null && resolved === void 0;
|
|
621
|
+
const displayName = nameProp ?? resolved?.name ?? (isLoading ? loadingFallback : "?");
|
|
622
|
+
return /* @__PURE__ */ jsx(
|
|
623
|
+
"span",
|
|
624
|
+
{
|
|
625
|
+
className: cn(isLoading && "animate-pulse opacity-60", className),
|
|
626
|
+
style,
|
|
627
|
+
title: displayName,
|
|
628
|
+
children: displayName
|
|
629
|
+
}
|
|
630
|
+
);
|
|
631
|
+
}
|
|
402
632
|
var actionBarVariants = {
|
|
403
633
|
hidden: {
|
|
404
634
|
opacity: 0,
|
|
@@ -455,10 +685,6 @@ function formatTime(iso) {
|
|
|
455
685
|
minute: "2-digit"
|
|
456
686
|
});
|
|
457
687
|
}
|
|
458
|
-
function getInitials(name) {
|
|
459
|
-
if (!name) return "??";
|
|
460
|
-
return name.split(" ").map((w) => w[0]).slice(0, 2).join("").toUpperCase();
|
|
461
|
-
}
|
|
462
688
|
function groupReactions(reactions) {
|
|
463
689
|
const map = /* @__PURE__ */ new Map();
|
|
464
690
|
reactions.forEach((r) => {
|
|
@@ -796,7 +1022,17 @@ function MessageBubble({
|
|
|
796
1022
|
showActions && "bg-theme-subtle"
|
|
797
1023
|
),
|
|
798
1024
|
children: [
|
|
799
|
-
/* @__PURE__ */ jsx(motion.div, { whileHover: { scale: 1.05 }, whileTap: { scale: 0.95 }, children: /* @__PURE__ */ jsx(
|
|
1025
|
+
/* @__PURE__ */ jsx(motion.div, { whileHover: { scale: 1.05 }, whileTap: { scale: 0.95 }, children: /* @__PURE__ */ jsx(
|
|
1026
|
+
UserAvatar,
|
|
1027
|
+
{
|
|
1028
|
+
userId: message.authorId,
|
|
1029
|
+
name: message.authorName,
|
|
1030
|
+
src: message.authorAvatarUrl,
|
|
1031
|
+
size: "sm",
|
|
1032
|
+
showHoverInfo: false,
|
|
1033
|
+
className: "mt-0.5 shrink-0"
|
|
1034
|
+
}
|
|
1035
|
+
) }),
|
|
800
1036
|
/* @__PURE__ */ jsxs("div", { className: "flex-1 min-w-0 relative", children: [
|
|
801
1037
|
/* @__PURE__ */ jsx(
|
|
802
1038
|
ActionBar,
|
|
@@ -837,7 +1073,7 @@ function MessageBubble({
|
|
|
837
1073
|
}
|
|
838
1074
|
) }),
|
|
839
1075
|
/* @__PURE__ */ jsxs("div", { className: "flex items-baseline gap-2 mb-0.5", children: [
|
|
840
|
-
/* @__PURE__ */ jsx("span", { className: "text-[13px] font-semibold text-theme", children:
|
|
1076
|
+
/* @__PURE__ */ jsx("span", { className: "text-[13px] font-semibold text-theme", children: /* @__PURE__ */ jsx(UserDisplayName, { userId: message.authorId, name: message.authorName }) }),
|
|
841
1077
|
/* @__PURE__ */ jsx("span", { className: "text-[11px] text-theme-muted", children: formatTime(message.createdAt) }),
|
|
842
1078
|
message.edited && /* @__PURE__ */ jsx(
|
|
843
1079
|
motion.span,
|
|
@@ -4471,6 +4707,6 @@ function useAiInline({ gatewayUrl, workspaceId, projectId }) {
|
|
|
4471
4707
|
return { loading, suggestion, requestSuggestion, dismiss };
|
|
4472
4708
|
}
|
|
4473
4709
|
|
|
4474
|
-
export { AiChatSidebar, Alert, Button, ChatMessages, ChatSidebar, CommandBar, CreateRoomDialog, Dialog, DialogClose, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogOverlay, DialogPortal, DialogTitle, DialogTrigger, InlineAiButton, Input, Label, MOCK_PROJECTS, MOCK_USERS, MentionPopover, MessageBubble, MessageInput, OrgLoader, OrgLoaderInline, OrganifyChat, ResponsiveDialog, RoomManagementPanel, Select, SelectContent, SelectGroup, SelectItem, SelectLabel, SelectScrollDownButton, SelectScrollUpButton, SelectSeparator, SelectTrigger, SelectValue, Separator, Tabs, TabsContent, TabsList, TabsTrigger, Textarea, TypingIndicatorMock, alertVariants, buttonVariants, generateAutoReplies, getMockMentionOptions, getRoomPermissions, inputVariants, orgLoaderVariants, typingIndicator, useAiInline, useChat };
|
|
4475
|
-
//# sourceMappingURL=chunk-
|
|
4476
|
-
//# sourceMappingURL=chunk-
|
|
4710
|
+
export { AiChatSidebar, Alert, Button, ChatMessages, ChatSidebar, CommandBar, CreateRoomDialog, Dialog, DialogClose, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogOverlay, DialogPortal, DialogTitle, DialogTrigger, InlineAiButton, Input, Label, MOCK_PROJECTS, MOCK_USERS, MentionPopover, MessageBubble, MessageInput, OrgLoader, OrgLoaderInline, OrganifyChat, ResponsiveDialog, RoomManagementPanel, Select, SelectContent, SelectGroup, SelectItem, SelectLabel, SelectScrollDownButton, SelectScrollUpButton, SelectSeparator, SelectTrigger, SelectValue, Separator, Tabs, TabsContent, TabsList, TabsTrigger, Textarea, TypingIndicatorMock, UserAvatar, UserDisplayName, alertVariants, buttonVariants, generateAutoReplies, getMockMentionOptions, getRoomPermissions, inputVariants, invalidateUserCache, orgLoaderVariants, resolveUser, seedUserCache, typingIndicator, useAiInline, useChat, useResolvedUser };
|
|
4711
|
+
//# sourceMappingURL=chunk-JGDJNAAW.js.map
|
|
4712
|
+
//# sourceMappingURL=chunk-JGDJNAAW.js.map
|