feat: Add default values to analysis presets and enhance input handling in components
This commit is contained in:
parent
5d03a2bc61
commit
7e85cf4e53
|
@ -1,4 +1,4 @@
|
|||
import React, { useState } from "react";
|
||||
import React, { useEffect, useState } from "react";
|
||||
import { AIIcon } from "../../../icons/ExportCommonIcons";
|
||||
import RegularDropDown from "../../../ui/inputs/RegularDropDown";
|
||||
import { AnalysisPresetsType } from "../../../../types/analysis";
|
||||
|
@ -19,55 +19,66 @@ const Analysis: React.FC = () => {
|
|||
// { type: "default", inputs: { label: "Machine uptime", activeOption: "%" } },
|
||||
],
|
||||
"Production capacity": [
|
||||
{ type: "range", inputs: { label: "Shift length", activeOption: "hr" } },
|
||||
{ type: "default", inputs: { label: "Shifts / day", activeOption: "unit" } },
|
||||
{ type: "default", inputs: { label: "Working days / year", activeOption: "days" } },
|
||||
{ type: "default", inputs: { label: "Yield rate", activeOption: "%" } },
|
||||
{ type: "range", inputs: { label: "Shift length", activeOption: "hr", defaultValue: 8 } },
|
||||
{ type: "default", inputs: { label: "Shifts / day", activeOption: "unit", defaultValue: 2 } },
|
||||
{ type: "default", inputs: { label: "Working days / year", activeOption: "days", defaultValue: 300 } },
|
||||
{ type: "default", inputs: { label: "Yield rate", activeOption: "%", defaultValue: 90 } },
|
||||
],
|
||||
ROI: [
|
||||
{
|
||||
type: "default",
|
||||
inputs: { label: "Selling price", activeOption: "INR" },
|
||||
inputs: { label: "Selling price", activeOption: "INR", defaultValue: 1500 },
|
||||
},
|
||||
{
|
||||
type: "default",
|
||||
inputs: { label: "Material cost", activeOption: "INR" },
|
||||
inputs: { label: "Material cost", activeOption: "INR", defaultValue: 300 },
|
||||
},
|
||||
{
|
||||
type: "default",
|
||||
inputs: { label: "Labor Cost", activeOption: "INR" },
|
||||
inputs: { label: "Labor Cost", activeOption: "INR", defaultValue: 200 },
|
||||
},
|
||||
{
|
||||
type: "default",
|
||||
inputs: { label: "Maintenance cost", activeOption: "INR" },
|
||||
inputs: { label: "Maintenance cost", activeOption: "INR", defaultValue: 1200 },
|
||||
},
|
||||
{
|
||||
type: "default",
|
||||
inputs: { label: "Electricity cost", activeOption: "INR" },
|
||||
inputs: { label: "Electricity cost", activeOption: "INR", defaultValue: 1000 },
|
||||
},
|
||||
{
|
||||
type: "default",
|
||||
inputs: { label: "Fixed costs", activeOption: "INR" },
|
||||
inputs: { label: "Fixed costs", activeOption: "INR", defaultValue: 5000 },
|
||||
},
|
||||
{
|
||||
type: "default",
|
||||
inputs: { label: "Initial Investment", activeOption: "INR" },
|
||||
inputs: { label: "Initial Investment", activeOption: "INR", defaultValue: 100000 },
|
||||
},
|
||||
{
|
||||
type: "default",
|
||||
inputs: { label: "Salvage value", activeOption: "Hrs" },
|
||||
inputs: { label: "Salvage value", activeOption: "Hrs", defaultValue: 5000 },
|
||||
},
|
||||
{
|
||||
type: "default",
|
||||
inputs: { label: "Production period", activeOption: "yrs" },
|
||||
inputs: { label: "Production period", activeOption: "yrs", defaultValue: 5 },
|
||||
},
|
||||
{
|
||||
type: "default",
|
||||
inputs: { label: "Tax rate", activeOption: "%" },
|
||||
inputs: { label: "Tax rate", activeOption: "%", defaultValue: 30 },
|
||||
},
|
||||
],
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
Object.values(AnalysisPresets).forEach((category) => {
|
||||
category.forEach((item) => {
|
||||
const { label, defaultValue } = item.inputs;
|
||||
if (defaultValue !== undefined) {
|
||||
updateInputValue(label, defaultValue.toString());
|
||||
}
|
||||
});
|
||||
});
|
||||
}, []);
|
||||
|
||||
const { inputValues, setInputValues, updateInputValue } = useInputValues();
|
||||
|
||||
return (
|
||||
|
|
|
@ -11,6 +11,7 @@ interface InputRendererProps {
|
|||
}
|
||||
|
||||
const RenderAnalysisInputs: React.FC<InputRendererProps> = ({ keyName, presets, inputValues, onInputChange }) => {
|
||||
|
||||
return (
|
||||
<div key={`main-${keyName}`} className="analysis-inputs">
|
||||
{presets.map((preset, index) => {
|
||||
|
@ -19,7 +20,7 @@ const RenderAnalysisInputs: React.FC<InputRendererProps> = ({ keyName, presets,i
|
|||
<InputWithDropDown
|
||||
key={index}
|
||||
label={preset.inputs.label}
|
||||
value={inputValues[preset.inputs.label] || ""}
|
||||
value={preset.inputs.defaultValue?.toString() || inputValues[preset.inputs.label] || ""}
|
||||
activeOption={preset.inputs.activeOption}
|
||||
onChange={(newValue) => onInputChange(preset.inputs.label, newValue)}
|
||||
/>
|
||||
|
@ -32,7 +33,7 @@ const RenderAnalysisInputs: React.FC<InputRendererProps> = ({ keyName, presets,i
|
|||
label={preset.inputs.label}
|
||||
min={0}
|
||||
max={8}
|
||||
value={5}
|
||||
value={Number(preset.inputs.defaultValue) || Number(inputValues[preset.inputs.label]) || 5}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
|
|
@ -26,6 +26,7 @@ const ProductionCapacity = ({
|
|||
const [isLoading, setIsLoading] = useState(true);
|
||||
|
||||
useEffect(() => {
|
||||
console.log('throughputData: ', throughputData);
|
||||
if (throughputData > 0) {
|
||||
setIsLoading(false);
|
||||
} else {
|
||||
|
|
|
@ -143,9 +143,10 @@ const List: React.FC<ListProps> = ({ items = [], remove }) => {
|
|||
let response = await setFloorItemApi(
|
||||
organization,
|
||||
zoneAssetId.id,
|
||||
newName
|
||||
newName,
|
||||
projectId
|
||||
);
|
||||
// console.log("response: ", response);
|
||||
console.log("response: ", response);
|
||||
|
||||
setName(zoneAssetId.id, response.modelName);
|
||||
}
|
||||
|
|
|
@ -16,6 +16,7 @@ export default function ROIData() {
|
|||
|
||||
useEffect(() => {
|
||||
if (!isPlaying) {
|
||||
console.log("running ROIData effect");
|
||||
setRoiSummaryData({
|
||||
productName: "",
|
||||
roiPercentage: 0,
|
||||
|
@ -25,11 +26,10 @@ export default function ROIData() {
|
|||
netProfit: 0,
|
||||
netLoss: 0,
|
||||
})
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if (inputValues === undefined) return;
|
||||
|
||||
const electricityCost = parseFloat(inputValues["Electricity cost"]);
|
||||
const fixedCost = parseFloat(inputValues["Fixed costs"]);
|
||||
const laborCost = parseFloat(inputValues["Labor Cost"]);
|
||||
|
@ -69,15 +69,6 @@ export default function ROIData() {
|
|||
const paybackPeriod = initialInvestment / (annualProfit || 1); // Avoid division by 0
|
||||
|
||||
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
|
||||
setRoiSummaryData({
|
||||
productName: selectedProduct.productName,
|
||||
roiPercentage: parseFloat((roiPercentage / 100).toFixed(2)), // normalized to 0.x format
|
||||
|
@ -99,14 +90,6 @@ export default function ROIData() {
|
|||
|
||||
const netProfitForTarget = profitForTargetUnits > 0 ? profitForTargetUnits : 0;
|
||||
const netLossForTarget = profitForTargetUnits < 0 ? -profitForTargetUnits : 0;
|
||||
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
|
||||
const productData = getProductById(selectedProduct.productUuid);
|
||||
|
||||
|
||||
|
@ -140,11 +123,30 @@ export default function ROIData() {
|
|||
return [...prev, newData];
|
||||
}
|
||||
});
|
||||
// console.log('compareProducts: ', compareProducts);
|
||||
|
||||
|
||||
}
|
||||
|
||||
}, [inputValues, productionCapacityData]);
|
||||
}, [inputValues, productionCapacityData, selectedProduct?.productUuid]);
|
||||
useEffect(() => {
|
||||
|
||||
console.log('compareProducts: ', compareProducts);
|
||||
}, [compareProducts]);
|
||||
useEffect(() => {
|
||||
// Clear ROI summary data when product changes
|
||||
setRoiSummaryData({
|
||||
productName: "",
|
||||
roiPercentage: 0,
|
||||
paybackPeriod: 0,
|
||||
totalCost: 0,
|
||||
revenueGenerated: 0,
|
||||
netProfit: 0,
|
||||
netLoss: 0,
|
||||
});
|
||||
|
||||
// Optionally clear comparison data for this product only
|
||||
setCompareProducts(prev => prev.filter(p => p.productUuid !== selectedProduct.productUuid));
|
||||
}, [selectedProduct?.productUuid]);
|
||||
|
||||
return (
|
||||
<></>
|
||||
|
|
|
@ -1,12 +1,15 @@
|
|||
import React, { useEffect } from 'react'
|
||||
import { useInputValues, useProductionCapacityData, useThroughPutData } from '../../../../store/builder/store'
|
||||
import { usePlayButtonStore } from '../../../../store/usePlayButtonStore';
|
||||
import { useProductContext } from '../../products/productContext';
|
||||
|
||||
export default function ProductionCapacityData() {
|
||||
const { throughputData } = useThroughPutData()
|
||||
const { productionCapacityData, setProductionCapacityData } = useProductionCapacityData()
|
||||
const { inputValues } = useInputValues();
|
||||
const { isPlaying } = usePlayButtonStore();
|
||||
const { selectedProductStore } = useProductContext();
|
||||
const { selectedProduct } = selectedProductStore();
|
||||
|
||||
useEffect(() => {
|
||||
if (!isPlaying) {
|
||||
|
@ -16,12 +19,17 @@ export default function ProductionCapacityData() {
|
|||
if (!inputValues || throughputData === undefined) return;
|
||||
|
||||
const shiftLength = parseFloat(inputValues["Shift length"]);
|
||||
console.log('shiftLength: ', shiftLength);
|
||||
|
||||
const shiftsPerDay = parseFloat(inputValues["Shifts / day"]);
|
||||
|
||||
const workingDaysPerYear = parseFloat(inputValues["Working days / year"]);
|
||||
|
||||
const yieldRate = parseFloat(inputValues["Yield rate"]);
|
||||
|
||||
|
||||
if (!isNaN(shiftLength) && !isNaN(shiftsPerDay) && !isNaN(workingDaysPerYear) &&
|
||||
!isNaN(yieldRate) && throughputData >= 0) {
|
||||
!isNaN(yieldRate) && throughputData > 0) {
|
||||
// Total units produced per day before yield
|
||||
const dailyProduction = throughputData * shiftLength * shiftsPerDay;
|
||||
|
||||
|
@ -42,6 +50,11 @@ export default function ProductionCapacityData() {
|
|||
setProductionCapacityData(Number(productionPerHour.toFixed(2)));
|
||||
}
|
||||
}, [throughputData, inputValues]);
|
||||
useEffect(() => {
|
||||
|
||||
setProductionCapacityData(0);
|
||||
|
||||
}, [selectedProduct?.productUuid]);
|
||||
|
||||
return (
|
||||
<></>
|
||||
|
|
|
@ -107,15 +107,15 @@ export default function ThroughPutData() {
|
|||
fetchProductSequenceData();
|
||||
}
|
||||
// if (materialCycleTime <= 0) return
|
||||
}, [products, selectedProduct, getProductById, setMachineCount, materialCycleTime, armBots, vehicles, machines]);
|
||||
}, [products, selectedProduct?.productUuid, getProductById, setMachineCount, materialCycleTime, armBots, vehicles, machines]);
|
||||
|
||||
useEffect(() => {
|
||||
let timeoutId: ReturnType<typeof setTimeout>;
|
||||
async function getMachineActive() {
|
||||
const productData = getProductById(selectedProduct.productUuid);
|
||||
let anyArmActive;
|
||||
let anyVehicleActive;
|
||||
let anyMachineActive;
|
||||
|
||||
if (productData) {
|
||||
const productSequenceData = await determineExecutionMachineSequences([productData]);
|
||||
if (productSequenceData?.length > 0) {
|
||||
|
@ -182,11 +182,15 @@ export default function ThroughPutData() {
|
|||
}
|
||||
}
|
||||
if (isPlaying) {
|
||||
setTimeout(() => {
|
||||
timeoutId = setTimeout(() => {
|
||||
getMachineActive();
|
||||
}, 500)
|
||||
}, 1500);
|
||||
}
|
||||
}, [armBots, materials, materialHistory, machines, vehicles, selectedProduct])
|
||||
|
||||
return () => {
|
||||
if (timeoutId) clearTimeout(timeoutId);
|
||||
};
|
||||
}, [armBots, materials, materialHistory, machines, vehicles, selectedProduct?.productUuid])
|
||||
|
||||
useEffect(() => {
|
||||
if (machineActiveTime > 0 && materialCycleTime > 0 && machineCount > 0) {
|
||||
|
@ -196,7 +200,16 @@ export default function ThroughPutData() {
|
|||
setThroughputData(Number(throughput.toFixed(2))); // Keep as number
|
||||
//
|
||||
}
|
||||
}, [machineActiveTime, materialCycleTime, machineCount]);
|
||||
}, [machineActiveTime, materialCycleTime, machineCount, selectedProduct?.productUuid]);
|
||||
useEffect(() => {
|
||||
totalActiveTime = 0;
|
||||
totalItems = 0;
|
||||
setMachineCount(0);
|
||||
setMachineActiveTime(0);
|
||||
setMaterialCycleTime(0);
|
||||
setProcessBar([]);
|
||||
setThroughputData(0);
|
||||
}, [selectedProduct?.productUuid]);
|
||||
|
||||
return (
|
||||
<>
|
||||
|
|
|
@ -3,24 +3,25 @@ export const setFloorItemApi = async (
|
|||
organization: string,
|
||||
modelUuid?: string,
|
||||
modelName?: string,
|
||||
projectId?: string,
|
||||
modelfileID?: string,
|
||||
position?: Object,
|
||||
rotation?: Object,
|
||||
isLocked?: boolean,
|
||||
isVisible?: boolean
|
||||
isVisible?: boolean,
|
||||
) => {
|
||||
try {
|
||||
const body: any = {
|
||||
organization,
|
||||
modelUuid,
|
||||
modelName,
|
||||
projectId,
|
||||
position,
|
||||
rotation,
|
||||
modelfileID,
|
||||
isLocked,
|
||||
isVisible,
|
||||
};
|
||||
|
||||
const response = await fetch(`${url_Backend_dwinzo}/api/V1/setAsset`, {
|
||||
method: "POST",
|
||||
headers: {
|
||||
|
|
|
@ -88,6 +88,7 @@ export const createMaterialStore = () => {
|
|||
clearMaterials: () => {
|
||||
set((state) => {
|
||||
state.materials = [];
|
||||
state.materialHistory = [];
|
||||
});
|
||||
},
|
||||
|
||||
|
|
|
@ -5,6 +5,7 @@ type Preset = {
|
|||
activeOption: string;
|
||||
min?: number;
|
||||
max?: number;
|
||||
defaultValue?: string | number;
|
||||
};
|
||||
};
|
||||
|
||||
|
|
Loading…
Reference in New Issue