feat: hide public link option based on permission

This commit is contained in:
CREDO23 2026-02-02 14:24:59 +02:00
parent 148daa23e1
commit a80dd25ee4

View file

@ -3,10 +3,11 @@
import { useQueryClient } from "@tanstack/react-query"; import { useQueryClient } from "@tanstack/react-query";
import { useAtomValue, useSetAtom } from "jotai"; import { useAtomValue, useSetAtom } from "jotai";
import { Globe, User, Users } from "lucide-react"; import { Globe, User, Users } from "lucide-react";
import { useCallback, useState } from "react"; import { useCallback, useMemo, useState } from "react";
import { toast } from "sonner"; import { toast } from "sonner";
import { createSnapshotMutationAtom } from "@/atoms/chat/chat-thread-mutation.atoms"; import { createSnapshotMutationAtom } from "@/atoms/chat/chat-thread-mutation.atoms";
import { currentThreadAtom, setThreadVisibilityAtom } from "@/atoms/chat/current-thread.atom"; import { currentThreadAtom, setThreadVisibilityAtom } from "@/atoms/chat/current-thread.atom";
import { myAccessAtom } from "@/atoms/members/members-query.atoms";
import { Button } from "@/components/ui/button"; import { Button } from "@/components/ui/button";
import { Popover, PopoverContent, PopoverTrigger } from "@/components/ui/popover"; import { Popover, PopoverContent, PopoverTrigger } from "@/components/ui/popover";
import { Tooltip, TooltipContent, TooltipTrigger } from "@/components/ui/tooltip"; import { Tooltip, TooltipContent, TooltipTrigger } from "@/components/ui/tooltip";
@ -56,6 +57,14 @@ export function ChatShareButton({ thread, onVisibilityChange, className }: ChatS
createSnapshotMutationAtom createSnapshotMutationAtom
); );
// Permission check for public sharing
const { data: access } = useAtomValue(myAccessAtom);
const canCreatePublicLink = useMemo(() => {
if (!access) return false;
if (access.is_owner) return true;
return access.permissions?.includes("public_sharing:create") ?? false;
}, [access]);
// Use Jotai visibility if available (synced from chat page), otherwise fall back to thread prop // Use Jotai visibility if available (synced from chat page), otherwise fall back to thread prop
const currentVisibility = currentThreadState.visibility ?? thread?.visibility ?? "PRIVATE"; const currentVisibility = currentThreadState.visibility ?? thread?.visibility ?? "PRIVATE";
@ -183,35 +192,39 @@ export function ChatShareButton({ thread, onVisibilityChange, className }: ChatS
); );
})} })}
{/* Divider */} {canCreatePublicLink && (
<div className="border-t border-border my-1" /> <>
{/* Divider */}
<div className="border-t border-border my-1" />
{/* Public Link Option */} {/* Public Link Option */}
<button <button
type="button" type="button"
onClick={handleCreatePublicLink} onClick={handleCreatePublicLink}
disabled={isCreatingSnapshot} disabled={isCreatingSnapshot}
className={cn( className={cn(
"w-full flex items-center gap-2.5 px-2.5 py-2 rounded-md transition-all", "w-full flex items-center gap-2.5 px-2.5 py-2 rounded-md transition-all",
"hover:bg-accent/50 cursor-pointer", "hover:bg-accent/50 cursor-pointer",
"focus:outline-none", "focus:outline-none",
"disabled:opacity-50 disabled:cursor-not-allowed" "disabled:opacity-50 disabled:cursor-not-allowed"
)} )}
> >
<div className="size-7 rounded-md shrink-0 grid place-items-center bg-muted"> <div className="size-7 rounded-md shrink-0 grid place-items-center bg-muted">
<Globe className="size-4 block text-muted-foreground" /> <Globe className="size-4 block text-muted-foreground" />
</div> </div>
<div className="flex-1 text-left min-w-0"> <div className="flex-1 text-left min-w-0">
<div className="flex items-center gap-1.5"> <div className="flex items-center gap-1.5">
<span className="text-sm font-medium"> <span className="text-sm font-medium">
{isCreatingSnapshot ? "Creating link..." : "Create public link"} {isCreatingSnapshot ? "Creating link..." : "Create public link"}
</span> </span>
</div> </div>
<p className="text-xs text-muted-foreground mt-0.5 leading-snug"> <p className="text-xs text-muted-foreground mt-0.5 leading-snug">
Creates a shareable snapshot of this chat Creates a shareable snapshot of this chat
</p> </p>
</div> </div>
</button> </button>
</>
)}
</div> </div>
</PopoverContent> </PopoverContent>
</Popover> </Popover>