mirror of
https://github.com/MODSetter/SurfSense.git
synced 2026-07-10 22:32:16 +02:00
feat: enhance chat sidebar functionality and UI
- Updated `LayoutDataProvider` to toggle sidebar states for shared and private chats more efficiently. - Added new props to `MobileSidebar`, `Sidebar`, and `LayoutShell` to manage the open states of chat panels. - Improved button interactions in the sidebar to show/hide chat panels with updated tooltip text. - Enhanced styling for tab triggers in `AllPrivateChatsSidebar` and `AllSharedChatsSidebar` for better user experience. - Added new localization strings for "show all" and "hide" actions in multiple languages.
This commit is contained in:
parent
54156633ff
commit
651d381bcb
12 changed files with 94 additions and 98 deletions
|
|
@ -628,17 +628,25 @@ export function LayoutDataProvider({ searchSpaceId, children }: LayoutDataProvid
|
||||||
}, [router]);
|
}, [router]);
|
||||||
|
|
||||||
const handleViewAllSharedChats = useCallback(() => {
|
const handleViewAllSharedChats = useCallback(() => {
|
||||||
setIsAllSharedChatsSidebarOpen(true);
|
setIsAllSharedChatsSidebarOpen((prev) => {
|
||||||
setIsAllPrivateChatsSidebarOpen(false);
|
if (!prev) {
|
||||||
setIsInboxSidebarOpen(false);
|
setIsAllPrivateChatsSidebarOpen(false);
|
||||||
setIsAnnouncementsSidebarOpen(false);
|
setIsInboxSidebarOpen(false);
|
||||||
|
setIsAnnouncementsSidebarOpen(false);
|
||||||
|
}
|
||||||
|
return !prev;
|
||||||
|
});
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
const handleViewAllPrivateChats = useCallback(() => {
|
const handleViewAllPrivateChats = useCallback(() => {
|
||||||
setIsAllPrivateChatsSidebarOpen(true);
|
setIsAllPrivateChatsSidebarOpen((prev) => {
|
||||||
setIsAllSharedChatsSidebarOpen(false);
|
if (!prev) {
|
||||||
setIsInboxSidebarOpen(false);
|
setIsAllSharedChatsSidebarOpen(false);
|
||||||
setIsAnnouncementsSidebarOpen(false);
|
setIsInboxSidebarOpen(false);
|
||||||
|
setIsAnnouncementsSidebarOpen(false);
|
||||||
|
}
|
||||||
|
return !prev;
|
||||||
|
});
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
// Delete handlers
|
// Delete handlers
|
||||||
|
|
|
||||||
|
|
@ -187,6 +187,8 @@ export function LayoutShell({
|
||||||
onChatArchive={onChatArchive}
|
onChatArchive={onChatArchive}
|
||||||
onViewAllSharedChats={onViewAllSharedChats}
|
onViewAllSharedChats={onViewAllSharedChats}
|
||||||
onViewAllPrivateChats={onViewAllPrivateChats}
|
onViewAllPrivateChats={onViewAllPrivateChats}
|
||||||
|
isSharedChatsPanelOpen={allSharedChatsPanel?.open}
|
||||||
|
isPrivateChatsPanelOpen={allPrivateChatsPanel?.open}
|
||||||
user={user}
|
user={user}
|
||||||
onSettings={onSettings}
|
onSettings={onSettings}
|
||||||
onManageMembers={onManageMembers}
|
onManageMembers={onManageMembers}
|
||||||
|
|
@ -305,6 +307,8 @@ export function LayoutShell({
|
||||||
onChatArchive={onChatArchive}
|
onChatArchive={onChatArchive}
|
||||||
onViewAllSharedChats={onViewAllSharedChats}
|
onViewAllSharedChats={onViewAllSharedChats}
|
||||||
onViewAllPrivateChats={onViewAllPrivateChats}
|
onViewAllPrivateChats={onViewAllPrivateChats}
|
||||||
|
isSharedChatsPanelOpen={allSharedChatsPanel?.open}
|
||||||
|
isPrivateChatsPanelOpen={allPrivateChatsPanel?.open}
|
||||||
user={user}
|
user={user}
|
||||||
onSettings={onSettings}
|
onSettings={onSettings}
|
||||||
onManageMembers={onManageMembers}
|
onManageMembers={onManageMembers}
|
||||||
|
|
|
||||||
|
|
@ -305,9 +305,9 @@ export function AllPrivateChatsSidebar({
|
||||||
<TabsList className="w-full h-auto p-0 bg-transparent rounded-none border-b">
|
<TabsList className="w-full h-auto p-0 bg-transparent rounded-none border-b">
|
||||||
<TabsTrigger
|
<TabsTrigger
|
||||||
value="active"
|
value="active"
|
||||||
className="flex-1 rounded-none border-b-2 border-transparent px-1 py-2 text-xs font-medium data-[state=active]:border-primary data-[state=active]:bg-transparent data-[state=active]:shadow-none"
|
className="group/tab flex-1 rounded-none border-b-2 border-transparent px-1 py-2 text-xs font-medium data-[state=active]:border-primary data-[state=active]:bg-transparent data-[state=active]:shadow-none"
|
||||||
>
|
>
|
||||||
<span className="w-full inline-flex items-center justify-center gap-1.5 px-3 py-1.5 rounded-lg hover:bg-muted transition-colors">
|
<span className="w-full inline-flex items-center justify-center gap-1.5 px-3 py-1.5 rounded-lg hover:bg-muted group-data-[state=active]/tab:bg-muted transition-colors">
|
||||||
<MessageCircleMore className="h-4 w-4" />
|
<MessageCircleMore className="h-4 w-4" />
|
||||||
<span>Active</span>
|
<span>Active</span>
|
||||||
<span className="inline-flex items-center justify-center min-w-5 h-5 px-1.5 rounded-full bg-primary/20 text-muted-foreground text-xs font-medium">
|
<span className="inline-flex items-center justify-center min-w-5 h-5 px-1.5 rounded-full bg-primary/20 text-muted-foreground text-xs font-medium">
|
||||||
|
|
@ -317,9 +317,9 @@ export function AllPrivateChatsSidebar({
|
||||||
</TabsTrigger>
|
</TabsTrigger>
|
||||||
<TabsTrigger
|
<TabsTrigger
|
||||||
value="archived"
|
value="archived"
|
||||||
className="flex-1 rounded-none border-b-2 border-transparent px-1 py-2 text-xs font-medium data-[state=active]:border-primary data-[state=active]:bg-transparent data-[state=active]:shadow-none"
|
className="group/tab flex-1 rounded-none border-b-2 border-transparent px-1 py-2 text-xs font-medium data-[state=active]:border-primary data-[state=active]:bg-transparent data-[state=active]:shadow-none"
|
||||||
>
|
>
|
||||||
<span className="w-full inline-flex items-center justify-center gap-1.5 px-3 py-1.5 rounded-lg hover:bg-muted transition-colors">
|
<span className="w-full inline-flex items-center justify-center gap-1.5 px-3 py-1.5 rounded-lg hover:bg-muted group-data-[state=active]/tab:bg-muted transition-colors">
|
||||||
<ArchiveIcon className="h-4 w-4" />
|
<ArchiveIcon className="h-4 w-4" />
|
||||||
<span>Archived</span>
|
<span>Archived</span>
|
||||||
<span className="inline-flex items-center justify-center min-w-5 h-5 px-1.5 rounded-full bg-primary/20 text-muted-foreground text-xs font-medium">
|
<span className="inline-flex items-center justify-center min-w-5 h-5 px-1.5 rounded-full bg-primary/20 text-muted-foreground text-xs font-medium">
|
||||||
|
|
@ -334,8 +334,8 @@ export function AllPrivateChatsSidebar({
|
||||||
<div className="flex-1 overflow-y-auto overflow-x-hidden p-2">
|
<div className="flex-1 overflow-y-auto overflow-x-hidden p-2">
|
||||||
{isLoading ? (
|
{isLoading ? (
|
||||||
<div className="space-y-1">
|
<div className="space-y-1">
|
||||||
{[75, 90, 55, 80, 65, 85].map((titleWidth, i) => (
|
{[75, 90, 55, 80, 65, 85].map((titleWidth) => (
|
||||||
<div key={`skeleton-${i}`} className="flex items-center gap-2 rounded-md px-2 py-1.5">
|
<div key={`skeleton-${titleWidth}`} className="flex items-center gap-2 rounded-md px-2 py-1.5">
|
||||||
<Skeleton className="h-4 w-4 shrink-0 rounded" />
|
<Skeleton className="h-4 w-4 shrink-0 rounded" />
|
||||||
<Skeleton className="h-4 rounded" style={{ width: `${titleWidth}%` }} />
|
<Skeleton className="h-4 rounded" style={{ width: `${titleWidth}%` }} />
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
|
|
@ -305,9 +305,9 @@ export function AllSharedChatsSidebar({
|
||||||
<TabsList className="w-full h-auto p-0 bg-transparent rounded-none border-b">
|
<TabsList className="w-full h-auto p-0 bg-transparent rounded-none border-b">
|
||||||
<TabsTrigger
|
<TabsTrigger
|
||||||
value="active"
|
value="active"
|
||||||
className="flex-1 rounded-none border-b-2 border-transparent px-1 py-2 text-xs font-medium data-[state=active]:border-primary data-[state=active]:bg-transparent data-[state=active]:shadow-none"
|
className="group/tab flex-1 rounded-none border-b-2 border-transparent px-1 py-2 text-xs font-medium data-[state=active]:border-primary data-[state=active]:bg-transparent data-[state=active]:shadow-none"
|
||||||
>
|
>
|
||||||
<span className="w-full inline-flex items-center justify-center gap-1.5 px-3 py-1.5 rounded-lg hover:bg-muted transition-colors">
|
<span className="w-full inline-flex items-center justify-center gap-1.5 px-3 py-1.5 rounded-lg hover:bg-muted group-data-[state=active]/tab:bg-muted transition-colors">
|
||||||
<MessageCircleMore className="h-4 w-4" />
|
<MessageCircleMore className="h-4 w-4" />
|
||||||
<span>Active</span>
|
<span>Active</span>
|
||||||
<span className="inline-flex items-center justify-center min-w-5 h-5 px-1.5 rounded-full bg-primary/20 text-muted-foreground text-xs font-medium">
|
<span className="inline-flex items-center justify-center min-w-5 h-5 px-1.5 rounded-full bg-primary/20 text-muted-foreground text-xs font-medium">
|
||||||
|
|
@ -317,9 +317,9 @@ export function AllSharedChatsSidebar({
|
||||||
</TabsTrigger>
|
</TabsTrigger>
|
||||||
<TabsTrigger
|
<TabsTrigger
|
||||||
value="archived"
|
value="archived"
|
||||||
className="flex-1 rounded-none border-b-2 border-transparent px-1 py-2 text-xs font-medium data-[state=active]:border-primary data-[state=active]:bg-transparent data-[state=active]:shadow-none"
|
className="group/tab flex-1 rounded-none border-b-2 border-transparent px-1 py-2 text-xs font-medium data-[state=active]:border-primary data-[state=active]:bg-transparent data-[state=active]:shadow-none"
|
||||||
>
|
>
|
||||||
<span className="w-full inline-flex items-center justify-center gap-1.5 px-3 py-1.5 rounded-lg hover:bg-muted transition-colors">
|
<span className="w-full inline-flex items-center justify-center gap-1.5 px-3 py-1.5 rounded-lg hover:bg-muted group-data-[state=active]/tab:bg-muted transition-colors">
|
||||||
<ArchiveIcon className="h-4 w-4" />
|
<ArchiveIcon className="h-4 w-4" />
|
||||||
<span>Archived</span>
|
<span>Archived</span>
|
||||||
<span className="inline-flex items-center justify-center min-w-5 h-5 px-1.5 rounded-full bg-primary/20 text-muted-foreground text-xs font-medium">
|
<span className="inline-flex items-center justify-center min-w-5 h-5 px-1.5 rounded-full bg-primary/20 text-muted-foreground text-xs font-medium">
|
||||||
|
|
@ -334,8 +334,8 @@ export function AllSharedChatsSidebar({
|
||||||
<div className="flex-1 overflow-y-auto overflow-x-hidden p-2">
|
<div className="flex-1 overflow-y-auto overflow-x-hidden p-2">
|
||||||
{isLoading ? (
|
{isLoading ? (
|
||||||
<div className="space-y-1">
|
<div className="space-y-1">
|
||||||
{[75, 90, 55, 80, 65, 85].map((titleWidth, i) => (
|
{[75, 90, 55, 80, 65, 85].map((titleWidth) => (
|
||||||
<div key={`skeleton-${i}`} className="flex items-center gap-2 rounded-md px-2 py-1.5">
|
<div key={`skeleton-${titleWidth}`} className="flex items-center gap-2 rounded-md px-2 py-1.5">
|
||||||
<Skeleton className="h-4 w-4 shrink-0 rounded" />
|
<Skeleton className="h-4 w-4 shrink-0 rounded" />
|
||||||
<Skeleton className="h-4 rounded" style={{ width: `${titleWidth}%` }} />
|
<Skeleton className="h-4 rounded" style={{ width: `${titleWidth}%` }} />
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
|
|
@ -14,8 +14,6 @@ interface MobileSidebarProps {
|
||||||
searchSpaces: SearchSpace[];
|
searchSpaces: SearchSpace[];
|
||||||
activeSearchSpaceId: number | null;
|
activeSearchSpaceId: number | null;
|
||||||
onSearchSpaceSelect: (id: number) => void;
|
onSearchSpaceSelect: (id: number) => void;
|
||||||
onSearchSpaceDelete?: (searchSpace: SearchSpace) => void;
|
|
||||||
onSearchSpaceSettings?: (searchSpace: SearchSpace) => void;
|
|
||||||
onAddSearchSpace: () => void;
|
onAddSearchSpace: () => void;
|
||||||
searchSpace: SearchSpace | null;
|
searchSpace: SearchSpace | null;
|
||||||
navItems: NavItem[];
|
navItems: NavItem[];
|
||||||
|
|
@ -30,6 +28,8 @@ interface MobileSidebarProps {
|
||||||
onChatArchive?: (chat: ChatItem) => void;
|
onChatArchive?: (chat: ChatItem) => void;
|
||||||
onViewAllSharedChats?: () => void;
|
onViewAllSharedChats?: () => void;
|
||||||
onViewAllPrivateChats?: () => void;
|
onViewAllPrivateChats?: () => void;
|
||||||
|
isSharedChatsPanelOpen?: boolean;
|
||||||
|
isPrivateChatsPanelOpen?: boolean;
|
||||||
user: User;
|
user: User;
|
||||||
onSettings?: () => void;
|
onSettings?: () => void;
|
||||||
onManageMembers?: () => void;
|
onManageMembers?: () => void;
|
||||||
|
|
@ -56,8 +56,7 @@ export function MobileSidebar({
|
||||||
searchSpaces,
|
searchSpaces,
|
||||||
activeSearchSpaceId,
|
activeSearchSpaceId,
|
||||||
onSearchSpaceSelect,
|
onSearchSpaceSelect,
|
||||||
onSearchSpaceDelete,
|
|
||||||
onSearchSpaceSettings,
|
|
||||||
onAddSearchSpace,
|
onAddSearchSpace,
|
||||||
searchSpace,
|
searchSpace,
|
||||||
navItems,
|
navItems,
|
||||||
|
|
@ -72,6 +71,8 @@ export function MobileSidebar({
|
||||||
onChatArchive,
|
onChatArchive,
|
||||||
onViewAllSharedChats,
|
onViewAllSharedChats,
|
||||||
onViewAllPrivateChats,
|
onViewAllPrivateChats,
|
||||||
|
isSharedChatsPanelOpen = false,
|
||||||
|
isPrivateChatsPanelOpen = false,
|
||||||
user,
|
user,
|
||||||
onSettings,
|
onSettings,
|
||||||
onManageMembers,
|
onManageMembers,
|
||||||
|
|
@ -165,6 +166,8 @@ export function MobileSidebar({
|
||||||
}
|
}
|
||||||
: undefined
|
: undefined
|
||||||
}
|
}
|
||||||
|
isSharedChatsPanelOpen={isSharedChatsPanelOpen}
|
||||||
|
isPrivateChatsPanelOpen={isPrivateChatsPanelOpen}
|
||||||
user={user}
|
user={user}
|
||||||
onSettings={
|
onSettings={
|
||||||
onSettings
|
onSettings
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
"use client";
|
"use client";
|
||||||
|
|
||||||
import { FolderOpen, PenSquare } from "lucide-react";
|
import { PenSquare } from "lucide-react";
|
||||||
import { useTranslations } from "next-intl";
|
import { useTranslations } from "next-intl";
|
||||||
import { useState } from "react";
|
import { useState } from "react";
|
||||||
import { Button } from "@/components/ui/button";
|
import { Button } from "@/components/ui/button";
|
||||||
|
|
@ -42,6 +42,8 @@ interface SidebarProps {
|
||||||
onChatArchive?: (chat: ChatItem) => void;
|
onChatArchive?: (chat: ChatItem) => void;
|
||||||
onViewAllSharedChats?: () => void;
|
onViewAllSharedChats?: () => void;
|
||||||
onViewAllPrivateChats?: () => void;
|
onViewAllPrivateChats?: () => void;
|
||||||
|
isSharedChatsPanelOpen?: boolean;
|
||||||
|
isPrivateChatsPanelOpen?: boolean;
|
||||||
user: User;
|
user: User;
|
||||||
onSettings?: () => void;
|
onSettings?: () => void;
|
||||||
onManageMembers?: () => void;
|
onManageMembers?: () => void;
|
||||||
|
|
@ -73,6 +75,8 @@ export function Sidebar({
|
||||||
onChatArchive,
|
onChatArchive,
|
||||||
onViewAllSharedChats,
|
onViewAllSharedChats,
|
||||||
onViewAllPrivateChats,
|
onViewAllPrivateChats,
|
||||||
|
isSharedChatsPanelOpen = false,
|
||||||
|
isPrivateChatsPanelOpen = false,
|
||||||
user,
|
user,
|
||||||
onSettings,
|
onSettings,
|
||||||
onManageMembers,
|
onManageMembers,
|
||||||
|
|
@ -158,34 +162,16 @@ export function Sidebar({
|
||||||
defaultOpen={true}
|
defaultOpen={true}
|
||||||
fillHeight={false}
|
fillHeight={false}
|
||||||
className="shrink-0 max-h-[50%] flex flex-col"
|
className="shrink-0 max-h-[50%] flex flex-col"
|
||||||
|
alwaysShowAction={!disableTooltips && isSharedChatsPanelOpen}
|
||||||
action={
|
action={
|
||||||
onViewAllSharedChats ? (
|
onViewAllSharedChats ? (
|
||||||
disableTooltips ? (
|
<button
|
||||||
<Button
|
type="button"
|
||||||
variant="ghost"
|
onClick={onViewAllSharedChats}
|
||||||
size="icon"
|
className="text-[10px] text-muted-foreground/70 hover:text-muted-foreground transition-colors whitespace-nowrap cursor-pointer bg-transparent border-none p-0"
|
||||||
className="h-8 w-8 shrink-0 hover:bg-transparent hover:text-current focus-visible:ring-0"
|
>
|
||||||
onClick={onViewAllSharedChats}
|
{!disableTooltips && isSharedChatsPanelOpen ? t("hide") : t("show_all")}
|
||||||
>
|
</button>
|
||||||
<FolderOpen className="h-4 w-4" />
|
|
||||||
</Button>
|
|
||||||
) : (
|
|
||||||
<Tooltip>
|
|
||||||
<TooltipTrigger asChild>
|
|
||||||
<Button
|
|
||||||
variant="ghost"
|
|
||||||
size="icon"
|
|
||||||
className="h-8 w-8 shrink-0 hover:bg-transparent hover:text-current focus-visible:ring-0"
|
|
||||||
onClick={onViewAllSharedChats}
|
|
||||||
>
|
|
||||||
<FolderOpen className="h-4 w-4" />
|
|
||||||
</Button>
|
|
||||||
</TooltipTrigger>
|
|
||||||
<TooltipContent side="top">
|
|
||||||
{t("view_all_shared_chats") || "View all shared chats"}
|
|
||||||
</TooltipContent>
|
|
||||||
</Tooltip>
|
|
||||||
)
|
|
||||||
) : undefined
|
) : undefined
|
||||||
}
|
}
|
||||||
>
|
>
|
||||||
|
|
@ -232,34 +218,16 @@ export function Sidebar({
|
||||||
title={t("chats")}
|
title={t("chats")}
|
||||||
defaultOpen={true}
|
defaultOpen={true}
|
||||||
fillHeight={true}
|
fillHeight={true}
|
||||||
|
alwaysShowAction={!disableTooltips && isPrivateChatsPanelOpen}
|
||||||
action={
|
action={
|
||||||
onViewAllPrivateChats ? (
|
onViewAllPrivateChats ? (
|
||||||
disableTooltips ? (
|
<button
|
||||||
<Button
|
type="button"
|
||||||
variant="ghost"
|
onClick={onViewAllPrivateChats}
|
||||||
size="icon"
|
className="text-[10px] text-muted-foreground/70 hover:text-muted-foreground transition-colors whitespace-nowrap cursor-pointer bg-transparent border-none p-0"
|
||||||
className="h-8 w-8 shrink-0 hover:bg-transparent hover:text-current focus-visible:ring-0"
|
>
|
||||||
onClick={onViewAllPrivateChats}
|
{!disableTooltips && isPrivateChatsPanelOpen ? t("hide") : t("show_all")}
|
||||||
>
|
</button>
|
||||||
<FolderOpen className="h-4 w-4" />
|
|
||||||
</Button>
|
|
||||||
) : (
|
|
||||||
<Tooltip>
|
|
||||||
<TooltipTrigger asChild>
|
|
||||||
<Button
|
|
||||||
variant="ghost"
|
|
||||||
size="icon"
|
|
||||||
className="h-8 w-8 shrink-0 hover:bg-transparent hover:text-current focus-visible:ring-0"
|
|
||||||
onClick={onViewAllPrivateChats}
|
|
||||||
>
|
|
||||||
<FolderOpen className="h-4 w-4" />
|
|
||||||
</Button>
|
|
||||||
</TooltipTrigger>
|
|
||||||
<TooltipContent side="top">
|
|
||||||
{t("view_all_private_chats") || "View all private chats"}
|
|
||||||
</TooltipContent>
|
|
||||||
</Tooltip>
|
|
||||||
)
|
|
||||||
) : undefined
|
) : undefined
|
||||||
}
|
}
|
||||||
>
|
>
|
||||||
|
|
|
||||||
|
|
@ -10,6 +10,7 @@ interface SidebarSectionProps {
|
||||||
defaultOpen?: boolean;
|
defaultOpen?: boolean;
|
||||||
children: React.ReactNode;
|
children: React.ReactNode;
|
||||||
action?: React.ReactNode;
|
action?: React.ReactNode;
|
||||||
|
alwaysShowAction?: boolean;
|
||||||
persistentAction?: React.ReactNode;
|
persistentAction?: React.ReactNode;
|
||||||
className?: string;
|
className?: string;
|
||||||
fillHeight?: boolean;
|
fillHeight?: boolean;
|
||||||
|
|
@ -20,6 +21,7 @@ export function SidebarSection({
|
||||||
defaultOpen = true,
|
defaultOpen = true,
|
||||||
children,
|
children,
|
||||||
action,
|
action,
|
||||||
|
alwaysShowAction = false,
|
||||||
persistentAction,
|
persistentAction,
|
||||||
className,
|
className,
|
||||||
fillHeight = false,
|
fillHeight = false,
|
||||||
|
|
@ -37,29 +39,30 @@ export function SidebarSection({
|
||||||
className
|
className
|
||||||
)}
|
)}
|
||||||
>
|
>
|
||||||
<div className="flex items-center group/section shrink-0">
|
<div className="flex items-center group/section shrink-0 px-2 py-1.5">
|
||||||
<CollapsibleTrigger className="flex flex-1 items-center gap-1.5 px-2 py-1.5 text-xs font-medium text-muted-foreground hover:text-foreground transition-colors min-w-0">
|
<CollapsibleTrigger className="flex items-center gap-1.5 text-xs font-medium text-muted-foreground hover:text-foreground transition-colors min-w-0">
|
||||||
<ChevronRight
|
<span className="truncate">{title}</span>
|
||||||
className={cn(
|
<ChevronRight
|
||||||
"h-3.5 w-3.5 shrink-0 transition-transform duration-200",
|
className={cn(
|
||||||
isOpen && "rotate-90"
|
"h-3.5 w-3.5 shrink-0 transition-transform duration-200",
|
||||||
)}
|
isOpen && "rotate-90"
|
||||||
/>
|
)}
|
||||||
<span className="uppercase tracking-wider truncate">{title}</span>
|
/>
|
||||||
</CollapsibleTrigger>
|
</CollapsibleTrigger>
|
||||||
|
|
||||||
{/* Action button - visible on hover (always visible on mobile) */}
|
{action && (
|
||||||
{action && (
|
<div className={cn(
|
||||||
<div className="shrink-0 opacity-100 md:opacity-0 md:group-hover/section:opacity-100 transition-opacity pr-1 flex items-center">
|
"transition-opacity ml-1.5 flex items-center",
|
||||||
{action}
|
alwaysShowAction ? "opacity-100" : "opacity-100 md:opacity-0 md:group-hover/section:opacity-100"
|
||||||
</div>
|
)}>
|
||||||
)}
|
{action}
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
|
||||||
{/* Persistent action - always visible */}
|
{persistentAction && (
|
||||||
{persistentAction && (
|
<div className="shrink-0 ml-auto flex items-center">{persistentAction}</div>
|
||||||
<div className="shrink-0 pr-1 flex items-center">{persistentAction}</div>
|
)}
|
||||||
)}
|
</div>
|
||||||
</div>
|
|
||||||
|
|
||||||
<CollapsibleContent className={cn("overflow-hidden flex-1 flex flex-col min-h-0")}>
|
<CollapsibleContent className={cn("overflow-hidden flex-1 flex flex-col min-h-0")}>
|
||||||
<div className={cn("px-2 pb-2 flex-1 flex flex-col min-h-0 overflow-hidden")}>
|
<div className={cn("px-2 pb-2 flex-1 flex flex-col min-h-0 overflow-hidden")}>
|
||||||
|
|
|
||||||
|
|
@ -655,6 +655,8 @@
|
||||||
"no_shared_chats": "No shared chats",
|
"no_shared_chats": "No shared chats",
|
||||||
"view_all_shared_chats": "View all shared chats",
|
"view_all_shared_chats": "View all shared chats",
|
||||||
"view_all_private_chats": "View all private chats",
|
"view_all_private_chats": "View all private chats",
|
||||||
|
"show_all": "Show all",
|
||||||
|
"hide": "Hide",
|
||||||
"no_chats": "No chats yet",
|
"no_chats": "No chats yet",
|
||||||
"start_new_chat_hint": "Start a new chat",
|
"start_new_chat_hint": "Start a new chat",
|
||||||
"error_loading_chats": "Error loading chats",
|
"error_loading_chats": "Error loading chats",
|
||||||
|
|
|
||||||
|
|
@ -655,6 +655,8 @@
|
||||||
"no_shared_chats": "No hay chats compartidos",
|
"no_shared_chats": "No hay chats compartidos",
|
||||||
"view_all_shared_chats": "Ver todos los chats compartidos",
|
"view_all_shared_chats": "Ver todos los chats compartidos",
|
||||||
"view_all_private_chats": "Ver todos los chats privados",
|
"view_all_private_chats": "Ver todos los chats privados",
|
||||||
|
"show_all": "Ver todo",
|
||||||
|
"hide": "Ocultar",
|
||||||
"no_chats": "Aún no hay chats",
|
"no_chats": "Aún no hay chats",
|
||||||
"start_new_chat_hint": "Iniciar un nuevo chat",
|
"start_new_chat_hint": "Iniciar un nuevo chat",
|
||||||
"error_loading_chats": "Error al cargar chats",
|
"error_loading_chats": "Error al cargar chats",
|
||||||
|
|
|
||||||
|
|
@ -655,6 +655,8 @@
|
||||||
"no_shared_chats": "कोई साझा चैट नहीं",
|
"no_shared_chats": "कोई साझा चैट नहीं",
|
||||||
"view_all_shared_chats": "सभी साझा चैट देखें",
|
"view_all_shared_chats": "सभी साझा चैट देखें",
|
||||||
"view_all_private_chats": "सभी निजी चैट देखें",
|
"view_all_private_chats": "सभी निजी चैट देखें",
|
||||||
|
"show_all": "सभी देखें",
|
||||||
|
"hide": "छिपाएँ",
|
||||||
"no_chats": "अभी तक कोई चैट नहीं",
|
"no_chats": "अभी तक कोई चैट नहीं",
|
||||||
"start_new_chat_hint": "नई चैट शुरू करें",
|
"start_new_chat_hint": "नई चैट शुरू करें",
|
||||||
"error_loading_chats": "चैट लोड करने में त्रुटि",
|
"error_loading_chats": "चैट लोड करने में त्रुटि",
|
||||||
|
|
|
||||||
|
|
@ -655,6 +655,8 @@
|
||||||
"no_shared_chats": "Nenhum chat compartilhado",
|
"no_shared_chats": "Nenhum chat compartilhado",
|
||||||
"view_all_shared_chats": "Ver todos os chats compartilhados",
|
"view_all_shared_chats": "Ver todos os chats compartilhados",
|
||||||
"view_all_private_chats": "Ver todos os chats privados",
|
"view_all_private_chats": "Ver todos os chats privados",
|
||||||
|
"show_all": "Ver tudo",
|
||||||
|
"hide": "Ocultar",
|
||||||
"no_chats": "Nenhum chat ainda",
|
"no_chats": "Nenhum chat ainda",
|
||||||
"start_new_chat_hint": "Iniciar um novo chat",
|
"start_new_chat_hint": "Iniciar um novo chat",
|
||||||
"error_loading_chats": "Erro ao carregar chats",
|
"error_loading_chats": "Erro ao carregar chats",
|
||||||
|
|
|
||||||
|
|
@ -639,6 +639,8 @@
|
||||||
"no_shared_chats": "暂无共享对话",
|
"no_shared_chats": "暂无共享对话",
|
||||||
"view_all_shared_chats": "查看所有共享对话",
|
"view_all_shared_chats": "查看所有共享对话",
|
||||||
"view_all_private_chats": "查看所有私人对话",
|
"view_all_private_chats": "查看所有私人对话",
|
||||||
|
"show_all": "查看全部",
|
||||||
|
"hide": "隐藏",
|
||||||
"no_chats": "暂无对话",
|
"no_chats": "暂无对话",
|
||||||
"start_new_chat_hint": "开始新对话",
|
"start_new_chat_hint": "开始新对话",
|
||||||
"error_loading_chats": "加载对话时出错",
|
"error_loading_chats": "加载对话时出错",
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue