import React from "react"; import { Card } from "@/src/components/ui/card"; import { Button } from "@/src/components/ui/button"; import { api } from "@/src/utils/api"; import { useForm } from "react-hook-form"; import { Form, FormControl, FormField, FormItem, FormMessage, } from "@/src/components/ui/form"; import Header from "@/src/components/layouts/header"; import { useHasProjectAccess } from "@/src/features/rbac/utils/checkProjectAccess"; import { useHasEntitlement } from "@/src/features/entitlements/hooks"; import { zodResolver } from "@hookform/resolvers/zod"; import { z } from "zod/v4"; import { XIcon, Check, ChevronsUpDown } from "lucide-react"; import { ActionButton } from "@/src/components/ActionButton"; import { cn } from "@/src/utils/tailwind"; import { Command, CommandEmpty, CommandGroup, CommandInput, CommandItem, } from "@/src/components/ui/command"; import { Popover, PopoverContent, PopoverTrigger, } from "@/src/components/ui/popover"; import { StatusBadge } from "@/src/components/layouts/status-badge"; import { LATEST_PROMPT_LABEL, PRODUCTION_LABEL, PromptLabelSchema, } from "@langfuse/shared"; const AddLabelFormSchema = z.object({ label: PromptLabelSchema, }); type AddLabelFormSchemaType = z.infer; export default function ProtectedLabelsSettings({ projectId, }: { projectId: string; }) { const hasAccess = useHasProjectAccess({ projectId, scope: "promptProtectedLabels:CUD", }); const hasEntitlement = useHasEntitlement("prompt-protected-labels"); const form = useForm({ resolver: zodResolver(AddLabelFormSchema), defaultValues: { label: "", }, }); const utils = api.useUtils(); const { data: protectedLabels = [] } = api.prompts.getProtectedLabels.useQuery( { projectId }, { enabled: Boolean(projectId), }, ); const { data: allLabels = [] } = api.prompts.allLabels.useQuery( { projectId }, { enabled: Boolean(projectId), }, ); // Filter out labels that are already protected const availableLabels = allLabels.filter( (label) => !protectedLabels.includes(label) && label !== LATEST_PROMPT_LABEL, ); const addProtectedLabel = api.prompts.addProtectedLabel.useMutation({ onSuccess: () => { utils.prompts.getProtectedLabels.invalidate(); form.reset(); }, }); const removeProtectedLabel = api.prompts.removeProtectedLabel.useMutation({ onSuccess: () => { utils.prompts.getProtectedLabels.invalidate(); }, }); function onSubmit(values: AddLabelFormSchemaType) { addProtectedLabel.mutate({ projectId, label: values.label, }); } const [open, setOpen] = React.useState(false); return (

Protected labels can only be modified by users with admin or owner access. This prevents other users from changing or removing these labels from prompts.

{protectedLabels.map((label) => ( {hasAccess && hasEntitlement && ( )} ))}
( { field.onChange(value); }} /> No label found {availableLabels.map((label) => ( { field.onChange(label); setOpen(false); }} > {label} ))} )} /> Add
); }