Merge pull request 'refactor: Update ExpandIcon to accept isActive prop for dynamic rendering; enhance ThroughputSummary and SimulationPlayer components with getAvatarColor for consistent color usage; improve styles across simulation and visualization components for bette…' (#73) from v2-ui into main

Reviewed-on: http://185.100.212.76:7776/Dwinzo-Beta/Dwinzo_dev/pulls/73
This commit is contained in:
Vishnu 2025-04-30 14:18:11 +00:00
commit f776ffa2dd
9 changed files with 167 additions and 155 deletions

View File

@ -655,8 +655,8 @@ export const MonthlyROI = () => {
);
};
export const ExpandIcon = () => {
return (
export const ExpandIcon = ({ isActive }: { isActive: boolean }) => {
return isActive ? (
<svg
width="20"
height="20"
@ -677,6 +677,36 @@ export const ExpandIcon = () => {
fill="var(--text-color)"
/>
</svg>
) : (
<svg
width="21"
height="20"
viewBox="0 0 21 20"
fill="none"
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M5 5.6875H15.5"
stroke="var(--text-color)"
strokeWidth="1.4"
strokeLinecap="round"
strokeLinejoin="round"
/>
<path
d="M5 8.60156H15.5"
stroke="var(--text-color)"
strokeWidth="1.4"
strokeLinecap="round"
strokeLinejoin="round"
/>
<path
d="M5 10.6484L10.25 14.7318L15.5 10.6484"
stroke="var(--text-color)"
strokeWidth="1.4"
strokeLinecap="round"
strokeLinejoin="round"
/>
</svg>
);
};
@ -784,22 +814,3 @@ export const SpeedIcon = () => {
</svg>
);
};
// export const DublicateIcon = () => {
// return (
// <svg
// width="20"
// height="20"
// viewBox="0 0 20 20"
// fill="none"
// xmlns="http://www.w3.org/2000/svg"
// >
// <path
// fillRule="evenodd"
// clipRule="evenodd"
// d="M14.3125 11.375C14.3125 11.7545 14.0045 12.0625 13.625 12.0625H8.125C7.7455 12.0625 7.4375 11.7545 7.4375 11.375V5.875C7.4375 5.4955 7.7455 5.1875 8.125 5.1875H13.625C14.0045 5.1875 14.3125 5.4955 14.3125 5.875V11.375ZM13.625 4.5H8.125C7.36566 4.5 6.75 5.11566 6.75 5.875V11.375C6.75 12.1343 7.36566 12.75 8.125 12.75H13.625C14.3843 12.75 15 12.1343 15 11.375V5.875C15 5.11566 14.3843 4.5 13.625 4.5ZM11.5625 14.125C11.5625 14.5045 11.2545 14.8125 10.875 14.8125H5.375C4.9955 14.8125 4.6875 14.5045 4.6875 14.125V8.625C4.6875 8.2455 4.9955 7.9375 5.375 7.9375H6.0625V7.25H5.375C4.61566 7.25 4 7.86566 4 8.625V14.125C4 14.8843 4.61566 15.5 5.375 15.5H10.875C11.6343 15.5 12.25 14.8843 12.25 14.125V13.4375H11.5625V14.125Z"
// fill="var(--text-color)"
// />
// </svg>
// );
// };

View File

@ -8,6 +8,7 @@ import {
PointElement,
} from "chart.js";
import { PowerIcon, ThroughputSummaryIcon } from "../../icons/analysis";
import { getAvatarColor } from "../../../modules/collaboration/functions/getAvatarColor";
ChartJS.register(LineElement, CategoryScale, LinearScale, PointElement);
@ -142,13 +143,13 @@ const ThroughputSummary = () => {
<div className="progress-wrapper">
{/* Dynamically create progress bars based on shiftUtilization array */}
{shiftUtilization.map((shift) => (
{shiftUtilization.map((shift, index) => (
<div
key={shift.shift}
className={`progress shift-${shift.shift}`}
style={{
width: `${shift.percentage}%`,
backgroundColor: getRandomColor(),
backgroundColor: getAvatarColor(index),
}}
></div>
))}
@ -156,11 +157,11 @@ const ThroughputSummary = () => {
<div className="progress-indicator">
{/* Dynamically create shift indicators with random colors */}
{shiftUtilization.map((shift) => (
{shiftUtilization.map((shift, index) => (
<div className="shift-wrapper" key={shift.shift}>
<span
className={`indicator shift-${shift.shift}`}
style={{ backgroundColor: getRandomColor() }} // Random color for indicator
style={{ backgroundColor: getAvatarColor(index) }} // Random color for indicator
></span>
<label>Shift {shift.shift}</label>
</div>

View File

@ -16,8 +16,13 @@ import {
SpeedIcon,
StartIcon,
} from "../../icons/ExportCommonIcons";
import { getAvatarColor } from "../../../modules/collaboration/functions/getAvatarColor";
const SimulationPlayer: React.FC = () => {
const MAX_SPEED = 8; // Maximum speed
const [expand, setExpand] = useState(true);
const { speed, setSpeed } = useAnimationPlaySpeed();
const [playSimulation, setPlaySimulation] = useState(false);
const { setIsPlaying } = usePlayButtonStore();
@ -29,8 +34,7 @@ const SimulationPlayer: React.FC = () => {
// Button functions
const handleReset = () => {
setReset(true);
// setReset(!isReset);
setReset(!isReset);
setSpeed(1);
};
const handlePlayStop = () => {
@ -49,7 +53,7 @@ const SimulationPlayer: React.FC = () => {
};
const calculateHandlePosition = () => {
return ((speed - 0.5) / (8 - 0.5)) * 100;
return ((speed - 0.5) / (MAX_SPEED - 0.5)) * 100;
};
const handleMouseDown = () => {
@ -99,7 +103,6 @@ const SimulationPlayer: React.FC = () => {
{ name: "process 9", completed: 90 }, // 90% completed
{ name: "process 10", completed: 30 }, // 30% completed
];
const [expand, setExpand] = useState(false);
// Move getRandomColor out of render
const getRandomColor = () => {
const letters = "0123456789ABCDEF";
@ -125,7 +128,7 @@ const SimulationPlayer: React.FC = () => {
const processPlayerRef = useRef<HTMLDivElement>(null);
const processWrapperRef = useRef<HTMLDivElement>(null);
const [playerPosition, setPlayerPosition] = useState(0);
const [playerPosition, setPlayerPosition] = useState(20); // initial position
const handleProcessMouseDown = (e: React.MouseEvent) => {
if (!processWrapperRef.current) return;
@ -204,7 +207,7 @@ const SimulationPlayer: React.FC = () => {
</div>
</div>
<div className="controls-wrapper">
<div
<button
className="simulation-button-container"
onClick={() => {
handleReset();
@ -212,8 +215,8 @@ const SimulationPlayer: React.FC = () => {
>
<ResetIcon />
Reset
</div>
<div
</button>
<button
className="simulation-button-container"
onClick={() => {
handlePlayStop();
@ -221,8 +224,8 @@ const SimulationPlayer: React.FC = () => {
>
<PlayStopIcon />
{playSimulation ? "Play" : "Stop"}
</div>
<div
</button>
<button
className="simulation-button-container"
onClick={() => {
handleExit();
@ -230,13 +233,13 @@ const SimulationPlayer: React.FC = () => {
>
<ExitIcon />
Exit
</div>
<div
className="simulation-button-container"
</button>
<button
className="expand-icon-container"
onClick={() => setExpand(!expand)}
>
<ExpandIcon />
</div>
<ExpandIcon isActive={!expand} />
</button>
</div>
</div>
<div className="progresser-wrapper">
@ -306,34 +309,36 @@ const SimulationPlayer: React.FC = () => {
<div className="marker marker-80"></div>
<div className="marker marker-90"></div>
<div className="custom-slider">
<div
<button
className={`slider-handle ${isDragging ? "dragging" : ""}`}
style={{ left: `${calculateHandlePosition()}%` }}
onMouseDown={handleMouseDown}
>
{speed.toFixed(1)}x
</div>
</button>
<input
type="range"
min="0.5"
max="8"
max={MAX_SPEED}
step="0.1"
value={speed}
onChange={handleSpeedChange}
className="slider-input"
/>
</div>
<div className="speed-label max-value">8x</div>
<div className="speed-label max-value">4x</div>
</div>
</div>
</div>
<div className="processDisplayer">
<div
className="process-player"
style={{ left: playerPosition, position: "absolute" }}
></div>
<div className="start-displayer timmer">00:00</div>
<div className="end-displayer timmer">24:00</div>
<div
className="process-wrapper"
style={{ padding: expand ? "0px" : "5px 35px" }}
>
<div
className="process-container"
ref={processWrapperRef}
onMouseDown={handleProcessMouseDown}
>
@ -343,17 +348,19 @@ const SimulationPlayer: React.FC = () => {
className="process"
style={{
width: `${item.completed}%`,
backgroundColor: processColors[index],
backgroundColor: getAvatarColor(index),
}}
></div>
))}
</div>
>
<div
className="process-player"
ref={processPlayerRef}
style={{ left: playerPosition, position: "absolute" }}
></div>
</div>
))}
</div>
</div>
</div>
</div>
</div>
);

View File

@ -3,11 +3,11 @@
.simulation-player-wrapper {
position: fixed;
bottom: 50px;
bottom: 12px;
left: 50%;
z-index: 2;
transform: translate(-50%, 0);
width: 70%;
width: 70vw;
.simulation-player-container {
background: var(--background-color);
@ -16,24 +16,21 @@
display: flex;
flex-direction: column;
gap: 8px;
backdrop-filter: blur(10px);
outline: 1px solid var(--border-color);
.progresser-wrapper {
outline: 1px solid var(--border-color);
background: var(--background-color);
// background-color: var(--highlight-accent-color);
padding: 4px 5px;
border-radius: 12px;
display: flex;
flex-direction: column;
gap: 12px;
padding-top: 30px;
padding: 12px 5px;
padding-top: 38px;
transition: height 0.2s linear;
}
.controls-container {
@include flex-center;
gap: 12px;
@ -41,13 +38,12 @@
.production-details,
.controls-wrapper {
display: flex;
@include flex-center;
gap: 6px;
}
.production-details {
.production-wrapper {
display: flex;
align-items: center;
flex-direction: column;
@ -56,33 +52,38 @@
.header {
display: flex;
flex-direction: row;
gap: 6px
gap: 6px;
}
.progress-wrapper {
width: 164px;
height: 8px;
border-radius: 5px;
// overflow: hidden;
outline: 1px solid var(--border-color);
background: var(--background-color);
background: var(--background-color-solid);
.progress {
border-radius: 5px;
height: 100%;
background-color: var(--accent-color);
background-color: var(--background-color-accent);
}
}
}
}
.expand-icon-container {
@include flex-center;
padding: 6px 8px;
cursor: pointer;
}
.simulation-button-container {
@include flex-center;
gap: 2px;
padding: 6px 8px;
padding: 4px 8px;
min-width: 64px;
background: var(--background-color);
border-radius: #{$border-radius-small};
border-radius: #{$border-radius-extra-large};
height: fit-content;
cursor: pointer;
&:hover {
@ -101,10 +102,8 @@
@include flex-center;
gap: 32px;
padding: 5px 16px;
// background: var(--background-color);
border-radius: #{$border-radius-medium};
box-sizing: #{$box-shadow-medium};
border-radius: 20px;
position: relative;
.min-value,
@ -118,11 +117,8 @@
width: 100%;
max-width: 80vw;
height: 28px;
// background: var(--background-color-gray);
border-radius: #{$border-radius-small};
position: relative;
// padding: 4px 26px;
.speed-label {
font-size: var(--font-size-tiny);
@ -135,13 +131,13 @@
}
&:last-child {
right: 0;
right: -10px;
}
}
&::after {
content: "";
background-color: #E5E5EA;
background-color: #e5e5ea;
position: absolute;
top: 50%;
transform: translate(0, -50%);
@ -166,13 +162,15 @@
.slider-handle {
position: absolute;
top: 50%;
width: 42px;
min-width: 44px;
padding: 0 8px;
line-height: 20px;
text-align: center;
background: var(--accent-color);
color: var(--primary-color);
border-radius: #{$border-radius-small};
background: var(--background-color-button);
color: var(--text-button-color);
border-radius: #{$border-radius-large};
transform: translate(-50%, -50%);
font-size: var(--font-size-small);
cursor: pointer;
z-index: 2;
}
@ -226,23 +224,23 @@
}
.time-displayer {
display: flex;
justify-content: space-between;
@include flex-space-between;
gap: 24px;
height: auto;
opacity: 1;
// overflow: hidden;
transition: all 0.5s ease;
.start-time-wrappper,
.end-time-wrappper {
display: flex;
align-items: center;
gap: 12px;
@include flex-center;
gap: 4px;
.icon {
@include flex-center;
}
}
.time-progresser {
width: 70%;
flex: 1;
.timeline {
padding: 16px;
@ -255,18 +253,15 @@
height: 33px;
.label-dot-wrapper {
display: flex;
flex-direction: column;
align-items: center;
gap: 6px;
@include flex-center;
position: relative;
.label {
position: absolute;
top: -200%;
top: -36px;
transform: translate(0, -0);
font-size: 12px;
color: #666;
color: var(--text-color);
white-space: nowrap;
}
@ -296,22 +291,32 @@
}
}
}
}
}
.processDisplayer {
border-radius: 5px;
// overflow: hidden;
border-radius: #{$border-radius-large};
outline: 1px solid var(--border-color);
background: var(--background-color);
padding: 14px 6px;
padding: 20px 6px;
position: relative;
.timmer {
width: auto;
position: absolute;
bottom: 0;
font-size: var(--font-size-tiny);
}
.start-displayer {
bottom: 4px;
left: 16px;
}
.end-displayer {
bottom: 4px;
width: auto;
right: 16px;
}
.process-player {
position: absolute;
top: 50%;
@ -321,29 +326,30 @@
left: 86.81px;
border-radius: 14px;
border-width: 1px;
background: var(--accent-color, #6F42C1);
background: var(--background-color-accent, #6f42c1);
}
.process-wrapper {
.process-wrapper{
.process-container {
position: relative;
display: flex;
// padding: 0px 16px;
width: 100%;
.process {
height: 5px;
background-color: #4caf50;
border-radius: 4px;
color: white;
text-align: center;
line-height: 30px;
transition: width 0.3s ease;
}
}
}
}
.simulation-player-container.open {
.timmer {
display: none;
}
.progresser-wrapper {
padding-top: 4px;
}
@ -356,7 +362,7 @@
}
.processDisplayer {
padding: 0;
padding: 0 8px;
background: transparent;
.process-player {
@ -364,5 +370,4 @@
display: none !important;
}
}
}

View File

@ -83,6 +83,8 @@
border-radius: #{$border-radius-medium};
background: var(--background-color);
backdrop-filter: blur(8px);
contain: layout paint;
will-change: backdrop-filter;
.option-list {
display: flex;

View File

@ -121,10 +121,8 @@
flex-direction: column;
gap: 6px;
border-radius: 5.2px;
width: 100%;
height: 150px;
display: flex;
justify-content: center;
align-items: center;
@ -254,7 +252,8 @@
gap: 5px;
.header {
color: #a0aec0;
color: var(--text-color);
opacity: 0.8;
}
.data-values {
@ -413,7 +412,6 @@
/* FleetEfficiency.module.css */
.fleetEfficiency {
width: 100%;
min-height: 240px !important;
padding: 20px;
background: var(--background-color);

View File

@ -5,8 +5,8 @@
display: flex;
flex-direction: column;
gap: 6px;
padding-top: 12px;
padding: 6px;
padding-top: 12px;
.floating {
min-height: 170px;
@ -28,13 +28,6 @@
}
}
.floatingWidgets-wrapper {
font-family: Arial, sans-serif;
color: #333;
}
.floating.working-state {
width: 100%;
height: 283px;
@ -51,7 +44,6 @@
justify-content: space-between;
align-items: center;
margin-bottom: 20px;
// flex-direction: column;
}
.state {

View File

@ -177,8 +177,6 @@
.panel {
position: absolute;
// background: var(--background-color);
// box-shadow: 0 0 10px rgba(0, 0, 0, 0.1);
transition: all 0.3s ease;
border-radius: 6px;
overflow: auto;
@ -415,7 +413,7 @@
}
path {
stroke: var(--text-color);
stroke: var(--text-button-color);
stroke-width: 2;
}
}
@ -920,8 +918,6 @@
// Add button
.extra-Bs {}
.extra-Bs-addopening {
animation: slideDown 0.3s ease forwards;
}

View File

@ -15,7 +15,7 @@
font-size: var(--font-size-large);
padding: 2px 8px;
background: var(--background-color-accent);
color: var(--text-color);
color: var(--text-button-color);
border-radius: #{$border-radius-medium};
box-shadow: var(--box-shadow-light);
}