feat: Implement runtime parsing and reduce button alpha
Adds runtime parsing from job imports and adds a runtime field to the job creation dialogue. Reduces the alpha on status buttons.
This commit is contained in:
@@ -1,3 +1,4 @@
|
|||||||
|
|
||||||
import React, { useState } from 'react';
|
import React, { useState } from 'react';
|
||||||
import { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/card';
|
import { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/card';
|
||||||
import { Button } from '@/components/ui/button';
|
import { Button } from '@/components/ui/button';
|
||||||
@@ -21,7 +22,8 @@ const JobForm: React.FC<JobFormProps> = ({ job, onSubmit, onCancel }) => {
|
|||||||
outputQuantity: job?.outputQuantity || 0,
|
outputQuantity: job?.outputQuantity || 0,
|
||||||
status: job?.status || IndJobStatusOptions.Planned,
|
status: job?.status || IndJobStatusOptions.Planned,
|
||||||
projectedCost: job?.projectedCost || 0,
|
projectedCost: job?.projectedCost || 0,
|
||||||
projectedRevenue: job?.projectedRevenue || 0
|
projectedRevenue: job?.projectedRevenue || 0,
|
||||||
|
runtime: job?.runtime || 0
|
||||||
});
|
});
|
||||||
|
|
||||||
const [jobDump, setJobDump] = useState('');
|
const [jobDump, setJobDump] = useState('');
|
||||||
@@ -35,7 +37,7 @@ const JobForm: React.FC<JobFormProps> = ({ job, onSubmit, onCancel }) => {
|
|||||||
|
|
||||||
const lines = dumpText.trim().split('\n').filter(line => line.trim());
|
const lines = dumpText.trim().split('\n').filter(line => line.trim());
|
||||||
|
|
||||||
if (lines.length >= 3) {
|
if (lines.length >= 4) {
|
||||||
// Parse first line: "Item Name Quantity"
|
// Parse first line: "Item Name Quantity"
|
||||||
const firstLine = lines[0].trim();
|
const firstLine = lines[0].trim();
|
||||||
const lastSpaceIndex = firstLine.lastIndexOf(' ');
|
const lastSpaceIndex = firstLine.lastIndexOf(' ');
|
||||||
@@ -44,22 +46,26 @@ const JobForm: React.FC<JobFormProps> = ({ job, onSubmit, onCancel }) => {
|
|||||||
const itemName = firstLine.substring(0, lastSpaceIndex).trim();
|
const itemName = firstLine.substring(0, lastSpaceIndex).trim();
|
||||||
const quantity = parseInt(firstLine.substring(lastSpaceIndex + 1).trim()) || 0;
|
const quantity = parseInt(firstLine.substring(lastSpaceIndex + 1).trim()) || 0;
|
||||||
|
|
||||||
// Parse cost (second line)
|
// Parse runtime (second line)
|
||||||
const cost = parseISKAmount(lines[1].replace(/,/g, ''));
|
const runtime = parseInt(lines[1].replace(/,/g, '')) || 0;
|
||||||
|
|
||||||
// Parse revenue (third line)
|
// Parse cost (third line)
|
||||||
const revenue = parseISKAmount(lines[2].replace(/,/g, ''));
|
const cost = parseISKAmount(lines[2].replace(/,/g, ''));
|
||||||
|
|
||||||
|
// Parse revenue (fourth line)
|
||||||
|
const revenue = parseISKAmount(lines[3].replace(/,/g, ''));
|
||||||
|
|
||||||
setFormData(prev => ({
|
setFormData(prev => ({
|
||||||
...prev,
|
...prev,
|
||||||
outputItem: itemName,
|
outputItem: itemName,
|
||||||
outputQuantity: quantity,
|
outputQuantity: quantity,
|
||||||
|
runtime: runtime,
|
||||||
projectedCost: cost,
|
projectedCost: cost,
|
||||||
projectedRevenue: revenue
|
projectedRevenue: revenue
|
||||||
}));
|
}));
|
||||||
|
|
||||||
// Parse BOM - everything after the first 3 lines is BOM
|
// Parse BOM - everything after the first 4 lines is BOM
|
||||||
const bomLines = lines.slice(3); // Start from line 4 (index 3)
|
const bomLines = lines.slice(4); // Start from line 5 (index 4)
|
||||||
const billOfMaterials: { name: string; quantity: number }[] = [];
|
const billOfMaterials: { name: string; quantity: number }[] = [];
|
||||||
|
|
||||||
for (const line of bomLines) {
|
for (const line of bomLines) {
|
||||||
@@ -95,7 +101,8 @@ const JobForm: React.FC<JobFormProps> = ({ job, onSubmit, onCancel }) => {
|
|||||||
outputQuantity: formData.outputQuantity,
|
outputQuantity: formData.outputQuantity,
|
||||||
status: formData.status,
|
status: formData.status,
|
||||||
projectedCost: formData.projectedCost,
|
projectedCost: formData.projectedCost,
|
||||||
projectedRevenue: formData.projectedRevenue
|
projectedRevenue: formData.projectedRevenue,
|
||||||
|
runtime: formData.runtime
|
||||||
}, parsedBillOfMaterials.length > 0 ? parsedBillOfMaterials : undefined);
|
}, parsedBillOfMaterials.length > 0 ? parsedBillOfMaterials : undefined);
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -159,7 +166,20 @@ const JobForm: React.FC<JobFormProps> = ({ job, onSubmit, onCancel }) => {
|
|||||||
</Select>
|
</Select>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className="grid grid-cols-2 gap-4">
|
<div className="grid grid-cols-3 gap-4">
|
||||||
|
<div className="space-y-2">
|
||||||
|
<Label htmlFor="runtime" className="text-gray-300">Runtime (seconds)</Label>
|
||||||
|
<Input
|
||||||
|
id="runtime"
|
||||||
|
type="number"
|
||||||
|
value={formData.runtime}
|
||||||
|
onChange={(e) => setFormData({
|
||||||
|
...formData,
|
||||||
|
runtime: parseInt(e.target.value) || 0
|
||||||
|
})}
|
||||||
|
className="bg-gray-800 border-gray-600 text-white"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
<div className="space-y-2">
|
<div className="space-y-2">
|
||||||
<Label htmlFor="projectedCost" className="text-gray-300">Projected Cost</Label>
|
<Label htmlFor="projectedCost" className="text-gray-300">Projected Cost</Label>
|
||||||
<Input
|
<Input
|
||||||
@@ -194,7 +214,7 @@ const JobForm: React.FC<JobFormProps> = ({ job, onSubmit, onCancel }) => {
|
|||||||
id="jobDump"
|
id="jobDump"
|
||||||
value={jobDump}
|
value={jobDump}
|
||||||
onChange={handleJobDumpChange}
|
onChange={handleJobDumpChange}
|
||||||
placeholder="Paste job dump here: Standup Light Guided Bomb 100 285,224,182 771,342,930 Megacyte 37 Zydrine 84 ..."
|
placeholder="Paste job dump here: Discovery Survey Probe I 800 468000 158,670,288 237,484,800 Tritanium 8888800 Pyerite 711200 ..."
|
||||||
className="bg-gray-800 border-gray-600 text-white min-h-[120px]"
|
className="bg-gray-800 border-gray-600 text-white min-h-[120px]"
|
||||||
rows={6}
|
rows={6}
|
||||||
/>
|
/>
|
||||||
|
@@ -74,7 +74,7 @@ const JobStatusNavigation: React.FC<JobStatusNavigationProps> = ({ job }) => {
|
|||||||
e.stopPropagation();
|
e.stopPropagation();
|
||||||
handleStatusChange(previousStatus);
|
handleStatusChange(previousStatus);
|
||||||
}}
|
}}
|
||||||
className={`${getStatusColor(previousStatus)} text-white px-4 py-2 rounded flex items-center justify-center gap-1 hover:opacity-80 transition-opacity w-32`}
|
className={`${getStatusColor(previousStatus)}/60 text-white px-4 py-2 rounded flex items-center justify-center gap-1 hover:opacity-80 transition-opacity w-32`}
|
||||||
data-no-navigate
|
data-no-navigate
|
||||||
title={`Move to ${previousStatus}`}
|
title={`Move to ${previousStatus}`}
|
||||||
>
|
>
|
||||||
@@ -88,7 +88,7 @@ const JobStatusNavigation: React.FC<JobStatusNavigationProps> = ({ job }) => {
|
|||||||
e.stopPropagation();
|
e.stopPropagation();
|
||||||
handleStatusChange(nextStatus);
|
handleStatusChange(nextStatus);
|
||||||
}}
|
}}
|
||||||
className={`${getStatusColor(nextStatus)} text-white px-4 py-2 rounded flex items-center justify-center gap-1 hover:opacity-80 transition-opacity w-32`}
|
className={`${getStatusColor(nextStatus)}/60 text-white px-4 py-2 rounded flex items-center justify-center gap-1 hover:opacity-80 transition-opacity w-32`}
|
||||||
data-no-navigate
|
data-no-navigate
|
||||||
title={`Move to ${nextStatus}`}
|
title={`Move to ${nextStatus}`}
|
||||||
>
|
>
|
||||||
|
Reference in New Issue
Block a user