(props: {
policy: {
id: string;
owner: Owner;
pattern: string;
action: ToolPolicyAction;
};
isFirst: boolean;
isLast: boolean;
onRemove: () => void;
onChangeAction: (action: ToolPolicyAction) => void;
onMoveUp: () => void;
onMoveDown: () => void;
showOwnerLabel: boolean;
})
| 195 | // --------------------------------------------------------------------------- |
| 196 | |
| 197 | function PolicyRow(props: { |
| 198 | policy: { |
| 199 | id: string; |
| 200 | owner: Owner; |
| 201 | pattern: string; |
| 202 | action: ToolPolicyAction; |
| 203 | }; |
| 204 | isFirst: boolean; |
| 205 | isLast: boolean; |
| 206 | onRemove: () => void; |
| 207 | onChangeAction: (action: ToolPolicyAction) => void; |
| 208 | onMoveUp: () => void; |
| 209 | onMoveDown: () => void; |
| 210 | showOwnerLabel: boolean; |
| 211 | }) { |
| 212 | return ( |
| 213 | <CardStackEntry> |
| 214 | <CardStackEntryContent> |
| 215 | <CardStackEntryTitle className="flex items-center gap-2 font-mono text-sm"> |
| 216 | <span className="truncate">{props.policy.pattern}</span> |
| 217 | {props.showOwnerLabel ? ( |
| 218 | <span className="shrink-0 rounded border border-border px-1.5 py-0.5 font-sans text-[10px] leading-none text-muted-foreground"> |
| 219 | {ownerLabel(props.policy.owner)} |
| 220 | </span> |
| 221 | ) : null} |
| 222 | </CardStackEntryTitle> |
| 223 | </CardStackEntryContent> |
| 224 | <CardStackEntryActions> |
| 225 | <Select |
| 226 | value={props.policy.action} |
| 227 | onValueChange={(v) => props.onChangeAction(v as ToolPolicyAction)} |
| 228 | > |
| 229 | <SelectPrimitiveTrigger |
| 230 | className={cn( |
| 231 | badgeVariants({ |
| 232 | variant: POLICY_BADGE_VARIANT[props.policy.action], |
| 233 | }), |
| 234 | "cursor-pointer pr-1.5 gap-1 transition-[opacity,box-shadow] hover:opacity-80 focus-visible:outline-none data-[state=open]:ring-2 data-[state=open]:ring-ring/50", |
| 235 | )} |
| 236 | > |
| 237 | {POLICY_ACTION_LABEL[props.policy.action]} |
| 238 | <ChevronDownIcon className="size-3 opacity-70" /> |
| 239 | </SelectPrimitiveTrigger> |
| 240 | <SelectContent position="popper" align="end"> |
| 241 | {POLICY_ACTIONS_IN_ORDER.map((a) => ( |
| 242 | <SelectItem key={a} value={a}> |
| 243 | {POLICY_ACTION_LABEL[a]} |
| 244 | </SelectItem> |
| 245 | ))} |
| 246 | </SelectContent> |
| 247 | </Select> |
| 248 | <DropdownMenu> |
| 249 | <DropdownMenuTrigger asChild> |
| 250 | <Button |
| 251 | variant="ghost" |
| 252 | size="icon" |
| 253 | className="size-7 opacity-0 transition-opacity group-hover/card-stack-entry:opacity-100 group-focus-within/card-stack-entry:opacity-100 data-[state=open]:opacity-100" |
| 254 | > |
nothing calls this directly
no test coverage detected