205 lines
6.9 KiB
TypeScript
205 lines
6.9 KiB
TypeScript
import { Box, Flex, HoverCard } from "@mantine/core"
|
|
import { ArrowBigRightDashIcon, MinusCircleIcon } from "lucide-react"
|
|
import { useCallback } from "react"
|
|
import { useBottomToolsStore } from "../useBottomToolsStore"
|
|
import { useDescToolsStore } from "../useDescToolsStore"
|
|
import { useTopToolsStore } from "../useTopToolsStore"
|
|
|
|
const MetaOperationTool = () => {
|
|
const { metaOperation, metaData } = useDescToolsStore()
|
|
const { activeImage } = useBottomToolsStore()
|
|
const currentImageData = metaData.get(activeImage) || []
|
|
|
|
const HoverContent = useCallback(
|
|
(index?: number) => {
|
|
if (!metaOperation) return <></>
|
|
const { sub_attributes_describe } = metaOperation
|
|
|
|
return (
|
|
<Box w={256}>
|
|
<Box
|
|
fw={600}
|
|
pb={4}
|
|
mb={4}
|
|
style={{
|
|
borderBottom:
|
|
"1px solid light-dark(var(--mantine-color-gray-4), var(--mantine-color-dark-4))",
|
|
}}>
|
|
子属性选择
|
|
</Box>
|
|
{sub_attributes_describe.length ? (
|
|
<Box w="100%">
|
|
{sub_attributes_describe.map((subDesc) => (
|
|
<Flex
|
|
key={subDesc.chinese_name}
|
|
w="100%"
|
|
gap="xs"
|
|
mb={4}
|
|
align="flex-start">
|
|
<Box style={{ minWidth: "fit-content" }} p={4} fw={600}>
|
|
{subDesc.chinese_name}
|
|
</Box>
|
|
<Flex flex={1} wrap="wrap" gap="xs">
|
|
{subDesc.optional_item.map((option) => (
|
|
<Box
|
|
key={option}
|
|
c="blue"
|
|
p={4}
|
|
style={{
|
|
cursor: "pointer",
|
|
borderRadius: "4px",
|
|
}}
|
|
onMouseEnter={(e) => {
|
|
e.currentTarget.style.backgroundColor =
|
|
"var(--mantine-color-gray-1)"
|
|
}}
|
|
onMouseLeave={(e) => {
|
|
e.currentTarget.style.backgroundColor = "transparent"
|
|
}}
|
|
onClick={() => {
|
|
const map = useDescToolsStore.getState().metaData
|
|
if (map.has(activeImage)) {
|
|
let arr = map.get(activeImage) || []
|
|
if (index || index === 0) arr[index] = option
|
|
else arr.push(option)
|
|
map.set(activeImage, arr)
|
|
} else {
|
|
map.set(activeImage, [option])
|
|
}
|
|
useDescToolsStore.getState().setMetaData(map)
|
|
}}>
|
|
{option}
|
|
</Box>
|
|
))}
|
|
</Flex>
|
|
</Flex>
|
|
))}
|
|
</Box>
|
|
) : (
|
|
<Flex w="100%" h={40} justify="center" align="center" bg="gray.1">
|
|
无
|
|
</Flex>
|
|
)}
|
|
</Box>
|
|
)
|
|
},
|
|
[activeImage, metaOperation]
|
|
)
|
|
|
|
const handleDelete = (index: number) => {
|
|
const map = useDescToolsStore.getState().metaData
|
|
let arr = (map.get(activeImage) || []).filter((_v, i) => i !== index)
|
|
map.set(activeImage, arr)
|
|
useDescToolsStore.getState().setMetaData(map)
|
|
}
|
|
|
|
return (
|
|
<Flex w="100%" h="100%">
|
|
{currentImageData.map((text, index) =>
|
|
!useTopToolsStore.getState().isView ? (
|
|
<Flex
|
|
key={`${index}${text}`}
|
|
style={{ minWidth: "fit-content" }}
|
|
align="center">
|
|
{/* Replaced Popover with HoverCard for better hover interaction */}
|
|
<HoverCard
|
|
shadow="md"
|
|
openDelay={100}
|
|
closeDelay={100}
|
|
withinPortal>
|
|
<HoverCard.Target>
|
|
<Flex
|
|
style={{
|
|
minWidth: "fit-content",
|
|
border:
|
|
"1px solid light-dark(var(--mantine-color-gray-4), var(--mantine-color-dark-4))",
|
|
borderRadius: "9999px",
|
|
cursor: "default",
|
|
}}
|
|
px={8}
|
|
justify="center"
|
|
align="center"
|
|
gap={4}>
|
|
{text}
|
|
<Box
|
|
style={{ cursor: "pointer", display: "flex" }}
|
|
onClick={(e) => {
|
|
e.stopPropagation()
|
|
handleDelete(index)
|
|
}}>
|
|
<MinusCircleIcon
|
|
style={{ width: 16, color: "var(--mantine-color-red-6)" }}
|
|
/>
|
|
</Box>
|
|
</Flex>
|
|
</HoverCard.Target>
|
|
<HoverCard.Dropdown>{HoverContent(index)}</HoverCard.Dropdown>
|
|
</HoverCard>
|
|
{index < currentImageData.length - 1 ? (
|
|
<Box w={24}>
|
|
<ArrowBigRightDashIcon
|
|
style={{ color: "var(--mantine-color-gray-4)" }}
|
|
/>
|
|
</Box>
|
|
) : null}
|
|
</Flex>
|
|
) : (
|
|
<Flex
|
|
key={`${index}${text}`}
|
|
style={{ minWidth: "fit-content" }}
|
|
align="center">
|
|
<Flex
|
|
style={{
|
|
minWidth: "fit-content",
|
|
border:
|
|
"1px solid light-dark(var(--mantine-color-gray-4), var(--mantine-color-dark-4))",
|
|
borderRadius: "9999px",
|
|
}}
|
|
px={8}
|
|
justify="center"
|
|
align="center"
|
|
gap={4}>
|
|
{text}
|
|
</Flex>
|
|
{index < currentImageData.length - 1 ? (
|
|
<Box w={24}>
|
|
<ArrowBigRightDashIcon
|
|
style={{ color: "var(--mantine-color-gray-4)" }}
|
|
/>
|
|
</Box>
|
|
) : null}
|
|
</Flex>
|
|
)
|
|
)}
|
|
{!useTopToolsStore.getState().isView ? (
|
|
<Flex
|
|
style={{ minWidth: "fit-content" }}
|
|
justify="center"
|
|
align="center"
|
|
ml={8}>
|
|
{/* Replaced Popover with HoverCard */}
|
|
<HoverCard shadow="md" openDelay={100} closeDelay={100} withinPortal>
|
|
<HoverCard.Target>
|
|
<Box
|
|
style={{
|
|
minWidth: "fit-content",
|
|
border: "1px solid var(--mantine-color-blue-6)",
|
|
borderRadius: "9999px",
|
|
cursor: "pointer",
|
|
}}
|
|
px={8}
|
|
c="white"
|
|
bg="blue">
|
|
新增
|
|
</Box>
|
|
</HoverCard.Target>
|
|
<HoverCard.Dropdown>{HoverContent()}</HoverCard.Dropdown>
|
|
</HoverCard>
|
|
</Flex>
|
|
) : null}
|
|
</Flex>
|
|
)
|
|
}
|
|
|
|
export default MetaOperationTool
|