Refactor DistanceLines component for improved label positioning and remove unused DistanceLine component

This commit is contained in:
Vishnu 2025-04-01 12:25:01 +05:30
parent b5833696a5
commit e95abfb4dd
3 changed files with 120 additions and 222 deletions

View File

@ -15,7 +15,6 @@ interface DisplayZoneProps {
[key: string]: { [key: string]: {
activeSides: Side[]; activeSides: Side[];
panelOrder: Side[]; panelOrder: Side[];
lockedPanels: Side[]; lockedPanels: Side[];
widgets: Widget[]; widgets: Widget[];
zoneId: string; zoneId: string;
@ -27,7 +26,6 @@ interface DisplayZoneProps {
zoneName: string; zoneName: string;
activeSides: Side[]; activeSides: Side[];
panelOrder: Side[]; panelOrder: Side[];
lockedPanels: Side[]; lockedPanels: Side[];
zoneId: string; zoneId: string;
zoneViewPortTarget: number[]; zoneViewPortTarget: number[];
@ -45,7 +43,6 @@ interface DisplayZoneProps {
zoneName: string; zoneName: string;
activeSides: Side[]; activeSides: Side[];
panelOrder: Side[]; panelOrder: Side[];
lockedPanels: Side[]; lockedPanels: Side[];
zoneId: string; zoneId: string;
zoneViewPortTarget: number[]; zoneViewPortTarget: number[];
@ -66,19 +63,18 @@ const DisplayZone: React.FC<DisplayZoneProps> = ({
selectedZone, selectedZone,
setSelectedZone, setSelectedZone,
}) => { }) => {
// Refs
// Ref for the container element
const containerRef = useRef<HTMLDivElement | null>(null); const containerRef = useRef<HTMLDivElement | null>(null);
const scrollContainerRef = useRef<HTMLDivElement | null>(null);
// State to track overflow visibility // State to track overflow visibility
const [showLeftArrow, setShowLeftArrow] = useState(false); const [showLeftArrow, setShowLeftArrow] = useState(false);
const [showRightArrow, setShowRightArrow] = useState(false); const [showRightArrow, setShowRightArrow] = useState(false);
const { floatingWidget, setFloatingWidget } = useFloatingWidget() const { floatingWidget, setFloatingWidget } = useFloatingWidget();
// Function to calculate overflow state // Function to calculate overflow state
const updateOverflowState = useCallback(() => { const updateOverflowState = useCallback(() => {
const container = containerRef.current; const container = scrollContainerRef.current;
if (container) { if (container) {
const isOverflowing = container.scrollWidth > container.clientWidth; const isOverflowing = container.scrollWidth > container.clientWidth;
const canScrollLeft = container.scrollLeft > 0; const canScrollLeft = container.scrollLeft > 0;
@ -91,59 +87,56 @@ const DisplayZone: React.FC<DisplayZoneProps> = ({
}, []); }, []);
useEffect(() => { useEffect(() => {
const container = containerRef.current; const container = scrollContainerRef.current;
if (!container) return;
if (container) {
// Initial calculation after the DOM has been rendered // Initial calculation after the DOM has been rendered
const handleInitialRender = () => { const observer = new ResizeObserver(updateOverflowState);
requestAnimationFrame(updateOverflowState); observer.observe(container);
};
handleInitialRender(); // Update on scroll
// Update on window resize or scroll
const handleResize = () => updateOverflowState();
const handleScroll = () => updateOverflowState(); const handleScroll = () => updateOverflowState();
container.addEventListener("scroll", handleScroll);
// Add mouse wheel listener for horizontal scrolling // Add mouse wheel listener for horizontal scrolling
const handleWheel = (event: WheelEvent) => { const handleWheel = (event: WheelEvent) => {
event.preventDefault(); // Prevent default vertical scrolling if (Math.abs(event.deltaY) > Math.abs(event.deltaX)) {
if (container) { event.preventDefault();
container.scrollBy({ container.scrollBy({
left: event.deltaY * 2, // Translate vertical scroll to horizontal scroll left: event.deltaY * 2,
behavior: "smooth", behavior: "smooth",
}); });
} }
}; };
container.addEventListener("scroll", handleScroll);
window.addEventListener("resize", handleResize);
container.addEventListener("wheel", handleWheel, { passive: false }); container.addEventListener("wheel", handleWheel, { passive: false });
// Initial check
updateOverflowState();
return () => { return () => {
observer.disconnect();
container.removeEventListener("scroll", handleScroll); container.removeEventListener("scroll", handleScroll);
window.removeEventListener("resize", handleResize);
container.removeEventListener("wheel", handleWheel); container.removeEventListener("wheel", handleWheel);
}; };
}
}, [updateOverflowState]); }, [updateOverflowState]);
// Handle scrolling with navigation arrows // Handle scrolling with navigation arrows
const handleScrollLeft = () => { const handleScrollLeft = () => {
const container = containerRef.current; const container = scrollContainerRef.current;
if (container) { if (container) {
container.scrollBy({ container.scrollBy({
left: -200, // Scroll left by 200px left: -200,
behavior: "smooth", behavior: "smooth",
}); });
} }
}; };
const handleScrollRight = () => { const handleScrollRight = () => {
const container = containerRef.current; const container = scrollContainerRef.current;
if (container) { if (container) {
container.scrollBy({ container.scrollBy({
left: 200, // Scroll right by 200px left: 200,
behavior: "smooth", behavior: "smooth",
}); });
} }
@ -152,24 +145,22 @@ const DisplayZone: React.FC<DisplayZoneProps> = ({
async function handleSelect2dZoneData(zoneId: string, zoneName: string) { async function handleSelect2dZoneData(zoneId: string, zoneName: string) {
try { try {
if (selectedZone?.zoneId === zoneId) { if (selectedZone?.zoneId === zoneId) {
return; return;
} }
const email = localStorage.getItem("email") || ""; const email = localStorage.getItem("email") || "";
const organization = email?.split("@")[1]?.split(".")[0]; const organization = email?.split("@")[1]?.split(".")[0];
// Fetch data from backend
let response = await getSelect2dZoneData(zoneId, organization); let response = await getSelect2dZoneData(zoneId, organization);
console.log('response: ', response); console.log('response: ', response);
let res = await getFloatingZoneData(zoneId, organization); let res = await getFloatingZoneData(zoneId, organization);
setFloatingWidget(res) setFloatingWidget(res);
// Set the selected zone in the store
useDroppedObjectsStore.getState().setZone(zoneName, zoneId); useDroppedObjectsStore.getState().setZone(zoneName, zoneId);
if (Array.isArray(res)) { if (Array.isArray(res)) {
res.forEach((val) => { res.forEach((val) => {
useDroppedObjectsStore.getState().addObject(zoneName, val); useDroppedObjectsStore.getState().addObject(zoneName, val);
}); });
} }
// Update selected zone state
setSelectedZone({ setSelectedZone({
zoneName, zoneName,
activeSides: response.activeSides || [], activeSides: response.activeSides || [],
@ -181,17 +172,14 @@ const DisplayZone: React.FC<DisplayZoneProps> = ({
zoneViewPortPosition: response.viewPortposition || {}, zoneViewPortPosition: response.viewPortposition || {},
}); });
} catch (error) { } catch (error) {
console.error(error);
} }
} }
return ( return (
<div <div
ref={containerRef} ref={containerRef}
className={`zone-wrapper ${selectedZone?.activeSides?.includes("bottom") && "bottom" className={`zone-wrapper ${selectedZone?.activeSides?.includes("bottom") ? "bottom" : ""}`}
}`}
> >
{/* Left Arrow */} {/* Left Arrow */}
{showLeftArrow && ( {showLeftArrow && (
@ -200,28 +188,31 @@ const DisplayZone: React.FC<DisplayZoneProps> = ({
</button> </button>
)} )}
{/* Zones Wrapper */} {/* Scrollable Zones Container */}
<div
ref={scrollContainerRef}
className="zones-wrapper"
style={{ overflowX: "auto", whiteSpace: "nowrap" }}
>
{Object.keys(zonesData).length !== 0 ? ( {Object.keys(zonesData).length !== 0 ? (
<div ref={containerRef} className="zones-wrapper"> <>
{Object.keys(zonesData).map((zoneName, index) => ( {Object.keys(zonesData).map((zoneName, index) => (
<div <div
key={index} key={index}
className={`zone ${selectedZone.zoneName === zoneName ? "active" : "" className={`zone ${selectedZone.zoneName === zoneName ? "active" : ""}`}
}`} onClick={() => handleSelect2dZoneData(zonesData[zoneName]?.zoneId, zoneName)}
onClick={() => {
handleSelect2dZoneData(zonesData[zoneName]?.zoneId, zoneName)
}}
> >
{zoneName} {zoneName}
</div> </div>
))} ))}
</div> </>
) : ( ) : (
<div className="no-zone"> <div className="no-zone">
<InfoIcon /> <InfoIcon />
No zones? Create one! No zones? Create one!
</div> </div>
)} )}
</div>
{/* Right Arrow */} {/* Right Arrow */}
{showRightArrow && ( {showRightArrow && (

View File

@ -1,130 +0,0 @@
import React from "react";
interface DistanceLinesProps {
obj: {
position: {
top?: number | "auto";
left?: number | "auto";
right?: number | "auto";
bottom?: number | "auto";
};
};
activeEdges: {
vertical: "top" | "bottom";
horizontal: "left" | "right";
} | null;
}
const DistanceLines: React.FC<DistanceLinesProps> = ({ obj, activeEdges }) => {
if (!activeEdges) return null;
return (
<>
{activeEdges.vertical === "top" &&
typeof obj.position.top === "number" && (
<div
className="distance-line top"
style={{
top: 0,
left:
activeEdges.horizontal === "left"
? `${(obj.position.left as number) + 125}px`
: `calc(100% - ${(obj.position.right as number) + 125}px)`,
height: `${obj.position.top}px`,
}}
>
<span
className="distance-label"
style={{
position: "absolute",
top: "50%",
transform: "translate(-50%,0%)",
}}
>
{obj.position.top}px
</span>
</div>
)}
{activeEdges.vertical === "bottom" &&
typeof obj.position.bottom === "number" && (
<div
className="distance-line bottom"
style={{
bottom: 0,
left:
activeEdges.horizontal === "left"
? `${(obj.position.left as number) + 125}px`
: `calc(100% - ${(obj.position.right as number) + 125}px)`,
height: `${obj.position.bottom}px`,
}}
>
<span
className="distance-label"
style={{
position: "absolute",
bottom: "50%",
transform: "translate(-50%,0%)",
}}
>
{obj.position.bottom}px
</span>
</div>
)}
{activeEdges.horizontal === "left" &&
typeof obj.position.left === "number" && (
<div
className="distance-line left"
style={{
left: 0,
top:
activeEdges.vertical === "top"
? `${(obj.position.top as number) + 41.5}px`
: `calc(100% - ${(obj.position.bottom as number) + 41.5}px)`,
width: `${obj.position.left}px`,
}}
>
<span
className="distance-label"
style={{
position: "absolute",
left: "50%",
transform: "translate(0,-50%)",
}}
>
{obj.position.left}px
</span>
</div>
)}
{activeEdges.horizontal === "right" &&
typeof obj.position.right === "number" && (
<div
className="distance-line right"
style={{
right: 0,
top:
activeEdges.vertical === "top"
? `${(obj.position.top as number) + 41.5}px`
: `calc(100% - ${(obj.position.bottom as number) + 41.5}px)`,
width: `${obj.position.right}px`,
}}
>
<span
className="distance-label"
style={{
position: "absolute",
right: "50%",
transform: "translate(0,-50%)",
}}
>
{obj.position.right}px
</span>
</div>
)}
</>
);
};
export default DistanceLines;

View File

@ -20,7 +20,8 @@ const DistanceLines: React.FC<DistanceLinesProps> = ({ obj, activeEdges }) => {
return ( return (
<> <>
{activeEdges.vertical === "top" && typeof obj.position.top === "number" && ( {activeEdges.vertical === "top" &&
typeof obj.position.top === "number" && (
<div <div
className="distance-line top" className="distance-line top"
style={{ style={{
@ -32,7 +33,16 @@ const DistanceLines: React.FC<DistanceLinesProps> = ({ obj, activeEdges }) => {
height: `${obj.position.top}px`, height: `${obj.position.top}px`,
}} }}
> >
<span className="distance-label">{obj.position.top}px</span> <span
className="distance-label"
style={{
position: "absolute",
top: "50%",
transform: "translate(-50%,0%)",
}}
>
{obj.position.top}px
</span>
</div> </div>
)} )}
@ -49,7 +59,16 @@ const DistanceLines: React.FC<DistanceLinesProps> = ({ obj, activeEdges }) => {
height: `${obj.position.bottom}px`, height: `${obj.position.bottom}px`,
}} }}
> >
<span className="distance-label">{obj.position.bottom}px</span> <span
className="distance-label"
style={{
position: "absolute",
bottom: "50%",
transform: "translate(-50%,0%)",
}}
>
{obj.position.bottom}px
</span>
</div> </div>
)} )}
@ -66,7 +85,16 @@ const DistanceLines: React.FC<DistanceLinesProps> = ({ obj, activeEdges }) => {
width: `${obj.position.left}px`, width: `${obj.position.left}px`,
}} }}
> >
<span className="distance-label">{obj.position.left}px</span> <span
className="distance-label"
style={{
position: "absolute",
left: "50%",
transform: "translate(0,-50%)",
}}
>
{obj.position.left}px
</span>
</div> </div>
)} )}
@ -83,7 +111,16 @@ const DistanceLines: React.FC<DistanceLinesProps> = ({ obj, activeEdges }) => {
width: `${obj.position.right}px`, width: `${obj.position.right}px`,
}} }}
> >
<span className="distance-label">{obj.position.right}px</span> <span
className="distance-label"
style={{
position: "absolute",
right: "50%",
transform: "translate(0,-50%)",
}}
>
{obj.position.right}px
</span>
</div> </div>
)} )}
</> </>