@arbidocs/blocks 0.3.128 → 0.3.130
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.cjs +138 -77
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +13 -14
- package/dist/index.d.ts +13 -14
- package/dist/index.js +140 -79
- package/dist/index.js.map +1 -1
- package/package.json +3 -3
package/dist/index.d.cts
CHANGED
|
@@ -537,19 +537,19 @@ interface WorkspaceCardProps {
|
|
|
537
537
|
* place of the count and drops the avatar stack, rather than lying with a `0`.
|
|
538
538
|
*/
|
|
539
539
|
membersHidden?: boolean;
|
|
540
|
-
/** ISO timestamp — renders
|
|
541
|
-
* line at rest, which gives way to the Open button on hover. */
|
|
540
|
+
/** ISO timestamp — renders "Updated {relative} ago" at the footer's right edge. */
|
|
542
541
|
updatedAt?: string;
|
|
543
|
-
/** Marks this as the current workspace:
|
|
544
|
-
* so in words instead of offering an Open button. */
|
|
542
|
+
/** Marks this as the current workspace: an accented card surface and a footer label. */
|
|
545
543
|
active?: boolean;
|
|
546
|
-
/** Shows a spinner in the Open
|
|
544
|
+
/** Shows a spinner in the Open affordance while a switch is in flight. */
|
|
547
545
|
busy?: boolean;
|
|
548
546
|
onOpen?: () => void;
|
|
549
547
|
/** Icon in the header tile. Defaults to a lock/folder glyph. */
|
|
550
548
|
icon?: LucideIcon;
|
|
551
549
|
/** Replaces the whole header icon tile — for a richer, app-supplied glyph. */
|
|
552
550
|
iconSlot?: ReactNode;
|
|
551
|
+
/** Canonical workspace entity pill shown at the top of the description tooltip. */
|
|
552
|
+
tooltipEntitySlot?: ReactNode;
|
|
553
553
|
/**
|
|
554
554
|
* Secondary context for the card (the ARBI app puts the owning project here).
|
|
555
555
|
* Sits top-right and is revealed on hover/focus, so the resting card stays
|
|
@@ -559,14 +559,14 @@ interface WorkspaceCardProps {
|
|
|
559
559
|
/**
|
|
560
560
|
* Accent as a theme colour-token key (e.g. `emerald`, or a firm's own brand
|
|
561
561
|
* token), resolved to `var(--color-<accent>)` at render — same contract as
|
|
562
|
-
* MetricCard. Tints the icon tile and the Open
|
|
562
|
+
* MetricCard. Tints the icon tile and the Open affordance, so a firm can accent
|
|
563
563
|
* the card without its brand classes leaking into the kit. `'default'` (or
|
|
564
564
|
* omitted) uses the semantic `primary` token.
|
|
565
565
|
*/
|
|
566
566
|
accent?: string;
|
|
567
|
-
/** Stable id for the card root; the footer
|
|
567
|
+
/** Stable id for the card root; the footer action gets `${testId}-open`. */
|
|
568
568
|
testId?: string;
|
|
569
|
-
/** Overrides the footer
|
|
569
|
+
/** Overrides the footer action's test id when a caller needs a specific one. */
|
|
570
570
|
buttonTestId?: string;
|
|
571
571
|
className?: string;
|
|
572
572
|
}
|
|
@@ -575,11 +575,10 @@ interface WorkspaceCardProps {
|
|
|
575
575
|
*
|
|
576
576
|
* 1. header — icon + workspace name; secondary context (`cornerSlot`) hides
|
|
577
577
|
* top-right until hover, keeping the resting card about the workspace.
|
|
578
|
-
* 2. body —
|
|
579
|
-
*
|
|
580
|
-
* 3. footer —
|
|
581
|
-
*
|
|
582
|
-
* workspace says so in words there instead.
|
|
578
|
+
* 2. body — an expanded description area with the centred Open/current
|
|
579
|
+
* affordance layered over it only on hover or keyboard focus.
|
|
580
|
+
* 3. footer — doc/chat counts stay left and membership stays right, followed
|
|
581
|
+
* by a final left-aligned update timestamp.
|
|
583
582
|
*
|
|
584
583
|
* State is said once, in words. There is deliberately no status badge.
|
|
585
584
|
*
|
|
@@ -587,7 +586,7 @@ interface WorkspaceCardProps {
|
|
|
587
586
|
* primary, card, border, accent), so every firm gets it in its own colours
|
|
588
587
|
* without any firm-branded classes leaking in.
|
|
589
588
|
*/
|
|
590
|
-
declare function WorkspaceCard({ name, matterRef, description, docCount, chatCount, memberCount, members, membersHidden, updatedAt, active, busy, onOpen, icon: Icon, iconSlot, cornerSlot, accent, testId, buttonTestId, className, }: WorkspaceCardProps): react.JSX.Element;
|
|
589
|
+
declare function WorkspaceCard({ name, matterRef, description, docCount, chatCount, memberCount, members, membersHidden, updatedAt, active, busy, onOpen, icon: Icon, iconSlot, tooltipEntitySlot, cornerSlot, accent, testId, buttonTestId, className, }: WorkspaceCardProps): react.JSX.Element;
|
|
591
590
|
|
|
592
591
|
interface StatItem {
|
|
593
592
|
value: string;
|
package/dist/index.d.ts
CHANGED
|
@@ -537,19 +537,19 @@ interface WorkspaceCardProps {
|
|
|
537
537
|
* place of the count and drops the avatar stack, rather than lying with a `0`.
|
|
538
538
|
*/
|
|
539
539
|
membersHidden?: boolean;
|
|
540
|
-
/** ISO timestamp — renders
|
|
541
|
-
* line at rest, which gives way to the Open button on hover. */
|
|
540
|
+
/** ISO timestamp — renders "Updated {relative} ago" at the footer's right edge. */
|
|
542
541
|
updatedAt?: string;
|
|
543
|
-
/** Marks this as the current workspace:
|
|
544
|
-
* so in words instead of offering an Open button. */
|
|
542
|
+
/** Marks this as the current workspace: an accented card surface and a footer label. */
|
|
545
543
|
active?: boolean;
|
|
546
|
-
/** Shows a spinner in the Open
|
|
544
|
+
/** Shows a spinner in the Open affordance while a switch is in flight. */
|
|
547
545
|
busy?: boolean;
|
|
548
546
|
onOpen?: () => void;
|
|
549
547
|
/** Icon in the header tile. Defaults to a lock/folder glyph. */
|
|
550
548
|
icon?: LucideIcon;
|
|
551
549
|
/** Replaces the whole header icon tile — for a richer, app-supplied glyph. */
|
|
552
550
|
iconSlot?: ReactNode;
|
|
551
|
+
/** Canonical workspace entity pill shown at the top of the description tooltip. */
|
|
552
|
+
tooltipEntitySlot?: ReactNode;
|
|
553
553
|
/**
|
|
554
554
|
* Secondary context for the card (the ARBI app puts the owning project here).
|
|
555
555
|
* Sits top-right and is revealed on hover/focus, so the resting card stays
|
|
@@ -559,14 +559,14 @@ interface WorkspaceCardProps {
|
|
|
559
559
|
/**
|
|
560
560
|
* Accent as a theme colour-token key (e.g. `emerald`, or a firm's own brand
|
|
561
561
|
* token), resolved to `var(--color-<accent>)` at render — same contract as
|
|
562
|
-
* MetricCard. Tints the icon tile and the Open
|
|
562
|
+
* MetricCard. Tints the icon tile and the Open affordance, so a firm can accent
|
|
563
563
|
* the card without its brand classes leaking into the kit. `'default'` (or
|
|
564
564
|
* omitted) uses the semantic `primary` token.
|
|
565
565
|
*/
|
|
566
566
|
accent?: string;
|
|
567
|
-
/** Stable id for the card root; the footer
|
|
567
|
+
/** Stable id for the card root; the footer action gets `${testId}-open`. */
|
|
568
568
|
testId?: string;
|
|
569
|
-
/** Overrides the footer
|
|
569
|
+
/** Overrides the footer action's test id when a caller needs a specific one. */
|
|
570
570
|
buttonTestId?: string;
|
|
571
571
|
className?: string;
|
|
572
572
|
}
|
|
@@ -575,11 +575,10 @@ interface WorkspaceCardProps {
|
|
|
575
575
|
*
|
|
576
576
|
* 1. header — icon + workspace name; secondary context (`cornerSlot`) hides
|
|
577
577
|
* top-right until hover, keeping the resting card about the workspace.
|
|
578
|
-
* 2. body —
|
|
579
|
-
*
|
|
580
|
-
* 3. footer —
|
|
581
|
-
*
|
|
582
|
-
* workspace says so in words there instead.
|
|
578
|
+
* 2. body — an expanded description area with the centred Open/current
|
|
579
|
+
* affordance layered over it only on hover or keyboard focus.
|
|
580
|
+
* 3. footer — doc/chat counts stay left and membership stays right, followed
|
|
581
|
+
* by a final left-aligned update timestamp.
|
|
583
582
|
*
|
|
584
583
|
* State is said once, in words. There is deliberately no status badge.
|
|
585
584
|
*
|
|
@@ -587,7 +586,7 @@ interface WorkspaceCardProps {
|
|
|
587
586
|
* primary, card, border, accent), so every firm gets it in its own colours
|
|
588
587
|
* without any firm-branded classes leaking in.
|
|
589
588
|
*/
|
|
590
|
-
declare function WorkspaceCard({ name, matterRef, description, docCount, chatCount, memberCount, members, membersHidden, updatedAt, active, busy, onOpen, icon: Icon, iconSlot, cornerSlot, accent, testId, buttonTestId, className, }: WorkspaceCardProps): react.JSX.Element;
|
|
589
|
+
declare function WorkspaceCard({ name, matterRef, description, docCount, chatCount, memberCount, members, membersHidden, updatedAt, active, busy, onOpen, icon: Icon, iconSlot, tooltipEntitySlot, cornerSlot, accent, testId, buttonTestId, className, }: WorkspaceCardProps): react.JSX.Element;
|
|
591
590
|
|
|
592
591
|
interface StatItem {
|
|
593
592
|
value: string;
|
package/dist/index.js
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
import { tid, initials, fromNow, fmtDate, assetRefId, applyStoredTheme, AssetResolverProvider, ThemeEditor, applyThemeVars, SectionHeading, PricingTable, Tabs as Tabs$1, Accordion, Gallery, VideoEmbed, ContactForm, Banner, MediaText, TeamGrid, Steps, TestimonialGrid, Columns, Spacer, Container, Hero, FeatureGrid, Testimonial, CTABanner, LogoCloud, FAQ, RichTextBlock, Callout, BlockImage, AvatarBlock, Navbar, Footer, ListBlock, isAssetRef, asAssetRef } from './chunk-L6GG4KN2.js';
|
|
2
2
|
export { ASSET_REF_PREFIX, Accordion, AssetResolverProvider, AvatarBlock, Banner, BlockImage, BlockLink, CTABanner, Callout, Columns, ContactForm, Container, FAQ, FONT_PAIRINGS, FeatureGrid, Footer, Gallery, Hero, ListBlock, LogoCloud, MediaText, Navbar, PricingTable, RichTextBlock, SectionHeading, Spacer, Steps, THEME_STYLE_ID, Tabs, TeamGrid, Testimonial, TestimonialGrid, ThemeEditor, VideoEmbed, applyFontVars, applyStoredTheme, applyThemeVars, asAssetRef, assetRefId, clearFontVars, clearThemeVars, createThemeStore, daysUntil, fmtDate, fmtDateTime, fontPackages, fromNow, gbp, getFontPairing, hrs, initials, isAssetRef, matchFontPairing, pct, tid, toEmbedUrl, toHslTriplet, useAssetRenderer, useAssetResolverActive } from './chunk-L6GG4KN2.js';
|
|
3
3
|
import { createContext, useState, useCallback, useMemo, useContext, useRef, useEffect } from 'react';
|
|
4
|
-
import { useArbi, ArbiProvider, useAiTask, useWorkspaceDocs as useWorkspaceDocs$1, useSemanticSearch as useSemanticSearch$1, cn, Table, TableHeader, TableRow, TableHead, TableBody, TableCell, Input, Card, CardHeader, CardTitle, CardDescription, CardContent, Avatar, AvatarImage, AvatarFallback,
|
|
4
|
+
import { useArbi, ArbiProvider, useAiTask, useWorkspaceDocs as useWorkspaceDocs$1, useSemanticSearch as useSemanticSearch$1, cn, Table, TableHeader, TableRow, TableHead, TableBody, TableCell, Input, Card, CardHeader, CardTitle, CardDescription, CardContent, Tooltip, TooltipTrigger, TooltipContent, CardFooter, Avatar, AvatarImage, AvatarFallback, TooltipProvider, Button, NotificationBell, UserMenu, useThumbnails, Badge, Switch, useConfigs, useAgents, Checkbox, Tabs, TabsList, TabsTrigger, TabsContent, Separator, ArbiWebSocketProvider, useDocuments, ImageCropModal, DEFAULT_ASPECT_OPTIONS, useConversations } from '@arbidocs/react';
|
|
5
5
|
export { DocumentCard, Table, TableBody, TableCell, TableHead, TableHeader, TableRow, Tooltip, TooltipContent, TooltipProvider, TooltipTrigger, redlineStats, textToArtifact, toRedlineMarkdown } from '@arbidocs/react';
|
|
6
6
|
import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
|
|
7
7
|
import { QueryClient, QueryClientProvider, useQuery, useQueryClient } from '@tanstack/react-query';
|
|
8
8
|
import { AgGridReact } from 'ag-grid-react';
|
|
9
9
|
import { themeQuartz, AllCommunityModule } from 'ag-grid-community';
|
|
10
|
-
import { MessageSquare, Cpu, Code, Cloud, Layers, Target, Award, MapPin, Phone, Mail, Lock, Globe, Heart, Star, Rocket, Shield, Zap, Sparkles, Gavel, Scale, Bell, Activity, BarChart3, DollarSign, TrendingUp, Info, AlertCircle, CheckCircle, Clock, Calendar, Briefcase, Users, Folder, FileText, Loader2, UploadCloud, Search, ArrowUpRight, ArrowDownRight, FolderLock,
|
|
10
|
+
import { MessageSquare, Cpu, Code, Cloud, Layers, Target, Award, MapPin, Phone, Mail, Lock, Globe, Heart, Star, Rocket, Shield, Zap, Sparkles, Gavel, Scale, Bell, Activity, BarChart3, DollarSign, TrendingUp, Info, AlertCircle, CheckCircle, Clock, Calendar, Briefcase, Users, Folder, FileText, Loader2, UploadCloud, Search, ArrowUpRight, ArrowDownRight, FolderLock, CheckCircle2, ArrowLeftRight, MessagesSquare, X, Menu, ArrowLeft, Palette, RotateCcw, ChevronUp, ChevronDown, BrainCircuit, Bot, LayoutGrid, FileJson, Download, Crop, ImagePlus, Upload, Link2, Check } from 'lucide-react';
|
|
11
11
|
import { useLocation, Link, useParams, NavLink } from 'react-router-dom';
|
|
12
12
|
import { Puck, Render } from '@measured/puck';
|
|
13
13
|
import { create } from 'zustand';
|
|
@@ -1058,7 +1058,6 @@ function MetricCard({
|
|
|
1058
1058
|
] });
|
|
1059
1059
|
}
|
|
1060
1060
|
var MAX_AVATARS = 3;
|
|
1061
|
-
var ON_HOVER = "opacity-0 transition-opacity group-hover:opacity-100 group-focus-within:opacity-100";
|
|
1062
1061
|
function WorkspaceCard({
|
|
1063
1062
|
name,
|
|
1064
1063
|
matterRef,
|
|
@@ -1074,6 +1073,7 @@ function WorkspaceCard({
|
|
|
1074
1073
|
onOpen,
|
|
1075
1074
|
icon: Icon = FolderLock,
|
|
1076
1075
|
iconSlot,
|
|
1076
|
+
tooltipEntitySlot,
|
|
1077
1077
|
cornerSlot,
|
|
1078
1078
|
accent = "default",
|
|
1079
1079
|
testId,
|
|
@@ -1083,24 +1083,57 @@ function WorkspaceCard({
|
|
|
1083
1083
|
const totalMembers = memberCount ?? members.length;
|
|
1084
1084
|
const shownMembers = membersHidden ? [] : members.slice(0, MAX_AVATARS);
|
|
1085
1085
|
const extraMembers = totalMembers - shownMembers.length;
|
|
1086
|
-
const
|
|
1086
|
+
const actionTestId = buttonTestId ?? (testId ? `${testId}-open` : void 0);
|
|
1087
|
+
const canOpen = Boolean(onOpen) && !busy;
|
|
1088
|
+
const [isHoverPointerActive, setIsHoverPointerActive] = useState(false);
|
|
1089
|
+
const [isKeyboardFocused, setIsKeyboardFocused] = useState(false);
|
|
1090
|
+
const revealInteractiveContent = isHoverPointerActive || isKeyboardFocused;
|
|
1091
|
+
const showOpenAction = busy || revealInteractiveContent;
|
|
1087
1092
|
const hue = accent && accent !== "default" ? `var(--color-${accent})` : null;
|
|
1088
1093
|
const tileStyle = hue ? { backgroundColor: `color-mix(in oklab, ${hue} 14%, transparent)`, color: hue } : void 0;
|
|
1089
|
-
const
|
|
1094
|
+
const openStyle = hue ? { backgroundColor: hue, color: "var(--color-background)" } : void 0;
|
|
1095
|
+
const handleKeyDown = (event) => {
|
|
1096
|
+
if (!canOpen || event.target !== event.currentTarget) return;
|
|
1097
|
+
if (event.key === "Enter" || event.key === " ") {
|
|
1098
|
+
event.preventDefault();
|
|
1099
|
+
onOpen?.();
|
|
1100
|
+
}
|
|
1101
|
+
};
|
|
1102
|
+
const handleFocusCapture = (event) => {
|
|
1103
|
+
setIsKeyboardFocused(event.target instanceof Element && event.target.matches(":focus-visible"));
|
|
1104
|
+
};
|
|
1105
|
+
const handleBlurCapture = (event) => {
|
|
1106
|
+
if (!event.currentTarget.contains(event.relatedTarget)) {
|
|
1107
|
+
setIsKeyboardFocused(false);
|
|
1108
|
+
}
|
|
1109
|
+
};
|
|
1090
1110
|
return /* @__PURE__ */ jsxs(
|
|
1091
1111
|
Card,
|
|
1092
1112
|
{
|
|
1093
|
-
variant: "
|
|
1113
|
+
variant: "flat",
|
|
1094
1114
|
className: cn(
|
|
1095
|
-
"card-hover
|
|
1096
|
-
|
|
1097
|
-
|
|
1098
|
-
active && "ring-1 ring-primary",
|
|
1115
|
+
"card-hover relative flex h-48 w-full flex-col gap-3 overflow-hidden rounded-xl bg-card p-4 shadow-sm",
|
|
1116
|
+
canOpen && "cursor-pointer focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-primary focus-visible:ring-offset-2",
|
|
1117
|
+
active && "bg-primary/10 shadow-md",
|
|
1099
1118
|
className
|
|
1100
1119
|
),
|
|
1101
1120
|
"data-testid": testId,
|
|
1121
|
+
"data-active": active || void 0,
|
|
1122
|
+
role: canOpen ? "button" : void 0,
|
|
1123
|
+
tabIndex: canOpen ? 0 : void 0,
|
|
1124
|
+
"aria-current": active ? "page" : void 0,
|
|
1125
|
+
"aria-label": canOpen ? `Open workspace ${name}` : void 0,
|
|
1126
|
+
"aria-busy": busy || void 0,
|
|
1127
|
+
onClick: canOpen ? onOpen : void 0,
|
|
1128
|
+
onKeyDown: handleKeyDown,
|
|
1129
|
+
onPointerEnter: (event) => {
|
|
1130
|
+
if (event.pointerType !== "touch") setIsHoverPointerActive(true);
|
|
1131
|
+
},
|
|
1132
|
+
onPointerLeave: () => setIsHoverPointerActive(false),
|
|
1133
|
+
onFocusCapture: handleFocusCapture,
|
|
1134
|
+
onBlurCapture: handleBlurCapture,
|
|
1102
1135
|
children: [
|
|
1103
|
-
/* @__PURE__ */ jsxs(CardHeader, { className: "flex flex-row items-
|
|
1136
|
+
/* @__PURE__ */ jsxs(CardHeader, { className: "flex flex-row items-center gap-3 space-y-0 p-0", children: [
|
|
1104
1137
|
iconSlot ?? /* @__PURE__ */ jsx(
|
|
1105
1138
|
"div",
|
|
1106
1139
|
{
|
|
@@ -1113,97 +1146,125 @@ function WorkspaceCard({
|
|
|
1113
1146
|
/* @__PURE__ */ jsx(
|
|
1114
1147
|
CardTitle,
|
|
1115
1148
|
{
|
|
1116
|
-
className: "line-clamp-2 text-base leading-tight",
|
|
1149
|
+
className: "line-clamp-2 text-base font-bold leading-tight",
|
|
1117
1150
|
"data-testid": testId && `${testId}-title`,
|
|
1118
1151
|
children: name
|
|
1119
1152
|
}
|
|
1120
1153
|
),
|
|
1121
1154
|
matterRef && /* @__PURE__ */ jsx(CardDescription, { className: "mt-0.5 truncate text-xs font-medium uppercase tracking-wide text-muted-foreground", children: matterRef })
|
|
1122
1155
|
] }),
|
|
1123
|
-
cornerSlot && /* @__PURE__ */ jsx(
|
|
1156
|
+
cornerSlot && /* @__PURE__ */ jsx(
|
|
1157
|
+
"div",
|
|
1158
|
+
{
|
|
1159
|
+
className: cn(
|
|
1160
|
+
"shrink-0 opacity-0 transition-opacity",
|
|
1161
|
+
revealInteractiveContent && "opacity-100"
|
|
1162
|
+
),
|
|
1163
|
+
children: cornerSlot
|
|
1164
|
+
}
|
|
1165
|
+
)
|
|
1124
1166
|
] }),
|
|
1125
|
-
/* @__PURE__ */ jsxs(CardContent, { className: "flex flex-1 flex-col
|
|
1126
|
-
description && /* @__PURE__ */
|
|
1127
|
-
|
|
1128
|
-
|
|
1129
|
-
|
|
1130
|
-
|
|
1131
|
-
|
|
1132
|
-
|
|
1133
|
-
|
|
1134
|
-
|
|
1135
|
-
|
|
1136
|
-
|
|
1137
|
-
|
|
1138
|
-
/* @__PURE__ */ jsx(
|
|
1167
|
+
/* @__PURE__ */ jsxs(CardContent, { className: "relative flex min-h-0 flex-1 flex-col p-0", children: [
|
|
1168
|
+
description && /* @__PURE__ */ jsxs(Tooltip, { children: [
|
|
1169
|
+
/* @__PURE__ */ jsx(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ jsx(
|
|
1170
|
+
"p",
|
|
1171
|
+
{
|
|
1172
|
+
className: cn(
|
|
1173
|
+
"line-clamp-2 text-sm text-muted-foreground opacity-100 transition-opacity",
|
|
1174
|
+
showOpenAction && "opacity-0"
|
|
1175
|
+
),
|
|
1176
|
+
children: description
|
|
1177
|
+
}
|
|
1178
|
+
) }),
|
|
1179
|
+
/* @__PURE__ */ jsx(TooltipContent, { side: "top", className: "max-w-sm p-0", children: /* @__PURE__ */ jsxs("div", { className: "overflow-hidden rounded-md", children: [
|
|
1180
|
+
/* @__PURE__ */ jsx("div", { className: "flex items-center bg-muted/70 px-3 py-2.5", children: tooltipEntitySlot ?? /* @__PURE__ */ jsx("span", { className: "text-sm font-semibold", children: name }) }),
|
|
1181
|
+
/* @__PURE__ */ jsx("p", { className: "px-3 py-3 text-sm leading-relaxed text-foreground/90", children: description })
|
|
1182
|
+
] }) })
|
|
1183
|
+
] }),
|
|
1184
|
+
/* @__PURE__ */ jsx(
|
|
1185
|
+
"span",
|
|
1186
|
+
{
|
|
1187
|
+
className: cn(
|
|
1188
|
+
"pointer-events-none absolute inset-0 z-10 inline-flex items-center justify-center whitespace-nowrap opacity-0 transition-opacity",
|
|
1189
|
+
showOpenAction && "opacity-100"
|
|
1190
|
+
),
|
|
1191
|
+
"data-testid": actionTestId,
|
|
1192
|
+
children: /* @__PURE__ */ jsx(
|
|
1139
1193
|
"span",
|
|
1140
1194
|
{
|
|
1141
|
-
className:
|
|
1142
|
-
|
|
1143
|
-
|
|
1195
|
+
className: cn(
|
|
1196
|
+
"inline-flex w-full items-center justify-center gap-2 rounded-md px-4 py-2 text-base font-semibold shadow-md",
|
|
1197
|
+
active ? "bg-muted-foreground text-background" : "bg-primary text-primary-foreground"
|
|
1198
|
+
),
|
|
1199
|
+
style: active ? void 0 : openStyle,
|
|
1200
|
+
children: active ? /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
1201
|
+
/* @__PURE__ */ jsx(CheckCircle2, { className: "size-4" }),
|
|
1202
|
+
" Current workspace"
|
|
1203
|
+
] }) : busy ? /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
1204
|
+
/* @__PURE__ */ jsx(Loader2, { className: "size-4 animate-spin" }),
|
|
1205
|
+
" Opening"
|
|
1206
|
+
] }) : /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
1207
|
+
/* @__PURE__ */ jsx(ArrowLeftRight, { className: "size-4" }),
|
|
1208
|
+
" Open"
|
|
1209
|
+
] })
|
|
1144
1210
|
}
|
|
1145
1211
|
)
|
|
1146
|
-
] }),
|
|
1147
|
-
/* @__PURE__ */ jsxs("div", { className: "ml-auto flex shrink-0 -space-x-2", children: [
|
|
1148
|
-
shownMembers.map((m, i) => /* @__PURE__ */ jsxs(Avatar, { className: "size-6 border-2 border-card", title: m.name, children: [
|
|
1149
|
-
m.picture && /* @__PURE__ */ jsx(AvatarImage, { src: m.picture, alt: m.name }),
|
|
1150
|
-
/* @__PURE__ */ jsx(AvatarFallback, { className: "bg-foreground text-[9px] font-medium text-background", children: initials(m.name || "?") })
|
|
1151
|
-
] }, i)),
|
|
1152
|
-
!membersHidden && extraMembers > 0 && /* @__PURE__ */ jsx(Avatar, { className: "size-6 border-2 border-card", children: /* @__PURE__ */ jsxs(AvatarFallback, { className: "bg-accent text-[9px] font-medium text-muted-foreground", children: [
|
|
1153
|
-
"+",
|
|
1154
|
-
extraMembers
|
|
1155
|
-
] }) })
|
|
1156
|
-
] })
|
|
1157
|
-
] })
|
|
1158
|
-
] }),
|
|
1159
|
-
/* @__PURE__ */ jsx(CardFooter, { className: "grid min-h-8 place-items-center p-0", children: active ? (
|
|
1160
|
-
// Reads as a statement, not a call to action — but stays clickable, so
|
|
1161
|
-
// re-entering the workspace you're already in still works.
|
|
1162
|
-
/* @__PURE__ */ jsxs(
|
|
1163
|
-
Button,
|
|
1164
|
-
{
|
|
1165
|
-
variant: "ghost",
|
|
1166
|
-
size: "sm",
|
|
1167
|
-
className: "col-start-1 row-start-1 h-8 whitespace-nowrap px-2 text-xs font-medium text-primary hover:bg-primary/10",
|
|
1168
|
-
onClick: onOpen,
|
|
1169
|
-
"data-testid": btnTestId,
|
|
1170
|
-
children: [
|
|
1171
|
-
/* @__PURE__ */ jsx(CheckCircle2, { className: "size-3.5" }),
|
|
1172
|
-
" Current workspace"
|
|
1173
|
-
]
|
|
1174
1212
|
}
|
|
1175
1213
|
)
|
|
1176
|
-
)
|
|
1214
|
+
] }),
|
|
1215
|
+
/* @__PURE__ */ jsxs(CardFooter, { className: "mt-auto flex w-full min-w-0 flex-col items-stretch gap-3 overflow-hidden p-0", children: [
|
|
1216
|
+
/* @__PURE__ */ jsxs("div", { className: "flex w-full items-center gap-x-3 text-sm", children: [
|
|
1217
|
+
/* @__PURE__ */ jsxs("div", { className: "flex items-center gap-x-3", children: [
|
|
1218
|
+
/* @__PURE__ */ jsxs("span", { className: "inline-flex items-center gap-1 text-foreground", title: "Documents", children: [
|
|
1219
|
+
/* @__PURE__ */ jsx(FileText, { className: "size-3.5 text-muted-foreground" }),
|
|
1220
|
+
/* @__PURE__ */ jsx("span", { className: "font-medium tabular-nums", children: docCount.toLocaleString() })
|
|
1221
|
+
] }),
|
|
1222
|
+
chatCount !== void 0 && /* @__PURE__ */ jsxs("span", { className: "inline-flex items-center gap-1 text-foreground", title: "Chats", children: [
|
|
1223
|
+
/* @__PURE__ */ jsx(MessagesSquare, { className: "size-3.5 text-muted-foreground" }),
|
|
1224
|
+
/* @__PURE__ */ jsx("span", { className: "font-medium tabular-nums", children: chatCount.toLocaleString() })
|
|
1225
|
+
] }),
|
|
1226
|
+
/* @__PURE__ */ jsxs("span", { className: "inline-flex items-center gap-1 text-foreground", title: "Members", children: [
|
|
1227
|
+
/* @__PURE__ */ jsx(Users, { className: "size-3.5 text-muted-foreground" }),
|
|
1228
|
+
/* @__PURE__ */ jsx(
|
|
1229
|
+
"span",
|
|
1230
|
+
{
|
|
1231
|
+
className: "font-medium tabular-nums",
|
|
1232
|
+
"data-testid": testId && `${testId}-member-count`,
|
|
1233
|
+
children: membersHidden ? "\u2014" : totalMembers
|
|
1234
|
+
}
|
|
1235
|
+
)
|
|
1236
|
+
] })
|
|
1237
|
+
] }),
|
|
1238
|
+
/* @__PURE__ */ jsxs(
|
|
1239
|
+
"div",
|
|
1240
|
+
{
|
|
1241
|
+
className: "ml-auto flex shrink-0 -space-x-2",
|
|
1242
|
+
"data-testid": testId && `${testId}-member-avatars`,
|
|
1243
|
+
children: [
|
|
1244
|
+
shownMembers.map((m, i) => /* @__PURE__ */ jsxs(Avatar, { className: "size-6 border-2 border-card", title: m.name, children: [
|
|
1245
|
+
m.picture && /* @__PURE__ */ jsx(AvatarImage, { src: m.picture, alt: m.name }),
|
|
1246
|
+
/* @__PURE__ */ jsx(AvatarFallback, { className: "bg-foreground text-[9px] font-medium text-background", children: initials(m.name || "?") })
|
|
1247
|
+
] }, i)),
|
|
1248
|
+
!membersHidden && extraMembers > 0 && /* @__PURE__ */ jsx(Avatar, { className: "size-6 border-2 border-card", children: /* @__PURE__ */ jsxs(AvatarFallback, { className: "bg-accent text-[9px] font-medium text-muted-foreground", children: [
|
|
1249
|
+
"+",
|
|
1250
|
+
extraMembers
|
|
1251
|
+
] }) })
|
|
1252
|
+
]
|
|
1253
|
+
}
|
|
1254
|
+
)
|
|
1255
|
+
] }),
|
|
1177
1256
|
updatedAt && /* @__PURE__ */ jsxs(
|
|
1178
1257
|
"span",
|
|
1179
1258
|
{
|
|
1180
|
-
className:
|
|
1181
|
-
"col-start-1 row-start-1 whitespace-nowrap text-xs text-muted-foreground",
|
|
1182
|
-
"transition-opacity group-hover:opacity-0 group-focus-within:opacity-0"
|
|
1183
|
-
),
|
|
1259
|
+
className: "min-w-0 max-w-full self-start truncate text-left text-xs text-muted-foreground",
|
|
1184
1260
|
title: fmtDate(updatedAt),
|
|
1185
1261
|
children: [
|
|
1186
1262
|
"Updated ",
|
|
1187
1263
|
fromNow(updatedAt)
|
|
1188
1264
|
]
|
|
1189
1265
|
}
|
|
1190
|
-
),
|
|
1191
|
-
/* @__PURE__ */ jsxs(
|
|
1192
|
-
Button,
|
|
1193
|
-
{
|
|
1194
|
-
size: "sm",
|
|
1195
|
-
className: cn("col-start-1 row-start-1 whitespace-nowrap", ON_HOVER),
|
|
1196
|
-
style: buttonStyle,
|
|
1197
|
-
onClick: onOpen,
|
|
1198
|
-
disabled: busy,
|
|
1199
|
-
"data-testid": btnTestId,
|
|
1200
|
-
children: [
|
|
1201
|
-
busy ? /* @__PURE__ */ jsx(Loader2, { className: "size-3.5 animate-spin" }) : /* @__PURE__ */ jsx(ArrowLeftRight, { className: "size-3.5" }),
|
|
1202
|
-
"Open"
|
|
1203
|
-
]
|
|
1204
|
-
}
|
|
1205
1266
|
)
|
|
1206
|
-
] })
|
|
1267
|
+
] })
|
|
1207
1268
|
]
|
|
1208
1269
|
}
|
|
1209
1270
|
);
|