-
Notifications
You must be signed in to change notification settings - Fork 184
Expand file tree
/
Copy pathProcessSteps.tsx
More file actions
121 lines (108 loc) · 4.29 KB
/
ProcessSteps.tsx
File metadata and controls
121 lines (108 loc) · 4.29 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
import React, { useEffect, useState, useRef } from "react";
import { Accordion, AccordionItem, AccordionHeader, AccordionPanel } from "@fluentui/react-components";
import { useSelector, shallowEqual } from 'react-redux';
import { RootState } from '../../../../store/index.ts';
import { JsonEditor } from "json-edit-react";
import { CheckmarkCircleFilled } from "@fluentui/react-icons";
import { Spinner } from "@fluentui/react-components";
type LoadingStates = {
[key: string]: boolean;
};
const ProcessSteps = () => {
const status = ['extract', 'processing', 'map', 'evaluate'];
const [loadingStates, setLoadingStates] = useState<LoadingStates>({});
const childRefs = useRef<{ [key: string]: HTMLDivElement | null }>({});
const store = useSelector((state: RootState) => ({
processStepsData: state.centerPanel.processStepsData,
selectedItem: state.leftPanel.selectedItem,
}), shallowEqual
);
const hasValidSelection = !!store.selectedItem && !!store.selectedItem.process_id;
const hasProcessStepsData = Array.isArray(store.processStepsData) && store.processStepsData.length > 0;
const renderProcessTimeInSeconds = (timeString: string) => {
if (!timeString) {
return timeString;
}
const parts = timeString.split(":");
if (parts.length !== 3) {
return timeString;
}
const [hours, minutes, seconds] = parts.map(Number);
const totalSeconds = (hours * 3600 + minutes * 60 + seconds).toFixed(2);
return `${totalSeconds}s`;
};
const handleExpand = (itemId: any) => {
setLoadingStates((prevState) => ({ ...prevState, [itemId]: true }));
setTimeout(() => {
const childDiv = childRefs.current[itemId];
if (childDiv) {
childDiv.classList.add('loaded');
}
}, 500);
};
useEffect(() => {
const observers: MutationObserver[] = [];
Object.keys(childRefs.current).forEach((itemId) => {
const childDiv = childRefs.current[itemId];
if (childDiv) {
const observer = new MutationObserver(() => {
if (childDiv.classList.contains('loaded')) {
setLoadingStates((prevState) => ({ ...prevState, [itemId]: false }));
}
});
observer.observe(childDiv, { attributes: true, attributeFilter: ['class'] });
observers.push(observer);
}
});
return () => {
observers.forEach((observer) => observer.disconnect());
};
}, []);
if (!hasValidSelection || !hasProcessStepsData) {
return (
<div style={{ padding: '20px', textAlign: 'center', color: '#666' }}>
No data available.
</div>
);
}
return (
<Accordion collapsible>
{!status.includes(store.selectedItem.status) && store.processStepsData?.map((step, index) => (
<AccordionItem key={index} value={step.step_name}>
<AccordionHeader onClick={() => handleExpand(index)}> {loadingStates[index] && <Spinner size="tiny" style={{ position: 'absolute', left: '10px' }} label="" />}
<span style={{ fontWeight: 'bold', textTransform: 'capitalize'}}>{step.step_name}</span>
<span style={{ color: 'green', marginLeft: 'auto', display: 'flex', alignItems: 'center' }}>
{renderProcessTimeInSeconds(step.processed_time)} <CheckmarkCircleFilled style={{ marginLeft: '4px' }} />
</span>
</AccordionHeader>
<div ref={(el) => (childRefs.current[index] = el)}>
<AccordionPanel >
<JsonEditor
key={`json-editor-${index}`}
data={step}
collapse={5}
restrictEdit={true}
restrictDelete={true}
restrictAdd={true}
rootName={step.step_name.toLowerCase()}
collapseAnimationTime={300}
theme={[{
styles: {
container: {
width: '89%',
minWidth: '100%',
fontFamily: '-apple-system, BlinkMacSystemFont, "Segoe UI", system-ui, "Apple Color Emoji", "Segoe UI Emoji", sans-serif',
fontSize: '14px',
paddingTop: '0px'
},
}
}]}
/>
</AccordionPanel>
</div>
</AccordionItem>
))}
</Accordion>
);
};
export default ProcessSteps;