From 6aff25a38f9f10c051d38a7136972379f43016a2 Mon Sep 17 00:00:00 2001 From: zhangheng Date: Fri, 10 Apr 2026 11:14:06 +0800 Subject: [PATCH] feat(tool): hide all object --- .../label/components/RightObjectTools.tsx | 840 +++++++++--------- 1 file changed, 433 insertions(+), 407 deletions(-) diff --git a/components/label/components/RightObjectTools.tsx b/components/label/components/RightObjectTools.tsx index 0d8934b..91ebed6 100644 --- a/components/label/components/RightObjectTools.tsx +++ b/components/label/components/RightObjectTools.tsx @@ -355,13 +355,10 @@ const RightObjectTools: React.FC = (props) => { if (operationMap) { const objList = operationMap.get(operationId) if (objList && objList.length) { - let hideFlag = true - objList.forEach(([id]) => { - const objStatus = - useObjectStore.getState().pathStatus[`${imgId}${id}`] - if (objStatus && !objStatus["HIDE"]) { - hideFlag = false - } + const hideFlag = objList.every(([id]) => { + return useObjectStore.getState().pathStatus[`${imgId}${id}`]?.["HIDE"] + ? true + : false }) updateOperationStatus(imgId + operationId, "HIDE", hideFlag) } @@ -401,6 +398,39 @@ const RightObjectTools: React.FC = (props) => { [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 index = name?.indexOf(input); // const beforeStr = name?.substring(0, index); @@ -509,9 +539,22 @@ const RightObjectTools: React.FC = (props) => { - - 对象列表 - + + { + if (!totalObjectCount) return + activeImageOperations.forEach((operationId) => { + operationHide(operationId, !areAllObjectsHidden) + }) + }}> + {areAllObjectsHidden ? : } + + + 对象列表 + + = (props) => { }}> - {labelState.get(activeImage) && - labelState.get(activeImage)?.map((operationId) => { - const operationSchema = getOperationSchema(operationId) - const isCollapsed = - operationStatus[activeImage + operationId]?.["COLLAPSE"] - const isHide = - operationStatus[activeImage + operationId]?.HIDE - const hasSubAttrError = getOperationSubAttrStatus(operationId) - const operationLabel = operationSchema?.label_class - const operationChildren = - storeLabel.get(activeImage)?.get(operationId) || [] - const objectCount = operationChildren.length - const visibleChildren = operationChildren.filter((child) => { - const { comment } = child[2] - let visibleFlag = true - if (comment && comment.length) { - const latest_comment = - (taskDetail && taskDetail.label_status === 2) || - comment.length === 1 - ? comment[comment.length - 1] - : comment[comment.length - 2] - let type = latest_comment.comment_type - if (type === 2) { - const { last_modified_timestamp } = child[2] - if ( - last_modified_timestamp && - last_modified_timestamp > latest_comment.date - ) - type = 3 - } - visibleFlag = checkBoxsChecked[3 - type] + {activeImageOperations.map((operationId) => { + const operationSchema = getOperationSchema(operationId) + const isCollapsed = + operationStatus[activeImage + operationId]?.["COLLAPSE"] + const isHide = isOperationHidden(activeImage, operationId) + const hasSubAttrError = getOperationSubAttrStatus(operationId) + const operationLabel = operationSchema?.label_class + const operationChildren = + storeLabel.get(activeImage)?.get(operationId) || [] + const objectCount = operationChildren.length + const visibleChildren = operationChildren.filter((child) => { + const { comment } = child[2] + let visibleFlag = true + if (comment && comment.length) { + const latest_comment = + (taskDetail && taskDetail.label_status === 2) || + comment.length === 1 + ? comment[comment.length - 1] + : comment[comment.length - 2] + let type = latest_comment.comment_type + if (type === 2) { + const { last_modified_timestamp } = child[2] + if ( + last_modified_timestamp && + last_modified_timestamp > latest_comment.date + ) + type = 3 } - if (checkBoxsChecked.every((value) => !value)) - visibleFlag = true - return visibleFlag - }) - return ( - - - - - - operationHide(operationId, !isHide) - }> - {!isHide ? ( - - ) : ( - - )} - - - - {renderOperationIcon(operationSchema)} - - {renderShortcutKey(operationId)} - - - - - {operationLabel} - - - - + visibleFlag = checkBoxsChecked[3 - type] + } + if (checkBoxsChecked.every((value) => !value)) + visibleFlag = true + return visibleFlag + }) + return ( + + + + + operationHide(operationId, !isHide)}> + {!isHide ? : } + - { - setSearchSubAttrs((searchValues) => ({ - ...searchValues, - [operationId]: e.target.value, - })) - }} - onKeyDown={(e) => - handleSelectedBySearchSubAttr(e, operationId) - } - /> - - {objectCount} - - { - updateOperationStatus( - activeImage + operationId, - "COLLAPSE", - !isCollapsed - ) + style={{ flex: 1, minWidth: 0 }}> + - {!isCollapsed ? ( - - ) : ( - - )} - + {renderOperationIcon(operationSchema)} + + {renderShortcutKey(operationId)} + + + + + {operationLabel} + + - - - - {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 - - 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)" + + { + setSearchSubAttrs((searchValues) => ({ + ...searchValues, + [operationId]: e.target.value, + })) + }} + onKeyDown={(e) => + handleSelectedBySearchSubAttr(e, operationId) } + /> + + {objectCount} + + { + updateOperationStatus( + activeImage + operationId, + "COLLAPSE", + !isCollapsed + ) + }}> + {!isCollapsed ? ( + + ) : ( + + )} + + + + + + + {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 ( + + style={{ + position: "absolute", + left: 7, + top: 0, + bottom: isLastVisibleChild ? "75%" : 0, + width: 1.5, + borderRadius: 999, + background: connectorColor, + opacity: isSelected ? 0.9 : 0.35, + }} + /> + {isLastVisibleChild ? ( - {isLastVisibleChild ? ( + ) : ( + <> - ) : ( - <> - - - - )} - - handleSelect(child[0], operationId) - } - style={{ cursor: "pointer" }}> - - - { - e.stopPropagation() - objectHide( - operationId, - child[0], - !isChildHide - ) - }}> - {!isChildHide ? ( - - ) : ( - - )} - - - {child[0]?.toString()} - - + + + )} + + handleSelect(child[0], operationId) + } + style={{ cursor: "pointer" }}> + + + { + e.stopPropagation() + objectHide( + operationId, + child[0], + !isChildHide + ) + }}> + {!isChildHide ? ( + + ) : ( + + )} + + + {child[0]?.toString()} + + + + 创建: + + { + userOpts.find( + (item) => + item.value === child[2]?.uid + )?.label + } + + + {dayjs( + (child[2]?.create_timestamp || + 0) * 1000 + ).format("YYYY-MM-DD HH:mm:ss")} + + + {child[2]?.first_modified_uid && ( - 创建: + 首次修改: { userOpts.find( (item) => item.value === - child[2]?.uid + child[2] + ?.first_modified_uid )?.label } {dayjs( - (child[2]?.create_timestamp || + (child[2] + ?.first_modified_timestamp || 0) * 1000 ).format("YYYY-MM-DD HH:mm:ss")} - {child[2]?.first_modified_uid && ( - - - 首次修改: - - - { - userOpts.find( - (item) => - item.value === - child[2] - ?.first_modified_uid - )?.label - } - - - {dayjs( - (child[2] - ?.first_modified_timestamp || - 0) * 1000 - ).format( - "YYYY-MM-DD HH:mm:ss" - )} - - - )} - {child[2]?.last_modified_uid && ( - - - 最新修改: - - - { - userOpts.find( - (item) => - item.value === - child[2] - ?.last_modified_uid - )?.label - } - - - {dayjs( - (child[2] - ?.last_modified_timestamp || - 0) * 1000 - ).format( - "YYYY-MM-DD HH:mm:ss" - )} - - - )} - - } - multiline - bg="white" - c="black" - withArrow> - - + )} + {child[2]?.last_modified_uid && ( + + 最新修改: + + { + userOpts.find( + (item) => + item.value === + child[2] + ?.last_modified_uid + )?.label + } + + + {dayjs( + (child[2] + ?.last_modified_timestamp || + 0) * 1000 + ).format("YYYY-MM-DD HH:mm:ss")} + + + )} + + } + multiline + bg="white" + c="black" + withArrow> + + + + {comment ? ( + + {comment.map((c: any) => { + const count = + c.check_box_comments.length + + c.text_comments.length + const { last_modified_timestamp } = + child[2] + let flag = false + 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 ( + + + + {count} + + + + + {`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" + ) + : "" + }`} + + + + ) + })} - {comment ? ( - - {comment.map((c: any) => { - const count = - c.check_box_comments.length + - c.text_comments.length - const { last_modified_timestamp } = - child[2] - let flag = false - 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 ( - - - - {count} - - - - - {`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" - ) - : "" - }`} - - - - ) - })} - - ) : null} - - - - ) - })} - - - - ) - })} + ) : null} + + + + ) + })} + + + + ) + })}