blob: 86e1c367e185457a6731acdc2439fa2d4bb43977 [file] [log] [blame]
import React, {useState} from 'react';
import {
Button,
Tooltip,
Flex, FlexItem, Label, Spinner, TooltipPosition
} from '@patternfly/react-core';
import '../designer/karavan.css';
import {ExpandableRowContent, Tbody, Td, Tr} from "@patternfly/react-table";
import StopIcon from "@patternfly/react-icons/dist/js/icons/stop-icon";
import PlayIcon from "@patternfly/react-icons/dist/esm/icons/play-icon";
import {DevService} from "../api/ServiceModels";
import {ContainerStatus} from "../api/ProjectModels";
import PauseIcon from "@patternfly/react-icons/dist/esm/icons/pause-icon";
import DeleteIcon from "@patternfly/react-icons/dist/js/icons/times-icon";
import {useAppConfigStore, useLogStore} from "../api/ProjectStore";
import {shallow} from "zustand/shallow";
import {KaravanApi} from "../api/KaravanApi";
import UpIcon from "@patternfly/react-icons/dist/esm/icons/check-circle-icon";
import DownIcon from "@patternfly/react-icons/dist/esm/icons/error-circle-o-icon";
interface Props {
index: number
service: DevService
container?: ContainerStatus
}
export function ServicesTableRow (props: Props) {
const [config] = useAppConfigStore((state) => [state.config], shallow)
const [isExpanded, setIsExpanded] = useState<boolean>(false);
function getButtons() {
const container = props.container;
const commands = container?.commands || ['run'];
const inTransit = container?.inTransit;
return (
<Td noPadding className="project-action-buttons">
<Flex direction={{default: "row"}} flexWrap={{default: "nowrap"}}
spaceItems={{default: 'spaceItemsNone'}}>
<FlexItem>
<Tooltip content={"Start container"} position={"bottom"}>
<Button variant={"plain"} icon={<PlayIcon/>} isDisabled={!commands.includes('run') || inTransit}
onClick={e => {
KaravanApi.manageContainer(config.environment, 'devservice', service.container_name, 'run', res => {});
}}></Button>
</Tooltip>
</FlexItem>
<FlexItem>
<Tooltip content={"Pause container"} position={"bottom"}>
<Button variant={"plain"} icon={<PauseIcon/>} isDisabled={!commands.includes('pause') || inTransit}
onClick={e => {
// KaravanApi.manageContainer(container.env, container.containerName, 'pause', res => {});
}}></Button>
</Tooltip>
</FlexItem>
<FlexItem>
<Tooltip content={"Stop container"} position={"bottom"}>
<Button variant={"plain"} icon={<StopIcon/>} isDisabled={!commands.includes('stop') || inTransit}
onClick={e => {
KaravanApi.manageContainer(config.environment, 'devservice', service.container_name, 'stop', res => {});
}}></Button>
</Tooltip>
</FlexItem>
<FlexItem>
<Tooltip content={"Delete container"} position={"bottom"}>
<Button variant={"plain"} icon={<DeleteIcon/>} isDisabled={!commands.includes('delete') || inTransit}
onClick={e => {
KaravanApi.deleteContainer(config.environment, 'devservice', service.container_name, res => {});
}}></Button>
</Tooltip>
</FlexItem>
</Flex>
</Td>
)
}
const service = props.service;
const healthcheck = service.healthcheck;
const env = service.environment;
const keys = Object.keys(env);
const container = props.container;
const isRunning = container?.state === 'running';
const inTransit = container?.inTransit;
const color = isRunning ? "green" : "grey";
const icon = isRunning ? <UpIcon/> : <DownIcon/>;
return (
<Tbody isExpanded={isExpanded}>
<Tr key={service.container_name}>
<Td expand={
service.container_name
? {
rowIndex: props.index,
isExpanded: isExpanded,
onToggle: () => setIsExpanded(!isExpanded),
expandId: 'composable-expandable-example'
}
: undefined}
modifier={"fitContent"}>
</Td>
<Td>
{container && <Label icon={icon} color={color}>
<Tooltip content={"Show log"} position={TooltipPosition.bottom}>
<Button className='labeled-button' variant="link" isDisabled={!isRunning}
onClick={e => {
useLogStore.setState({showLog: true, type: 'container', podName: container.containerName});
}}>
{service.container_name}
</Button>
</Tooltip>
</Label>}
{!container && <Label color={color}>{service.container_name}</Label>}
</Td>
<Td>{service.container_name}</Td>
<Td>{service.image}</Td>
<Td>
<Flex direction={{default: "row"}}>
{service.ports.map(port => <FlexItem key={port}>{port}</FlexItem>)}
</Flex>
</Td>
<Td>
{!inTransit && container?.state && <Label color={color}>{container?.state}</Label>}
{inTransit && <Spinner size="lg" aria-label="spinner"/>}
</Td>
{getButtons()}
</Tr>
{keys.length > 0 && <Tr isExpanded={isExpanded}>
<Td></Td>
<Td colSpan={2}>Environment Variables</Td>
<Td colSpan={2}>
<ExpandableRowContent>
<Flex direction={{default: "column"}} cellPadding={"0px"}>
{keys.map(key => <FlexItem key={key}>{key + ": " + env[key]}</FlexItem>)}
</Flex>
</ExpandableRowContent>
</Td>
</Tr>}
{healthcheck && <Tr isExpanded={isExpanded}>
<Td></Td>
<Td colSpan={2}>Healthcheck</Td>
<Td colSpan={2}>
<ExpandableRowContent>
<Flex direction={{default: "column"}} cellPadding={"0px"}>
<FlexItem>{"test: " + healthcheck.test.join(" ")}</FlexItem>
<FlexItem>{"interval " + healthcheck.interval}</FlexItem>
<FlexItem>{"timeout: " + healthcheck.timeout}</FlexItem>
<FlexItem>{"retries: " + healthcheck.retries}</FlexItem>
</Flex>
</ExpandableRowContent>
</Td>
</Tr>}
</Tbody>
)
}