solved bugs(while use backspace key and escape key) and added the groupnames correctly

This commit is contained in:
2025-10-23 18:04:31 +05:30
parent efb95e6680
commit 3f45fda3bb
2 changed files with 10 additions and 341 deletions

View File

@@ -68,7 +68,7 @@ const TreeNode: React.FC<TreeNodeProps> = ({
const [isVisible, setIsVisible] = useState(item.isVisible ?? true); const [isVisible, setIsVisible] = useState(item.isVisible ?? true);
const [isLocked, setIsLocked] = useState(item.isLocked ?? false); const [isLocked, setIsLocked] = useState(item.isLocked ?? false);
const [isEditing, setIsEditing] = useState(false); const [isEditing, setIsEditing] = useState(false);
const [name, setName] = useState(isGroupNode ? item.groupName : item.modelName); const [name, setName] = useState(item.groupName || item.modelName);
const handleDragStart = (e: React.DragEvent) => { const handleDragStart = (e: React.DragEvent) => {
e.stopPropagation(); e.stopPropagation();
@@ -108,10 +108,11 @@ const TreeNode: React.FC<TreeNodeProps> = ({
}; };
const handleDivKeyDown = (e: React.KeyboardEvent<HTMLDivElement>) => { const handleDivKeyDown = (e: React.KeyboardEvent<HTMLDivElement>) => {
// support Enter and Space for accessibility if (e.key === "Enter") {
if (e.key === "Enter" || e.key === " ") {
e.preventDefault(); e.preventDefault();
toggleSelect(); toggleSelect();
} else if (e.key === "Escape") {
setIsEditing(false);
} }
}; };
@@ -122,7 +123,6 @@ const TreeNode: React.FC<TreeNodeProps> = ({
return ( return (
<div className="tree-node"> <div className="tree-node">
<div <div
tabIndex={0}
onKeyDown={handleDivKeyDown} onKeyDown={handleDivKeyDown}
onTouchStart={handleTouchStart} onTouchStart={handleTouchStart}
className={clsx("tree-node-content", { className={clsx("tree-node-content", {
@@ -140,7 +140,7 @@ const TreeNode: React.FC<TreeNodeProps> = ({
id={item.modelUuid || item.groupUuid} id={item.modelUuid || item.groupUuid}
onClick={toggleSelect} onClick={toggleSelect}
> >
<div className="node-wrapper" style={{ paddingLeft: `${level * 25 + 8}px` }}> <div className="node-wrapper" style={{ paddingLeft: `${level * 6 + 1}px` }}>
{isGroupNode && ( {isGroupNode && (
<button <button
className="expand-button" className="expand-button"
@@ -217,7 +217,7 @@ const TreeNode: React.FC<TreeNodeProps> = ({
</div> </div>
</div> </div>
{isExpanded && item.children?.length ? ( {isExpanded && item.children?.length ? (
<div className="tree-children"> <div className="tree-children" style={{ paddingLeft: "10px" }}>
{item.children.map((child) => ( {item.children.map((child) => (
<TreeNode <TreeNode
key={child.groupUuid || child.modelUuid} key={child.groupUuid || child.modelUuid}
@@ -301,8 +301,6 @@ export const OutlineList: React.FC<OutlinePanelProps> = ({
if (!insertItemByAction(draggedItem, targetId, action, updatedHierarchy)) { if (!insertItemByAction(draggedItem, targetId, action, updatedHierarchy)) {
updatedHierarchy.push(draggedItem); updatedHierarchy.push(draggedItem);
} }
// Commit changes
setGroupHierarchy(updatedHierarchy); setGroupHierarchy(updatedHierarchy);
setDraggingItem(null); setDraggingItem(null);
hoveredDiv.style.borderTop = "none"; hoveredDiv.style.borderTop = "none";
@@ -404,7 +402,6 @@ export const OutlineList: React.FC<OutlinePanelProps> = ({
const hoveredDiv = document.getElementById(targetId); const hoveredDiv = document.getElementById(targetId);
if (!hoveredDiv) return; if (!hoveredDiv) return;
// Remove previous outlines before applying new one
hoveredDiv.style.outline = "none"; hoveredDiv.style.outline = "none";
hoveredDiv.style.borderTop = "none"; hoveredDiv.style.borderTop = "none";
hoveredDiv.style.borderBottom = "none"; hoveredDiv.style.borderBottom = "none";
@@ -412,21 +409,13 @@ export const OutlineList: React.FC<OutlinePanelProps> = ({
const rect = hoveredDiv.getBoundingClientRect(); const rect = hoveredDiv.getBoundingClientRect();
const y = (event as any).clientY - rect.top; const y = (event as any).clientY - rect.top;
// Determine where the user is hovering
if (y >= 0 && y < 7) { if (y >= 0 && y < 7) {
// Top region
console.log("Top: ");
hoveredDiv.style.borderTop = "2px solid purple"; hoveredDiv.style.borderTop = "2px solid purple";
return "above"; return "above";
} else if (y >= 19 && y < 32) { } else if (y >= 19 && y < 32) {
// Bottom region
console.log("Bottom: ");
hoveredDiv.style.borderBottom = "2px solid purple"; hoveredDiv.style.borderBottom = "2px solid purple";
return "below"; return "below";
} else { } else {
// Middle region (child)
console.log("Middle: ");
hoveredDiv.style.outline = "2px solid #b188ff"; hoveredDiv.style.outline = "2px solid #b188ff";
return "child"; return "child";
} }
@@ -475,8 +464,8 @@ export const OutlineList: React.FC<OutlinePanelProps> = ({
onDrop={handleDrop} onDrop={handleDrop}
onDragOver={handleDragOver} onDragOver={handleDragOver}
draggingItem={draggingItem} draggingItem={draggingItem}
selectedObject={selectedObject} // pass UUID selectedObject={selectedObject}
setSelectedObject={setSelectedObject} // pass setter setSelectedObject={setSelectedObject}
/> />
))} ))}
</div> </div>

View File

@@ -1,321 +1,3 @@
// .outline-overlay {
// padding: 0 4px;
// font-family: "Segoe UI", sans-serif;
// display: flex;
// position: absolute;
// top: 0;
// bottom: 0;
// width: 100vw;
// pointer-events: none;
// .outline-card {
// pointer-events: all;
// }
// }
// .outline-header {
// display: flex;
// align-items: center;
// justify-content: space-between;
// padding: 10px 16px;
// border-bottom: 1px solid #2e2e3e;
// .header-title {
// p {
// margin: 0;
// font-weight: 600;
// font-size: 14px;
// color: #ffffff;
// }
// }
// .outline-toolbar {
// display: flex;
// gap: 8px;
// .toolbar-button {
// background: none;
// border: none;
// color: #aaa;
// cursor: pointer;
// width: 24px;
// height: 24px;
// border-radius: 4px;
// transition: background 0.3s;
// &:hover {
// background-color: rgba(255, 255, 255, 0.1);
// color: #a855f7;
// }
// svg {
// width: 100%;
// height: 100%;
// }
// }
// .close-button {
// background: none;
// border: none;
// color: #aaa;
// cursor: pointer;
// width: 24px;
// height: 24px;
// border-radius: 4px;
// transition: transform 0.3s ease;
// &:hover {
// background-color: rgba(255, 255, 255, 0.1);
// transform: rotate(-90deg);
// color: #a855f7;
// }
// svg {
// width: 100%;
// height: 100%;
// }
// }
// }
// }
// .outline-content {
// max-height: 52vh;
// overflow-y: auto;
// padding: 8px 0;
// &::-webkit-scrollbar {
// width: 6px;
// }
// &::-webkit-scrollbar-thumb {
// background: #a855f7;
// border-radius: 10px;
// }
// }
// .tree-node {
// display: flex;
// flex-direction: column;
// width: 100%;
// outline: 2px solid transparent;
// transition: all 0.3s ease;
// .tree-node-content {
// display: flex;
// align-items: center;
// width: 100%;
// padding: 6px 10px;
// border-radius: 8px;
// background: transparent;
// transition: background 0.2s ease, outline 0.2s ease;
// box-sizing: border-box;
// position: relative;
// &:hover {
// background: rgba(255, 255, 255, 0.05);
// }
// &.selected {
// background: var(--background-color-accent, #6f42c1);
// }
// &.multi-selected {
// background: rgba(167, 139, 250, 0.2);
// border-left: 3px solid var(--highlight-secondary-color, #a855f7);
// }
// .expand-button {
// background: none;
// border: none;
// color: #aaa;
// cursor: pointer;
// width: 18px;
// height: 18px;
// flex-shrink: 0;
// display: flex;
// align-items: center;
// justify-content: center;
// &:hover {
// color: #a855f7;
// }
// }
// .node-wrapper {
// display: flex;
// align-items: center;
// flex: 1;
// min-width: 0;
// gap: 8px;
// }
// .node-icon {
// color: #a855f7;
// flex-shrink: 0;
// width: 16px;
// height: 16px;
// display: flex;
// align-items: center;
// justify-content: center;
// }
// .rename-input {
// flex: 1;
// min-width: 0;
// overflow: hidden;
// white-space: nowrap;
// text-overflow: ellipsis;
// font-size: 14px;
// color: #fff;
// input.renaming {
// width: 100%;
// border: none;
// outline: none;
// border-radius: 6px;
// background: rgba(255, 255, 255, 0.1);
// color: #fff;
// padding: 3px 6px;
// font-size: 14px;
// box-sizing: border-box;
// }
// }
// .node-controls {
// display: flex;
// align-items: center;
// gap: 4px;
// flex-shrink: 0;
// .control-button {
// background: none;
// border: none;
// color: #aaa;
// cursor: pointer;
// border-radius: 4px;
// padding: 4px;
// display: flex;
// align-items: center;
// justify-content: center;
// &:hover {
// background: rgba(255, 255, 255, 0.1);
// color: #a855f7;
// }
// svg {
// width: 14px;
// height: 14px;
// }
// }
// }
// }
// .tree-children {
// padding-left: 16px;
// border-left: 1px dashed rgba(255, 255, 255, 0.1);
// margin-left: 6px;
// }
// }
// // .tree-node {
// // display: flex;
// // flex-direction: column;
// // outline: 2px solid transparent;
// // transition: background 0.3s;
// // .tree-node-content {
// // display: flex;
// // align-items: center;
// // padding: 8px 9px;
// // gap: 6px;
// // transition: background 0.2s ease;
// // position: relative;
// // &.selected {
// // background: #6f42c1;
// // border-radius: 45px;
// // }
// // &:hover {
// // outline: 1px solid pink;
// // border-radius: 80px;
// // }
// // .node-wrapper {
// // display: flex;
// // gap: 40px;
// // }
// // .expand-button {
// // background: none;
// // border: none;
// // cursor: pointer;
// // width: 20px;
// // height: 20px;
// // padding: 0;
// // color: #aaa;
// // &:hover {
// // color: #a855f7;
// // }
// // }
// // .node-icon {
// // color: white;
// // width: 18px;
// // flex-shrink: 0;
// // }
// // .rename-input {
// // background: transparent;
// // border: none;
// // color: #fff;
// // font-size: 14px;
// // flex: 1;
// // outline: none;
// // padding: 2px 4px;
// // &:focus {
// // border-bottom: 1px solid #a855f7;
// // }
// // .renaming {
// // outline: none;
// // border: none;
// // border-radius: 15px;
// // height: 20px;
// // }
// // }
// // .node-controls {
// // display: flex;
// // gap: 6px;
// // .control-button {
// // background: none;
// // border: none;
// // color: #888;
// // cursor: pointer;
// // // padding: 4px;
// // border-radius: 4px;
// // &:hover {
// // background-color: rgba(255, 255, 255, 0.1);
// // color: #a855f7;
// // }
// // svg {
// // width: 16px;
// // height: 16px;
// // }
// // }
// // }
// // }
// // }
// // .tree-children {
// // padding-left: 16px;
// // border-left: 1px dashed rgba(255, 255, 255, 0.05);
// // }
// Outline Component Styles
// Professional tree/hierarchy view with drag-and-drop support
.outline-overlay { .outline-overlay {
padding: 0 4px; padding: 0 4px;
font-family: "Segoe UI", sans-serif; font-family: "Segoe UI", sans-serif;
@@ -434,14 +116,13 @@
.tree-node-content { .tree-node-content {
display: flex; display: flex;
align-items: center; align-items: center;
padding: 8px 12px; padding: 3px 8px;
margin: 2px 2px;
gap: 8px; gap: 8px;
transition: background 0.2s ease; transition: background 0.2s ease;
position: relative; position: relative;
cursor: pointer; cursor: pointer;
border-radius: 6px; border-radius: 6px;
margin: 2px 8px;
&.selected { &.selected {
background: #6f42c1; background: #6f42c1;
border-radius: 50px; border-radius: 50px;
@@ -560,7 +241,6 @@
} }
.tree-children { .tree-children {
padding-left: 16px;
border-left: 1px dashed rgba(255, 255, 255, 0.05); border-left: 1px dashed rgba(255, 255, 255, 0.05);
} }