@arbidocs/blocks 0.3.127 → 0.3.128
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 +109 -39
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +44 -10
- package/dist/index.d.ts +44 -10
- package/dist/index.js +111 -41
- package/dist/index.js.map +1 -1
- package/package.json +3 -3
package/dist/index.d.cts
CHANGED
|
@@ -520,23 +520,50 @@ interface WorkspaceCardMember {
|
|
|
520
520
|
}
|
|
521
521
|
interface WorkspaceCardProps {
|
|
522
522
|
name: string;
|
|
523
|
-
/** Uppercase eyebrow
|
|
523
|
+
/** Uppercase eyebrow under the name, e.g. the matter reference. Omit to let
|
|
524
|
+
* the name and description carry the card on their own. */
|
|
524
525
|
matterRef?: string;
|
|
525
526
|
description?: string;
|
|
526
527
|
docCount: number;
|
|
528
|
+
/** Conversation count, shown as a third stat. Omit to hide the stat entirely. */
|
|
529
|
+
chatCount?: number;
|
|
527
530
|
/** Defaults to `members.length` when omitted. */
|
|
528
531
|
memberCount?: number;
|
|
529
|
-
/** Drives the overlapping avatar stack (shows up to
|
|
532
|
+
/** Drives the overlapping avatar stack (shows up to 3, then a `+N` overflow). */
|
|
530
533
|
members?: WorkspaceCardMember[];
|
|
531
|
-
/**
|
|
534
|
+
/**
|
|
535
|
+
* The member list is not visible to this viewer (e.g. row-level security hides
|
|
536
|
+
* the members of a public workspace you haven't joined). Renders an em dash in
|
|
537
|
+
* place of the count and drops the avatar stack, rather than lying with a `0`.
|
|
538
|
+
*/
|
|
539
|
+
membersHidden?: boolean;
|
|
540
|
+
/** ISO timestamp — renders a centred "Updated {relative} ago" on the footer
|
|
541
|
+
* line at rest, which gives way to the Open button on hover. */
|
|
532
542
|
updatedAt?: string;
|
|
533
|
-
/** Marks this as the current workspace: a
|
|
543
|
+
/** Marks this as the current workspace: a ring on the card, and the footer says
|
|
544
|
+
* so in words instead of offering an Open button. */
|
|
534
545
|
active?: boolean;
|
|
535
|
-
/** Shows a spinner in the
|
|
546
|
+
/** Shows a spinner in the Open button while a switch is in flight. */
|
|
536
547
|
busy?: boolean;
|
|
537
548
|
onOpen?: () => void;
|
|
538
549
|
/** Icon in the header tile. Defaults to a lock/folder glyph. */
|
|
539
550
|
icon?: LucideIcon;
|
|
551
|
+
/** Replaces the whole header icon tile — for a richer, app-supplied glyph. */
|
|
552
|
+
iconSlot?: ReactNode;
|
|
553
|
+
/**
|
|
554
|
+
* Secondary context for the card (the ARBI app puts the owning project here).
|
|
555
|
+
* Sits top-right and is revealed on hover/focus, so the resting card stays
|
|
556
|
+
* about the workspace itself.
|
|
557
|
+
*/
|
|
558
|
+
cornerSlot?: ReactNode;
|
|
559
|
+
/**
|
|
560
|
+
* Accent as a theme colour-token key (e.g. `emerald`, or a firm's own brand
|
|
561
|
+
* token), resolved to `var(--color-<accent>)` at render — same contract as
|
|
562
|
+
* MetricCard. Tints the icon tile and the Open button, so a firm can accent
|
|
563
|
+
* the card without its brand classes leaking into the kit. `'default'` (or
|
|
564
|
+
* omitted) uses the semantic `primary` token.
|
|
565
|
+
*/
|
|
566
|
+
accent?: string;
|
|
540
567
|
/** Stable id for the card root; the footer button gets `${testId}-open`. */
|
|
541
568
|
testId?: string;
|
|
542
569
|
/** Overrides the footer button's test id when a caller needs a specific one. */
|
|
@@ -544,16 +571,23 @@ interface WorkspaceCardProps {
|
|
|
544
571
|
className?: string;
|
|
545
572
|
}
|
|
546
573
|
/**
|
|
547
|
-
* The one true workspace card. A themeable, source-agnostic tile
|
|
548
|
-
*
|
|
549
|
-
*
|
|
550
|
-
*
|
|
574
|
+
* The one true workspace card. A themeable, source-agnostic tile, in three bands:
|
|
575
|
+
*
|
|
576
|
+
* 1. header — icon + workspace name; secondary context (`cornerSlot`) hides
|
|
577
|
+
* top-right until hover, keeping the resting card about the workspace.
|
|
578
|
+
* 2. body — two-line description, then one stat line: doc/chat/member counts
|
|
579
|
+
* on the left, the member avatar stack right-justified on the same row.
|
|
580
|
+
* 3. footer — one centred line with the full width to itself: "Updated … ago"
|
|
581
|
+
* at rest, swapping to the Open button on hover. The current
|
|
582
|
+
* workspace says so in words there instead.
|
|
583
|
+
*
|
|
584
|
+
* State is said once, in words. There is deliberately no status badge.
|
|
551
585
|
*
|
|
552
586
|
* Styled with the kit's SEMANTIC tokens only (foreground, muted-foreground,
|
|
553
587
|
* primary, card, border, accent), so every firm gets it in its own colours
|
|
554
588
|
* without any firm-branded classes leaking in.
|
|
555
589
|
*/
|
|
556
|
-
declare function WorkspaceCard({ name, matterRef, description, docCount, memberCount, members, updatedAt, active, busy, onOpen, icon: Icon, testId, buttonTestId, className, }: WorkspaceCardProps): react.JSX.Element;
|
|
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;
|
|
557
591
|
|
|
558
592
|
interface StatItem {
|
|
559
593
|
value: string;
|
package/dist/index.d.ts
CHANGED
|
@@ -520,23 +520,50 @@ interface WorkspaceCardMember {
|
|
|
520
520
|
}
|
|
521
521
|
interface WorkspaceCardProps {
|
|
522
522
|
name: string;
|
|
523
|
-
/** Uppercase eyebrow
|
|
523
|
+
/** Uppercase eyebrow under the name, e.g. the matter reference. Omit to let
|
|
524
|
+
* the name and description carry the card on their own. */
|
|
524
525
|
matterRef?: string;
|
|
525
526
|
description?: string;
|
|
526
527
|
docCount: number;
|
|
528
|
+
/** Conversation count, shown as a third stat. Omit to hide the stat entirely. */
|
|
529
|
+
chatCount?: number;
|
|
527
530
|
/** Defaults to `members.length` when omitted. */
|
|
528
531
|
memberCount?: number;
|
|
529
|
-
/** Drives the overlapping avatar stack (shows up to
|
|
532
|
+
/** Drives the overlapping avatar stack (shows up to 3, then a `+N` overflow). */
|
|
530
533
|
members?: WorkspaceCardMember[];
|
|
531
|
-
/**
|
|
534
|
+
/**
|
|
535
|
+
* The member list is not visible to this viewer (e.g. row-level security hides
|
|
536
|
+
* the members of a public workspace you haven't joined). Renders an em dash in
|
|
537
|
+
* place of the count and drops the avatar stack, rather than lying with a `0`.
|
|
538
|
+
*/
|
|
539
|
+
membersHidden?: boolean;
|
|
540
|
+
/** ISO timestamp — renders a centred "Updated {relative} ago" on the footer
|
|
541
|
+
* line at rest, which gives way to the Open button on hover. */
|
|
532
542
|
updatedAt?: string;
|
|
533
|
-
/** Marks this as the current workspace: a
|
|
543
|
+
/** Marks this as the current workspace: a ring on the card, and the footer says
|
|
544
|
+
* so in words instead of offering an Open button. */
|
|
534
545
|
active?: boolean;
|
|
535
|
-
/** Shows a spinner in the
|
|
546
|
+
/** Shows a spinner in the Open button while a switch is in flight. */
|
|
536
547
|
busy?: boolean;
|
|
537
548
|
onOpen?: () => void;
|
|
538
549
|
/** Icon in the header tile. Defaults to a lock/folder glyph. */
|
|
539
550
|
icon?: LucideIcon;
|
|
551
|
+
/** Replaces the whole header icon tile — for a richer, app-supplied glyph. */
|
|
552
|
+
iconSlot?: ReactNode;
|
|
553
|
+
/**
|
|
554
|
+
* Secondary context for the card (the ARBI app puts the owning project here).
|
|
555
|
+
* Sits top-right and is revealed on hover/focus, so the resting card stays
|
|
556
|
+
* about the workspace itself.
|
|
557
|
+
*/
|
|
558
|
+
cornerSlot?: ReactNode;
|
|
559
|
+
/**
|
|
560
|
+
* Accent as a theme colour-token key (e.g. `emerald`, or a firm's own brand
|
|
561
|
+
* token), resolved to `var(--color-<accent>)` at render — same contract as
|
|
562
|
+
* MetricCard. Tints the icon tile and the Open button, so a firm can accent
|
|
563
|
+
* the card without its brand classes leaking into the kit. `'default'` (or
|
|
564
|
+
* omitted) uses the semantic `primary` token.
|
|
565
|
+
*/
|
|
566
|
+
accent?: string;
|
|
540
567
|
/** Stable id for the card root; the footer button gets `${testId}-open`. */
|
|
541
568
|
testId?: string;
|
|
542
569
|
/** Overrides the footer button's test id when a caller needs a specific one. */
|
|
@@ -544,16 +571,23 @@ interface WorkspaceCardProps {
|
|
|
544
571
|
className?: string;
|
|
545
572
|
}
|
|
546
573
|
/**
|
|
547
|
-
* The one true workspace card. A themeable, source-agnostic tile
|
|
548
|
-
*
|
|
549
|
-
*
|
|
550
|
-
*
|
|
574
|
+
* The one true workspace card. A themeable, source-agnostic tile, in three bands:
|
|
575
|
+
*
|
|
576
|
+
* 1. header — icon + workspace name; secondary context (`cornerSlot`) hides
|
|
577
|
+
* top-right until hover, keeping the resting card about the workspace.
|
|
578
|
+
* 2. body — two-line description, then one stat line: doc/chat/member counts
|
|
579
|
+
* on the left, the member avatar stack right-justified on the same row.
|
|
580
|
+
* 3. footer — one centred line with the full width to itself: "Updated … ago"
|
|
581
|
+
* at rest, swapping to the Open button on hover. The current
|
|
582
|
+
* workspace says so in words there instead.
|
|
583
|
+
*
|
|
584
|
+
* State is said once, in words. There is deliberately no status badge.
|
|
551
585
|
*
|
|
552
586
|
* Styled with the kit's SEMANTIC tokens only (foreground, muted-foreground,
|
|
553
587
|
* primary, card, border, accent), so every firm gets it in its own colours
|
|
554
588
|
* without any firm-branded classes leaking in.
|
|
555
589
|
*/
|
|
556
|
-
declare function WorkspaceCard({ name, matterRef, description, docCount, memberCount, members, updatedAt, active, busy, onOpen, icon: Icon, testId, buttonTestId, className, }: WorkspaceCardProps): react.JSX.Element;
|
|
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;
|
|
557
591
|
|
|
558
592
|
interface StatItem {
|
|
559
593
|
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,
|
|
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, CardFooter, Button, TooltipProvider, 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, CheckCircle2, ArrowLeftRight, X, Menu, ArrowLeft, Palette, RotateCcw, ChevronUp, ChevronDown, BrainCircuit, Bot, LayoutGrid, FileJson, Download, Crop, ImagePlus, Upload, Link2, Check
|
|
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, MessagesSquare, CheckCircle2, ArrowLeftRight, 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';
|
|
@@ -1057,82 +1057,152 @@ function MetricCard({
|
|
|
1057
1057
|
] })
|
|
1058
1058
|
] });
|
|
1059
1059
|
}
|
|
1060
|
-
var MAX_AVATARS =
|
|
1060
|
+
var MAX_AVATARS = 3;
|
|
1061
|
+
var ON_HOVER = "opacity-0 transition-opacity group-hover:opacity-100 group-focus-within:opacity-100";
|
|
1061
1062
|
function WorkspaceCard({
|
|
1062
1063
|
name,
|
|
1063
1064
|
matterRef,
|
|
1064
1065
|
description,
|
|
1065
1066
|
docCount,
|
|
1067
|
+
chatCount,
|
|
1066
1068
|
memberCount,
|
|
1067
1069
|
members = [],
|
|
1070
|
+
membersHidden = false,
|
|
1068
1071
|
updatedAt,
|
|
1069
1072
|
active = false,
|
|
1070
1073
|
busy = false,
|
|
1071
1074
|
onOpen,
|
|
1072
1075
|
icon: Icon = FolderLock,
|
|
1076
|
+
iconSlot,
|
|
1077
|
+
cornerSlot,
|
|
1078
|
+
accent = "default",
|
|
1073
1079
|
testId,
|
|
1074
1080
|
buttonTestId,
|
|
1075
1081
|
className
|
|
1076
1082
|
}) {
|
|
1077
1083
|
const totalMembers = memberCount ?? members.length;
|
|
1078
|
-
const shownMembers = members.slice(0, MAX_AVATARS);
|
|
1084
|
+
const shownMembers = membersHidden ? [] : members.slice(0, MAX_AVATARS);
|
|
1079
1085
|
const extraMembers = totalMembers - shownMembers.length;
|
|
1080
1086
|
const btnTestId = buttonTestId ?? (testId ? `${testId}-open` : void 0);
|
|
1087
|
+
const hue = accent && accent !== "default" ? `var(--color-${accent})` : null;
|
|
1088
|
+
const tileStyle = hue ? { backgroundColor: `color-mix(in oklab, ${hue} 14%, transparent)`, color: hue } : void 0;
|
|
1089
|
+
const buttonStyle = hue ? { backgroundColor: hue, color: "var(--color-primary-foreground)" } : void 0;
|
|
1081
1090
|
return /* @__PURE__ */ jsxs(
|
|
1082
1091
|
Card,
|
|
1083
1092
|
{
|
|
1084
1093
|
variant: "outline",
|
|
1085
|
-
className: cn(
|
|
1094
|
+
className: cn(
|
|
1095
|
+
"card-hover group flex flex-col gap-3 p-4",
|
|
1096
|
+
// The current workspace is marked by a ring, not a badge — the footer
|
|
1097
|
+
// already says "Current workspace" in words.
|
|
1098
|
+
active && "ring-1 ring-primary",
|
|
1099
|
+
className
|
|
1100
|
+
),
|
|
1086
1101
|
"data-testid": testId,
|
|
1087
1102
|
children: [
|
|
1088
|
-
/* @__PURE__ */ jsxs(CardHeader, { className: "p-0", children: [
|
|
1089
|
-
/* @__PURE__ */
|
|
1090
|
-
|
|
1091
|
-
|
|
1092
|
-
|
|
1093
|
-
|
|
1094
|
-
|
|
1103
|
+
/* @__PURE__ */ jsxs(CardHeader, { className: "flex flex-row items-start gap-3 p-0", children: [
|
|
1104
|
+
iconSlot ?? /* @__PURE__ */ jsx(
|
|
1105
|
+
"div",
|
|
1106
|
+
{
|
|
1107
|
+
className: "flex size-9 shrink-0 items-center justify-center rounded-md bg-primary/10 text-primary",
|
|
1108
|
+
style: tileStyle,
|
|
1109
|
+
children: /* @__PURE__ */ jsx(Icon, { className: "size-5" })
|
|
1110
|
+
}
|
|
1111
|
+
),
|
|
1112
|
+
/* @__PURE__ */ jsxs("div", { className: "min-w-0 flex-1", children: [
|
|
1113
|
+
/* @__PURE__ */ jsx(
|
|
1114
|
+
CardTitle,
|
|
1115
|
+
{
|
|
1116
|
+
className: "line-clamp-2 text-base leading-tight",
|
|
1117
|
+
"data-testid": testId && `${testId}-title`,
|
|
1118
|
+
children: name
|
|
1119
|
+
}
|
|
1120
|
+
),
|
|
1121
|
+
matterRef && /* @__PURE__ */ jsx(CardDescription, { className: "mt-0.5 truncate text-xs font-medium uppercase tracking-wide text-muted-foreground", children: matterRef })
|
|
1095
1122
|
] }),
|
|
1096
|
-
/* @__PURE__ */ jsx(
|
|
1097
|
-
matterRef && /* @__PURE__ */ jsx(CardDescription, { className: "text-xs font-medium uppercase tracking-wide text-muted-foreground", children: matterRef })
|
|
1123
|
+
cornerSlot && /* @__PURE__ */ jsx("div", { className: cn("shrink-0", ON_HOVER), children: cornerSlot })
|
|
1098
1124
|
] }),
|
|
1099
|
-
/* @__PURE__ */ jsxs(CardContent, { className: "
|
|
1125
|
+
/* @__PURE__ */ jsxs(CardContent, { className: "flex flex-1 flex-col gap-2 p-0", children: [
|
|
1100
1126
|
description && /* @__PURE__ */ jsx("p", { className: "line-clamp-2 text-sm text-muted-foreground", children: description }),
|
|
1101
|
-
/* @__PURE__ */ jsxs("div", { className: "flex items-center gap-
|
|
1102
|
-
/* @__PURE__ */ jsxs("span", { className: "inline-flex items-center gap-1
|
|
1103
|
-
/* @__PURE__ */ jsx(FileText, { className: "size-
|
|
1104
|
-
/* @__PURE__ */ jsx("span", { className: "font-medium", children: docCount.toLocaleString() })
|
|
1105
|
-
/* @__PURE__ */ jsx("span", { className: "text-muted-foreground", children: "docs" })
|
|
1127
|
+
/* @__PURE__ */ jsxs("div", { className: "flex items-center gap-x-3 text-sm", children: [
|
|
1128
|
+
/* @__PURE__ */ jsxs("span", { className: "inline-flex items-center gap-1 text-foreground", title: "Documents", children: [
|
|
1129
|
+
/* @__PURE__ */ jsx(FileText, { className: "size-3.5 text-muted-foreground" }),
|
|
1130
|
+
/* @__PURE__ */ jsx("span", { className: "font-medium tabular-nums", children: docCount.toLocaleString() })
|
|
1106
1131
|
] }),
|
|
1107
|
-
/* @__PURE__ */ jsxs("span", { className: "inline-flex items-center gap-1
|
|
1108
|
-
/* @__PURE__ */ jsx(
|
|
1109
|
-
/* @__PURE__ */ jsx("span", { className: "font-medium", children:
|
|
1110
|
-
|
|
1111
|
-
|
|
1112
|
-
|
|
1113
|
-
|
|
1114
|
-
|
|
1115
|
-
|
|
1132
|
+
chatCount !== void 0 && /* @__PURE__ */ jsxs("span", { className: "inline-flex items-center gap-1 text-foreground", title: "Chats", children: [
|
|
1133
|
+
/* @__PURE__ */ jsx(MessagesSquare, { className: "size-3.5 text-muted-foreground" }),
|
|
1134
|
+
/* @__PURE__ */ jsx("span", { className: "font-medium tabular-nums", children: chatCount.toLocaleString() })
|
|
1135
|
+
] }),
|
|
1136
|
+
/* @__PURE__ */ jsxs("span", { className: "inline-flex items-center gap-1 text-foreground", title: "Members", children: [
|
|
1137
|
+
/* @__PURE__ */ jsx(Users, { className: "size-3.5 text-muted-foreground" }),
|
|
1138
|
+
/* @__PURE__ */ jsx(
|
|
1139
|
+
"span",
|
|
1140
|
+
{
|
|
1141
|
+
className: "font-medium tabular-nums",
|
|
1142
|
+
"data-testid": testId && `${testId}-member-count`,
|
|
1143
|
+
children: membersHidden ? "\u2014" : totalMembers
|
|
1144
|
+
}
|
|
1145
|
+
)
|
|
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: [
|
|
1116
1149
|
m.picture && /* @__PURE__ */ jsx(AvatarImage, { src: m.picture, alt: m.name }),
|
|
1117
|
-
/* @__PURE__ */ jsx(AvatarFallback, { className: "bg-foreground text-[
|
|
1150
|
+
/* @__PURE__ */ jsx(AvatarFallback, { className: "bg-foreground text-[9px] font-medium text-background", children: initials(m.name || "?") })
|
|
1118
1151
|
] }, i)),
|
|
1119
|
-
extraMembers > 0 && /* @__PURE__ */ jsx(Avatar, { className: "size-
|
|
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: [
|
|
1120
1153
|
"+",
|
|
1121
1154
|
extraMembers
|
|
1122
1155
|
] }) })
|
|
1123
|
-
] }),
|
|
1124
|
-
updatedAt && /* @__PURE__ */ jsxs("span", { className: "text-xs text-muted-foreground", title: fmtDate(updatedAt), children: [
|
|
1125
|
-
"Updated ",
|
|
1126
|
-
fromNow(updatedAt)
|
|
1127
1156
|
] })
|
|
1128
1157
|
] })
|
|
1129
1158
|
] }),
|
|
1130
|
-
/* @__PURE__ */ jsx(CardFooter, { className: "
|
|
1131
|
-
|
|
1132
|
-
|
|
1133
|
-
|
|
1134
|
-
|
|
1135
|
-
|
|
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
|
+
}
|
|
1175
|
+
)
|
|
1176
|
+
) : /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
1177
|
+
updatedAt && /* @__PURE__ */ jsxs(
|
|
1178
|
+
"span",
|
|
1179
|
+
{
|
|
1180
|
+
className: cn(
|
|
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
|
+
),
|
|
1184
|
+
title: fmtDate(updatedAt),
|
|
1185
|
+
children: [
|
|
1186
|
+
"Updated ",
|
|
1187
|
+
fromNow(updatedAt)
|
|
1188
|
+
]
|
|
1189
|
+
}
|
|
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
|
+
)
|
|
1136
1206
|
] }) })
|
|
1137
1207
|
]
|
|
1138
1208
|
}
|