mirror of
https://github.com/multica-ai/multica.git
synced 2026-07-26 20:45:37 +02:00
* refactor(views): reuse AssigneePicker in CreateIssueModal Replace the hand-rolled inline assignee Popover in CreateIssueModal with the shared AssigneePicker component. This fixes missing features (private agent permission checks, lock icon, disabled state, selection checkmark) and ensures consistent behavior across all assignee dropdowns. * refactor(views): consolidate all picker components across the codebase Enhance shared pickers (StatusPicker, PriorityPicker, DueDatePicker, ProjectPicker) with triggerRender, controlled open/onOpenChange, and align props — matching the AssigneePicker API. Replace inline implementations in: - create-issue.tsx: Status, Priority, DueDate, Project (4 pickers) - issue-detail.tsx sidebar: Status, Priority (2 pickers) - batch-action-toolbar.tsx: Status, Priority (2 pickers) StatusPicker now has its first consumer (was defined but unused). Removes ~200 lines of duplicated picker code.
68 lines
1.9 KiB
TypeScript
68 lines
1.9 KiB
TypeScript
"use client";
|
|
|
|
import { useState } from "react";
|
|
import type { IssuePriority, UpdateIssueRequest } from "@multica/core/types";
|
|
import { PRIORITY_ORDER, PRIORITY_CONFIG } from "@multica/core/issues/config";
|
|
import { PriorityIcon } from "../priority-icon";
|
|
import { PropertyPicker, PickerItem } from "./property-picker";
|
|
|
|
export function PriorityPicker({
|
|
priority,
|
|
onUpdate,
|
|
trigger: customTrigger,
|
|
triggerRender,
|
|
open: controlledOpen,
|
|
onOpenChange: controlledOnOpenChange,
|
|
align,
|
|
}: {
|
|
priority: IssuePriority;
|
|
onUpdate: (updates: Partial<UpdateIssueRequest>) => void;
|
|
trigger?: React.ReactNode;
|
|
triggerRender?: React.ReactElement;
|
|
open?: boolean;
|
|
onOpenChange?: (v: boolean) => void;
|
|
align?: "start" | "center" | "end";
|
|
}) {
|
|
const [internalOpen, setInternalOpen] = useState(false);
|
|
const open = controlledOpen ?? internalOpen;
|
|
const setOpen = controlledOnOpenChange ?? setInternalOpen;
|
|
const cfg = PRIORITY_CONFIG[priority];
|
|
|
|
return (
|
|
<PropertyPicker
|
|
open={open}
|
|
onOpenChange={setOpen}
|
|
width="w-44"
|
|
align={align}
|
|
triggerRender={triggerRender}
|
|
trigger={
|
|
customTrigger ?? (
|
|
<>
|
|
<PriorityIcon priority={priority} className="shrink-0" />
|
|
<span className="truncate">{cfg.label}</span>
|
|
</>
|
|
)
|
|
}
|
|
>
|
|
{PRIORITY_ORDER.map((p) => {
|
|
const c = PRIORITY_CONFIG[p];
|
|
return (
|
|
<PickerItem
|
|
key={p}
|
|
selected={p === priority}
|
|
onClick={() => {
|
|
onUpdate({ priority: p });
|
|
setOpen(false);
|
|
}}
|
|
>
|
|
<span className={`inline-flex items-center gap-1 rounded px-1.5 py-0.5 text-xs font-medium ${c.badgeBg} ${c.badgeText}`}>
|
|
<PriorityIcon priority={p} className="h-3 w-3" inheritColor />
|
|
{c.label}
|
|
</span>
|
|
</PickerItem>
|
|
);
|
|
})}
|
|
</PropertyPicker>
|
|
);
|
|
}
|