Добавил табы

jwt
Rinsvent 2 years ago
parent f885199b2b
commit f966ee198c
  1. 80
      components/elements/processes/index.tsx
  2. 7
      components/elements/processes/styles.module.css
  3. 11
      components/elements/tabs/context.ts
  4. 20
      components/elements/tabs/elements/tab-section/index.tsx
  5. 20
      components/elements/tabs/elements/tab-title/index.tsx
  6. 20
      components/elements/tabs/elements/tab/index.tsx
  7. 46
      components/elements/tabs/index.tsx
  8. 15
      components/elements/tabs/tab-context.ts
  9. 29
      pages/index.tsx
  10. 19
      styles/Home.module.css

@ -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}&nbsp;
</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

@ -3,6 +3,11 @@ import styles from '../styles/Home.module.css'
import {OptionInterface} from "../components/elements/command/elements/option";
import {ArgumentInterface} from "../components/elements/command/elements/argument";
import Command from "../components/elements/command";
import Tabs from "../components/elements/tabs";
import Tab from "../components/elements/tabs/elements/tab";
import TabTitle from "../components/elements/tabs/elements/tab-title";
import TabSection from "../components/elements/tabs/elements/tab-section";
import Processes from "../components/elements/processes";
interface CommandInterface {
class: string,
@ -26,12 +31,24 @@ export default function Home({commands}: CommandsInterface) {
<link rel="icon" href="/favicon.ico"/>
</Head>
<main className={styles.main}>
<h1>Tasks</h1>
<div className={styles.tasks}>
{commands.map((command: CommandInterface, index: number) => (
<Command key={index} {...command} />
))}
</div>
<Tabs tabsClassName={styles.tabPanel}>
<Tab>
<TabTitle className={styles.tabPanelItem}>Команды</TabTitle>
<TabSection>
<div className={styles.tasks}>
{commands.map((command: CommandInterface, index: number) => (
<Command key={index} {...command} />
))}
</div>
</TabSection>
</Tab>
<Tab>
<TabTitle className={styles.tabPanelItem}>Процессы</TabTitle>
<TabSection>
<Processes />
</TabSection>
</Tab>
</Tabs>
</main>
</>
)

@ -14,3 +14,22 @@
display: grid;
grid-template-columns: 11fr 1fr;
}
.tabPanel {
display: flex;
}
.tabPanelItem {
flex-grow: 1;
padding: 5px;
cursor: pointer;
border-bottom: solid 2px #cae5fa;
}
.tabPanelItem:hover {
border-bottom: solid 2px #298df8;
}
.tabPanelItemActive {
border-bottom: solid 2px #298df8;
}
Loading…
Cancel
Save