mirror of
https://github.com/MODSetter/SurfSense.git
synced 2026-05-31 19:45:15 +02:00
refactor: update icon usage in CommentActions and enhance Tooltip component for mobile responsiveness
This commit is contained in:
parent
1f162f52c3
commit
c9e5fe9cdb
6 changed files with 113 additions and 138 deletions
|
|
@ -1,6 +1,6 @@
|
||||||
"use client";
|
"use client";
|
||||||
|
|
||||||
import { MoreHorizontal, Pencil, Trash2 } from "lucide-react";
|
import { MoreHorizontal, PenLine, Trash2 } from "lucide-react";
|
||||||
import { Button } from "@/components/ui/button";
|
import { Button } from "@/components/ui/button";
|
||||||
import {
|
import {
|
||||||
DropdownMenu,
|
DropdownMenu,
|
||||||
|
|
@ -29,7 +29,7 @@ export function CommentActions({ canEdit, canDelete, onEdit, onDelete }: Comment
|
||||||
<DropdownMenuContent align="end">
|
<DropdownMenuContent align="end">
|
||||||
{canEdit && (
|
{canEdit && (
|
||||||
<DropdownMenuItem onClick={onEdit}>
|
<DropdownMenuItem onClick={onEdit}>
|
||||||
<Pencil className="mr-2 size-4" />
|
<PenLine className="mr-2 size-4" />
|
||||||
Edit
|
Edit
|
||||||
</DropdownMenuItem>
|
</DropdownMenuItem>
|
||||||
)}
|
)}
|
||||||
|
|
|
||||||
|
|
@ -12,7 +12,6 @@ import {
|
||||||
Trash2,
|
Trash2,
|
||||||
} from "lucide-react";
|
} from "lucide-react";
|
||||||
import React, { useCallback, useRef, useState } from "react";
|
import React, { useCallback, useRef, useState } from "react";
|
||||||
import { useIsMobile } from "@/hooks/use-mobile";
|
|
||||||
import { useDrag } from "react-dnd";
|
import { useDrag } from "react-dnd";
|
||||||
import { getDocumentTypeIcon } from "@/app/dashboard/[search_space_id]/documents/(manage)/components/DocumentTypeIcon";
|
import { getDocumentTypeIcon } from "@/app/dashboard/[search_space_id]/documents/(manage)/components/DocumentTypeIcon";
|
||||||
import { ExportContextItems, ExportDropdownItems } from "@/components/shared/ExportMenuItems";
|
import { ExportContextItems, ExportDropdownItems } from "@/components/shared/ExportMenuItems";
|
||||||
|
|
@ -110,7 +109,6 @@ export const DocumentNode = React.memo(function DocumentNode({
|
||||||
const [titleTooltipOpen, setTitleTooltipOpen] = useState(false);
|
const [titleTooltipOpen, setTitleTooltipOpen] = useState(false);
|
||||||
const rowRef = useRef<HTMLDivElement>(null);
|
const rowRef = useRef<HTMLDivElement>(null);
|
||||||
const titleRef = useRef<HTMLSpanElement>(null);
|
const titleRef = useRef<HTMLSpanElement>(null);
|
||||||
const isMobile = useIsMobile();
|
|
||||||
|
|
||||||
const handleExport = useCallback(
|
const handleExport = useCallback(
|
||||||
(format: string) => {
|
(format: string) => {
|
||||||
|
|
@ -122,17 +120,13 @@ export const DocumentNode = React.memo(function DocumentNode({
|
||||||
[doc, onExport]
|
[doc, onExport]
|
||||||
);
|
);
|
||||||
|
|
||||||
const handleTitleTooltipOpenChange = useCallback(
|
const handleTitleTooltipOpenChange = useCallback((open: boolean) => {
|
||||||
(open: boolean) => {
|
|
||||||
if (isMobile) return;
|
|
||||||
if (open && titleRef.current) {
|
if (open && titleRef.current) {
|
||||||
setTitleTooltipOpen(titleRef.current.scrollWidth > titleRef.current.clientWidth);
|
setTitleTooltipOpen(titleRef.current.scrollWidth > titleRef.current.clientWidth);
|
||||||
} else {
|
} else {
|
||||||
setTitleTooltipOpen(false);
|
setTitleTooltipOpen(false);
|
||||||
}
|
}
|
||||||
},
|
}, []);
|
||||||
[isMobile]
|
|
||||||
);
|
|
||||||
|
|
||||||
const attachRef = useCallback(
|
const attachRef = useCallback(
|
||||||
(node: HTMLDivElement | null) => {
|
(node: HTMLDivElement | null) => {
|
||||||
|
|
|
||||||
|
|
@ -375,7 +375,7 @@ export function AllPrivateChatsSidebarContent({
|
||||||
<span className="truncate">{thread.title || "New Chat"}</span>
|
<span className="truncate">{thread.title || "New Chat"}</span>
|
||||||
</button>
|
</button>
|
||||||
) : (
|
) : (
|
||||||
<Tooltip>
|
<Tooltip delayDuration={600}>
|
||||||
<TooltipTrigger asChild>
|
<TooltipTrigger asChild>
|
||||||
<button
|
<button
|
||||||
type="button"
|
type="button"
|
||||||
|
|
|
||||||
|
|
@ -375,7 +375,7 @@ export function AllSharedChatsSidebarContent({
|
||||||
<span className="truncate">{thread.title || "New Chat"}</span>
|
<span className="truncate">{thread.title || "New Chat"}</span>
|
||||||
</button>
|
</button>
|
||||||
) : (
|
) : (
|
||||||
<Tooltip>
|
<Tooltip delayDuration={600}>
|
||||||
<TooltipTrigger asChild>
|
<TooltipTrigger asChild>
|
||||||
<button
|
<button
|
||||||
type="button"
|
type="button"
|
||||||
|
|
|
||||||
|
|
@ -779,18 +779,6 @@ export function InboxSidebarContent({
|
||||||
</DropdownMenuContent>
|
</DropdownMenuContent>
|
||||||
</DropdownMenu>
|
</DropdownMenu>
|
||||||
)}
|
)}
|
||||||
{isMobile ? (
|
|
||||||
<Button
|
|
||||||
variant="ghost"
|
|
||||||
size="icon"
|
|
||||||
className="h-7 w-7 rounded-full"
|
|
||||||
onClick={handleMarkAllAsRead}
|
|
||||||
disabled={totalUnreadCount === 0}
|
|
||||||
>
|
|
||||||
<CheckCheck className="h-4 w-4 text-muted-foreground" />
|
|
||||||
<span className="sr-only">{t("mark_all_read") || "Mark all as read"}</span>
|
|
||||||
</Button>
|
|
||||||
) : (
|
|
||||||
<Tooltip>
|
<Tooltip>
|
||||||
<TooltipTrigger asChild>
|
<TooltipTrigger asChild>
|
||||||
<Button
|
<Button
|
||||||
|
|
@ -808,7 +796,6 @@ export function InboxSidebarContent({
|
||||||
{t("mark_all_read") || "Mark all as read"}
|
{t("mark_all_read") || "Mark all as read"}
|
||||||
</TooltipContent>
|
</TooltipContent>
|
||||||
</Tooltip>
|
</Tooltip>
|
||||||
)}
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
@ -921,7 +908,6 @@ export function InboxSidebarContent({
|
||||||
)}
|
)}
|
||||||
style={{ contentVisibility: "auto", containIntrinsicSize: "0 80px" }}
|
style={{ contentVisibility: "auto", containIntrinsicSize: "0 80px" }}
|
||||||
>
|
>
|
||||||
{isMobile ? (
|
|
||||||
<button
|
<button
|
||||||
type="button"
|
type="button"
|
||||||
onClick={() => handleItemClick(item)}
|
onClick={() => handleItemClick(item)}
|
||||||
|
|
@ -943,39 +929,6 @@ export function InboxSidebarContent({
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
</button>
|
</button>
|
||||||
) : (
|
|
||||||
<Tooltip>
|
|
||||||
<TooltipTrigger asChild>
|
|
||||||
<button
|
|
||||||
type="button"
|
|
||||||
onClick={() => handleItemClick(item)}
|
|
||||||
disabled={isMarkingAsRead}
|
|
||||||
className="flex items-center gap-3 flex-1 min-w-0 text-left overflow-hidden"
|
|
||||||
>
|
|
||||||
<div className="shrink-0">{getStatusIcon(item)}</div>
|
|
||||||
<div className="flex-1 min-w-0 overflow-hidden">
|
|
||||||
<p
|
|
||||||
className={cn(
|
|
||||||
"text-xs font-medium line-clamp-2",
|
|
||||||
!item.read && "font-semibold"
|
|
||||||
)}
|
|
||||||
>
|
|
||||||
{item.title}
|
|
||||||
</p>
|
|
||||||
<p className="text-[11px] text-muted-foreground line-clamp-2 mt-0.5">
|
|
||||||
{convertRenderedToDisplay(item.message)}
|
|
||||||
</p>
|
|
||||||
</div>
|
|
||||||
</button>
|
|
||||||
</TooltipTrigger>
|
|
||||||
<TooltipContent side="bottom" align="start" className="max-w-[250px]">
|
|
||||||
<p className="font-medium">{item.title}</p>
|
|
||||||
<p className="text-muted-foreground mt-1">
|
|
||||||
{convertRenderedToDisplay(item.message)}
|
|
||||||
</p>
|
|
||||||
</TooltipContent>
|
|
||||||
</Tooltip>
|
|
||||||
)}
|
|
||||||
|
|
||||||
<div className="flex items-center justify-end gap-1.5 shrink-0 w-10">
|
<div className="flex items-center justify-end gap-1.5 shrink-0 w-10">
|
||||||
<span className="text-[10px] text-muted-foreground">
|
<span className="text-[10px] text-muted-foreground">
|
||||||
|
|
|
||||||
|
|
@ -2,9 +2,26 @@
|
||||||
|
|
||||||
import * as TooltipPrimitive from "@radix-ui/react-tooltip";
|
import * as TooltipPrimitive from "@radix-ui/react-tooltip";
|
||||||
import type * as React from "react";
|
import type * as React from "react";
|
||||||
|
import { useEffect, useState } from "react";
|
||||||
|
|
||||||
import { cn } from "@/lib/utils";
|
import { cn } from "@/lib/utils";
|
||||||
|
|
||||||
|
const MOBILE_BREAKPOINT = 768;
|
||||||
|
|
||||||
|
function useIsTouchDevice() {
|
||||||
|
const [isTouch, setIsTouch] = useState(false);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
const mql = window.matchMedia(`(max-width: ${MOBILE_BREAKPOINT - 1}px)`);
|
||||||
|
const update = () => setIsTouch(mql.matches);
|
||||||
|
update();
|
||||||
|
mql.addEventListener("change", update);
|
||||||
|
return () => mql.removeEventListener("change", update);
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
return isTouch;
|
||||||
|
}
|
||||||
|
|
||||||
function TooltipProvider({
|
function TooltipProvider({
|
||||||
delayDuration = 0,
|
delayDuration = 0,
|
||||||
disableHoverableContent = true,
|
disableHoverableContent = true,
|
||||||
|
|
@ -20,10 +37,21 @@ function TooltipProvider({
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
function Tooltip({ ...props }: React.ComponentProps<typeof TooltipPrimitive.Root>) {
|
function Tooltip({
|
||||||
|
open,
|
||||||
|
onOpenChange,
|
||||||
|
...props
|
||||||
|
}: React.ComponentProps<typeof TooltipPrimitive.Root>) {
|
||||||
|
const isMobile = useIsTouchDevice();
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<TooltipProvider>
|
<TooltipProvider>
|
||||||
<TooltipPrimitive.Root data-slot="tooltip" {...props} />
|
<TooltipPrimitive.Root
|
||||||
|
data-slot="tooltip"
|
||||||
|
open={isMobile ? false : open}
|
||||||
|
onOpenChange={isMobile ? undefined : onOpenChange}
|
||||||
|
{...props}
|
||||||
|
/>
|
||||||
</TooltipProvider>
|
</TooltipProvider>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue