- Finish department cycle times.

Signed-off-by: Dave Richer <dave@imexsystems.ca>
This commit is contained in:
Dave Richer
2024-01-26 16:09:46 -05:00
parent 89224e871c
commit 120a8a4576
7 changed files with 47735 additions and 71 deletions

View File

@@ -5,6 +5,7 @@ import {Badge, Card, Space, Table, Tag} from 'antd';
import {gql, useQuery} from "@apollo/client";
import {DateTimeFormatterFunction} from "../../utils/DateFormatter";
import {isEmpty} from "lodash";
import {useTranslation} from "react-i18next";
require('./job-lifecycle.styles.scss');
@@ -12,8 +13,8 @@ require('./job-lifecycle.styles.scss');
export function JobLifecycleComponent({job, statuses, ...rest}) {
const [loading, setLoading] = useState(true);
const [lifecycleData, setLifecycleData] = useState(null);
const { t } = useTranslation(); // Used for tracking external state changes.
// Used for tracking external state changes.
const {data} = useQuery(gql`
query get_job_test($id: uuid!){
jobs_by_pk(id:$id){
@@ -43,7 +44,7 @@ export function JobLifecycleComponent({job, statuses, ...rest}) {
const data = response.data.transition[job.id];
setLifecycleData(data);
} catch (err) {
console.error(`Error getting Job Lifecycle Data: ${err.message}`);
console.error(`${t('job_lifecycle.errors.fetch')}: ${err.message}`);
} finally {
setLoading(false);
}
@@ -53,30 +54,30 @@ export function JobLifecycleComponent({job, statuses, ...rest}) {
useEffect(() => {
if (!data) return;
setTimeout(() => {
getLifecycleData().catch(err => console.error(`Error getting Job Lifecycle Data: ${err.message}`));
}, 1000);
getLifecycleData().catch(err => console.error(`${t('job_lifecycle.errors.fetch')}: ${err.message}`));
}, 500);
}, [data, getLifecycleData]);
const columns = [
{
title: 'Value',
title: t('job_lifecycle.columns.value'),
dataIndex: 'value',
key: 'value',
},
{
title: 'Start',
title: t('job_lifecycle.columns.start'),
dataIndex: 'start',
key: 'start',
render: (text) => DateTimeFormatterFunction(text),
sorter: (a, b) => moment(a.start).unix() - moment(b.start).unix(),
},
{
title: 'Relative Start',
title: t('job_lifecycle.columns.relative_start'),
dataIndex: 'start_readable',
key: 'start_readable',
},
{
title: 'End',
title: t('job_lifecycle.columns.end'),
dataIndex: 'end',
key: 'end',
sorter: (a, b) => {
@@ -88,33 +89,23 @@ export function JobLifecycleComponent({job, statuses, ...rest}) {
}
return moment(a.end).unix() - moment(b.end).unix();
},
render: (text) => isEmpty(text) ? 'N/A' : DateTimeFormatterFunction(text)
render: (text) => isEmpty(text) ? t('job_lifecycle.content.not_available') : DateTimeFormatterFunction(text)
},
{
title: 'Relative End',
title: t('job_lifecycle.columns.relative_end'),
dataIndex: 'end_readable',
key: 'end_readable',
},
{
title: 'Duration',
title: t('job_lifecycle.columns.duration'),
dataIndex: 'duration_readable',
key: 'duration_readable',
sorter: (a, b) => a.duration - b.duration,
},
];
useEffect(() => {
console.log('Statuses');
console.dir(statuses, {depth: null});
}, [statuses]);
// useEffect(() => {
// console.log('LifeCycle Data');
// console.dir(lifecycleData, {depth: null})
// }, [lifecycleData]);
return (
<Card loading={loading} title='Job Lifecycle Component'>
<Card loading={loading} title={t('job_lifecycle.content.title')}>
{!loading ? (
lifecycleData && lifecycleData.lifecycle && lifecycleData.durations ? (
<Space direction='vertical' style={{width: '100%'}}>
@@ -123,7 +114,7 @@ export function JobLifecycleComponent({job, statuses, ...rest}) {
title={(
<Space direction='horizontal' size='small'>
<Badge status='processing' count={lifecycleData.durations.totalStatuses}/>
Historical Status Durations
{t('job_lifecycle.content.title_durations')}
</Space>
)}
@@ -165,22 +156,26 @@ export function JobLifecycleComponent({job, statuses, ...rest}) {
aria-label={`${key.status} | ${key.roundedPercentage} | ${key.humanReadable}`}
title={`${key.status} | ${key.roundedPercentage} | ${key.humanReadable}`}
>
<div>{key.roundedPercentage}</div>
{key.percentage > 5 ?
<div style={{
backgroundColor: '#f0f2f5',
borderRadius: '5px',
paddingRight: '2px',
paddingLeft: '2px',
fontSize: '0.8rem',
}}>
{key.status}
</div> : null}
<>
<div>{key.roundedPercentage}</div>
<div style={{
backgroundColor: '#f0f2f5',
borderRadius: '5px',
paddingRight: '2px',
paddingLeft: '2px',
fontSize: '0.8rem',
}}>
{key.status}
</div>
</>
: null}
</div>
);
})}
</div>
<Card type='inner' title='Legend' style={{marginTop: '10px'}}>
<Card type='inner' title={t('job_lifecycle.content.legend_title')} style={{marginTop: '10px'}}>
<div>
{lifecycleData.durations.summations.map((key) => (
<Tag color={key.color} style={{width: '13vh', padding: '4px', margin: '4px'}}>
@@ -200,15 +195,21 @@ export function JobLifecycleComponent({job, statuses, ...rest}) {
</div>
</Card>
<Card style={{marginTop: '10px'}}>
<span
style={{fontWeight: 'bold'}}>Previous Status Accumulated Time:</span> {lifecycleData.durations.humanReadableTotal}
<ul>
<li>
<span style={{fontWeight: 'bold'}}>{t('job_lifecycle.content.previous_status_accumulated_time')}:</span> {lifecycleData.durations.humanReadableTotal}
</li>
<li>
<span style={{fontWeight: 'bold'}}>{t('job_lifecycle.content.current_status_accumulated_time')} ({lifecycleData.lifecycle[0].value}):</span> {lifecycleData.durations.totalCurrentStatusDuration.humanReadable}
</li>
</ul>
</Card>
</Card>
<Card type='inner' title={(
<>
<Space direction="horizontal" size="small">
<Badge status='processing' count={lifecycleData.lifecycle.length}/>
Transitions
{t('job_lifecycle.content.title_transitions')}
</Space>
</>
)}>
@@ -217,12 +218,12 @@ export function JobLifecycleComponent({job, statuses, ...rest}) {
</Space>
) : (
<Card type='inner' style={{textAlign: 'center'}}>
There is currently no lifecycle data for this job.
{t('job_lifecycle.content.data_unavailable')}
</Card>
)
) : (
<Card type='inner' title='Loading'>
Loading Job Timelines....
<Card type='inner' title={t('job_lifecycle.content.title_loading')}>
{t('job_lifecycle.content.loading')}
</Card>
)}
</Card>