You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@camel.apache.org by ma...@apache.org on 2022/11/19 02:03:36 UTC
[camel-karavan] 04/12: Align Look and feel
This is an automated email from the ASF dual-hosted git repository.
marat pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/camel-karavan.git
commit f1382d702f6ae8b9cd15f5c7478d3bcd3fb1b4a4
Author: Marat Gubaidullin <ma...@gmail.com>
AuthorDate: Fri Nov 18 17:05:42 2022 -0500
Align Look and feel
---
.../src/main/webui/src/dashboard/DashboardPage.tsx | 35 +++-
.../src/main/webui/src/designer/karavan.css | 1 +
karavan-app/src/main/webui/src/index.css | 14 +-
.../src/main/webui/src/projects/ProjectPage.tsx | 4 +-
.../src/main/webui/src/projects/ProjectsPage.tsx | 181 ++++++++++++---------
karavan-designer/src/designer/karavan.css | 1 +
6 files changed, 135 insertions(+), 101 deletions(-)
diff --git a/karavan-app/src/main/webui/src/dashboard/DashboardPage.tsx b/karavan-app/src/main/webui/src/dashboard/DashboardPage.tsx
index 8f5fe20..e1e5ced 100644
--- a/karavan-app/src/main/webui/src/dashboard/DashboardPage.tsx
+++ b/karavan-app/src/main/webui/src/dashboard/DashboardPage.tsx
@@ -1,13 +1,13 @@
import React from 'react';
import {
- Badge,
- Button,
+ Badge, Bullseye,
+ Button, EmptyState, EmptyStateIcon, EmptyStateVariant,
Flex,
FlexItem, HelperText, HelperTextItem, Label, LabelGroup,
- PageSection,
+ PageSection, Spinner,
Text,
TextContent,
- TextInput, ToggleGroup, ToggleGroupItem,
+ TextInput, Title, ToggleGroup, ToggleGroupItem,
Toolbar,
ToolbarContent,
ToolbarItem, Tooltip
@@ -22,6 +22,7 @@ import Icon from "../Logo";
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";
import RefreshIcon from "@patternfly/react-icons/dist/esm/icons/sync-alt-icon";
+import SearchIcon from "@patternfly/react-icons/dist/esm/icons/search-icon";
interface Props {
config: any,
@@ -37,6 +38,7 @@ interface State {
isCreateModalOpen: boolean,
isDeleteModalOpen: boolean,
isCopy: boolean,
+ loading: boolean,
projectToCopy?: Project,
projectToDelete?: Project,
filter: string,
@@ -56,6 +58,7 @@ export class DashboardPage extends React.Component<Props, State> {
isCreateModalOpen: false,
isDeleteModalOpen: false,
isCopy: false,
+ loading: true,
filter: '',
name: '',
description: '',
@@ -75,7 +78,7 @@ export class DashboardPage extends React.Component<Props, State> {
onGetProjects = () => {
KaravanApi.getConfiguration((config: any) => {
KaravanApi.getProjects((projects: Project[]) => {
- this.setState({projects: projects})
+ this.setState({projects: projects, loading: false})
});
KaravanApi.getAllDeploymentStatuses((statuses: DeploymentStatus[]) => {
this.setState({deploymentStatuses: statuses});
@@ -223,6 +226,27 @@ export class DashboardPage extends React.Component<Props, State> {
}
}
+ getEmptyState() {
+ const {loading} = this.state;
+ return (
+ <Tr>
+ <Td colSpan={8}>
+ <Bullseye>
+ {loading && <Spinner className="progress-stepper" isSVG diameter="80px" aria-label="Loading..."/>}
+ {!loading &&
+ <EmptyState variant={EmptyStateVariant.small}>
+ <EmptyStateIcon icon={SearchIcon}/>
+ <Title headingLevel="h2" size="lg">
+ No results found
+ </Title>
+ </EmptyState>
+ }
+ </Bullseye>
+ </Td>
+ </Tr>
+ )
+ }
+
render() {
const deployments = Array.from(new Set(this.state.deploymentStatuses.filter(d => d.name.toLowerCase().includes(this.state.filter)).map(d => d.name)));
return (
@@ -315,6 +339,7 @@ export class DashboardPage extends React.Component<Props, State> {
</Td>
</Tr>
))}
+ {deployments.length === 0 && this.getEmptyState()}
</Tbody>
</TableComposable>
</PageSection>
diff --git a/karavan-app/src/main/webui/src/designer/karavan.css b/karavan-app/src/main/webui/src/designer/karavan.css
index 38e2973..77ff41e 100644
--- a/karavan-app/src/main/webui/src/designer/karavan.css
+++ b/karavan-app/src/main/webui/src/designer/karavan.css
@@ -1274,6 +1274,7 @@
overflow: auto;
flex-shrink: unset;
flex-grow: 1;
+ background-color: var(--pf-global--BackgroundColor--light-300);
}
.karavan .designer-page {
diff --git a/karavan-app/src/main/webui/src/index.css b/karavan-app/src/main/webui/src/index.css
index b19e0f5..efa6238 100644
--- a/karavan-app/src/main/webui/src/index.css
+++ b/karavan-app/src/main/webui/src/index.css
@@ -68,18 +68,6 @@
background-color: var(--pf-global--BackgroundColor--dark-400);
}
-.karavan .kamelet-section {
- display: flex;
- flex-direction: column;
- height: 100%;
-}
-
-.karavan .kamelets-page {
- overflow: auto;
- flex-shrink: unset;
- flex-grow: 1;
-}
-
.karavan .integration-card .pf-c-card__footer {
text-align: end;
}
@@ -128,7 +116,7 @@
font-size: 14px;
}
-.karavan .project-page .project-page-section {
+.karavan .project-page .project-tabs {
background-color: white;
}
diff --git a/karavan-app/src/main/webui/src/projects/ProjectPage.tsx b/karavan-app/src/main/webui/src/projects/ProjectPage.tsx
index e09b981..e1edd56 100644
--- a/karavan-app/src/main/webui/src/projects/ProjectPage.tsx
+++ b/karavan-app/src/main/webui/src/projects/ProjectPage.tsx
@@ -420,7 +420,7 @@ export class ProjectPage extends React.Component<Props, State> {
padding={{default: file !== undefined ? 'noPadding' : 'noPadding'}}>
<Flex direction={{default: "column"}} spaceItems={{default: "spaceItemsNone"}}>
{!isTemplates &&
- <FlexItem>
+ <FlexItem className="project-tabs">
<Tabs activeKey={tab} onSelect={(event, tabIndex) => this.setState({tab: tabIndex})}>
<Tab eventKey="development" title="Development"/>
<Tab eventKey="operations" title="Operations"/>
@@ -431,12 +431,12 @@ export class ProjectPage extends React.Component<Props, State> {
<FlexItem>
<PageSection padding={{default: "padding"}}>
{tab === 'development' && <ProjectInfo project={this.props.project} config={this.props.config} deleteEntity={this.deleteEntity} showLog={this.showLogs}/>}
+ {tab === 'development' && this.getProjectFiles()}
{tab === 'operations' && <ProjectOperations environments={this.state.environments} project={this.props.project} config={this.props.config}/>}
</PageSection>
</FlexItem>
}
</Flex>
- {tab === 'development' && this.getProjectFiles()}
</PageSection>}
{showDesigner && this.getDesigner()}
{showEditor && this.getEditor()}
diff --git a/karavan-app/src/main/webui/src/projects/ProjectsPage.tsx b/karavan-app/src/main/webui/src/projects/ProjectsPage.tsx
index 32a7a4d..320be76 100644
--- a/karavan-app/src/main/webui/src/projects/ProjectsPage.tsx
+++ b/karavan-app/src/main/webui/src/projects/ProjectsPage.tsx
@@ -23,7 +23,7 @@ import {
OverflowMenuContent,
OverflowMenuGroup,
OverflowMenuItem,
- Flex, FlexItem, Radio
+ Flex, FlexItem, Radio, Spinner
} from '@patternfly/react-core';
import '../designer/karavan.css';
import {MainToolbar} from "../MainToolbar";
@@ -51,6 +51,7 @@ interface State {
isCreateModalOpen: boolean,
isDeleteModalOpen: boolean,
isCopy: boolean,
+ loading: boolean,
projectToCopy?: Project,
projectToDelete?: Project,
filter: string,
@@ -68,6 +69,7 @@ export class ProjectsPage extends React.Component<Props, State> {
isCreateModalOpen: false,
isDeleteModalOpen: false,
isCopy: false,
+ loading: true,
filter: '',
name: '',
description: '',
@@ -114,8 +116,9 @@ export class ProjectsPage extends React.Component<Props, State> {
};
onGetProjects = () => {
+ this.setState({loading: true});
KaravanApi.getProjects((projects: Project[]) => {
- this.setState({projects: projects})
+ this.setState({projects: projects, loading: false})
});
KaravanApi.getDeploymentStatuses(this.props.config.environment, (statuses: DeploymentStatus[]) => {
this.setState({deploymentStatuses: statuses});
@@ -144,7 +147,7 @@ export class ProjectsPage extends React.Component<Props, State> {
</TextContent>);
closeModal = () => {
- this.setState({isCreateModalOpen: false, isCopy: false, name: this.props.config.groupId, description: '', projectId: '', runtime: this.props.config.runtime });
+ this.setState({isCreateModalOpen: false, isCopy: false, name: this.props.config.groupId, description: '', projectId: '', runtime: this.props.config.runtime});
this.onGetProjects();
}
@@ -245,6 +248,99 @@ export class ProjectsPage extends React.Component<Props, State> {
});
}
+ getEmptyState() {
+ const {loading} = this.state;
+ return (
+ <Tr>
+ <Td colSpan={8}>
+ <Bullseye>
+ {loading && <Spinner className="progress-stepper" isSVG diameter="80px" aria-label="Loading..."/>}
+ {!loading &&
+ <EmptyState variant={EmptyStateVariant.small}>
+ <EmptyStateIcon icon={SearchIcon}/>
+ <Title headingLevel="h2" size="lg">
+ No results found
+ </Title>
+ </EmptyState>
+ }
+ </Bullseye>
+ </Td>
+ </Tr>
+ )
+ }
+
+ getProjectsTable() {
+ const {projects, filter} = this.state;
+ const projs = projects.filter(p => p.name.toLowerCase().includes(filter) || p.description.toLowerCase().includes(filter));
+ return (
+ <TableComposable 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 => (
+ <Tr key={project.projectId}>
+ <Td modifier={"fitContent"}>
+ <Tooltip content={project.runtime} position={"left"}>
+ <Badge className="runtime-badge">{project.runtime.substring(0, 1).toUpperCase()}</Badge>
+ </Tooltip>
+ </Td>
+ <Td>
+ <Button style={{padding: '6px'}} variant={"link"} onClick={e => this.props.onSelect?.call(this, project)}>
+ {project.projectId}
+ </Button>
+ </Td>
+ <Td>{project.name}</Td>
+ <Td>{project.description}</Td>
+ <Td isActionCell>
+ <Tooltip content={project.lastCommit} position={"bottom"}>
+ <Badge>{project.lastCommit?.substr(0, 7)}</Badge>
+ </Tooltip>
+ </Td>
+ <Td noPadding style={{width: "180px"}}>
+ <Flex direction={{default: "row"}}>
+ {this.getDeploymentByEnvironments(project.projectId).map(value => (
+ <FlexItem className="badge-flex-item" key={value[0]}>
+ <Badge className="badge" isRead={!value[1]}>{value[0]}</Badge>
+ </FlexItem>
+ ))}
+ </Flex>
+ </Td>
+ <Td isActionCell>
+ <OverflowMenu breakpoint="md">
+ <OverflowMenuContent>
+ <OverflowMenuGroup groupType="button">
+ <OverflowMenuItem>
+ <Tooltip content={"Copy project"} position={"bottom"}>
+ <Button variant={"plain"} icon={<CopyIcon/>}
+ onClick={e => this.setState({isCreateModalOpen: true, isCopy: true, projectToCopy: project})}></Button>
+ </Tooltip>
+ </OverflowMenuItem>
+ <OverflowMenuItem>
+ <Tooltip content={"Delete project"} position={"bottom"}>
+ <Button variant={"plain"} icon={<DeleteIcon/>} onClick={e => this.onProjectDelete(project)}></Button>
+ </Tooltip>
+ </OverflowMenuItem>
+ </OverflowMenuGroup>
+ </OverflowMenuContent>
+ </OverflowMenu>
+ </Td>
+ </Tr>
+ ))}
+ {projs.length === 0 && this.getEmptyState()}
+ </Tbody>
+ </TableComposable>
+ )
+ }
+
render() {
const projects = this.state.projects.filter(p => p.name.toLowerCase().includes(this.state.filter) || p.description.toLowerCase().includes(this.state.filter));
return (
@@ -253,84 +349,7 @@ export class ProjectsPage extends React.Component<Props, State> {
<MainToolbar title={this.title()} tools={this.tools()}/>
</PageSection>
<PageSection isFilled className="kamelets-page">
- <TableComposable 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>
- {projects.map(project => (
- <Tr key={project.projectId}>
- <Td modifier={"fitContent"}>
- <Tooltip content={project.runtime} position={"left"}>
- <Badge className="runtime-badge">{project.runtime.substring(0, 1).toUpperCase()}</Badge>
- </Tooltip>
- </Td>
- <Td>
- <Button style={{padding: '6px'}} variant={"link"} onClick={e => this.props.onSelect?.call(this, project)}>
- {project.projectId}
- </Button>
- </Td>
- <Td>{project.name}</Td>
- <Td>{project.description}</Td>
- <Td isActionCell>
- <Tooltip content={project.lastCommit} position={"bottom"}>
- <Badge>{project.lastCommit?.substr(0, 7)}</Badge>
- </Tooltip>
- </Td>
- <Td noPadding style={{width: "180px"}}>
- <Flex direction={{default: "row"}}>
- {this.getDeploymentByEnvironments(project.projectId).map(value => (
- <FlexItem className="badge-flex-item" key={value[0]}>
- <Badge className="badge" isRead={!value[1]}>{value[0]}</Badge>
- </FlexItem>
- ))}
- </Flex>
- </Td>
- <Td isActionCell>
- <OverflowMenu breakpoint="md">
- <OverflowMenuContent>
- <OverflowMenuGroup groupType="button">
- <OverflowMenuItem>
- <Tooltip content={"Copy project"} position={"bottom"}>
- <Button variant={"plain"} icon={<CopyIcon/>}
- onClick={e => this.setState({isCreateModalOpen: true, isCopy: true, projectToCopy: project})}></Button>
- </Tooltip>
- </OverflowMenuItem>
- <OverflowMenuItem>
- <Tooltip content={"Delete project"} position={"bottom"}>
- <Button variant={"plain"} icon={<DeleteIcon/>} onClick={e => this.onProjectDelete(project)}></Button>
- </Tooltip>
- </OverflowMenuItem>
- </OverflowMenuGroup>
- </OverflowMenuContent>
- </OverflowMenu>
- </Td>
- </Tr>
- ))}
- {projects.length === 0 &&
- <Tr>
- <Td colSpan={8}>
- <Bullseye>
- <EmptyState variant={EmptyStateVariant.small}>
- <EmptyStateIcon icon={SearchIcon}/>
- <Title headingLevel="h2" size="lg">
- No results found
- </Title>
- </EmptyState>
- </Bullseye>
- </Td>
- </Tr>
- }
- </Tbody>
- </TableComposable>
+ {this.getProjectsTable()}
</PageSection>
{this.createModalForm()}
{this.deleteModalForm()}
diff --git a/karavan-designer/src/designer/karavan.css b/karavan-designer/src/designer/karavan.css
index 38e2973..77ff41e 100644
--- a/karavan-designer/src/designer/karavan.css
+++ b/karavan-designer/src/designer/karavan.css
@@ -1274,6 +1274,7 @@
overflow: auto;
flex-shrink: unset;
flex-grow: 1;
+ background-color: var(--pf-global--BackgroundColor--light-300);
}
.karavan .designer-page {