Merge branch 'v2-ui' of http://185.100.212.76:7776/Dwinzo-Beta/Dwinzo_dev into v2-ui
This commit is contained in:
commit
3944588cb0
|
@ -12,140 +12,198 @@ import Widget4InputCard3D from './Widget4InputCard3D'
|
|||
import WarehouseThroughputInputComponent from './WarehouseThroughputInputComponent'
|
||||
import { useWidgetStore } from '../../../../../store/useWidgetStore'
|
||||
|
||||
// const InputSelecterComponent = () => {
|
||||
// const { selectedChartId } = useWidgetStore();
|
||||
|
||||
// if (selectedChartId && selectedChartId.type && selectedChartId.type === 'bar' ) {
|
||||
// return (
|
||||
// <>
|
||||
// <div className="sideBarHeader">2D Widget Input</div>
|
||||
// <BarChartInput />
|
||||
// </>
|
||||
// )
|
||||
// }
|
||||
|
||||
// else if (selectedChartId && selectedChartId.type && selectedChartId.type === 'line' ) {
|
||||
// return (
|
||||
// <>
|
||||
// <div className="sideBarHeader">2D Widget Input</div>
|
||||
// <LineGrapInput />
|
||||
// </>
|
||||
// )
|
||||
// }
|
||||
|
||||
// else if (selectedChartId && selectedChartId.type && selectedChartId.type === 'pie' ) {
|
||||
// return (
|
||||
// <>
|
||||
// <div className="sideBarHeader">2D Widget Input</div>
|
||||
// <PieChartInput />
|
||||
// </>
|
||||
// )
|
||||
// }
|
||||
|
||||
// else if (selectedChartId && selectedChartId.type && selectedChartId.type === 'doughnut' ) {
|
||||
// return (
|
||||
// <>
|
||||
// <div className="sideBarHeader">2D Widget Input</div>
|
||||
// <PieChartInput />
|
||||
// </>
|
||||
// )
|
||||
// }
|
||||
|
||||
// else if (selectedChartId && selectedChartId.type && selectedChartId.type === 'polarArea' ) {
|
||||
// return (
|
||||
// <>
|
||||
// <div className="sideBarHeader">2D Widget Input</div>
|
||||
// <PieChartInput />
|
||||
// </>
|
||||
// )
|
||||
// }
|
||||
|
||||
// else if (selectedChartId && selectedChartId.type && selectedChartId.type === 'progress 1' ) {
|
||||
// return (
|
||||
// <>
|
||||
// <div className="sideBarHeader">2D Widget Input</div>
|
||||
// <Progress1Input />
|
||||
// </>
|
||||
// )
|
||||
// }
|
||||
|
||||
// else if (selectedChartId && selectedChartId.type && selectedChartId.type === 'progress 2' ) {
|
||||
// return (
|
||||
// <>
|
||||
// <div className="sideBarHeader">2D Widget Input</div>
|
||||
// <Progress2Input />
|
||||
// </>
|
||||
// )
|
||||
// }
|
||||
|
||||
// else if (selectedChartId && selectedChartId.className && selectedChartId.className === 'warehouseThroughput floating' ) {
|
||||
// return (
|
||||
// <>
|
||||
// <div className="sideBarHeader">Floting Widget Input</div>
|
||||
// <WarehouseThroughputInputComponent />
|
||||
// </>
|
||||
// )
|
||||
// }
|
||||
|
||||
// else if (selectedChartId && selectedChartId.className && selectedChartId.className === 'fleetEfficiency floating' ) {
|
||||
// return (
|
||||
// <>
|
||||
// <div className="sideBarHeader">Floting Widget Input</div>
|
||||
// <FleetEfficiencyInputComponent />
|
||||
// </>
|
||||
// )
|
||||
// }
|
||||
|
||||
// else if (selectedChartId && selectedChartId.className && selectedChartId.className === 'floating total-card' ) {
|
||||
// return (
|
||||
// <>
|
||||
// <div className="sideBarHeader">Floting Widget Input</div>
|
||||
// <FleetEfficiencyInputComponent />
|
||||
// </>
|
||||
// )
|
||||
// }
|
||||
|
||||
// else if (selectedChartId && selectedChartId.type && selectedChartId.type === 'ui-Widget 1' ) {
|
||||
// return (
|
||||
// <>
|
||||
// <div className="sideBarHeader">3D Widget Input</div>
|
||||
// <Widget4InputCard3D />
|
||||
// </>
|
||||
// )
|
||||
// }
|
||||
|
||||
// else if (selectedChartId && selectedChartId.type && selectedChartId.type === 'ui-Widget 2' ) {
|
||||
// return (
|
||||
// <>
|
||||
// <div className="sideBarHeader">3D Widget Input</div>
|
||||
// <Widget2InputCard3D />
|
||||
// </>
|
||||
// )
|
||||
// }
|
||||
|
||||
// else if (selectedChartId && selectedChartId.type && selectedChartId.type === 'ui-Widget 3' ) {
|
||||
// return (
|
||||
// <>
|
||||
// <div className="sideBarHeader">3D Widget Input</div>
|
||||
// <Widget3InputCard3D />
|
||||
// </>
|
||||
// )
|
||||
// }
|
||||
|
||||
// else if (selectedChartId && selectedChartId.type && selectedChartId.type === 'ui-Widget 4' ) {
|
||||
// return (
|
||||
// <>
|
||||
// <div className="sideBarHeader">3D Widget Input</div>
|
||||
// <Widget4InputCard3D />
|
||||
// </>
|
||||
// )
|
||||
// }
|
||||
|
||||
// else {
|
||||
// return (
|
||||
// <div>No chart selected</div>
|
||||
// )
|
||||
// }
|
||||
// }
|
||||
|
||||
const chartTypeMap: Record<| 'bar'| 'line'| 'pie' | 'doughnut' | 'polarArea'| 'progress 1' | 'progress 2'
|
||||
| 'ui-Widget 1'| 'ui-Widget 2'| 'ui-Widget 3'| 'ui-Widget 4',JSX.Element> = {
|
||||
bar: <BarChartInput />,
|
||||
line: <LineGrapInput />,
|
||||
pie: <PieChartInput />,
|
||||
doughnut: <PieChartInput />,
|
||||
polarArea: <PieChartInput />,
|
||||
'progress 1': <Progress1Input />,
|
||||
'progress 2': <Progress2Input />,
|
||||
'ui-Widget 1': <Widget4InputCard3D />,
|
||||
'ui-Widget 2': <Widget2InputCard3D />,
|
||||
'ui-Widget 3': <Widget3InputCard3D />,
|
||||
'ui-Widget 4': <Widget4InputCard3D />,
|
||||
};
|
||||
|
||||
const classNameMap: Record<
|
||||
| 'warehouseThroughput floating'
|
||||
| 'fleetEfficiency floating'
|
||||
| 'floating total-card',
|
||||
JSX.Element
|
||||
> = {
|
||||
'warehouseThroughput floating': <WarehouseThroughputInputComponent />,
|
||||
'fleetEfficiency floating': <FleetEfficiencyInputComponent />,
|
||||
'floating total-card': <FleetEfficiencyInputComponent />,
|
||||
};
|
||||
|
||||
const InputSelecterComponent = () => {
|
||||
const { selectedChartId } = useWidgetStore();
|
||||
const { selectedChartId } = useWidgetStore();
|
||||
|
||||
if (selectedChartId && selectedChartId.type && selectedChartId.type === 'bar' ) {
|
||||
return (
|
||||
if (selectedChartId) {
|
||||
const { type, className } = selectedChartId;
|
||||
|
||||
if (type && chartTypeMap[type as keyof typeof chartTypeMap]) {
|
||||
const label = ['ui-Widget 1', 'ui-Widget 2', 'ui-Widget 3', 'ui-Widget 4'].includes(type)
|
||||
? '3D Widget Input'
|
||||
: '2D Widget Input';
|
||||
|
||||
return (
|
||||
<>
|
||||
<div className="sideBarHeader">2D Widget Input</div>
|
||||
<BarChartInput />
|
||||
<div className="sideBarHeader">{label}</div>
|
||||
{chartTypeMap[type as keyof typeof chartTypeMap]}
|
||||
</>
|
||||
)
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
else if (selectedChartId && selectedChartId.type && selectedChartId.type === 'line' ) {
|
||||
return (
|
||||
if (className && classNameMap[className as keyof typeof classNameMap]) {
|
||||
return (
|
||||
<>
|
||||
<div className="sideBarHeader">2D Widget Input</div>
|
||||
<LineGrapInput />
|
||||
<div className="sideBarHeader">Floting Widget Input</div>
|
||||
{classNameMap[className as keyof typeof classNameMap]}
|
||||
</>
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
else if (selectedChartId && selectedChartId.type && selectedChartId.type === 'pie' ) {
|
||||
return (
|
||||
<>
|
||||
<div className="sideBarHeader">2D Widget Input</div>
|
||||
<PieChartInput />
|
||||
</>
|
||||
)
|
||||
}
|
||||
return <div>No chart selected</div>;
|
||||
};
|
||||
|
||||
else if (selectedChartId && selectedChartId.type && selectedChartId.type === 'doughnut' ) {
|
||||
return (
|
||||
<>
|
||||
<div className="sideBarHeader">2D Widget Input</div>
|
||||
<PieChartInput />
|
||||
</>
|
||||
)
|
||||
}
|
||||
|
||||
else if (selectedChartId && selectedChartId.type && selectedChartId.type === 'polarArea' ) {
|
||||
return (
|
||||
<>
|
||||
<div className="sideBarHeader">2D Widget Input</div>
|
||||
<PieChartInput />
|
||||
</>
|
||||
)
|
||||
}
|
||||
|
||||
else if (selectedChartId && selectedChartId.type && selectedChartId.type === 'progress 1' ) {
|
||||
return (
|
||||
<>
|
||||
<div className="sideBarHeader">2D Widget Input</div>
|
||||
<Progress1Input />
|
||||
</>
|
||||
)
|
||||
}
|
||||
|
||||
else if (selectedChartId && selectedChartId.type && selectedChartId.type === 'progress 2' ) {
|
||||
return (
|
||||
<>
|
||||
<div className="sideBarHeader">2D Widget Input</div>
|
||||
<Progress2Input />
|
||||
</>
|
||||
)
|
||||
}
|
||||
|
||||
else if (selectedChartId && selectedChartId.className && selectedChartId.className === 'warehouseThroughput floating' ) {
|
||||
return (
|
||||
<>
|
||||
<div className="sideBarHeader">Floting Widget Input</div>
|
||||
<WarehouseThroughputInputComponent />
|
||||
</>
|
||||
)
|
||||
}
|
||||
|
||||
else if (selectedChartId && selectedChartId.className && selectedChartId.className === 'fleetEfficiency floating' ) {
|
||||
return (
|
||||
<>
|
||||
<div className="sideBarHeader">Floting Widget Input</div>
|
||||
<FleetEfficiencyInputComponent />
|
||||
</>
|
||||
)
|
||||
}
|
||||
|
||||
else if (selectedChartId && selectedChartId.className && selectedChartId.className === 'floating total-card' ) {
|
||||
return (
|
||||
<>
|
||||
<div className="sideBarHeader">Floting Widget Input</div>
|
||||
<FleetEfficiencyInputComponent />
|
||||
</>
|
||||
)
|
||||
}
|
||||
|
||||
else if (selectedChartId && selectedChartId.type && selectedChartId.type === 'ui-Widget 1' ) {
|
||||
return (
|
||||
<>
|
||||
<div className="sideBarHeader">3D Widget Input</div>
|
||||
<Widget4InputCard3D />
|
||||
</>
|
||||
)
|
||||
}
|
||||
|
||||
else if (selectedChartId && selectedChartId.type && selectedChartId.type === 'ui-Widget 2' ) {
|
||||
return (
|
||||
<>
|
||||
<div className="sideBarHeader">3D Widget Input</div>
|
||||
<Widget2InputCard3D />
|
||||
</>
|
||||
)
|
||||
}
|
||||
|
||||
else if (selectedChartId && selectedChartId.type && selectedChartId.type === 'ui-Widget 3' ) {
|
||||
return (
|
||||
<>
|
||||
<div className="sideBarHeader">3D Widget Input</div>
|
||||
<Widget3InputCard3D />
|
||||
</>
|
||||
)
|
||||
}
|
||||
|
||||
else if (selectedChartId && selectedChartId.type && selectedChartId.type === 'ui-Widget 4' ) {
|
||||
return (
|
||||
<>
|
||||
<div className="sideBarHeader">3D Widget Input</div>
|
||||
<Widget4InputCard3D />
|
||||
</>
|
||||
)
|
||||
}
|
||||
|
||||
else {
|
||||
return (
|
||||
<div>No chart selected</div>
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
export default InputSelecterComponent
|
||||
export default InputSelecterComponent;
|
|
@ -1,30 +1,75 @@
|
|||
import React, { useState } from "react";
|
||||
import React, { useEffect, useRef, useState } from "react";
|
||||
import { getAvatarColor } from "../../../modules/collaboration/functions/getAvatarColor";
|
||||
import { KebabIcon } from "../../icons/ExportCommonIcons";
|
||||
import { adjustHeight } from "./function/textAreaHeightAdjust";
|
||||
|
||||
interface MessageProps {
|
||||
val: Reply;
|
||||
val: Reply | CommentSchema;
|
||||
i: number;
|
||||
}
|
||||
|
||||
const Messages: React.FC<MessageProps> = ({ val, i }) => {
|
||||
const [isEditing, setIsEditing] = useState(false);
|
||||
const [openOptions, setOpenOptions] = useState(false);
|
||||
|
||||
// input
|
||||
const [value, setValue] = useState<string>(
|
||||
"reply" in val ? val.reply : val.comment
|
||||
);
|
||||
const textareaRef = useRef<HTMLTextAreaElement>(null);
|
||||
const currentUser = "1";
|
||||
|
||||
const UserName = "username";
|
||||
|
||||
useEffect(() => {
|
||||
if (textareaRef.current) adjustHeight(textareaRef.current);
|
||||
}, [value]);
|
||||
|
||||
function handleCancelAction() {
|
||||
setIsEditing(false);
|
||||
}
|
||||
|
||||
function handleSaveAction() {
|
||||
setIsEditing(false);
|
||||
}
|
||||
|
||||
function handleDeleteAction() {
|
||||
setOpenOptions(false);
|
||||
}
|
||||
|
||||
return (
|
||||
<>
|
||||
{isEditing ? (
|
||||
<div className="edit-container">
|
||||
<div className="input-container">
|
||||
<textarea />
|
||||
<textarea
|
||||
placeholder="type here"
|
||||
ref={textareaRef}
|
||||
autoFocus
|
||||
value={value}
|
||||
onChange={(e) => setValue(e.target.value)}
|
||||
style={{ resize: "none" }}
|
||||
/>
|
||||
</div>
|
||||
<div className="actions-container">
|
||||
<div className="options"></div>
|
||||
<div className="actions">
|
||||
<button className="cancel-button">Cancel</button>
|
||||
<button className="save-button">Save</button>
|
||||
<button
|
||||
className="cancel-button"
|
||||
onClick={() => {
|
||||
handleCancelAction();
|
||||
}}
|
||||
>
|
||||
Cancel
|
||||
</button>
|
||||
<button
|
||||
className="save-button"
|
||||
onClick={() => {
|
||||
handleSaveAction();
|
||||
}}
|
||||
>
|
||||
Save
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -46,7 +91,7 @@ const Messages: React.FC<MessageProps> = ({ val, i }) => {
|
|||
<button
|
||||
className="more-options-button"
|
||||
onClick={() => {
|
||||
setOpenOptions(true);
|
||||
setOpenOptions(!openOptions);
|
||||
}}
|
||||
>
|
||||
<KebabIcon />
|
||||
|
@ -56,17 +101,27 @@ const Messages: React.FC<MessageProps> = ({ val, i }) => {
|
|||
<button
|
||||
className="option"
|
||||
onClick={() => {
|
||||
setOpenOptions(false);
|
||||
setIsEditing(true);
|
||||
}}
|
||||
>
|
||||
Edit
|
||||
</button>
|
||||
<button className="option">Delete</button>
|
||||
<button
|
||||
className="option"
|
||||
onClick={() => {
|
||||
handleDeleteAction();
|
||||
}}
|
||||
>
|
||||
Delete
|
||||
</button>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
)}
|
||||
<div className="message">{val.reply}</div>
|
||||
<div className="message">
|
||||
{"reply" in val ? val.reply : val.comment}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
|
|
|
@ -1,38 +1,115 @@
|
|||
import React, { useState } from "react";
|
||||
import React, { useEffect, useRef, useState } from "react";
|
||||
import { CloseIcon, KebabIcon } from "../../icons/ExportCommonIcons";
|
||||
import Messages from "./Messages";
|
||||
import { ExpandIcon } from "../../icons/SimulationIcons";
|
||||
import { adjustHeight } from "./function/textAreaHeightAdjust";
|
||||
|
||||
const ThreadChat: React.FC = () => {
|
||||
const [openThreadOptions, setOpenThreadOptions] = useState(false);
|
||||
const [inputActive, setInputActive] = useState(false);
|
||||
const [value, setValue] = useState<string>("");
|
||||
|
||||
const textareaRef = useRef<HTMLTextAreaElement>(null);
|
||||
const wrapperRef = useRef<HTMLDivElement>(null);
|
||||
|
||||
const [dragging, setDragging] = useState(false);
|
||||
const [dragOffset, setDragOffset] = useState({ x: 0, y: 0 });
|
||||
const [position, setPosition] = useState({ x: 100, y: 100 });
|
||||
|
||||
const messages = [
|
||||
{
|
||||
replyId: "user 1",
|
||||
creatorId: "1",
|
||||
createdAt: "hello, thread check",
|
||||
createdAt: "2 hrs ago",
|
||||
lastUpdatedAt: "2 hrs ago",
|
||||
reply: "true",
|
||||
reply:
|
||||
"reply testing reply content 1, reply testing reply content 1reply testing reply content 1",
|
||||
},
|
||||
{
|
||||
replyId: "user 2",
|
||||
creatorId: "2",
|
||||
createdAt: "hello, thread check",
|
||||
createdAt: "2 hrs ago",
|
||||
lastUpdatedAt: "2 hrs ago",
|
||||
reply: "true",
|
||||
reply: "reply 2",
|
||||
},
|
||||
];
|
||||
|
||||
useEffect(() => {
|
||||
if (textareaRef.current) adjustHeight(textareaRef.current);
|
||||
}, [value]);
|
||||
|
||||
const clamp = (val: number, min: number, max: number) => {
|
||||
return Math.min(Math.max(val, min), max);
|
||||
};
|
||||
|
||||
const handlePointerDown = (event: React.PointerEvent<HTMLDivElement>) => {
|
||||
if (event.button !== 0) return;
|
||||
|
||||
const wrapper = wrapperRef.current;
|
||||
if (!wrapper) return;
|
||||
|
||||
const rect = wrapper.getBoundingClientRect();
|
||||
const offsetX = event.clientX - rect.left;
|
||||
const offsetY = event.clientY - rect.top;
|
||||
|
||||
setDragging(true);
|
||||
setDragOffset({ x: offsetX, y: offsetY });
|
||||
|
||||
wrapper.setPointerCapture(event.pointerId);
|
||||
};
|
||||
|
||||
const handlePointerMove = (event: React.PointerEvent<HTMLDivElement>) => {
|
||||
if (!dragging) return;
|
||||
|
||||
const container = document.getElementById("work-space-three-d-canvas");
|
||||
const wrapper = wrapperRef.current;
|
||||
if (!container || !wrapper) return;
|
||||
|
||||
const containerRect = container.getBoundingClientRect();
|
||||
const wrapperRect = wrapper.getBoundingClientRect();
|
||||
|
||||
let newX = event.clientX - containerRect.left - dragOffset.x;
|
||||
let newY = event.clientY - containerRect.top - dragOffset.y;
|
||||
|
||||
const maxX = containerRect.width - wrapper.offsetWidth;
|
||||
const maxY = containerRect.height - wrapper.offsetHeight;
|
||||
|
||||
newX = clamp(newX, 0, maxX);
|
||||
newY = clamp(newY, 0, maxY);
|
||||
|
||||
setPosition({ x: newX, y: newY });
|
||||
};
|
||||
|
||||
const handlePointerUp = (event: React.PointerEvent<HTMLDivElement>) => {
|
||||
if (!dragging) return;
|
||||
setDragging(false);
|
||||
const wrapper = wrapperRef.current;
|
||||
if (wrapper) wrapper.releasePointerCapture(event.pointerId);
|
||||
};
|
||||
|
||||
return (
|
||||
<div className="thread-char-wrapper">
|
||||
<div className="thread-char-container">
|
||||
<div
|
||||
ref={wrapperRef}
|
||||
className="thread-chat-wrapper"
|
||||
onPointerDown={handlePointerDown}
|
||||
onPointerMove={handlePointerMove}
|
||||
onPointerUp={handlePointerUp}
|
||||
style={{
|
||||
position: "absolute",
|
||||
left: position.x,
|
||||
top: position.y,
|
||||
cursor: dragging ? "grabbing" : "grab",
|
||||
userSelect: "none",
|
||||
zIndex: 9999,
|
||||
}}
|
||||
>
|
||||
<div className="thread-chat-container">
|
||||
<div className="header-wrapper">
|
||||
<div className="header">Comment</div>
|
||||
<div className="header-options">
|
||||
<button
|
||||
className="options-button"
|
||||
onClick={() => {
|
||||
setOpenThreadOptions(true);
|
||||
}}
|
||||
onClick={() => setOpenThreadOptions(!openThreadOptions)}
|
||||
>
|
||||
<KebabIcon />
|
||||
</button>
|
||||
|
@ -40,7 +117,7 @@ const ThreadChat: React.FC = () => {
|
|||
<div className="options-list">
|
||||
<div className="options">Mark as Unread</div>
|
||||
<div className="options">Mark as Resolved</div>
|
||||
<div className="options">Delete Thread</div>
|
||||
<div className="options delete">Delete Thread</div>
|
||||
</div>
|
||||
)}
|
||||
<button className="close-button">
|
||||
|
@ -48,15 +125,25 @@ const ThreadChat: React.FC = () => {
|
|||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="messages-wrapper">
|
||||
{messages.map((val, i) => (
|
||||
<Messages val={val as Reply} i={i} key={val.replyId} />
|
||||
<Messages val={val as any} i={i} key={val.replyId} />
|
||||
))}
|
||||
</div>
|
||||
|
||||
<div className="send-message-wrapper">
|
||||
<div className="input-container">
|
||||
<input type="text" />
|
||||
<div className="sent-button">
|
||||
<div className={`input-container ${inputActive ? "active" : ""}`}>
|
||||
<textarea
|
||||
placeholder="type something"
|
||||
ref={textareaRef}
|
||||
value={value}
|
||||
onChange={(e) => setValue(e.target.value)}
|
||||
onFocus={() => setInputActive(true)}
|
||||
onBlur={() => setInputActive(false)}
|
||||
style={{ resize: "none" }}
|
||||
/>
|
||||
<div className={`sent-button ${value === "" ? "disable-send-btn" : ""}`}>
|
||||
<ExpandIcon />
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -0,0 +1,17 @@
|
|||
export const adjustHeight = (textareaRef: HTMLTextAreaElement) => {
|
||||
const el = textareaRef;
|
||||
if (el) {
|
||||
el.style.height = "auto";
|
||||
el.style.height = "38px";
|
||||
|
||||
// Clamp to max height for 6 lines
|
||||
const lineHeight = 18; // px, adjust if needed
|
||||
const maxHeight = lineHeight * 6;
|
||||
if (el.scrollHeight > maxHeight) {
|
||||
el.style.overflowY = "auto";
|
||||
el.style.height = `${maxHeight}px`;
|
||||
} else {
|
||||
el.style.overflowY = "hidden";
|
||||
}
|
||||
}
|
||||
};
|
|
@ -5,7 +5,6 @@ import Controls from '../controls/controls';
|
|||
import { Environment } from '@react-three/drei'
|
||||
|
||||
import background from "../../../assets/textures/hdr/mudroadpuresky2k.hdr";
|
||||
import { MovingClouds } from '../clouds/clouds';
|
||||
|
||||
function Setup() {
|
||||
return (
|
||||
|
@ -18,7 +17,7 @@ function Setup() {
|
|||
|
||||
<PostProcessing />
|
||||
|
||||
<MovingClouds />
|
||||
{/* <MovingClouds /> */}
|
||||
|
||||
<Environment files={background} environmentIntensity={1.5} />
|
||||
</>
|
||||
|
|
|
@ -31,6 +31,7 @@ interface ProductionCapacityProps {
|
|||
type: string;
|
||||
position: [number, number, number];
|
||||
rotation: [number, number, number];
|
||||
scale?: [number, number, number];
|
||||
Data?: any;
|
||||
onContextMenu?: (event: React.MouseEvent) => void;
|
||||
// onPointerDown:any
|
||||
|
@ -41,7 +42,8 @@ const ProductionCapacity: React.FC<ProductionCapacityProps> = ({
|
|||
type,
|
||||
Data,
|
||||
position,
|
||||
rotation,
|
||||
rotation = [0, 0, 0],
|
||||
scale = [0.5, 0.5, 0.5],
|
||||
onContextMenu,
|
||||
}) => {
|
||||
const { selectedChartId, setSelectedChartId } = useWidgetStore();
|
||||
|
@ -198,74 +200,75 @@ const ProductionCapacity: React.FC<ProductionCapacityProps> = ({
|
|||
useEffect(() => {}, [rotation]);
|
||||
|
||||
return (
|
||||
<Html
|
||||
// data
|
||||
position={position}
|
||||
scale={[0.5, 0.5, 0.5]}
|
||||
rotation={rotation}
|
||||
// class
|
||||
wrapperClass="pointer-none"
|
||||
// other
|
||||
transform
|
||||
zIndexRange={[1, 0]}
|
||||
prepend
|
||||
// sprite
|
||||
distanceFactor={20}
|
||||
// events
|
||||
onDragOver={(e) => {
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
}}
|
||||
onDrop={(e) => {
|
||||
e.preventDefault();
|
||||
}}
|
||||
>
|
||||
<div
|
||||
className={`productionCapacity-wrapper card ${
|
||||
selectedChartId?.id === id ? "activeChart" : ""
|
||||
}`}
|
||||
onClick={() => setSelectedChartId({ id: id, type: type })}
|
||||
onContextMenu={onContextMenu}
|
||||
style={{
|
||||
width: "300px", // Original width
|
||||
height: "300px", // Original height
|
||||
// transform: transformStyle.transform,
|
||||
transformStyle: "preserve-3d",
|
||||
position: "absolute",
|
||||
transform: "translate(-50%, -50%)",
|
||||
<>
|
||||
{position && scale && rotation && <Html
|
||||
// data
|
||||
position={position}
|
||||
scale={scale}
|
||||
rotation={rotation}
|
||||
// class
|
||||
wrapperClass="pointer-none"
|
||||
// other
|
||||
transform
|
||||
zIndexRange={[1, 0]}
|
||||
prepend
|
||||
// sprite
|
||||
distanceFactor={20}
|
||||
// events
|
||||
onDragOver={(e) => {
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
}}
|
||||
onDrop={(e) => {
|
||||
e.preventDefault();
|
||||
}}
|
||||
>
|
||||
<div className="headeproductionCapacityr-wrapper">
|
||||
<div className="header">Production Capacity</div>
|
||||
<div className="production-capacity">
|
||||
<div className="value">1,200</div>{" "}
|
||||
<div className="value">units/hour</div>
|
||||
</div>
|
||||
<div className="production-capacity">
|
||||
<div className="current">
|
||||
<div className="key">Current</div>
|
||||
<div className="value">1500</div>
|
||||
<div
|
||||
className={`productionCapacity-wrapper card ${selectedChartId?.id === id ? "activeChart" : ""
|
||||
}`}
|
||||
onClick={() => setSelectedChartId({ id: id, type: type })}
|
||||
onContextMenu={onContextMenu}
|
||||
style={{
|
||||
width: "300px", // Original width
|
||||
height: "300px", // Original height
|
||||
// transform: transformStyle.transform,
|
||||
transformStyle: "preserve-3d",
|
||||
position: "absolute",
|
||||
transform: "translate(-50%, -50%)",
|
||||
}}
|
||||
>
|
||||
<div className="headeproductionCapacityr-wrapper">
|
||||
<div className="header">Production Capacity</div>
|
||||
<div className="production-capacity">
|
||||
<div className="value">1,200</div>{" "}
|
||||
<div className="value">units/hour</div>
|
||||
</div>
|
||||
<div className="target">
|
||||
<div className="key">Target</div>
|
||||
<div className="value">2.345</div>
|
||||
<div className="production-capacity">
|
||||
<div className="current">
|
||||
<div className="key">Current</div>
|
||||
<div className="value">1500</div>
|
||||
</div>
|
||||
<div className="target">
|
||||
<div className="key">Target</div>
|
||||
<div className="value">2.345</div>
|
||||
</div>
|
||||
{/* <div className="value">units/hour</div> */}
|
||||
</div>
|
||||
{/* <div className="value">units/hour</div> */}
|
||||
</div>{" "}
|
||||
<div className="bar-chart charts">
|
||||
{/* Bar Chart */}
|
||||
<Bar
|
||||
data={
|
||||
Object.keys(measurements).length > 0
|
||||
? chartData
|
||||
: defaultChartData
|
||||
}
|
||||
options={chartOptions}
|
||||
/>
|
||||
</div>
|
||||
</div>{" "}
|
||||
<div className="bar-chart charts">
|
||||
{/* Bar Chart */}
|
||||
<Bar
|
||||
data={
|
||||
Object.keys(measurements).length > 0
|
||||
? chartData
|
||||
: defaultChartData
|
||||
}
|
||||
options={chartOptions}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</Html>
|
||||
</Html>}
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
|
|
|
@ -185,7 +185,6 @@ const Project: React.FC = () => {
|
|||
</>
|
||||
)}
|
||||
<VersionSaved />
|
||||
{/* <ThreadChat /> */}
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
|
|
@ -3,7 +3,8 @@
|
|||
|
||||
// global input style
|
||||
|
||||
input {
|
||||
input,
|
||||
textarea {
|
||||
width: 100%;
|
||||
padding: 4px 8px;
|
||||
border-radius: #{$border-radius-large};
|
||||
|
|
|
@ -93,66 +93,216 @@
|
|||
}
|
||||
}
|
||||
|
||||
.thread-char-wrapper {
|
||||
.thread-chat-wrapper {
|
||||
position: absolute;
|
||||
// remove later
|
||||
top: 50%;
|
||||
left: 50%;
|
||||
transform: translate(-50%, -50%);
|
||||
// ----
|
||||
z-index: 10000;
|
||||
.thread-char-container {
|
||||
z-index: #{$z-index-ui-highest};
|
||||
.thread-chat-container {
|
||||
background: var(--background-color);
|
||||
backdrop-filter: blur(14px);
|
||||
border-radius: #{$border-radius-extra-large};
|
||||
width: 20rem;
|
||||
.header-wrapper {
|
||||
.header {
|
||||
}
|
||||
padding: 12px;
|
||||
@include flex-space-between;
|
||||
.header-options {
|
||||
.options-button {
|
||||
}
|
||||
@include flex-center;
|
||||
position: relative;
|
||||
.options-list {
|
||||
position: absolute;
|
||||
bottom: 0;
|
||||
right: 0;
|
||||
transform: translate(-24px, 100%);
|
||||
background: var(--background-color);
|
||||
padding: 8px 4px;
|
||||
border-radius: #{$border-radius-medium};
|
||||
backdrop-filter: blur(10px);
|
||||
z-index: 100;
|
||||
.options {
|
||||
text-wrap: nowrap;
|
||||
padding: 2px 4px;
|
||||
border-radius: #{$border-radius-medium};
|
||||
cursor: pointer;
|
||||
&:hover {
|
||||
color: var(--text-button-color);
|
||||
background: var(--background-color-accent);
|
||||
}
|
||||
&.delete {
|
||||
&:hover {
|
||||
color: var(--log-error-text-color);
|
||||
background: var(--log-error-background-color);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
.options-button,
|
||||
.close-button {
|
||||
@include flex-center;
|
||||
height: 24px;
|
||||
width: 24px;
|
||||
border-radius: #{$border-radius-medium};
|
||||
&:hover {
|
||||
background: var(--background-color-solid);
|
||||
}
|
||||
}
|
||||
.close-button {
|
||||
svg {
|
||||
scale: 1.4;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
.messages-wrapper {
|
||||
padding: 12px;
|
||||
padding-top: 0;
|
||||
.edit-container {
|
||||
.input-container {
|
||||
textarea{
|
||||
background: var(--background-color);
|
||||
&:focus{
|
||||
outline-color: var(--border-color-accent);
|
||||
}
|
||||
}
|
||||
}
|
||||
.actions-container {
|
||||
@include flex-space-between;
|
||||
width: 100%;
|
||||
margin: 8px 0;
|
||||
.actions {
|
||||
.cancel-button {
|
||||
@include flex-center;
|
||||
gap: 4px;
|
||||
.cancel-button,
|
||||
.save-button {
|
||||
padding: 4px 10px;
|
||||
border-radius: #{$border-radius-large};
|
||||
background: var(--background-color-solid);
|
||||
outline: 1px solid var(--border-color);
|
||||
}
|
||||
.save-button {
|
||||
color: var(--text-button-color);
|
||||
background: var(--background-color-accent);
|
||||
outline: none;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
.message-container {
|
||||
position: relative;
|
||||
@include flex-space-between;
|
||||
align-items: flex-start;
|
||||
gap: 12px;
|
||||
margin-top: 8px;
|
||||
&:first-child{
|
||||
margin: 0;
|
||||
}
|
||||
.profile {
|
||||
height: 28px;
|
||||
width: 28px;
|
||||
min-width: 28px;
|
||||
text-transform: uppercase;
|
||||
line-height: 28px;
|
||||
text-align: center;
|
||||
border-radius: #{$border-radius-circle};
|
||||
}
|
||||
.content {
|
||||
width: 100%;
|
||||
.user-details {
|
||||
display: flex;
|
||||
align-items: flex-end;
|
||||
gap: 8px;
|
||||
.user-name {
|
||||
text-transform: capitalize;
|
||||
}
|
||||
.time {
|
||||
font-size: var(--font-size-tiny);
|
||||
color: var(--input-text-color);
|
||||
}
|
||||
}
|
||||
}
|
||||
.more-options {
|
||||
position: absolute;
|
||||
right: 0;
|
||||
top: 0;
|
||||
.more-options-button {
|
||||
}
|
||||
.options-list {
|
||||
.option {
|
||||
@include flex-center;
|
||||
height: 18px;
|
||||
width: 18px;
|
||||
border-radius: #{$border-radius-small};
|
||||
&:hover{
|
||||
background: var(--background-color-solid);
|
||||
}
|
||||
}
|
||||
.options-list {
|
||||
position: absolute;
|
||||
right: 0;
|
||||
padding: 3px 6px;
|
||||
background: var(--background-color);
|
||||
backdrop-filter: blur(10px);
|
||||
outline: 1px solid var(--border-color);
|
||||
border-radius: #{$border-radius-medium};
|
||||
z-index: 100;
|
||||
.option {
|
||||
width: 100%;
|
||||
border-radius: #{$border-radius-medium};
|
||||
padding: 2px 6px;
|
||||
text-align: start;
|
||||
&:hover{
|
||||
background: var(--background-color-accent);
|
||||
color: var(--text-button-color);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
.message{
|
||||
margin-top: 6px;
|
||||
}
|
||||
}
|
||||
}
|
||||
.send-message-wrapper {
|
||||
padding: 12px;
|
||||
padding-top: 8px;
|
||||
.input-container {
|
||||
position: relative;
|
||||
@include flex-space-between;
|
||||
background: var(--background-color);
|
||||
border-radius: #{$border-radius-extra-large};
|
||||
outline: 1px solid var(--border-color);
|
||||
textarea {
|
||||
background: transparent;
|
||||
outline: none;
|
||||
width: calc(100% - 36px);
|
||||
overflow: hidden;
|
||||
line-height: 28px;
|
||||
max-height: 108px;
|
||||
}
|
||||
.sent-button {
|
||||
position: absolute;
|
||||
right: 2px;
|
||||
bottom: 2px;
|
||||
@include flex-center;
|
||||
padding: 2px;
|
||||
svg {
|
||||
rotate: 45deg;
|
||||
}
|
||||
}
|
||||
.disable-send-btn {
|
||||
filter: saturate(0);
|
||||
}
|
||||
&.active {
|
||||
background: var(--background-color-solid);
|
||||
padding-top: 4px;
|
||||
flex-direction: column;
|
||||
align-items: end;
|
||||
textarea {
|
||||
width: 100%;
|
||||
line-height: 18px;
|
||||
}
|
||||
.sent-button {
|
||||
position: relative;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue