blob: a18b6bd1b36b007d6f6309b4d7e2dde8b2a1c3ab [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import React from 'react';
import {
Badge,
Button, Flex, FlexItem,
Form, FormGroup, Modal, PageSection,
Tab, Tabs, TabTitleText, TextInput,
} from '@patternfly/react-core';
import '../../karavan.css';
import {TableComposable, Tbody, Td, Th, Thead, Tr} from "@patternfly/react-table";
import {KubernetesAPI} from "../../utils/KubernetesAPI";
interface Props {
onSelect: (value: string) => void,
onClose?: () => void,
isOpen: boolean,
dark: boolean,
}
interface State {
tabIndex: string | number
filter?: string
configMaps: string[]
secrets: string[]
services: string[]
}
export class KubernetesSelector extends React.Component<Props, State> {
public state: State = {
tabIndex: "configMap",
configMaps: KubernetesAPI.configMaps,
secrets: KubernetesAPI.secrets,
services: KubernetesAPI.services
};
selectTab = (evt: React.MouseEvent<HTMLElement, MouseEvent>, eventKey: string | number) => {
this.setState({tabIndex: eventKey})
}
checkFilter = (name: string): boolean => {
if (this.state.filter !== undefined && name) {
return name.toLowerCase().includes(this.state.filter.toLowerCase())
} else {
return true;
}
}
searchInput = () => {
return (
<Form isHorizontal className="search" autoComplete="off">
<FormGroup fieldId="search">
<TextInput className="text-field" type="text" id="search" name="search" iconVariant='search'
value={this.state.filter}
onChange={e => this.setState({filter: e})}/>
</FormGroup>
</Form>
)
}
getConfigMapTable() {
const configMaps = this.state.configMaps;
return (
<TableComposable variant='compact' borders={false}>
<Thead>
<Tr>
<Th/>
<Th key='name'>Name</Th>
<Th key='data'>Data</Th>
</Tr>
</Thead>
<Tbody>
{configMaps
.filter(name => this.checkFilter(name))
.map((name, idx: number) => {
const configMapName = name.split("/")[0];
const data = name.split("/")[1];
return (
<Tr key={name}>
<Td noPadding isActionCell>
<Badge>CM</Badge>
</Td>
<Td noPadding>
{configMapName}
</Td>
<Td noPadding>
<Button style={{padding: '6px'}} variant={"link"} onClick={
e => this.props.onSelect?.call(this, "configmap:" + name)}>
{data}
</Button>
</Td>
</Tr>
)
})}
</Tbody>
</TableComposable>
)
}
getSecretsTable() {
const secrets = this.state.secrets;
return (
<TableComposable variant='compact' borders={false}>
<Thead>
<Tr>
<Th/>
<Th key='name'>Name</Th>
<Th key='data'>Data</Th>
</Tr>
</Thead>
<Tbody>
{secrets
.filter(name => this.checkFilter(name))
.map((name, idx: number) => {
const configMapName = name.split("/")[0];
const data = name.split("/")[1];
return (
<Tr key={name}>
<Td noPadding isActionCell>
<Badge>S</Badge>
</Td>
<Td noPadding>
{configMapName}
</Td>
<Td noPadding>
<Button style={{padding: '6px'}} variant={"link"} onClick={
e => this.props.onSelect?.call(this, "secret:" + name)}>
{data}
</Button>
</Td>
</Tr>
)
})}
</Tbody>
</TableComposable>
)
}
getServicesTable() {
const services = this.state.services;
return (
<TableComposable variant='compact' borders={false}>
<Thead>
<Tr>
<Th/>
<Th key='name'>Name</Th>
{/*<Th key='hostPort'>Host:Port</Th>*/}
<Th key='host'>Host</Th>
<Th key='port'>Port</Th>
</Tr>
</Thead>
<Tbody>
{services
.filter(name => this.checkFilter(name))
.map((name, idx: number) => {
const serviceName = name.split("|")[0];
const hostPort = name.split("|")[1];
const host = hostPort.split(":")[0];
const port = hostPort.split(":")[1];
return (
<Tr key={name}>
<Td noPadding isActionCell>
<Badge>S</Badge>
</Td>
{/*<Td noPadding>*/}
{/* {serviceName}*/}
{/*</Td>*/}
<Td noPadding>
<Button style={{padding: '6px'}} variant={"link"} onClick={
e => this.props.onSelect?.call(this, hostPort)}>
{serviceName}
</Button>
</Td>
<Td noPadding>
<Button style={{padding: '6px'}} variant={"link"} onClick={
e => this.props.onSelect?.call(this, host)}>
{host}
</Button>
</Td>
<Td noPadding>
<Button style={{padding: '6px'}} variant={"link"} onClick={
e => this.props.onSelect?.call(this, port)}>
{port}
</Button>
</Td>
</Tr>
)
})}
</Tbody>
</TableComposable>
)
}
render() {
const tabIndex = this.state.tabIndex;
return (
<Modal
aria-label="Select from Kubernetes"
width={'50%'}
className='dsl-modal'
isOpen={this.props.isOpen}
onClose={this.props.onClose}
header={
<Flex direction={{default: "column"}}>
<FlexItem>
<h3>{"Select from Kubernetes"}</h3>
{this.searchInput()}
</FlexItem>
<FlexItem>
<Tabs data-tour="selector-tabs" style={{overflow: 'hidden'}} activeKey={this.state.tabIndex} onSelect={this.selectTab}>
<Tab eventKey={"configMap"} key={"configMap"} title={<TabTitleText>ConfigMaps</TabTitleText>} />
<Tab eventKey={"secret"} key={"secret"} title={<TabTitleText>Secrets</TabTitleText>} />
<Tab eventKey={"service"} key={"service"} title={<TabTitleText>Services</TabTitleText>} />
</Tabs>
</FlexItem>
</Flex>
}
actions={{}}>
<PageSection variant={this.props.dark ? "darker" : "light"}>
{this.searchInput()}
{tabIndex === 'configMap' && this.getConfigMapTable()}
{tabIndex === 'secret' && this.getSecretsTable()}
{tabIndex === 'service' && this.getServicesTable()}
</PageSection>
</Modal>
)
}
}