feat(tool): hide all object
This commit is contained in:
@@ -355,13 +355,10 @@ const RightObjectTools: React.FC<RightObjectToolsComponentProps> = (props) => {
|
|||||||
if (operationMap) {
|
if (operationMap) {
|
||||||
const objList = operationMap.get(operationId)
|
const objList = operationMap.get(operationId)
|
||||||
if (objList && objList.length) {
|
if (objList && objList.length) {
|
||||||
let hideFlag = true
|
const hideFlag = objList.every(([id]) => {
|
||||||
objList.forEach(([id]) => {
|
return useObjectStore.getState().pathStatus[`${imgId}${id}`]?.["HIDE"]
|
||||||
const objStatus =
|
? true
|
||||||
useObjectStore.getState().pathStatus[`${imgId}${id}`]
|
: false
|
||||||
if (objStatus && !objStatus["HIDE"]) {
|
|
||||||
hideFlag = false
|
|
||||||
}
|
|
||||||
})
|
})
|
||||||
updateOperationStatus(imgId + operationId, "HIDE", hideFlag)
|
updateOperationStatus(imgId + operationId, "HIDE", hideFlag)
|
||||||
}
|
}
|
||||||
@@ -401,6 +398,39 @@ const RightObjectTools: React.FC<RightObjectToolsComponentProps> = (props) => {
|
|||||||
[activeImage]
|
[activeImage]
|
||||||
)
|
)
|
||||||
|
|
||||||
|
const activeImageOperations = labelState.get(activeImage) || []
|
||||||
|
|
||||||
|
const isObjectHidden = (imageId: string, objectId: number) => {
|
||||||
|
return pathStatus[imageId + objectId]?.["HIDE"] ?? false
|
||||||
|
}
|
||||||
|
|
||||||
|
const isOperationHidden = (imageId: string, operationId: string) => {
|
||||||
|
const operationChildren = storeLabel.get(imageId)?.get(operationId) || []
|
||||||
|
return (
|
||||||
|
operationChildren.length > 0 &&
|
||||||
|
operationChildren.every(([objectId]) => isObjectHidden(imageId, objectId))
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
const totalObjectCount = activeImageOperations.reduce(
|
||||||
|
(count, operationId) => {
|
||||||
|
return (
|
||||||
|
count + (storeLabel.get(activeImage)?.get(operationId)?.length || 0)
|
||||||
|
)
|
||||||
|
},
|
||||||
|
0
|
||||||
|
)
|
||||||
|
|
||||||
|
const areAllObjectsHidden =
|
||||||
|
totalObjectCount > 0 &&
|
||||||
|
activeImageOperations.every((operationId) => {
|
||||||
|
const operationChildren =
|
||||||
|
storeLabel.get(activeImage)?.get(operationId) || []
|
||||||
|
return operationChildren.every(([objectId]) =>
|
||||||
|
isObjectHidden(activeImage, objectId)
|
||||||
|
)
|
||||||
|
})
|
||||||
|
|
||||||
// const renderObjectName = useCallback((name: string, input: string) => {
|
// const renderObjectName = useCallback((name: string, input: string) => {
|
||||||
// const index = name?.indexOf(input);
|
// const index = name?.indexOf(input);
|
||||||
// const beforeStr = name?.substring(0, index);
|
// const beforeStr = name?.substring(0, index);
|
||||||
@@ -509,9 +539,22 @@ const RightObjectTools: React.FC<RightObjectToolsComponentProps> = (props) => {
|
|||||||
<Box h="100%" w="100%">
|
<Box h="100%" w="100%">
|
||||||
<Flex direction="column" h="100%" gap="xs">
|
<Flex direction="column" h="100%" gap="xs">
|
||||||
<Flex justify="space-between" align="center" px="md" py="xs">
|
<Flex justify="space-between" align="center" px="md" py="xs">
|
||||||
<Title order={4} size="h4">
|
<Group gap="xs">
|
||||||
对象列表
|
<ActionIcon
|
||||||
</Title>
|
variant="subtle"
|
||||||
|
aria-label={areAllObjectsHidden ? "显示全部对象" : "隐藏全部对象"}
|
||||||
|
onClick={() => {
|
||||||
|
if (!totalObjectCount) return
|
||||||
|
activeImageOperations.forEach((operationId) => {
|
||||||
|
operationHide(operationId, !areAllObjectsHidden)
|
||||||
|
})
|
||||||
|
}}>
|
||||||
|
{areAllObjectsHidden ? <EyeOff size={16} /> : <Eye size={16} />}
|
||||||
|
</ActionIcon>
|
||||||
|
<Title order={4} size="h4">
|
||||||
|
对象列表
|
||||||
|
</Title>
|
||||||
|
</Group>
|
||||||
<Group gap="xs">
|
<Group gap="xs">
|
||||||
<TextInput
|
<TextInput
|
||||||
w={96}
|
w={96}
|
||||||
@@ -566,441 +609,424 @@ const RightObjectTools: React.FC<RightObjectToolsComponentProps> = (props) => {
|
|||||||
}}>
|
}}>
|
||||||
<ScrollArea style={{ flex: 1 }} px="md">
|
<ScrollArea style={{ flex: 1 }} px="md">
|
||||||
<Stack gap="xs" pb="md">
|
<Stack gap="xs" pb="md">
|
||||||
{labelState.get(activeImage) &&
|
{activeImageOperations.map((operationId) => {
|
||||||
labelState.get(activeImage)?.map((operationId) => {
|
const operationSchema = getOperationSchema(operationId)
|
||||||
const operationSchema = getOperationSchema(operationId)
|
const isCollapsed =
|
||||||
const isCollapsed =
|
operationStatus[activeImage + operationId]?.["COLLAPSE"]
|
||||||
operationStatus[activeImage + operationId]?.["COLLAPSE"]
|
const isHide = isOperationHidden(activeImage, operationId)
|
||||||
const isHide =
|
const hasSubAttrError = getOperationSubAttrStatus(operationId)
|
||||||
operationStatus[activeImage + operationId]?.HIDE
|
const operationLabel = operationSchema?.label_class
|
||||||
const hasSubAttrError = getOperationSubAttrStatus(operationId)
|
const operationChildren =
|
||||||
const operationLabel = operationSchema?.label_class
|
storeLabel.get(activeImage)?.get(operationId) || []
|
||||||
const operationChildren =
|
const objectCount = operationChildren.length
|
||||||
storeLabel.get(activeImage)?.get(operationId) || []
|
const visibleChildren = operationChildren.filter((child) => {
|
||||||
const objectCount = operationChildren.length
|
const { comment } = child[2]
|
||||||
const visibleChildren = operationChildren.filter((child) => {
|
let visibleFlag = true
|
||||||
const { comment } = child[2]
|
if (comment && comment.length) {
|
||||||
let visibleFlag = true
|
const latest_comment =
|
||||||
if (comment && comment.length) {
|
(taskDetail && taskDetail.label_status === 2) ||
|
||||||
const latest_comment =
|
comment.length === 1
|
||||||
(taskDetail && taskDetail.label_status === 2) ||
|
? comment[comment.length - 1]
|
||||||
comment.length === 1
|
: comment[comment.length - 2]
|
||||||
? comment[comment.length - 1]
|
let type = latest_comment.comment_type
|
||||||
: comment[comment.length - 2]
|
if (type === 2) {
|
||||||
let type = latest_comment.comment_type
|
const { last_modified_timestamp } = child[2]
|
||||||
if (type === 2) {
|
if (
|
||||||
const { last_modified_timestamp } = child[2]
|
last_modified_timestamp &&
|
||||||
if (
|
last_modified_timestamp > latest_comment.date
|
||||||
last_modified_timestamp &&
|
)
|
||||||
last_modified_timestamp > latest_comment.date
|
type = 3
|
||||||
)
|
|
||||||
type = 3
|
|
||||||
}
|
|
||||||
visibleFlag = checkBoxsChecked[3 - type]
|
|
||||||
}
|
}
|
||||||
if (checkBoxsChecked.every((value) => !value))
|
visibleFlag = checkBoxsChecked[3 - type]
|
||||||
visibleFlag = true
|
}
|
||||||
return visibleFlag
|
if (checkBoxsChecked.every((value) => !value))
|
||||||
})
|
visibleFlag = true
|
||||||
return (
|
return visibleFlag
|
||||||
<Box key={operationId} w="100%">
|
})
|
||||||
<Paper withBorder p="xs" radius="md" shadow="sm">
|
return (
|
||||||
<Flex align="center" gap="xs" style={{ minWidth: 0 }}>
|
<Box key={operationId} w="100%">
|
||||||
<Flex
|
<Paper withBorder p="xs" radius="md" shadow="sm">
|
||||||
align="center"
|
<Flex align="center" gap="xs" style={{ minWidth: 0 }}>
|
||||||
gap="xs"
|
<Flex
|
||||||
style={{ flex: 1, minWidth: 0 }}>
|
align="center"
|
||||||
<ActionIcon
|
gap="xs"
|
||||||
variant="subtle"
|
style={{ flex: 1, minWidth: 0 }}>
|
||||||
size="sm"
|
<ActionIcon
|
||||||
onClick={() =>
|
variant="subtle"
|
||||||
operationHide(operationId, !isHide)
|
size="sm"
|
||||||
}>
|
onClick={() => operationHide(operationId, !isHide)}>
|
||||||
{!isHide ? (
|
{!isHide ? <Eye size={16} /> : <EyeOff size={16} />}
|
||||||
<Eye size={16} />
|
</ActionIcon>
|
||||||
) : (
|
|
||||||
<EyeOff size={16} />
|
|
||||||
)}
|
|
||||||
</ActionIcon>
|
|
||||||
<Group
|
|
||||||
gap={8}
|
|
||||||
wrap="nowrap"
|
|
||||||
style={{ flex: 1, minWidth: 0 }}>
|
|
||||||
<Group
|
|
||||||
gap={6}
|
|
||||||
wrap="nowrap"
|
|
||||||
px="xs"
|
|
||||||
py={4}
|
|
||||||
style={{
|
|
||||||
flexShrink: 0,
|
|
||||||
borderRadius: 999,
|
|
||||||
border: `1px solid ${
|
|
||||||
hasSubAttrError
|
|
||||||
? "var(--mantine-color-red-2)"
|
|
||||||
: "var(--mantine-color-gray-2)"
|
|
||||||
}`,
|
|
||||||
background: hasSubAttrError
|
|
||||||
? "var(--mantine-color-red-0)"
|
|
||||||
: "var(--mantine-color-gray-0)",
|
|
||||||
}}>
|
|
||||||
{renderOperationIcon(operationSchema)}
|
|
||||||
<Text
|
|
||||||
size="xs"
|
|
||||||
fw={700}
|
|
||||||
c={hasSubAttrError ? "red" : "dimmed"}
|
|
||||||
style={{
|
|
||||||
whiteSpace: "nowrap",
|
|
||||||
lineHeight: 1,
|
|
||||||
}}>
|
|
||||||
{renderShortcutKey(operationId)}
|
|
||||||
</Text>
|
|
||||||
</Group>
|
|
||||||
<Box style={{ flex: 1, minWidth: 0 }}>
|
|
||||||
<Text
|
|
||||||
size="sm"
|
|
||||||
fw={500}
|
|
||||||
c={hasSubAttrError ? "red" : undefined}
|
|
||||||
title={operationLabel || undefined}
|
|
||||||
style={{
|
|
||||||
minWidth: 0,
|
|
||||||
overflow: "hidden",
|
|
||||||
textOverflow: "ellipsis",
|
|
||||||
whiteSpace: "nowrap",
|
|
||||||
}}>
|
|
||||||
{operationLabel}
|
|
||||||
</Text>
|
|
||||||
</Box>
|
|
||||||
</Group>
|
|
||||||
</Flex>
|
|
||||||
<Group
|
<Group
|
||||||
gap={6}
|
gap={8}
|
||||||
wrap="nowrap"
|
wrap="nowrap"
|
||||||
style={{ flexShrink: 0, marginLeft: "auto" }}>
|
style={{ flex: 1, minWidth: 0 }}>
|
||||||
<TextInput
|
<Group
|
||||||
w={88}
|
gap={6}
|
||||||
size="xs"
|
wrap="nowrap"
|
||||||
placeholder="搜索子属性"
|
px="xs"
|
||||||
value={searchSubAttrs[operationId] || ""}
|
py={4}
|
||||||
onChange={(e) => {
|
style={{
|
||||||
setSearchSubAttrs((searchValues) => ({
|
flexShrink: 0,
|
||||||
...searchValues,
|
borderRadius: 999,
|
||||||
[operationId]: e.target.value,
|
border: `1px solid ${
|
||||||
}))
|
hasSubAttrError
|
||||||
}}
|
? "var(--mantine-color-red-2)"
|
||||||
onKeyDown={(e) =>
|
: "var(--mantine-color-gray-2)"
|
||||||
handleSelectedBySearchSubAttr(e, operationId)
|
}`,
|
||||||
}
|
background: hasSubAttrError
|
||||||
/>
|
? "var(--mantine-color-red-0)"
|
||||||
<Badge
|
: "var(--mantine-color-gray-0)",
|
||||||
size="sm"
|
|
||||||
variant="light"
|
|
||||||
radius="xl"
|
|
||||||
color={hasSubAttrError ? "red" : "gray"}>
|
|
||||||
{objectCount}
|
|
||||||
</Badge>
|
|
||||||
<ActionIcon
|
|
||||||
variant="subtle"
|
|
||||||
size="sm"
|
|
||||||
onClick={() => {
|
|
||||||
updateOperationStatus(
|
|
||||||
activeImage + operationId,
|
|
||||||
"COLLAPSE",
|
|
||||||
!isCollapsed
|
|
||||||
)
|
|
||||||
}}>
|
}}>
|
||||||
{!isCollapsed ? (
|
{renderOperationIcon(operationSchema)}
|
||||||
<ChevronUp size={16} />
|
<Text
|
||||||
) : (
|
size="xs"
|
||||||
<ChevronDown size={16} />
|
fw={700}
|
||||||
)}
|
c={hasSubAttrError ? "red" : "dimmed"}
|
||||||
</ActionIcon>
|
style={{
|
||||||
|
whiteSpace: "nowrap",
|
||||||
|
lineHeight: 1,
|
||||||
|
}}>
|
||||||
|
{renderShortcutKey(operationId)}
|
||||||
|
</Text>
|
||||||
|
</Group>
|
||||||
|
<Box style={{ flex: 1, minWidth: 0 }}>
|
||||||
|
<Text
|
||||||
|
size="sm"
|
||||||
|
fw={500}
|
||||||
|
c={hasSubAttrError ? "red" : undefined}
|
||||||
|
title={operationLabel || undefined}
|
||||||
|
style={{
|
||||||
|
minWidth: 0,
|
||||||
|
overflow: "hidden",
|
||||||
|
textOverflow: "ellipsis",
|
||||||
|
whiteSpace: "nowrap",
|
||||||
|
}}>
|
||||||
|
{operationLabel}
|
||||||
|
</Text>
|
||||||
|
</Box>
|
||||||
</Group>
|
</Group>
|
||||||
</Flex>
|
</Flex>
|
||||||
</Paper>
|
<Group
|
||||||
<Collapse in={!isCollapsed}>
|
gap={6}
|
||||||
<Stack gap="xs" mt="xs" ml="xs">
|
wrap="nowrap"
|
||||||
{visibleChildren.map((child, childIndex) => {
|
style={{ flexShrink: 0, marginLeft: "auto" }}>
|
||||||
const { comment } = child[2]
|
<TextInput
|
||||||
const isSelected = selectedPath[
|
w={88}
|
||||||
activeImage
|
size="xs"
|
||||||
]?.includes(child[0])
|
placeholder="搜索子属性"
|
||||||
const isChildHide =
|
value={searchSubAttrs[operationId] || ""}
|
||||||
pathStatus[activeImage + child[0]]?.["HIDE"]
|
onChange={(e) => {
|
||||||
const hasChildError = getSubAttrStatus(
|
setSearchSubAttrs((searchValues) => ({
|
||||||
getOperationSchema(operationId),
|
...searchValues,
|
||||||
child[2]?.sub_attributes
|
[operationId]: e.target.value,
|
||||||
)
|
}))
|
||||||
const isLastVisibleChild =
|
}}
|
||||||
childIndex === visibleChildren.length - 1
|
onKeyDown={(e) =>
|
||||||
|
handleSelectedBySearchSubAttr(e, operationId)
|
||||||
let textColor = undefined
|
|
||||||
let connectorColor = "var(--mantine-color-gray-4)"
|
|
||||||
|
|
||||||
if (hasChildError) {
|
|
||||||
textColor = "red"
|
|
||||||
connectorColor = "var(--mantine-color-red-3)"
|
|
||||||
} else if (isSelected) {
|
|
||||||
textColor = "white"
|
|
||||||
connectorColor =
|
|
||||||
"var(--mantine-primary-color-filled)"
|
|
||||||
}
|
}
|
||||||
|
/>
|
||||||
|
<Badge
|
||||||
|
size="sm"
|
||||||
|
variant="light"
|
||||||
|
radius="xl"
|
||||||
|
color={hasSubAttrError ? "red" : "gray"}>
|
||||||
|
{objectCount}
|
||||||
|
</Badge>
|
||||||
|
<ActionIcon
|
||||||
|
variant="subtle"
|
||||||
|
size="sm"
|
||||||
|
onClick={() => {
|
||||||
|
updateOperationStatus(
|
||||||
|
activeImage + operationId,
|
||||||
|
"COLLAPSE",
|
||||||
|
!isCollapsed
|
||||||
|
)
|
||||||
|
}}>
|
||||||
|
{!isCollapsed ? (
|
||||||
|
<ChevronUp size={16} />
|
||||||
|
) : (
|
||||||
|
<ChevronDown size={16} />
|
||||||
|
)}
|
||||||
|
</ActionIcon>
|
||||||
|
</Group>
|
||||||
|
</Flex>
|
||||||
|
</Paper>
|
||||||
|
<Collapse in={!isCollapsed}>
|
||||||
|
<Stack gap="xs" mt="xs" ml="xs">
|
||||||
|
{visibleChildren.map((child, childIndex) => {
|
||||||
|
const { comment } = child[2]
|
||||||
|
const isSelected = selectedPath[
|
||||||
|
activeImage
|
||||||
|
]?.includes(child[0])
|
||||||
|
const isChildHide =
|
||||||
|
pathStatus[activeImage + child[0]]?.["HIDE"]
|
||||||
|
const hasChildError = getSubAttrStatus(
|
||||||
|
getOperationSchema(operationId),
|
||||||
|
child[2]?.sub_attributes
|
||||||
|
)
|
||||||
|
const isLastVisibleChild =
|
||||||
|
childIndex === visibleChildren.length - 1
|
||||||
|
|
||||||
return (
|
let textColor = undefined
|
||||||
|
let connectorColor = "var(--mantine-color-gray-4)"
|
||||||
|
|
||||||
|
if (hasChildError) {
|
||||||
|
textColor = "red"
|
||||||
|
connectorColor = "var(--mantine-color-red-3)"
|
||||||
|
} else if (isSelected) {
|
||||||
|
textColor = "white"
|
||||||
|
connectorColor =
|
||||||
|
"var(--mantine-primary-color-filled)"
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Box
|
||||||
|
key={child[0]}
|
||||||
|
pl="lg"
|
||||||
|
style={{ position: "relative" }}>
|
||||||
<Box
|
<Box
|
||||||
key={child[0]}
|
style={{
|
||||||
pl="lg"
|
position: "absolute",
|
||||||
style={{ position: "relative" }}>
|
left: 7,
|
||||||
|
top: 0,
|
||||||
|
bottom: isLastVisibleChild ? "75%" : 0,
|
||||||
|
width: 1.5,
|
||||||
|
borderRadius: 999,
|
||||||
|
background: connectorColor,
|
||||||
|
opacity: isSelected ? 0.9 : 0.35,
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
{isLastVisibleChild ? (
|
||||||
<Box
|
<Box
|
||||||
style={{
|
style={{
|
||||||
position: "absolute",
|
position: "absolute",
|
||||||
left: 7,
|
left: 7,
|
||||||
top: 0,
|
top: "calc(50% - 10px)",
|
||||||
bottom: isLastVisibleChild ? "75%" : 0,
|
width: 14,
|
||||||
width: 1.5,
|
height: 10,
|
||||||
borderRadius: 999,
|
borderLeft: `1.5px solid ${connectorColor}`,
|
||||||
background: connectorColor,
|
borderBottom: `1.5px solid ${connectorColor}`,
|
||||||
opacity: isSelected ? 0.9 : 0.35,
|
borderBottomLeftRadius: 10,
|
||||||
|
opacity: isSelected ? 0.9 : 0.55,
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
{isLastVisibleChild ? (
|
) : (
|
||||||
|
<>
|
||||||
<Box
|
<Box
|
||||||
style={{
|
style={{
|
||||||
position: "absolute",
|
position: "absolute",
|
||||||
left: 7,
|
left: 7,
|
||||||
top: "calc(50% - 10px)",
|
top: "50%",
|
||||||
width: 14,
|
width: 14,
|
||||||
height: 10,
|
borderTop: `1.5px solid ${connectorColor}`,
|
||||||
borderLeft: `1.5px solid ${connectorColor}`,
|
opacity: isSelected ? 0.9 : 0.45,
|
||||||
borderBottom: `1.5px solid ${connectorColor}`,
|
|
||||||
borderBottomLeftRadius: 10,
|
|
||||||
opacity: isSelected ? 0.9 : 0.55,
|
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
) : (
|
<Box
|
||||||
<>
|
style={{
|
||||||
<Box
|
position: "absolute",
|
||||||
style={{
|
left: 4,
|
||||||
position: "absolute",
|
top: "calc(50% - 3px)",
|
||||||
left: 7,
|
width: 6,
|
||||||
top: "50%",
|
height: 6,
|
||||||
width: 14,
|
borderRadius: 999,
|
||||||
borderTop: `1.5px solid ${connectorColor}`,
|
background: connectorColor,
|
||||||
opacity: isSelected ? 0.9 : 0.45,
|
boxShadow:
|
||||||
}}
|
"0 0 0 2px var(--mantine-color-body)",
|
||||||
/>
|
opacity: isSelected ? 1 : 0.85,
|
||||||
<Box
|
}}
|
||||||
style={{
|
/>
|
||||||
position: "absolute",
|
</>
|
||||||
left: 4,
|
)}
|
||||||
top: "calc(50% - 3px)",
|
<Paper
|
||||||
width: 6,
|
withBorder
|
||||||
height: 6,
|
p="xs"
|
||||||
borderRadius: 999,
|
radius="md"
|
||||||
background: connectorColor,
|
shadow="sm"
|
||||||
boxShadow:
|
bg={
|
||||||
"0 0 0 2px var(--mantine-color-body)",
|
isSelected
|
||||||
opacity: isSelected ? 1 : 0.85,
|
? "var(--mantine-primary-color-filled)"
|
||||||
}}
|
: "var(--mantine-color-gray-0)"
|
||||||
/>
|
}
|
||||||
</>
|
c={isSelected ? "white" : undefined}
|
||||||
)}
|
onClick={() =>
|
||||||
<Paper
|
handleSelect(child[0], operationId)
|
||||||
withBorder
|
}
|
||||||
p="xs"
|
style={{ cursor: "pointer" }}>
|
||||||
radius="md"
|
<Flex justify="space-between" align="center">
|
||||||
shadow="sm"
|
<Group gap="xs">
|
||||||
bg={
|
<ActionIcon
|
||||||
isSelected
|
variant="subtle"
|
||||||
? "var(--mantine-primary-color-filled)"
|
size="sm"
|
||||||
: "var(--mantine-color-gray-0)"
|
c={isSelected ? "white" : undefined}
|
||||||
}
|
onClick={(e) => {
|
||||||
c={isSelected ? "white" : undefined}
|
e.stopPropagation()
|
||||||
onClick={() =>
|
objectHide(
|
||||||
handleSelect(child[0], operationId)
|
operationId,
|
||||||
}
|
child[0],
|
||||||
style={{ cursor: "pointer" }}>
|
!isChildHide
|
||||||
<Flex justify="space-between" align="center">
|
)
|
||||||
<Group gap="xs">
|
}}>
|
||||||
<ActionIcon
|
{!isChildHide ? (
|
||||||
variant="subtle"
|
<Eye size={16} />
|
||||||
size="sm"
|
) : (
|
||||||
c={isSelected ? "white" : undefined}
|
<EyeOff size={16} />
|
||||||
onClick={(e) => {
|
)}
|
||||||
e.stopPropagation()
|
</ActionIcon>
|
||||||
objectHide(
|
<Text size="sm" c={textColor}>
|
||||||
operationId,
|
{child[0]?.toString()}
|
||||||
child[0],
|
</Text>
|
||||||
!isChildHide
|
<Tooltip
|
||||||
)
|
label={
|
||||||
}}>
|
<Stack gap={0}>
|
||||||
{!isChildHide ? (
|
<Group gap={4}>
|
||||||
<Eye size={16} />
|
<Text size="xs">创建:</Text>
|
||||||
) : (
|
<Text size="xs">
|
||||||
<EyeOff size={16} />
|
{
|
||||||
)}
|
userOpts.find(
|
||||||
</ActionIcon>
|
(item) =>
|
||||||
<Text size="sm" c={textColor}>
|
item.value === child[2]?.uid
|
||||||
{child[0]?.toString()}
|
)?.label
|
||||||
</Text>
|
}
|
||||||
<Tooltip
|
</Text>
|
||||||
label={
|
<Text size="xs">
|
||||||
<Stack gap={0}>
|
{dayjs(
|
||||||
|
(child[2]?.create_timestamp ||
|
||||||
|
0) * 1000
|
||||||
|
).format("YYYY-MM-DD HH:mm:ss")}
|
||||||
|
</Text>
|
||||||
|
</Group>
|
||||||
|
{child[2]?.first_modified_uid && (
|
||||||
<Group gap={4}>
|
<Group gap={4}>
|
||||||
<Text size="xs">创建:</Text>
|
<Text size="xs">首次修改:</Text>
|
||||||
<Text size="xs">
|
<Text size="xs">
|
||||||
{
|
{
|
||||||
userOpts.find(
|
userOpts.find(
|
||||||
(item) =>
|
(item) =>
|
||||||
item.value ===
|
item.value ===
|
||||||
child[2]?.uid
|
child[2]
|
||||||
|
?.first_modified_uid
|
||||||
)?.label
|
)?.label
|
||||||
}
|
}
|
||||||
</Text>
|
</Text>
|
||||||
<Text size="xs">
|
<Text size="xs">
|
||||||
{dayjs(
|
{dayjs(
|
||||||
(child[2]?.create_timestamp ||
|
(child[2]
|
||||||
|
?.first_modified_timestamp ||
|
||||||
0) * 1000
|
0) * 1000
|
||||||
).format("YYYY-MM-DD HH:mm:ss")}
|
).format("YYYY-MM-DD HH:mm:ss")}
|
||||||
</Text>
|
</Text>
|
||||||
</Group>
|
</Group>
|
||||||
{child[2]?.first_modified_uid && (
|
)}
|
||||||
<Group gap={4}>
|
{child[2]?.last_modified_uid && (
|
||||||
<Text size="xs">
|
<Group gap={4}>
|
||||||
首次修改:
|
<Text size="xs">最新修改:</Text>
|
||||||
</Text>
|
<Text size="xs">
|
||||||
<Text size="xs">
|
{
|
||||||
{
|
userOpts.find(
|
||||||
userOpts.find(
|
(item) =>
|
||||||
(item) =>
|
item.value ===
|
||||||
item.value ===
|
child[2]
|
||||||
child[2]
|
?.last_modified_uid
|
||||||
?.first_modified_uid
|
)?.label
|
||||||
)?.label
|
}
|
||||||
}
|
</Text>
|
||||||
</Text>
|
<Text size="xs">
|
||||||
<Text size="xs">
|
{dayjs(
|
||||||
{dayjs(
|
(child[2]
|
||||||
(child[2]
|
?.last_modified_timestamp ||
|
||||||
?.first_modified_timestamp ||
|
0) * 1000
|
||||||
0) * 1000
|
).format("YYYY-MM-DD HH:mm:ss")}
|
||||||
).format(
|
</Text>
|
||||||
"YYYY-MM-DD HH:mm:ss"
|
</Group>
|
||||||
)}
|
)}
|
||||||
</Text>
|
</Stack>
|
||||||
</Group>
|
}
|
||||||
)}
|
multiline
|
||||||
{child[2]?.last_modified_uid && (
|
bg="white"
|
||||||
<Group gap={4}>
|
c="black"
|
||||||
<Text size="xs">
|
withArrow>
|
||||||
最新修改:
|
<Info
|
||||||
</Text>
|
size={16}
|
||||||
<Text size="xs">
|
style={{ cursor: "pointer" }}
|
||||||
{
|
color={isSelected ? "white" : "black"}
|
||||||
userOpts.find(
|
/>
|
||||||
(item) =>
|
</Tooltip>
|
||||||
item.value ===
|
</Group>
|
||||||
child[2]
|
{comment ? (
|
||||||
?.last_modified_uid
|
<Group gap={4}>
|
||||||
)?.label
|
{comment.map((c: any) => {
|
||||||
}
|
const count =
|
||||||
</Text>
|
c.check_box_comments.length +
|
||||||
<Text size="xs">
|
c.text_comments.length
|
||||||
{dayjs(
|
const { last_modified_timestamp } =
|
||||||
(child[2]
|
child[2]
|
||||||
?.last_modified_timestamp ||
|
let flag = false
|
||||||
0) * 1000
|
if (
|
||||||
).format(
|
count > 0 &&
|
||||||
"YYYY-MM-DD HH:mm:ss"
|
last_modified_timestamp &&
|
||||||
)}
|
last_modified_timestamp > c.date
|
||||||
</Text>
|
)
|
||||||
</Group>
|
flag = true
|
||||||
)}
|
|
||||||
</Stack>
|
let badgeColor = "gray"
|
||||||
}
|
if (c.comment_type === 1)
|
||||||
multiline
|
badgeColor = "green"
|
||||||
bg="white"
|
if (c.comment_type === 2)
|
||||||
c="black"
|
badgeColor = "red"
|
||||||
withArrow>
|
if (flag) badgeColor = "yellow"
|
||||||
<Info
|
|
||||||
size={16}
|
return (
|
||||||
style={{ cursor: "pointer" }}
|
<Popover
|
||||||
color={isSelected ? "white" : "black"}
|
key={`${child[0]}${c.turn}${c.times}`}
|
||||||
/>
|
position="left"
|
||||||
</Tooltip>
|
withArrow>
|
||||||
|
<Popover.Target>
|
||||||
|
<Badge
|
||||||
|
size="xs"
|
||||||
|
circle
|
||||||
|
color={badgeColor}
|
||||||
|
style={{
|
||||||
|
cursor: "pointer",
|
||||||
|
}}>
|
||||||
|
{count}
|
||||||
|
</Badge>
|
||||||
|
</Popover.Target>
|
||||||
|
<Popover.Dropdown>
|
||||||
|
<Text size="xs" c={badgeColor}>
|
||||||
|
{`P${child[2].image_id}:${
|
||||||
|
child[2].uid
|
||||||
|
}:${c.check_box_comments.join(
|
||||||
|
","
|
||||||
|
)},${c.text_comments.join(
|
||||||
|
","
|
||||||
|
)} ${
|
||||||
|
c.date
|
||||||
|
? dayjs(
|
||||||
|
c.date * 1000
|
||||||
|
).format(
|
||||||
|
"YYYY-MM-DD HH:mm:ss"
|
||||||
|
)
|
||||||
|
: ""
|
||||||
|
}`}
|
||||||
|
</Text>
|
||||||
|
</Popover.Dropdown>
|
||||||
|
</Popover>
|
||||||
|
)
|
||||||
|
})}
|
||||||
</Group>
|
</Group>
|
||||||
{comment ? (
|
) : null}
|
||||||
<Group gap={4}>
|
</Flex>
|
||||||
{comment.map((c: any) => {
|
</Paper>
|
||||||
const count =
|
</Box>
|
||||||
c.check_box_comments.length +
|
)
|
||||||
c.text_comments.length
|
})}
|
||||||
const { last_modified_timestamp } =
|
</Stack>
|
||||||
child[2]
|
</Collapse>
|
||||||
let flag = false
|
</Box>
|
||||||
if (
|
)
|
||||||
count > 0 &&
|
})}
|
||||||
last_modified_timestamp &&
|
|
||||||
last_modified_timestamp > c.date
|
|
||||||
)
|
|
||||||
flag = true
|
|
||||||
|
|
||||||
let badgeColor = "gray"
|
|
||||||
if (c.comment_type === 1)
|
|
||||||
badgeColor = "green"
|
|
||||||
if (c.comment_type === 2)
|
|
||||||
badgeColor = "red"
|
|
||||||
if (flag) badgeColor = "yellow"
|
|
||||||
|
|
||||||
return (
|
|
||||||
<Popover
|
|
||||||
key={`${child[0]}${c.turn}${c.times}`}
|
|
||||||
position="left"
|
|
||||||
withArrow>
|
|
||||||
<Popover.Target>
|
|
||||||
<Badge
|
|
||||||
size="xs"
|
|
||||||
circle
|
|
||||||
color={badgeColor}
|
|
||||||
style={{
|
|
||||||
cursor: "pointer",
|
|
||||||
}}>
|
|
||||||
{count}
|
|
||||||
</Badge>
|
|
||||||
</Popover.Target>
|
|
||||||
<Popover.Dropdown>
|
|
||||||
<Text size="xs" c={badgeColor}>
|
|
||||||
{`P${child[2].image_id}:${
|
|
||||||
child[2].uid
|
|
||||||
}:${c.check_box_comments.join(
|
|
||||||
","
|
|
||||||
)},${c.text_comments.join(
|
|
||||||
","
|
|
||||||
)} ${
|
|
||||||
c.date
|
|
||||||
? dayjs(
|
|
||||||
c.date * 1000
|
|
||||||
).format(
|
|
||||||
"YYYY-MM-DD HH:mm:ss"
|
|
||||||
)
|
|
||||||
: ""
|
|
||||||
}`}
|
|
||||||
</Text>
|
|
||||||
</Popover.Dropdown>
|
|
||||||
</Popover>
|
|
||||||
)
|
|
||||||
})}
|
|
||||||
</Group>
|
|
||||||
) : null}
|
|
||||||
</Flex>
|
|
||||||
</Paper>
|
|
||||||
</Box>
|
|
||||||
)
|
|
||||||
})}
|
|
||||||
</Stack>
|
|
||||||
</Collapse>
|
|
||||||
</Box>
|
|
||||||
)
|
|
||||||
})}
|
|
||||||
</Stack>
|
</Stack>
|
||||||
</ScrollArea>
|
</ScrollArea>
|
||||||
</Collapse>
|
</Collapse>
|
||||||
|
|||||||
Reference in New Issue
Block a user