| import React, {useEffect, useState} from 'react'; |
| import { |
| Toolbar, |
| ToolbarContent, |
| ToolbarItem, |
| TextInput, |
| PageSection, |
| TextContent, |
| Text, |
| Button, |
| Bullseye, |
| EmptyState, |
| EmptyStateVariant, |
| EmptyStateIcon, EmptyStateHeader |
| } from '@patternfly/react-core'; |
| import '../designer/karavan.css'; |
| import PlusIcon from '@patternfly/react-icons/dist/esm/icons/plus-icon'; |
| import { |
| Tbody, |
| Td, |
| Th, |
| Thead, |
| Tr |
| } from '@patternfly/react-table'; |
| import { |
| Table |
| } from '@patternfly/react-table/deprecated'; |
| import SearchIcon from '@patternfly/react-icons/dist/esm/icons/search-icon'; |
| import {ProjectsTableRow} from "./ProjectsTableRow"; |
| import {DeleteProjectModal} from "./DeleteProjectModal"; |
| import {CreateProjectModal} from "./CreateProjectModal"; |
| import {useProjectsStore, useProjectStore} from "../api/ProjectStore"; |
| import {MainToolbar} from "../designer/MainToolbar"; |
| import {Project, ProjectType} from "../api/ProjectModels"; |
| import {shallow} from "zustand/shallow"; |
| import {useParams} from "react-router-dom"; |
| import {KaravanApi} from "../api/KaravanApi"; |
| |
| export function ProjectsPage () { |
| |
| const [projects] = useProjectsStore((state) => [state.projects], shallow) |
| const [operation] = useProjectStore((state) => [state.operation], shallow) |
| const [filter, setFilter] = useState<string>(''); |
| |
| function getTools() { |
| return <Toolbar id="toolbar-group-types"> |
| <ToolbarContent> |
| <ToolbarItem> |
| <TextInput className="text-field" type="search" id="search" name="search" |
| autoComplete="off" placeholder="Search by name" |
| value={filter} |
| onChange={(_, e) => setFilter(e)}/> |
| </ToolbarItem> |
| <ToolbarItem> |
| <Button icon={<PlusIcon/>} |
| onClick={e => |
| useProjectStore.setState({operation: "create", project: new Project()})} |
| >Create</Button> |
| </ToolbarItem> |
| </ToolbarContent> |
| </Toolbar> |
| } |
| |
| function title() { |
| return <TextContent> |
| <Text component="h2">Projects</Text> |
| </TextContent> |
| } |
| |
| function getEmptyState() { |
| return ( |
| <Tr> |
| <Td colSpan={8}> |
| <Bullseye> |
| <EmptyState variant={EmptyStateVariant.sm}> |
| <EmptyStateHeader titleText="No results found" |
| icon={<EmptyStateIcon icon={SearchIcon}/>} headingLevel="h2"/> |
| </EmptyState> |
| </Bullseye> |
| </Td> |
| </Tr> |
| ) |
| } |
| |
| function getProjectsTable() { |
| const projs = projects |
| .filter(p => p.type === ProjectType.normal) |
| .filter(p => p.name.toLowerCase().includes(filter) || p.description.toLowerCase().includes(filter)); |
| return ( |
| <Table aria-label="Projects" variant={"compact"}> |
| <Thead> |
| <Tr> |
| <Th key='type'>Runtime</Th> |
| <Th key='projectId'>Project ID</Th> |
| <Th key='name'>Name</Th> |
| <Th key='description'>Description</Th> |
| <Th key='commit'>Commit</Th> |
| <Th key='deployment'>Environment</Th> |
| <Th key='action'></Th> |
| </Tr> |
| </Thead> |
| <Tbody> |
| {projs.map(project => ( |
| <ProjectsTableRow |
| key={project.projectId} |
| project={project}/> |
| ))} |
| {projs.length === 0 && getEmptyState()} |
| </Tbody> |
| </Table> |
| ) |
| } |
| |
| return ( |
| <PageSection className="kamelet-section projects-page" padding={{default: 'noPadding'}}> |
| <PageSection className="tools-section" padding={{default: 'noPadding'}}> |
| <MainToolbar title={title()} tools={getTools()}/> |
| </PageSection> |
| <PageSection isFilled className="kamelets-page"> |
| {getProjectsTable()} |
| </PageSection> |
| {["create", "copy"].includes(operation) && <CreateProjectModal/>} |
| {["delete"].includes(operation) && <DeleteProjectModal/>} |
| </PageSection> |
| |
| ) |
| } |