kopia lustrzana https://github.com/OpenDroneMap/WebODM
processing time
rodzic
a8ab95131f
commit
ec57a5fc77
|
@ -125,7 +125,8 @@ export default function MainMenu(props) {
|
|||
...task,
|
||||
progressPct,
|
||||
status: taskStatus,
|
||||
running_progress: taskDetail.running_progress || 0
|
||||
running_progress: taskDetail.running_progress || 0,
|
||||
processing_time: taskDetail.processing_time || null
|
||||
};
|
||||
} catch (e) {
|
||||
// This catch block handles network errors or JSON parsing errors, but not 404s
|
||||
|
@ -366,6 +367,7 @@ export default function MainMenu(props) {
|
|||
} finally {
|
||||
sessionStorage.removeItem('username');
|
||||
props.setIsLogged(false);
|
||||
navigate('/');
|
||||
}
|
||||
}} className="logout-dialog-btn">Yes</button>
|
||||
<button onClick={() => setShowLogoutDialog(false)} className="logout-dialog-btn no">No</button>
|
||||
|
|
|
@ -374,6 +374,15 @@
|
|||
background: #ddd;
|
||||
color: #222;
|
||||
}
|
||||
.task-processing-time {
|
||||
margin-top: 0.75rem;
|
||||
}
|
||||
|
||||
.processing-time-text {
|
||||
color: #718096;
|
||||
font-size: 0.85rem;
|
||||
font-weight: 400;
|
||||
}
|
||||
|
||||
/* ====== THUMBNAILS ====== */
|
||||
.task-thumbnail {
|
||||
|
|
|
@ -4,11 +4,23 @@ import ProjectViewer from "./ProjectContainer.jsx";
|
|||
import Export from './Export.jsx';
|
||||
import { authorizedFetch } from '../utils/api.js';
|
||||
|
||||
// New TaskBox component with thumbnail hover functionality
|
||||
// Helper function from the first code block for processing time format
|
||||
const formatProcessingTime = (milliseconds) => {
|
||||
const totalSeconds = Math.floor(milliseconds / 1000);
|
||||
const hours = Math.floor(totalSeconds / 3600);
|
||||
const minutes = Math.floor((totalSeconds % 3600) / 60);
|
||||
const seconds = totalSeconds % 60;
|
||||
|
||||
return `${hours.toString().padStart(2, '0')}:${minutes.toString().padStart(2, '0')}:${seconds.toString().padStart(2, '0')}`;
|
||||
};
|
||||
|
||||
// New TaskBox component with processing time functionality and second block's UI
|
||||
const TaskBox = ({ task, onAction, onShowDeleteDialog, fetchJSON, isDeleteDialogOpen = false, openExportTaskId, setOpenExportTaskId }) => {
|
||||
const [lastError, setLastError] = useState(null);
|
||||
const [isHovering, setIsHovering] = useState(false);
|
||||
const [thumbnailUrl, setThumbnailUrl] = useState(null);
|
||||
// Added state for processing time
|
||||
const [processingTime, setProcessingTime] = useState(null);
|
||||
|
||||
const fetchLastError = useCallback(async () => {
|
||||
if (task.status === 30) {
|
||||
|
@ -30,7 +42,11 @@ const TaskBox = ({ task, onAction, onShowDeleteDialog, fetchJSON, isDeleteDialog
|
|||
|
||||
useEffect(() => {
|
||||
fetchLastError();
|
||||
}, [fetchLastError]);
|
||||
// Added logic for setting processing time on completion
|
||||
if (task.status === 40 && task.processing_time && !processingTime) {
|
||||
setProcessingTime(task.processing_time);
|
||||
}
|
||||
}, [fetchLastError, task, processingTime]); // Dependency array updated
|
||||
|
||||
const getStatusText = (statusCode) => {
|
||||
switch (statusCode) {
|
||||
|
@ -83,7 +99,7 @@ const TaskBox = ({ task, onAction, onShowDeleteDialog, fetchJSON, isDeleteDialog
|
|||
</div>
|
||||
</div>
|
||||
<div className="task-id-row">
|
||||
<span className="task-id">{task.id}</span>
|
||||
<span className="task-id">ID: {task.id}</span>
|
||||
</div>
|
||||
<div className="task-content">
|
||||
{effectiveStatus === 30 && lastError && (
|
||||
|
@ -109,6 +125,12 @@ const TaskBox = ({ task, onAction, onShowDeleteDialog, fetchJSON, isDeleteDialog
|
|||
)}
|
||||
</div>
|
||||
)}
|
||||
{/* Processing Time Display added here, as per the first code block's functionality */}
|
||||
{effectiveStatus === 40 && processingTime && (
|
||||
<div className="task-processing-time">
|
||||
<span className="processing-time-text">{formatProcessingTime(processingTime)}</span>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
<div className="task-actions">
|
||||
{effectiveStatus === 20 && (
|
||||
|
@ -148,17 +170,10 @@ const TaskBox = ({ task, onAction, onShowDeleteDialog, fetchJSON, isDeleteDialog
|
|||
)}
|
||||
</div>
|
||||
</div>
|
||||
{/* Thumbnail container outside the main content but inside the task-box */}
|
||||
{/* Thumbnail container exactly as in the second code block (no click handler) */}
|
||||
{isHovering && effectiveStatus === 40 && thumbnailUrl && (
|
||||
<div className="task-thumbnail-wrapper">
|
||||
<button
|
||||
type="button"
|
||||
className="thumbnail-button"
|
||||
onClick={() => handleAction('view')}
|
||||
title="View"
|
||||
>
|
||||
<img src={thumbnailUrl} alt={`Thumbnail for task ${task.id}`} className="task-thumbnail" />
|
||||
</button>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
|
@ -169,9 +184,7 @@ const TaskBox = ({ task, onAction, onShowDeleteDialog, fetchJSON, isDeleteDialog
|
|||
const Tasks = ({ runningTasks, loading, onRefresh, onTaskAction ,isViewing,exitView,selectedTask, filterProjectId, setFilterProjectId, projects }) => {
|
||||
const [deleteDialogTask, setDeleteDialogTask] = useState(null);
|
||||
const [filterProjectName, setFilterProjectName] = useState(null);
|
||||
// Share delete dialog state with child components
|
||||
const [isDeleteDialogOpen, setIsDeleteDialogOpen] = useState(false);
|
||||
// Add state to track the currently open Export dropdown
|
||||
const [openExportTaskId, setOpenExportTaskId] = useState(null);
|
||||
|
||||
useEffect(() => {
|
||||
|
@ -266,6 +279,7 @@ const Tasks = ({ runningTasks, loading, onRefresh, onTaskAction ,isViewing,exitV
|
|||
<>
|
||||
{categorizedTasks.running.length > 0 && (
|
||||
<div className="task-category">
|
||||
<h3>Running Tasks ({categorizedTasks.running.length})</h3>
|
||||
<div className="tasks-grid">
|
||||
{categorizedTasks.running.map((task) => (
|
||||
<TaskBox
|
||||
|
@ -284,6 +298,7 @@ const Tasks = ({ runningTasks, loading, onRefresh, onTaskAction ,isViewing,exitV
|
|||
)}
|
||||
{categorizedTasks.completed.length > 0 && (
|
||||
<div className="task-category">
|
||||
<h3>Completed Tasks ({categorizedTasks.completed.length})</h3>
|
||||
<div className="tasks-grid">
|
||||
{categorizedTasks.completed.map((task) => (
|
||||
<TaskBox
|
||||
|
@ -302,6 +317,7 @@ const Tasks = ({ runningTasks, loading, onRefresh, onTaskAction ,isViewing,exitV
|
|||
)}
|
||||
{categorizedTasks.failed.length > 0 && (
|
||||
<div className="task-category">
|
||||
<h3>Failed Tasks ({categorizedTasks.failed.length})</h3>
|
||||
<div className="tasks-grid">
|
||||
{categorizedTasks.failed.map((task) => (
|
||||
<TaskBox
|
||||
|
@ -320,6 +336,7 @@ const Tasks = ({ runningTasks, loading, onRefresh, onTaskAction ,isViewing,exitV
|
|||
)}
|
||||
{categorizedTasks.canceled.length > 0 && (
|
||||
<div className="task-category">
|
||||
<h3>Canceled Tasks ({categorizedTasks.canceled.length})</h3>
|
||||
<div className="tasks-grid">
|
||||
{categorizedTasks.canceled.map((task) => (
|
||||
<TaskBox
|
||||
|
@ -338,6 +355,7 @@ const Tasks = ({ runningTasks, loading, onRefresh, onTaskAction ,isViewing,exitV
|
|||
)}
|
||||
{categorizedTasks.queued.length > 0 && (
|
||||
<div className="task-category">
|
||||
<h3>Queued Tasks ({categorizedTasks.queued.length})</h3>
|
||||
<div className="tasks-grid">
|
||||
{categorizedTasks.queued.map((task) => (
|
||||
<TaskBox
|
||||
|
|
Ładowanie…
Reference in New Issue