This commit is contained in:
Jerald-Golden-B 2025-06-13 18:27:17 +05:30
commit 73bf97d8af
15 changed files with 806 additions and 598 deletions

View File

@ -52,7 +52,7 @@ function MainScene() {
const { visualizationSocket } = useSocketStore();
const { selectedZone } = useSelectedZoneStore();
const { setFloatingWidget } = useFloatingWidget();
const { clearComparisonProduct } = useComparisonProduct();
const { comparisonProduct, clearComparisonProduct } = useComparisonProduct();
const { selectedFloorItem, setSelectedFloorItem } = useSelectedFloorItem();
const { setName } = useAssetsStore();
const { projectId } = useParams()
@ -120,7 +120,9 @@ function MainScene() {
</>
)}
<div
className="scene-container"
className={`scene-container${
comparisonProduct?.productUuid ? " half-view" : ""
}`}
id="work-space-three-d-canvas"
style={{
height: isPlaying || activeModule !== "visualization" ? "100vh" : "",

View File

@ -13,23 +13,26 @@ type Material = {
textureName: string;
};
// Initial and default material
const initialMaterial: Material = {
texture: wallTexture1,
textureName: "Grunge Concrete Wall",
};
// Default and initial materials
const defaultMaterial: Material = {
texture: defaultTexture,
textureName: "Default Material",
};
const initialMaterial: Material = {
texture: wallTexture1,
textureName: "Grunge Concrete Wall",
};
const WallProperties = () => {
const { wallHeight, wallThickness, setWallHeight, setWallThickness } = useBuilderStore();
const [activeSide, setActiveSide] = useState<"side1" | "side2">("side1");
const [materials, setMaterials] = useState<Material[]>([initialMaterial]);
const [materials, setMaterials] = useState<Material[]>([
defaultMaterial,
initialMaterial,
]);
const [selectedMaterials, setSelectedMaterials] = useState<{
side1: Material | null;
@ -39,11 +42,11 @@ const WallProperties = () => {
side2: null,
});
// Select initial material for both sides on mount
// Set default material initially for both sides
useEffect(() => {
setSelectedMaterials({
side1: initialMaterial,
side2: initialMaterial,
side1: defaultMaterial,
side2: defaultMaterial,
});
}, []);
@ -71,21 +74,16 @@ const WallProperties = () => {
};
const handleRemoveMaterial = (index: number) => {
const updatedMaterials = materials.filter((_, i) => i !== index);
const removedTexture = materials[index].texture;
// Ensure there's always at least one material
const newMaterials =
updatedMaterials.length === 0 ? [defaultMaterial] : updatedMaterials;
const updatedMaterials = materials.filter((_, i) => i !== index);
const newMaterials = updatedMaterials.length === 0 ? [defaultMaterial] : updatedMaterials;
setMaterials(newMaterials);
// Deselect the material if it's the one removed
setSelectedMaterials((prev) => {
const updated = { ...prev };
["side1", "side2"].forEach((side) => {
if (
updated[side as "side1" | "side2"]?.texture ===
materials[index].texture
) {
if (updated[side as "side1" | "side2"]?.texture === removedTexture) {
updated[side as "side1" | "side2"] = defaultMaterial;
}
});
@ -119,42 +117,43 @@ const WallProperties = () => {
<div className="material-preview">
<div className="sides-wrapper">
<div
className={`side-wrapper ${activeSide === "side1" ? "active" : ""
}`}
<button
className={`side-wrapper ${activeSide === "side1" ? "active" : ""}`}
onClick={() => setActiveSide("side1")}
>
<div className="label">Side 1</div>
<div className="texture-image">
{selectedMaterials.side1 && (
<img
draggable={false}
src={selectedMaterials.side1.texture}
alt={selectedMaterials.side1.textureName}
/>
)}
</div>
</div>
</button>
<div
className={`side-wrapper ${activeSide === "side2" ? "active" : ""
}`}
<button
className={`side-wrapper ${activeSide === "side2" ? "active" : ""}`}
onClick={() => setActiveSide("side2")}
>
<div className="label">Side 2</div>
<div className="texture-image">
{selectedMaterials.side2 && (
<img
draggable={false}
src={selectedMaterials.side2.texture}
alt={selectedMaterials.side2.textureName}
/>
)}
</div>
</div>
</button>
</div>
<div className="preview">
{selectedMaterials[activeSide] && (
<img
draggable={false}
src={selectedMaterials[activeSide]!.texture}
alt={selectedMaterials[activeSide]!.textureName}
/>
@ -167,19 +166,26 @@ const WallProperties = () => {
<div className="no-materials">No materials added yet.</div>
) : (
<div className="material-container">
{materials.map((material, index) => (
<div
className="material-wrapper"
{materials.map((material, index) => {
const isSelected = selectedMaterials[activeSide]?.texture === material.texture;
return (
<button
className={`material-wrapper ${isSelected ? "selectedMaterial" : ""}`}
key={`${material.textureName}_${index}`}
onClick={() => handleSelectMaterial(material)}
>
<div className="material-property">
<div className="material-image">
<img src={material.texture} alt={material.textureName} />
<img
draggable={false}
src={material.texture}
alt={material.textureName}
/>
</div>
<div className="material-name">{material.textureName}</div>
</div>
<div
<button
className="delete-material"
onClick={(e) => {
e.stopPropagation();
@ -187,9 +193,10 @@ const WallProperties = () => {
}}
>
<RemoveIcon />
</div>
</div>
))}
</button>
</button>
);
})}
</div>
)}
</div>

View File

@ -127,7 +127,7 @@ const CompareLayOut = () => {
ref={wrapperRef}
style={{ width }}
>
{loadingProgress == 0 && comparisonProduct && (
{loadingProgress == 0 && comparisonProduct?.productUuid && (
<button
title="resize-canvas"
id="compare-resize-slider-btn"

View File

@ -153,7 +153,7 @@ const ComparisonResult = () => {
<div className="cycle-time-container comparisionCard">
<div className="cycle-main">
<div className="cycle-header">Cycle Time</div>
<h4 className="cycle-header">Cycle Time</h4>
<div className="layers-wrapper">
<div className="layers">
<div className="layer-name">{comparedProducts[0]?.productName}</div>
@ -202,7 +202,7 @@ const ComparisonResult = () => {
</div>
{/*
<div className="overallDowntime-container comparisionCard">
<div className="overallDowntime-header">Overall Downtime</div>
<h4 className="overallDowntime-header">Overall Downtime</h4>
<div className="totalDownTime-wrapper">
<div className="totalDownTime">
<div className="totalDownTime-right">
@ -221,7 +221,7 @@ const ComparisonResult = () => {
</div> */}
<div className="overallScrapRate comparisionCard">
<div className="overallScrapRate-header">Production Capacity</div>
<h4 className="overallScrapRate-header">Production Capacity</h4>
<div className="overallScrapRate-wrapper">
<div className="overallScrapRate-value">
<div className="overallScrapRate-label">{highestProductivityProduct?.productName}</div>

View File

@ -13,7 +13,7 @@ const PerformanceResult = ({ comparedProducts }: any) => {
<div className="icon">
<PerformanceIcon />
</div>
<div className="head">Performance result</div>
<h4 className="head">Performance result</h4>
</div>
<div className="metrics-container">

View File

@ -13,6 +13,7 @@ interface AssetDetailsCardInterface {
enableStatue?: boolean;
count?: number;
totalCapacity?: number;
activeTime?: any;
assetDetails?: {
assetName: string;
const: string;
@ -59,6 +60,7 @@ const AssetDetailsCard: React.FC<AssetDetailsCardInterface> = ({
status,
count,
totalCapacity,
activeTime,
assetDetails,
}) => {
const [moreDetails, setMoreDetails] = useState(false);
@ -75,7 +77,10 @@ const AssetDetailsCard: React.FC<AssetDetailsCardInterface> = ({
<div className="content">
<div className="name">{name}</div>
{enableStatue && (
<>
<div className="active-time">Active Time : <span className="value">{activeTime}</span></div>
<div className="status-container">{GetStatus(status)}</div>
</>
)}
{!enableStatue && totalCapacity && (
<div className="storage-container">Storage/Inventory</div>

View File

@ -167,7 +167,7 @@ const SimulationPlayer: React.FC = () => {
return (
<>
{isPlaying && activeModule === "simulation" && (
<div className="label-toogler">
<div className="label-toogler "> {/* bottom */}
<InputToggle
value={viewSceneLabels}
inputKey="1"
@ -187,7 +187,7 @@ const SimulationPlayer: React.FC = () => {
<div className="icon">
<HourlySimulationIcon />
</div>
<div className="label">ThroughPut</div>
<h4 className="label">ThroughPut</h4>
</div>
<div className="progress-wrapper">
<div

View File

@ -26,7 +26,7 @@ const MachineContentUi: React.FC<MachineContentUiProps> = ({ machine }) => {
center
distanceFactor={20}
>
<AssetDetailsCard name={machine.modelName} status={machine.state} />
<AssetDetailsCard name={machine.modelName} status={machine.state} activeTime={machine.activeTime}/>
</Html>
);
};

View File

@ -26,7 +26,7 @@ const RoboticArmContentUi: React.FC<RoboticArmContentUiProps> = ({ roboticArm })
center
distanceFactor={20}
>
<AssetDetailsCard name={roboticArm.modelName} status={roboticArm.state} />
<AssetDetailsCard name={roboticArm.modelName} status={roboticArm.state} activeTime={roboticArm.activeTime}/>
</Html>
);
};

View File

@ -44,6 +44,8 @@ const VehicleContentUi: React.FC<VehicleContentUiProps> = ({ vehicle }) => {
status={vehicle.state}
count={vehicle.currentLoad}
totalCapacity={vehicle.point.action.loadCapacity}
activeTime={vehicle.activeTime}
/>
</Html>
);

View File

@ -28,6 +28,9 @@ section,
border: none;
}
}
.scene-container.half-view{
width: 50vw !important;
}
.tooltip {
position: absolute;

View File

@ -9,15 +9,16 @@
transform: translate(-50%, 0);
width: 70vw;
transition: all 0.3s;
&.hide {
width: fit-content;
.simulation-player-container
.controls-container
.simulation-button-container {
.simulation-player-container .controls-container .simulation-button-container {
width: 32px;
height: 24px;
}
}
.simulation-player-container {
background: var(--background-color);
padding: 7px;
@ -327,6 +328,7 @@
}
.open {
.start-displayer,
.end-displayer {
display: none;
@ -423,13 +425,16 @@
cursor: pointer;
transition: all 0.2s;
outline: 1px solid transparent;
&:hover {
outline: 1px solid var(--border-color);
color: var(--accent-color);
}
&.hide {
width: 32px;
}
.icon {
width: 16px;
height: 16px;
@ -496,6 +501,7 @@
.asset-details-card-wrapper {
pointer-events: none;
.asset-details-card-container {
position: relative;
padding: 8px;
@ -527,6 +533,7 @@
.asset-details-header {
@include flex-space-between;
gap: 12px;
.content {
.name {
text-wrap: nowrap;
@ -536,20 +543,34 @@
margin-bottom: 4px;
text-transform: capitalize;
}
.status-container {
.status {
display: flex;
align-items: center;
gap: 6px;
padding-top: 4px;
.icon {
@include flex-center;
}
}
}
.active-time {
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
.value {
color: var(--highlight-text-color);
}
}
.storage-container {
font-size: var(--font-size-tiny);
color: var(--highlight-text-color);
}
}
}
@ -561,6 +582,7 @@
border-radius: #{$border-radius-small};
overflow: hidden;
position: relative;
.process-running {
height: 100%;
width: 35%;
@ -584,6 +606,7 @@
top: -2px;
padding: 4px;
padding-right: 8px;
.count-ui-container {
background: var(--background-color-solid);
padding: 8px;
@ -593,19 +616,24 @@
max-width: 80px;
position: absolute;
left: 0;
.content {
@include flex-center;
gap: 2px;
.icon {
@include flex-center;
}
.display {
font-size: var(--font-size-small);
}
}
.value-container {
@include flex-center;
gap: 4px;
.progress-bar {
display: flex;
align-items: center;
@ -621,13 +649,12 @@
background: var(--background-color);
overflow: hidden;
position: relative;
.fill {
height: 100%;
background: linear-gradient(
to top,
background: linear-gradient(to top,
var(--background-color-accent) var(--process-fill-percentage),
transparent var(--process-fill-percentage)
);
transparent var(--process-fill-percentage));
}
}
@ -645,6 +672,7 @@
from {
transform: translateX(-100%);
}
to {
transform: translateX(300%);
}
@ -654,9 +682,11 @@
0% {
background-position: 0% 50%;
}
50% {
background-position: 100% 50%;
}
100% {
background-position: 0% 50%;
}

View File

@ -55,7 +55,8 @@
cursor: ew-resize;
transition: transform 0.1s ease;
z-index: 100;
pointer-events: all;
// pointer-events: all;
opacity: 0;
}
.chooseLayout-container {
@ -70,7 +71,7 @@
.compare-layout-canvas-container {
position: absolute;
height: 100vh;
width: 100vw;
width: 50vw;
top: 0;
right: 0;
}
@ -165,9 +166,7 @@
width: 100%;
&:hover {
background-color: var(
--highlight-text-color
) !important;
background-color: var(--highlight-text-color) !important;
border-radius: 4px;
.layout {
@ -212,6 +211,10 @@
display: flex;
gap: 12px;
h4 {
font-weight: 600;
}
.comparisionCard {
position: relative;
flex: 1;
@ -427,10 +430,6 @@
position: relative;
.energy-usage-wrapper {
h4 {
font-weight: 600;
}
.value {
padding-top: 25px;
font-size: var(--font-size-xxxlarge);
@ -560,7 +559,7 @@
display: flex;
justify-content: space-between;
align-items: center;
gap: 20px;
// gap: 20px;
padding: 8px 10px;
margin: 44px 0;

View File

@ -1114,6 +1114,7 @@
input {
padding: 5px 4px;
text-align: center;
}
.dropdown {
@ -1393,16 +1394,20 @@
}
&.selected {
background: var(--background-color-accent);
color: var(--text-button-color);
background: var(--highlight-accent-color);
.aisle-color {
// color: var(--text-button-color);
}
&:hover {
background: var(--background-color-accent);
// background: var(--background-color-accent);
}
}
&:hover {
background: var(--background-color-secondary);
background: var(--highlight-accent-color);
// background: var(--background-color-secondary);
}
}
}
@ -1527,6 +1532,7 @@
.header {
@include flex-space-between;
border: none;
.eyedrop-button {
@include flex-center;
}
@ -1534,6 +1540,7 @@
.inputs-container {
@include flex-space-between;
.input-container {
padding: 0 4px;
gap: 6px;
@ -1652,6 +1659,154 @@
}
}
.sidebar-right-wrapper {
.wall-properties-container {
.header {
color: var(--background-color-button);
}
.wall-properties {
padding: 12px 0;
.value-field-container {
padding: 0;
.input {
input {
text-align: center;
}
}
}
}
section {
padding: 0;
margin: 0;
max-height: 50vh;
overflow: hidden;
.header-wrapper {
display: flex;
justify-content: space-between;
padding: 12px;
}
.material-preview {
display: flex;
flex-direction: column;
align-items: center;
gap: 15px;
background: var(--Grays-Gray-6, #F2F2F7);
padding: 18px 25px;
.sides-wrapper {
display: flex;
justify-content: space-between;
width: 100%;
background-color: #FCFDFD;
border-radius: 4px;
overflow: hidden;
.side-wrapper {
flex: 1;
display: flex;
justify-content: center;
align-items: center;
gap: 8px;
padding: 8px 0;
cursor: pointer;
.label {
color: var(--background-color-button);
}
&.active {
background-color: #E0DFFF;
}
.texture-image {
width: 20px;
height: 20px;
border-radius: 50%;
overflow: hidden;
img {
width: 100%;
height: 100%;
object-fit: cover;
}
}
}
}
.preview {
width: 90%;
height: 111px;
img {
width: 100%;
height: 100%;
object-fit: cover;
}
}
}
.materials {
max-height: 250px;
overflow: auto;
margin-bottom: 6px;
padding: 0 12px;
.material-container {
display: flex;
flex-direction: column;
gap: 6px;
.material-wrapper {
display: flex;
justify-content: space-between;
align-items: center;
padding: 4px 6px;
border-radius: 12px;
&:hover {
background: var(--highlight-accent-color);
}
&.selectedMaterial {
background: var(--highlight-accent-color);
}
.material-property {
display: flex;
align-items: center;
gap: 6px;
.material-image {
width: 34px;
height: 34px;
border-radius: 6px;
overflow: hidden;
img {
width: 100%;
height: 100%;
object-fit: cover;
}
}
}
.delete-material {
cursor: pointer;
}
}
}
}
}
}
}
.assets-container-main {
width: 100%;
display: flex;

View File

@ -98,7 +98,7 @@
right: 1.5%;
z-index: 10;
border-radius: 8px;
transition: all 0.3s ease-in-out;
.input-toggle-container {
padding: 0;
display: flex;
@ -117,4 +117,9 @@
}
}
}
}
.label-toogler.bottom{
bottom: 32%;
}