parent
f885199b2b
commit
f966ee198c
@ -0,0 +1,80 @@ |
|||||||
|
import styles from './styles.module.css' |
||||||
|
import {useEffect, useState} from "react"; |
||||||
|
|
||||||
|
export interface ProcessExceptionInterface { |
||||||
|
message: string, |
||||||
|
file: string, |
||||||
|
line: bigint, |
||||||
|
code: bigint, |
||||||
|
trace: any[], |
||||||
|
} |
||||||
|
|
||||||
|
export interface ProcessProgressInterface { |
||||||
|
total: bigint, |
||||||
|
progress: bigint, |
||||||
|
memory: any[], |
||||||
|
} |
||||||
|
|
||||||
|
export interface ProcessInterface { |
||||||
|
id: string, |
||||||
|
lock: string|null, |
||||||
|
containerUuid: string|null, |
||||||
|
pid: bigint|null, |
||||||
|
name: string, |
||||||
|
options: Record<string, any>, |
||||||
|
arguments: Record<string, any>, |
||||||
|
exception: ProcessExceptionInterface|null, |
||||||
|
progress: ProcessProgressInterface|null, |
||||||
|
createdAt: string, |
||||||
|
updatedAt: string|null, |
||||||
|
startedAt: string|null, |
||||||
|
pausedAt: string|null, |
||||||
|
cancelledAt: string|null |
||||||
|
completedAt: string|null |
||||||
|
} |
||||||
|
|
||||||
|
export default function Processes() { |
||||||
|
const [processes, setProcesses] = useState<ProcessInterface[]>([]); |
||||||
|
|
||||||
|
let refreshProcesses = async () => { |
||||||
|
let response = await fetch('http://fmw.sipachev.sv/system-monitoring/processes', { |
||||||
|
method: 'GET', |
||||||
|
headers: { |
||||||
|
'Content-Type': 'application/json;charset=utf-8', |
||||||
|
'X-Plugin-Token': 'passw0rd' |
||||||
|
}, |
||||||
|
}); |
||||||
|
const processes: ProcessInterface[] = await response.json() |
||||||
|
setProcesses(processes) |
||||||
|
setTimeout(() => refreshProcesses, 1000) |
||||||
|
} |
||||||
|
|
||||||
|
useEffect(() => { |
||||||
|
refreshProcesses() |
||||||
|
}, []) |
||||||
|
|
||||||
|
|
||||||
|
return ( |
||||||
|
<div className={styles.processes}> |
||||||
|
{processes.map((process: ProcessInterface, index: number) => ( |
||||||
|
<div className={styles.process} key={index}> |
||||||
|
<div> |
||||||
|
{process.name} |
||||||
|
</div> |
||||||
|
<div> |
||||||
|
{!process.progress && 'N/A'} |
||||||
|
{process.progress && <span> |
||||||
|
{`${process.progress.progress}`} / {`${process.progress.total}`} - 50% [53Mb] / 20 sec |
||||||
|
</span>} |
||||||
|
</div> |
||||||
|
<div> |
||||||
|
{process.completedAt && <button>Repeat</button>} |
||||||
|
{process.pausedAt && <button>Play</button>} |
||||||
|
{!process.pausedAt && !process.completedAt && !process.cancelledAt && <button>Pause</button>} |
||||||
|
{!process.completedAt && !process.cancelledAt && <button>Stop</button>} |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
))} |
||||||
|
</div> |
||||||
|
) |
||||||
|
} |
@ -0,0 +1,7 @@ |
|||||||
|
.processes { |
||||||
|
display: block; |
||||||
|
} |
||||||
|
.process { |
||||||
|
display: grid; |
||||||
|
grid-template-columns: 6fr 4fr 2fr; |
||||||
|
} |
@ -0,0 +1,11 @@ |
|||||||
|
import React from 'react' |
||||||
|
|
||||||
|
export interface ContextInterface { |
||||||
|
tabCount: number, |
||||||
|
tab: number, |
||||||
|
setTab: (number: number) => void, |
||||||
|
} |
||||||
|
|
||||||
|
const Context = React.createContext({} as ContextInterface) |
||||||
|
export const Provider = Context.Provider |
||||||
|
export default Context |
@ -0,0 +1,20 @@ |
|||||||
|
import React, {PropsWithChildren, useContext} from "react"; |
||||||
|
import TabContext, {Mode} from '../../tab-context' |
||||||
|
import TabsContext from "../../context"; |
||||||
|
|
||||||
|
const TabSection = ({children}: PropsWithChildren<any>) => { |
||||||
|
const {tab: activeTab} = useContext(TabsContext) |
||||||
|
const {tab, mode} = useContext(TabContext) |
||||||
|
|
||||||
|
if (Mode.SECTIONS !== mode) { |
||||||
|
return <></> |
||||||
|
} |
||||||
|
|
||||||
|
if (activeTab !== tab) { |
||||||
|
return <></> |
||||||
|
} |
||||||
|
|
||||||
|
return <>{children}</> |
||||||
|
} |
||||||
|
|
||||||
|
export default TabSection |
@ -0,0 +1,20 @@ |
|||||||
|
import React, {PropsWithChildren, useContext} from "react"; |
||||||
|
import TabsContext from '../../context' |
||||||
|
import TabContext, {Mode} from '../../tab-context' |
||||||
|
|
||||||
|
const TabTitle = ({children, className}: PropsWithChildren<any>) => { |
||||||
|
const {setTab} = useContext(TabsContext) |
||||||
|
const {tab, mode} = useContext(TabContext) |
||||||
|
|
||||||
|
if (Mode.TABS !== mode) { |
||||||
|
return <></> |
||||||
|
} |
||||||
|
|
||||||
|
return ( |
||||||
|
<span className={className} onClick={() => {setTab(tab)}}> |
||||||
|
{children} |
||||||
|
</span> |
||||||
|
) |
||||||
|
} |
||||||
|
|
||||||
|
export default TabTitle |
@ -0,0 +1,20 @@ |
|||||||
|
import React, {Fragment} from "react"; |
||||||
|
|
||||||
|
interface Props { |
||||||
|
children: React.ReactNode[]; |
||||||
|
} |
||||||
|
|
||||||
|
const Tab = ({children}: Props) => { |
||||||
|
return ( |
||||||
|
<> |
||||||
|
{children.map((child: React.ReactNode, index: number) => { |
||||||
|
return ( |
||||||
|
<Fragment key={index}>{child}</Fragment> |
||||||
|
) |
||||||
|
})} |
||||||
|
</> |
||||||
|
) |
||||||
|
} |
||||||
|
|
||||||
|
export default Tab |
||||||
|
|
@ -0,0 +1,46 @@ |
|||||||
|
import React, {FC, Fragment, useState} from "react"; |
||||||
|
import {Provider} from './context' |
||||||
|
import {Mode, Provider as TabProvider} from './tab-context' |
||||||
|
|
||||||
|
interface ITabs { |
||||||
|
children: React.ReactNode[]; |
||||||
|
tabsClassName?: string; |
||||||
|
sectionsClassName?: string; |
||||||
|
} |
||||||
|
|
||||||
|
const Tabs: FC<ITabs> = ({children, tabsClassName, sectionsClassName}) => { |
||||||
|
const [tab, setTab] = useState<number>(0) |
||||||
|
const tabCount = children.length |
||||||
|
|
||||||
|
return ( |
||||||
|
<div> |
||||||
|
<Provider value={{tabCount, tab, setTab}}> |
||||||
|
<div className={tabsClassName}> |
||||||
|
{children.map((child: React.ReactNode, index: number) => { |
||||||
|
return ( |
||||||
|
<Fragment key={index}> |
||||||
|
<TabProvider value={{tab:index, mode: Mode.TABS}}> |
||||||
|
{child} |
||||||
|
</TabProvider> |
||||||
|
</Fragment> |
||||||
|
) |
||||||
|
})} |
||||||
|
</div> |
||||||
|
<div className={sectionsClassName}> |
||||||
|
{children.map((child: React.ReactNode, index: number) => { |
||||||
|
return ( |
||||||
|
<Fragment key={index}> |
||||||
|
<TabProvider value={{tab:index, mode: Mode.SECTIONS }}> |
||||||
|
{child} |
||||||
|
</TabProvider> |
||||||
|
</Fragment> |
||||||
|
) |
||||||
|
})} |
||||||
|
</div> |
||||||
|
</Provider> |
||||||
|
</div> |
||||||
|
) |
||||||
|
} |
||||||
|
|
||||||
|
export default Tabs |
||||||
|
|
@ -0,0 +1,15 @@ |
|||||||
|
import React from 'react' |
||||||
|
|
||||||
|
export enum Mode { |
||||||
|
TABS, |
||||||
|
SECTIONS |
||||||
|
} |
||||||
|
|
||||||
|
export interface ContextInterface { |
||||||
|
tab: number, |
||||||
|
mode: Mode, |
||||||
|
} |
||||||
|
|
||||||
|
const Context = React.createContext({} as ContextInterface) |
||||||
|
export const Provider = Context.Provider |
||||||
|
export default Context |
Loading…
Reference in new issue