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/06/22 17:26:21 UTC
[camel-karavan] branch main updated: Start PipelineRUn from UI (#387)
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
The following commit(s) were added to refs/heads/main by this push:
new fb85e4f Start PipelineRUn from UI (#387)
fb85e4f is described below
commit fb85e4fdebde2c9ba6650520dc306362522ffc39
Author: Marat Gubaidullin <ma...@gmail.com>
AuthorDate: Wed Jun 22 13:26:15 2022 -0400
Start PipelineRUn from UI (#387)
---
karavan-app/pom.xml | 6 +-
.../camel/karavan/api/ConfigurationResource.java | 6 +-
.../apache/camel/karavan/api/TektonResource.java | 34 ++++-
.../camel/karavan/model/KaravanConfiguration.java | 1 +
.../org/apache/camel/karavan/model/Project.java | 13 +-
.../camel/karavan/service/KubernetesService.java | 49 ++++---
.../src/main/resources/application.properties | 3 +
karavan-app/src/main/webapp/src/api/KaravanApi.tsx | 10 ++
karavan-app/src/main/webapp/src/index.css | 6 +-
.../src/main/webapp/src/models/ProjectModels.ts | 4 +-
.../src/main/webapp/src/projects/ProjectPage.tsx | 161 +++++++++++++++------
.../src/main/webapp/src/projects/ProjectsPage.tsx | 6 +-
12 files changed, 220 insertions(+), 79 deletions(-)
diff --git a/karavan-app/pom.xml b/karavan-app/pom.xml
index d1a67ed..086b59b 100644
--- a/karavan-app/pom.xml
+++ b/karavan-app/pom.xml
@@ -56,11 +56,7 @@
</dependency>
<dependency>
<groupId>io.quarkus</groupId>
- <artifactId>quarkus-resteasy-reactive</artifactId>
- </dependency>
- <dependency>
- <groupId>io.quarkus</groupId>
- <artifactId>quarkus-resteasy-reactive-jsonb</artifactId>
+ <artifactId>quarkus-resteasy-reactive-jackson</artifactId>
</dependency>
<dependency>
<groupId>io.quarkus</groupId>
diff --git a/karavan-app/src/main/java/org/apache/camel/karavan/api/ConfigurationResource.java b/karavan-app/src/main/java/org/apache/camel/karavan/api/ConfigurationResource.java
index 5e01b29..b2f23ef 100644
--- a/karavan-app/src/main/java/org/apache/camel/karavan/api/ConfigurationResource.java
+++ b/karavan-app/src/main/java/org/apache/camel/karavan/api/ConfigurationResource.java
@@ -18,13 +18,13 @@ package org.apache.camel.karavan.api;
import org.apache.camel.karavan.model.KaravanConfiguration;
import org.eclipse.microprofile.config.inject.ConfigProperty;
-import org.jboss.resteasy.reactive.RestResponse;
import javax.inject.Inject;
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;
+import javax.ws.rs.core.Response;
import java.util.Map;
import java.util.stream.Collectors;
@@ -40,8 +40,8 @@ public class ConfigurationResource {
@GET
@Produces(MediaType.APPLICATION_JSON)
- public RestResponse<Map<String, Object>> getConfiguration() throws Exception {
- return RestResponse.ResponseBuilder.ok(
+ public Response getConfiguration() throws Exception {
+ return Response.ok(
Map.of(
"version", version,
"environments", configuration.environments().stream().map(e -> e.name()).collect(Collectors.toList()),
diff --git a/karavan-app/src/main/java/org/apache/camel/karavan/api/TektonResource.java b/karavan-app/src/main/java/org/apache/camel/karavan/api/TektonResource.java
index aa71762..d2c98ef 100644
--- a/karavan-app/src/main/java/org/apache/camel/karavan/api/TektonResource.java
+++ b/karavan-app/src/main/java/org/apache/camel/karavan/api/TektonResource.java
@@ -16,6 +16,8 @@
*/
package org.apache.camel.karavan.api;
+import io.fabric8.tekton.pipeline.v1beta1.PipelineRun;
+import org.apache.camel.karavan.model.KaravanConfiguration;
import org.apache.camel.karavan.model.Project;
import org.apache.camel.karavan.model.ProjectFile;
import org.apache.camel.karavan.service.InfinispanService;
@@ -24,12 +26,15 @@ import org.jboss.logging.Logger;
import javax.inject.Inject;
import javax.ws.rs.Consumes;
+import javax.ws.rs.GET;
import javax.ws.rs.HeaderParam;
import javax.ws.rs.POST;
import javax.ws.rs.Path;
+import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;
-import java.util.List;
+import javax.ws.rs.core.Response;
+import java.util.Optional;
@Path("/tekton")
public class TektonResource {
@@ -40,15 +45,36 @@ public class TektonResource {
@Inject
KubernetesService kubernetesService;
+ @Inject
+ KaravanConfiguration configuration;
+
private static final Logger LOGGER = Logger.getLogger(TektonResource.class.getName());
@POST
@Produces(MediaType.APPLICATION_JSON)
@Consumes(MediaType.APPLICATION_JSON)
- public Project push(@HeaderParam("username") String username, Project project) throws Exception {
+ @Path("/{environment}")
+ public Project push(@HeaderParam("username") String username, @PathParam("environment") String environment, Project project) throws Exception {
Project p = infinispanService.getProject(project.getProjectId());
- List<ProjectFile> files = infinispanService.getProjectFiles(project.getProjectId());
- String pipelineRunId = kubernetesService.createPipelineRun(project);
+ Optional<KaravanConfiguration.Environment> env = configuration.environments().stream().filter(e -> e.name().equals(environment)).findFirst();
+ if (env.isPresent()) {
+ String pipelineRunId = kubernetesService.createPipelineRun(project, env.get().namespace());
+ p.setLastPipelineRun(pipelineRunId);
+ infinispanService.saveProject(p);
+ }
return p;
}
+
+ @GET
+ @Produces(MediaType.APPLICATION_JSON)
+ @Path("/{environment}/{name}")
+ public Response get(@HeaderParam("username") String username, @PathParam("environment") String environment,
+ @PathParam("name") String name) throws Exception {
+ Optional<KaravanConfiguration.Environment> env = configuration.environments().stream().filter(e -> e.name().equals(environment)).findFirst();
+ if (env.isPresent()) {
+ return Response.ok(kubernetesService.getPipelineRun(name, env.get().namespace())).build();
+ } else {
+ return Response.noContent().build();
+ }
+ }
}
\ No newline at end of file
diff --git a/karavan-app/src/main/java/org/apache/camel/karavan/model/KaravanConfiguration.java b/karavan-app/src/main/java/org/apache/camel/karavan/model/KaravanConfiguration.java
index 0db0b9d..a843798 100644
--- a/karavan-app/src/main/java/org/apache/camel/karavan/model/KaravanConfiguration.java
+++ b/karavan-app/src/main/java/org/apache/camel/karavan/model/KaravanConfiguration.java
@@ -16,5 +16,6 @@ public interface KaravanConfiguration {
interface Environment {
String name();
String cluster();
+ String namespace();
}
}
diff --git a/karavan-app/src/main/java/org/apache/camel/karavan/model/Project.java b/karavan-app/src/main/java/org/apache/camel/karavan/model/Project.java
index 6f0b4cb..174d5f6 100644
--- a/karavan-app/src/main/java/org/apache/camel/karavan/model/Project.java
+++ b/karavan-app/src/main/java/org/apache/camel/karavan/model/Project.java
@@ -17,6 +17,8 @@ public class Project {
Project.CamelRuntime runtime;
@ProtoField(number = 5)
String lastCommit;
+ @ProtoField(number = 6)
+ String lastPipelineRun;
public enum CamelRuntime {
@ProtoEnumValue(number = 0, name = "Quarkus")
@@ -28,12 +30,13 @@ public class Project {
}
@ProtoFactory
- public Project(String projectId, String name, String description, CamelRuntime runtime, String lastCommit) {
+ public Project(String projectId, String name, String description, CamelRuntime runtime, String lastCommit, String lastPipelineRun) {
this.projectId = projectId;
this.name = name;
this.description = description;
this.runtime = runtime;
this.lastCommit = lastCommit;
+ this.lastPipelineRun = lastPipelineRun;
}
public Project(String projectId, String name, String description, CamelRuntime runtime) {
@@ -86,4 +89,12 @@ public class Project {
public void setLastCommit(String lastCommit) {
this.lastCommit = lastCommit;
}
+
+ public String getLastPipelineRun() {
+ return lastPipelineRun;
+ }
+
+ public void setLastPipelineRun(String lastPipelineRun) {
+ this.lastPipelineRun = lastPipelineRun;
+ }
}
diff --git a/karavan-app/src/main/java/org/apache/camel/karavan/service/KubernetesService.java b/karavan-app/src/main/java/org/apache/camel/karavan/service/KubernetesService.java
index 1004343..7a5f221 100644
--- a/karavan-app/src/main/java/org/apache/camel/karavan/service/KubernetesService.java
+++ b/karavan-app/src/main/java/org/apache/camel/karavan/service/KubernetesService.java
@@ -16,12 +16,16 @@
*/
package org.apache.camel.karavan.service;
+import io.fabric8.kubernetes.api.model.ObjectMeta;
import io.fabric8.kubernetes.api.model.ObjectMetaBuilder;
import io.fabric8.kubernetes.client.DefaultKubernetesClient;
import io.fabric8.tekton.client.DefaultTektonClient;
import io.fabric8.tekton.pipeline.v1beta1.ParamBuilder;
+import io.fabric8.tekton.pipeline.v1beta1.PipelineRef;
import io.fabric8.tekton.pipeline.v1beta1.PipelineRefBuilder;
+import io.fabric8.tekton.pipeline.v1beta1.PipelineRun;
import io.fabric8.tekton.pipeline.v1beta1.PipelineRunBuilder;
+import io.fabric8.tekton.pipeline.v1beta1.PipelineRunSpec;
import io.fabric8.tekton.pipeline.v1beta1.PipelineRunSpecBuilder;
import org.apache.camel.karavan.model.Project;
import org.eclipse.microprofile.config.inject.ConfigProperty;
@@ -44,26 +48,35 @@ public class KubernetesService {
private static final Logger LOGGER = Logger.getLogger(KubernetesService.class.getName());
- public String createPipelineRun(Project project) throws Exception {
+ public String createPipelineRun(Project project, String namespace) throws Exception {
+
+ Map<String, String> labels = Map.of(
+ "karavan-project-id", project.getProjectId(),
+ "tekton.dev/pipeline", "karavan-quarkus"
+ );
+
+ ObjectMeta meta = new ObjectMetaBuilder()
+ .withGenerateName("karavan-" + project.getProjectId() + "-")
+ .withLabels(labels)
+ .withNamespace(namespace)
+ .build();
+
+ PipelineRef ref = new PipelineRefBuilder().withName("karavan-quarkus").build();
+
+ PipelineRunSpec spec = new PipelineRunSpecBuilder()
+ .withPipelineRef(ref)
+ .withServiceAccountName("pipeline")
+ .withParams(new ParamBuilder().withName("PROJECT_NAME").withNewValue(project.getProjectId()).build())
+ .build();
PipelineRunBuilder pipelineRun = new PipelineRunBuilder()
- .withMetadata(
- new ObjectMetaBuilder()
- .withGenerateName("karavan-" + project.getProjectId() + "-")
- .withLabels(Map.of(
- "karavan-project-id", project.getProjectId(),
- "tekton.dev/pipeline", "karavan-quarkus"
- )).build()
- )
- .withSpec(
- new PipelineRunSpecBuilder()
- .withPipelineRef(
- new PipelineRefBuilder().withName("karavan-quarkus").build()
- )
- .withServiceAccountName("pipeline")
- .withParams(new ParamBuilder().withName("PROJECT_NAME").withNewValue(project.getProjectId()).build())
- .build()
- );
+ .withMetadata(meta)
+ .withSpec(spec);
+
return tektonClient().v1beta1().pipelineRuns().create(pipelineRun.build()).getMetadata().getName();
}
+
+ public PipelineRun getPipelineRun(String name, String namespace) throws Exception {
+ return tektonClient().v1beta1().pipelineRuns().inNamespace(namespace).withName(name).get();
+ }
}
diff --git a/karavan-app/src/main/resources/application.properties b/karavan-app/src/main/resources/application.properties
index 1f5929e..b3724db 100644
--- a/karavan-app/src/main/resources/application.properties
+++ b/karavan-app/src/main/resources/application.properties
@@ -29,10 +29,13 @@ karavan.config.image-group=karavan
karavan.config.runtime=QUARKUS
karavan.config.runtime-version=2.9.2.Final
karavan.config.environments[0].name=dev
+karavan.config.environments[0].namespace=karavan
karavan.config.environments[0].cluster=kubernetes.default.svc
karavan.config.environments[1].name=test
+karavan.config.environments[1].namespace=test
karavan.config.environments[1].cluster=kubernetes.default.svc
karavan.config.environments[2].name=prod
+karavan.config.environments[2].namespace=prod
karavan.config.environments[2].cluster=kubernetes.default.svc
# Infinispan Server address
diff --git a/karavan-app/src/main/webapp/src/api/KaravanApi.tsx b/karavan-app/src/main/webapp/src/api/KaravanApi.tsx
index b8616ee..46f3d84 100644
--- a/karavan-app/src/main/webapp/src/api/KaravanApi.tsx
+++ b/karavan-app/src/main/webapp/src/api/KaravanApi.tsx
@@ -111,6 +111,16 @@ export const KaravanApi = {
});
},
+ tekton: async (project: Project, environment: string, after: (res: AxiosResponse<any>) => void) => {
+ axios.post('/tekton/' + environment, project,
+ {headers: {'Accept': 'application/json', 'Content-Type': 'application/json', 'username': 'cameleer'}})
+ .then(res => {
+ after(res);
+ }).catch(err => {
+ after(err);
+ });
+ },
+
getKameletNames: async (after: (names: []) => void) => {
axios.get('/kamelet',
{headers: {'Accept': 'application/json'}})
diff --git a/karavan-app/src/main/webapp/src/index.css b/karavan-app/src/main/webapp/src/index.css
index b2a580b..7f33f3c 100644
--- a/karavan-app/src/main/webapp/src/index.css
+++ b/karavan-app/src/main/webapp/src/index.css
@@ -99,13 +99,17 @@
.karavan .project-page .table {
margin-top: 16px;
}
+.karavan .project-page .project-button {
+ width: 100px;
+}
.karavan .action-cell {
padding: 0;
}
.karavan .runtime-badge {
- width: 75px;
+ min-width: 18px;
+ padding: 0;
}
.create-file-form .pf-c-form__group {
diff --git a/karavan-app/src/main/webapp/src/models/ProjectModels.ts b/karavan-app/src/main/webapp/src/models/ProjectModels.ts
index 89daf48..51474f8 100644
--- a/karavan-app/src/main/webapp/src/models/ProjectModels.ts
+++ b/karavan-app/src/main/webapp/src/models/ProjectModels.ts
@@ -3,8 +3,9 @@ export class Project {
name: string = '';
description: string = '';
lastCommit: string = '';
+ lastPipelineRun: string = '';
- public constructor(projectId: string, name: string, description: string, lastCommit: string);
+ public constructor(projectId: string, name: string, description: string, lastCommit: string, lastPipelineRun: string);
public constructor(init?: Partial<Project>);
public constructor(...args: any[]) {
if (args.length === 1){
@@ -15,6 +16,7 @@ export class Project {
this.name = args[1];
this.description = args[2];
this.lastCommit = args[3];
+ this.lastPipelineRun = args[4];
return;
}
}
diff --git a/karavan-app/src/main/webapp/src/projects/ProjectPage.tsx b/karavan-app/src/main/webapp/src/projects/ProjectPage.tsx
index acdf5ae..2648f41 100644
--- a/karavan-app/src/main/webapp/src/projects/ProjectPage.tsx
+++ b/karavan-app/src/main/webapp/src/projects/ProjectPage.tsx
@@ -21,7 +21,7 @@ import {
EmptyStateVariant,
EmptyStateIcon,
Title,
- ModalVariant, Modal, Spinner, Tooltip, Flex, FlexItem,
+ ModalVariant, Modal, Spinner, Tooltip, Flex, FlexItem, ToggleGroup, ToggleGroupItem,
} from '@patternfly/react-core';
import '../designer/karavan.css';
import {MainToolbar} from "../MainToolbar";
@@ -38,8 +38,13 @@ import Editor from "@monaco-editor/react";
import SearchIcon from '@patternfly/react-icons/dist/esm/icons/search-icon';
import PlusIcon from "@patternfly/react-icons/dist/esm/icons/plus-icon";
import {CreateFileModal} from "./CreateFileModal";
+import BuildIcon from "@patternfly/react-icons/dist/esm/icons/build-icon";
+import DeployIcon from "@patternfly/react-icons/dist/esm/icons/process-automation-icon";
import PushIcon from "@patternfly/react-icons/dist/esm/icons/code-branch-icon";
import {PropertiesEditor} from "./PropertiesEditor";
+import PendingIcon from "@patternfly/react-icons/dist/esm/icons/pending-icon";
+import CheckCircleIcon from "@patternfly/react-icons/dist/esm/icons/check-circle-icon";
+import ExclamationCircleIcon from "@patternfly/react-icons/dist/esm/icons/exclamation-circle-icon";
interface Props {
project: Project,
@@ -53,9 +58,11 @@ interface State {
isUploadModalOpen: boolean,
isDeleteModalOpen: boolean,
isCreateModalOpen: boolean,
- isPushModalOpen: boolean,
isPushing: boolean,
- fileToDelete?: ProjectFile
+ isBuilding: boolean,
+ fileToDelete?: ProjectFile,
+ environments: string[],
+ environment: string
}
export class ProjectPage extends React.Component<Props, State> {
@@ -65,9 +72,13 @@ export class ProjectPage extends React.Component<Props, State> {
isUploadModalOpen: false,
isCreateModalOpen: false,
isDeleteModalOpen: false,
- isPushModalOpen: false,
isPushing: false,
- files: []
+ isBuilding: false,
+ files: [],
+ environments: this.props.config.environments && Array.isArray(this.props.config.environments)
+ ? Array.from(this.props.config.environments) : [],
+ environment: this.props.config.environments && Array.isArray(this.props.config.environments)
+ ? this.props.config.environments[0] : ''
};
componentDidMount() {
@@ -118,7 +129,6 @@ export class ProjectPage extends React.Component<Props, State> {
tools = () => {
const isFile = this.state.file !== undefined;
- const isPushing = this.state.isPushing;
return <Toolbar id="toolbar-group-types">
{isFile && <ToolbarContent>
<ToolbarItem>
@@ -127,23 +137,13 @@ export class ProjectPage extends React.Component<Props, State> {
</ToolbarContent>}
{!isFile && <ToolbarContent>
<ToolbarItem>
- {!isPushing && <Button variant={"primary"} icon={<PlusIcon/>}
- onClick={e => this.setState({isCreateModalOpen: true})}>Create</Button>}
- </ToolbarItem>
- <ToolbarItem>
- {!isPushing && <Button variant="secondary" icon={<UploadIcon/>}
- onClick={e => this.setState({isUploadModalOpen: true})}>Upload</Button>}
+ <Button variant={"primary"} icon={<PlusIcon/>}
+ onClick={e => this.setState({isCreateModalOpen: true})}>Create</Button>
</ToolbarItem>
<ToolbarItem>
- {!isPushing && <Button variant="secondary" icon={<PushIcon/>}
- onClick={e => this.setState({isPushModalOpen: true})}>Push</Button>}
+ <Button variant="secondary" icon={<UploadIcon/>}
+ onClick={e => this.setState({isUploadModalOpen: true})}>Upload</Button>
</ToolbarItem>
- {isPushing && <ToolbarItem>
- <Button variant="link" isDisabled>Pushing...</Button>
- </ToolbarItem>}
- {isPushing && <ToolbarItem>
- <Spinner isSVG diameter="30px"/>
- </ToolbarItem>}
</ToolbarContent>}
</Toolbar>
};
@@ -189,7 +189,6 @@ export class ProjectPage extends React.Component<Props, State> {
this.setState({
isUploadModalOpen: false,
isCreateModalOpen: false,
- isPushModalOpen: false,
isPushing: isPushing
});
this.onRefresh();
@@ -215,12 +214,26 @@ export class ProjectPage extends React.Component<Props, State> {
}
}
- push = () => {
- this.closeModal(true);
+ push = (after?: () => void) => {
+ this.setState({isPushing: true});
KaravanApi.push(this.props.project, res => {
console.log(res)
if (res.status === 200 || res.status === 201) {
this.setState({isPushing: false});
+ after?.call(this);
+ this.onRefresh();
+ } else {
+ // Todo notification
+ }
+ });
+ }
+
+ build = () => {
+ this.setState({isBuilding: true});
+ KaravanApi.tekton(this.props.project, this.state.environment, res => {
+ console.log(res)
+ if (res.status === 200 || res.status === 201) {
+ this.setState({isBuilding: false});
this.onRefresh();
} else {
// Todo notification
@@ -238,11 +251,53 @@ export class ProjectPage extends React.Component<Props, State> {
}
}
+ pushButton = () => {
+ const isPushing = this.state.isPushing;
+ return (<Tooltip content="Commit and push to git" position={"left"}>
+ <Button isLoading={isPushing ? true : undefined} isSmall variant="secondary"
+ className="project-button"
+ icon={!isPushing ? <PushIcon/> : <div></div>}
+ onClick={e => this.push()}>
+ {isPushing ? "..." : "Commit"}
+ </Button>
+ </Tooltip>)
+ }
+
+ buildButton = () => {
+ const isDeploying = this.state.isBuilding;
+ return (<Tooltip content="Commit, push, build and deploy" position={"left"}>
+ <Button isLoading={isDeploying ? true : undefined} isSmall variant="secondary"
+ className="project-button"
+ icon={!isDeploying ? <BuildIcon/> : <div></div>}
+ onClick={e => {
+ this.push(() => this.build());
+ }}>
+ {isDeploying ? "..." : "Run"}
+ </Button>
+ </Tooltip>)
+ }
+
+ getProgressIcon(status?: 'pending' | 'progress' | 'done' | 'error') {
+ switch (status) {
+ case "pending":
+ return <PendingIcon color={"grey"}/>;
+ case "progress":
+ return <Spinner isSVG size="md"/>
+ case "done":
+ return <CheckCircleIcon color={"green"}/>;
+ case "error":
+ return <ExclamationCircleIcon color={"red"}/>;
+ default:
+ return undefined;
+ }
+ }
+
+ getCurrentStatus() {
+ return (<Text>OK</Text>)
+ }
+
getProjectForm = () => {
- const project = this.state.project;
- const environments: string[] = this.props.config.environments && Array.isArray(this.props.config.environments)
- ? Array.from(this.props.config.environments)
- : [];
+ const {project, environments, environment, isBuilding} = this.state;
return (
<Card>
<CardBody isFilled>
@@ -262,21 +317,28 @@ export class ProjectPage extends React.Component<Props, State> {
<DescriptionListTerm>Description</DescriptionListTerm>
<DescriptionListDescription>{project?.description}</DescriptionListDescription>
</DescriptionListGroup>
-
</DescriptionList>
</FlexItem>
<FlexItem flex={{default: "flex_1"}}>
<DescriptionList isHorizontal>
<DescriptionListGroup>
- <DescriptionListTerm>Latest Commit</DescriptionListTerm>
+ <DescriptionListTerm>Last Commit</DescriptionListTerm>
<DescriptionListDescription>
<Tooltip content={project?.lastCommit} position={"bottom"}>
- <Badge>{project?.lastCommit?.substr(0, 7)}</Badge>
+ <Badge>{project?.lastCommit ? project?.lastCommit?.substr(0, 7) : "-"}</Badge>
</Tooltip>
</DescriptionListDescription>
</DescriptionListGroup>
<DescriptionListGroup>
- <DescriptionListTerm>Deployment</DescriptionListTerm>
+ <DescriptionListTerm>Last Pipeline Run</DescriptionListTerm>
+ <DescriptionListDescription>
+ <Tooltip content={project?.lastPipelineRun} position={"bottom"}>
+ <Badge>{project?.lastPipelineRun ? project?.lastPipelineRun : "-"}</Badge>
+ </Tooltip>
+ </DescriptionListDescription>
+ </DescriptionListGroup>
+ <DescriptionListGroup>
+ <DescriptionListTerm>Status</DescriptionListTerm>
<DescriptionListDescription>
<Flex direction={{default: "row"}}>
{environments.filter(e => e !== undefined)
@@ -284,8 +346,32 @@ export class ProjectPage extends React.Component<Props, State> {
</Flex>
</DescriptionListDescription>
</DescriptionListGroup>
+ {/*<DescriptionListGroup>*/}
+ {/* <DescriptionListTerm>Environment</DescriptionListTerm>*/}
+ {/* <DescriptionListDescription>*/}
+ {/* <ToggleGroup isCompact>*/}
+ {/* {environments.filter(e => e !== undefined)*/}
+ {/* .map(e => <ToggleGroupItem key={e} text={e} isSelected={environment === e}*/}
+ {/* onChange={s => this.setState({environment: e})}>*/}
+ {/* </ToggleGroupItem>)}*/}
+ {/* </ToggleGroup>*/}
+ {/* </DescriptionListDescription>*/}
+ {/*</DescriptionListGroup>*/}
</DescriptionList>
</FlexItem>
+ <FlexItem >
+ <Flex direction={{default: "column"}}>
+ <FlexItem>
+ {this.pushButton()}
+ </FlexItem>
+ <FlexItem>
+ {this.buildButton()}
+ </FlexItem>
+ <FlexItem>
+ <Button isSmall style={{visibility:"hidden"}}>Refresh</Button>
+ </FlexItem>
+ </Flex>
+ </FlexItem>
</Flex>
</CardBody>
</Card>
@@ -423,19 +509,6 @@ export class ProjectPage extends React.Component<Props, State> {
onEscapePress={e => this.setState({isDeleteModalOpen: false})}>
<div>{"Are you sure you want to delete the file " + this.state.fileToDelete?.name + "?"}</div>
</Modal>
- <Modal
- title="Push"
- variant={ModalVariant.small}
- isOpen={this.state.isPushModalOpen}
- onClose={() => this.setState({isPushModalOpen: false})}
- actions={[
- <Button key="confirm" variant="primary" onClick={e => this.push()}>Push</Button>,
- <Button key="cancel" variant="link"
- onClick={e => this.setState({isPushModalOpen: false})}>Cancel</Button>
- ]}
- onEscapePress={e => this.setState({isPushModalOpen: false})}>
- <div>{"Push project to repository"}</div>
- </Modal>
</PageSection>
)
}
diff --git a/karavan-app/src/main/webapp/src/projects/ProjectsPage.tsx b/karavan-app/src/main/webapp/src/projects/ProjectsPage.tsx
index 7f19ac6..836e54a 100644
--- a/karavan-app/src/main/webapp/src/projects/ProjectsPage.tsx
+++ b/karavan-app/src/main/webapp/src/projects/ProjectsPage.tsx
@@ -99,7 +99,7 @@ export class ProjectsPage extends React.Component<Props, State> {
saveAndCloseCreateModal = () => {
const {name, description, projectId} = this.state;
- const p = new Project(projectId, name, description, '');
+ const p = new Project(projectId, name, description, '', '');
this.props.onCreate.call(this, p);
this.setState({isCreateModalOpen: false, isCopy: false, name: this.props.config.groupId, description: '', projectId: ''});
}
@@ -173,7 +173,9 @@ export class ProjectsPage extends React.Component<Props, State> {
{projects.map(project => (
<Tr key={project.projectId}>
<Td modifier={"fitContent"}>
- <Badge className="runtime-badge">{this.props.config.runtime}</Badge>
+ <Tooltip content={this.props.config.runtime} position={"left"}>
+ <Badge className="runtime-badge">{this.props.config.runtime.substring(0,1)}</Badge>
+ </Tooltip>
</Td>
<Td>
<Button style={{padding: '6px'}} variant={"link"} onClick={e=>this.props.onSelect?.call(this, project)}>