Mirror of https://github.com/roostorg/osprey github.com/roostorg/osprey
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

at main 119 lines 4.1 kB view raw
1import React from 'react'; 2 3import type { BulkActionJob } from '../../types/BulkActionTypes'; 4 5import styles from './BulkActionTable.module.css'; 6import CopyLinkButton from '../common/CopyLinkButton'; 7import { Spin } from 'antd'; 8 9interface JobTableProps { 10 jobs?: BulkActionJob[]; 11 onCancelJob: (jobId: string) => void; 12 jobPollingInProgress: boolean; 13} 14 15function isJobInProgress(job: BulkActionJob): boolean { 16 return job.status === 'processing' || job.status === 'uploaded' || job.status === 'parsing'; 17} 18 19export const BulkActionJobTable: React.FC<JobTableProps> = ({ jobs = [], onCancelJob, jobPollingInProgress }) => { 20 const formatDate = (dateString: string): string => { 21 return new Date(dateString).toLocaleDateString('en-US', { 22 year: 'numeric', 23 month: 'short', 24 day: 'numeric', 25 hour: '2-digit', 26 minute: '2-digit', 27 }); 28 }; 29 30 const getStatusClass = (status: string): string => { 31 switch (status) { 32 case 'completed': 33 return styles.statusCompleted; 34 case 'processing': 35 case 'uploaded': 36 case 'parsing': 37 return styles.statusInProgress; 38 case 'failed': 39 case 'cancelled': 40 return styles.statusFailed; 41 default: 42 return styles.statusDefault; 43 } 44 }; 45 46 const getStatusDisplay = (job: BulkActionJob) => { 47 switch (job.status) { 48 case 'completed': 49 return 'Completed'; 50 case 'processing': 51 return 'Processing'; 52 case 'uploaded': 53 case 'pending_upload': 54 return 'Uploaded & Pending '; 55 case 'parsing': 56 return 'Setting up job'; 57 case 'failed': 58 return 'Failed'; 59 case 'cancelled': 60 return 'Cancelled'; 61 default: 62 return 'Unknown'; 63 } 64 }; 65 66 return ( 67 <div className={styles.tableContainer}> 68 <table className={styles.jobTable}> 69 <thead> 70 <tr className={styles.tableHeader}> 71 <th>Job ID</th> 72 <th>Job Name</th> 73 <th>Job Description</th> 74 <th>Workflow</th> 75 <th>Status</th> 76 <th>Progress</th> 77 <th>Created By</th> 78 <th>Created At</th> 79 <th>Actions</th> 80 </tr> 81 </thead> 82 <tbody> 83 {jobs.map((job: BulkActionJob, index: number) => ( 84 <tr key={job.id || index} className={`${styles.tableRow} ${isJobInProgress(job) ? styles.inProgress : ''}`}> 85 <td className={styles.tableCell}>{job.id}</td> 86 <td className={`${styles.tableCell} ${styles.descriptionCell}`}>{job.name}</td> 87 <td className={`${styles.tableCell} ${styles.descriptionCell}`}>{job.description}</td> 88 <td className={styles.tableCell}>{job.action_workflow_name}</td> 89 <td className={styles.tableCell}> 90 <span className={`${styles.statusBadge} ${getStatusClass(job.status)}`}>{getStatusDisplay(job)}</span> 91 {jobPollingInProgress && isJobInProgress(job) && <Spin size="small" />} 92 </td> 93 <td className={styles.tableCell}> 94 {job.processed_rows ?? 0}/{job.total_rows ?? 0} actions processed 95 </td> 96 <td className={styles.tableCell}>{job.user_id}</td> 97 <td className={styles.tableCell}>{formatDate(job.created_at)}</td> 98 <td className={styles.tableCell}> 99 <div className={styles.actionsContainer}> 100 <button 101 className={`${styles.actionButton} ${styles.deleteButton} ${ 102 job.status === 'completed' || job.status === 'failed' || job.status === 'cancelled' 103 ? styles.disabledButton 104 : '' 105 }`} 106 onClick={() => onCancelJob(job.id)} 107 disabled={job.status === 'completed' || job.status === 'failed' || job.status === 'cancelled'} 108 > 109 Cancel 110 </button> 111 </div> 112 </td> 113 </tr> 114 ))} 115 </tbody> 116 </table> 117 </div> 118 ); 119};