fix(toptools): fix

This commit is contained in:
2026-03-19 17:37:34 +08:00
parent 9c6266cdf8
commit a6c83ef3f6

View File

@@ -168,6 +168,8 @@ const TopTools = (
const [duplicateName, setDuplicateName] = useState("")
const [recoverOpen, setRecoverOpen] = useState(false)
const [taskOpen, setTaskOpen] = useState(false)
const [operationPickerOpened, setOperationPickerOpened] = useState(false)
const [operationKeyword, setOperationKeyword] = useState("")
const labelData = useLabelStore((state) => state.label)
const setLabel = useLabelStore((state) => state.setLabel)
const pushStateStack = useLabelStore((state) => state.pushStateStack)
@@ -255,6 +257,18 @@ const TopTools = (
)
}, [objectOperations])
const filteredObjectOperations = useMemo(() => {
const keyword = operationKeyword.trim().toLowerCase()
if (!keyword) return objectOperations
return objectOperations.filter((item) => {
return (
item.label_class.toLowerCase().includes(keyword) ||
item.category_id.toString().includes(keyword) ||
item.super_category.toLowerCase().includes(keyword)
)
})
}, [objectOperations, operationKeyword])
useEffect(() => {
if (
taskDetail?.label_status &&
@@ -2058,30 +2072,124 @@ const TopTools = (
</Popover.Target>
<Popover.Dropdown>{subAttrForm}</Popover.Dropdown>
</Popover>
<Popover position="bottom" shadow="md">
<Popover
position="bottom-start"
shadow="md"
width={280}
opened={operationPickerOpened}
onChange={setOperationPickerOpened}>
<Popover.Target>
<ActionIcon variant="transparent" c={"var(--mantine-color-text)"}>
<ActionIcon
variant="transparent"
c={"var(--mantine-color-text)"}
onClick={() => {
setOperationPickerOpened((opened) => !opened)
if (operationPickerOpened) setOperationKeyword("")
}}>
<IconChevronDown size={16} />
</ActionIcon>
</Popover.Target>
<Popover.Dropdown>
{objectOperations.map((item) => (
<ActionIcon
key={item.category_id}
variant="transparent"
c="dark"
style={{ width: "auto", display: "flex", gap: 6 }}
onClick={() => {
setActiveOperation(item.category_id.toString())
}}>
{renderOperationIcon(
getOperationSchema(item.category_id.toString())
)}
<Text span size="xs" style={{ width: "max-content" }} ml={4}>
{item.label_class || ""}
<Popover.Dropdown p="xs">
<Stack gap="xs">
<TextInput
value={operationKeyword}
size="xs"
placeholder="搜索类别名 / 超类 / ID"
onChange={(event) => {
setOperationKeyword(event.currentTarget.value)
}}
onFocus={() => {
useKeyEventStore.getState().setFocusInput(true)
}}
onBlur={() => {
useKeyEventStore.getState().setFocusInput(false)
}}
/>
<Group justify="space-between" gap="xs">
<Text size="10px" c="dimmed">
{objectOperations.length}
</Text>
</ActionIcon>
))}
{operationKeyword ? (
<Text size="10px" c="dimmed">
{filteredObjectOperations.length}
</Text>
) : null}
</Group>
<ScrollArea.Autosize mah={320} offsetScrollbars>
<Stack gap={4}>
{filteredObjectOperations.length ? (
filteredObjectOperations.map((item) => {
const isActive =
item.category_id.toString() === activeOperation
return (
<UnstyledButton
key={item.category_id}
onClick={() => {
setActiveOperation(item.category_id.toString())
setOperationPickerOpened(false)
setOperationKeyword("")
}}
style={{
width: "100%",
borderRadius: 8,
padding: "8px 10px",
border: isActive
? "1px solid var(--mantine-color-blue-4)"
: "1px solid transparent",
background: isActive
? "var(--mantine-color-blue-light)"
: "transparent",
}}>
<Flex
align="center"
justify="space-between"
gap="xs">
<Group gap={8} wrap="nowrap">
<Box
style={{
display: "flex",
alignItems: "center",
justifyContent: "center",
}}>
{renderOperationIcon(
getOperationSchema(
item.category_id.toString()
)
)}
</Box>
<Box style={{ minWidth: 0 }}>
<Text
size="xs"
fw={isActive ? 600 : 500}
truncate="end">
{item.label_class || ""}
</Text>
<Text size="10px" c="dimmed" truncate="end">
ID: {item.category_id}
{item.super_category
? ` / ${item.super_category}`
: ""}
</Text>
</Box>
</Group>
{isActive ? (
<Text size="10px" c="blue" fw={700}>
</Text>
) : null}
</Flex>
</UnstyledButton>
)
})
) : (
<Text size="xs" c="dimmed" ta="center" py="sm">
</Text>
)}
</Stack>
</ScrollArea.Autosize>
</Stack>
</Popover.Dropdown>
</Popover>
</Flex>