langfuse
120 строк · 3.0 Кб
1import { Switch } from "@/src/components/ui/switch";
2import { useHasAccess } from "@/src/features/rbac/utils/checkAccess";
3import { api } from "@/src/utils/api";
4import { Link, LockIcon } from "lucide-react";
5import { usePostHog } from "posthog-js/react";
6import { useState } from "react";
7
8export const PublishTraceSwitch = (props: {
9traceId: string;
10projectId: string;
11isPublic: boolean;
12}) => {
13const posthog = usePostHog();
14const hasAccess = useHasAccess({
15projectId: props.projectId,
16scope: "objects:publish",
17});
18const utils = api.useUtils();
19const mut = api.traces.publish.useMutation({
20onSuccess: () => utils.traces.invalidate(),
21});
22
23return (
24<Base
25id={props.traceId}
26isPublic={props.isPublic}
27onChange={(val) => {
28mut.mutate({
29projectId: props.projectId,
30traceId: props.traceId,
31public: val,
32});
33posthog.capture("trace_detail:publish_trace_button_click");
34}}
35isLoading={mut.isLoading}
36disabled={!hasAccess}
37/>
38);
39};
40
41export const PublishSessionSwitch = (props: {
42sessionId: string;
43projectId: string;
44isPublic: boolean;
45}) => {
46const posthog = usePostHog();
47const hasAccess = useHasAccess({
48projectId: props.projectId,
49scope: "objects:publish",
50});
51const utils = api.useUtils();
52const mut = api.sessions.publish.useMutation({
53onSuccess: () => utils.sessions.invalidate(),
54});
55
56return (
57<Base
58id={props.sessionId}
59isPublic={props.isPublic}
60onChange={(val) => {
61mut.mutate({
62projectId: props.projectId,
63sessionId: props.sessionId,
64public: val,
65});
66posthog.capture("session_detail:publish_session_button_click");
67}}
68isLoading={mut.isLoading}
69disabled={!hasAccess}
70/>
71);
72};
73
74const Base = (props: {
75id: string;
76onChange: (value: boolean) => void;
77isLoading: boolean;
78isPublic: boolean;
79disabled?: boolean;
80}) => {
81const [isCopied, setIsCopied] = useState(false);
82
83const copyUrl = () => {
84setIsCopied(true);
85void navigator.clipboard.writeText(window.location.href);
86setTimeout(() => setIsCopied(false), 1500);
87};
88
89return (
90<div className="flex items-center gap-3">
91<div className="text-sm font-semibold">
92{props.isLoading ? (
93"Loading.."
94) : props.isPublic ? (
95<div
96className="flex cursor-pointer items-center gap-1 text-green-800"
97onClick={() => copyUrl()}
98>
99{isCopied ? "Link copied ..." : "Public"}
100<Link size={16} />
101</div>
102) : (
103<div className="flex items-center gap-1">
104Private
105<LockIcon size={16} />
106</div>
107)}
108</div>
109<Switch
110id="publish-trace"
111checked={props.isPublic}
112onCheckedChange={() => {
113if (props.isLoading) return;
114props.onChange(!props.isPublic);
115}}
116disabled={props.disabled}
117/>
118</div>
119);
120};
121