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 6238883 Simplified Project Management (#380) 6238883 is described below commit 62388835216f34216ccaa98ca5a1db2ec2138aba Author: Marat Gubaidullin <marat.gubaidul...@gmail.com> AuthorDate: Tue Jun 21 11:43:41 2022 -0400 Simplified Project Management (#380) --- .../camel/karavan/api/ConfigurationResource.java | 7 +- .../org/apache/camel/karavan/api/GitResource.java | 4 +- .../camel/karavan/api/ProjectFileResource.java | 6 +- .../apache/camel/karavan/api/ProjectResource.java | 4 +- .../camel/karavan/model/KaravanConfiguration.java | 3 +- .../org/apache/camel/karavan/model/Project.java | 77 +++++++------------- .../apache/camel/karavan/model/ProjectFile.java | 14 ++-- .../camel/karavan/service/GeneratorService.java | 22 +++--- .../apache/camel/karavan/service/GitService.java | 6 +- .../camel/karavan/service/InfinispanService.java | 71 +++++++++++-------- .../src/main/resources/application.properties | 5 +- karavan-app/src/main/webapp/src/Main.tsx | 2 +- karavan-app/src/main/webapp/src/api/KaravanApi.tsx | 4 +- .../main/webapp/src/builder/PropertiesTable.tsx | 2 +- .../src/main/webapp/src/models/ProjectModels.ts | 31 +++----- .../main/webapp/src/projects/CreateFileModal.tsx | 4 +- .../src/main/webapp/src/projects/ProjectPage.tsx | 29 +++----- .../src/main/webapp/src/projects/ProjectsPage.tsx | 82 ++++++++++------------ karavan-designer/src/builder/PropertiesTable.tsx | 2 +- 19 files changed, 161 insertions(+), 214 deletions(-) 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 d215181..5e01b29 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 @@ -25,7 +25,6 @@ import javax.ws.rs.GET; import javax.ws.rs.Path; import javax.ws.rs.Produces; import javax.ws.rs.core.MediaType; -import java.util.List; import java.util.Map; import java.util.stream.Collectors; @@ -35,8 +34,6 @@ public class ConfigurationResource { @ConfigProperty(name = "karavan.version") String version; - @ConfigProperty(name = "karavan.mode") - String mode; @Inject KaravanConfiguration configuration; @@ -47,10 +44,8 @@ public class ConfigurationResource { return RestResponse.ResponseBuilder.ok( Map.of( "version", version, - "mode", mode, "environments", configuration.environments().stream().map(e -> e.name()).collect(Collectors.toList()), - "defaultRuntime", configuration.defaultRuntime(), - "groupId", configuration.groupId() + "runtime", configuration.runtime() ) ).build(); } diff --git a/karavan-app/src/main/java/org/apache/camel/karavan/api/GitResource.java b/karavan-app/src/main/java/org/apache/camel/karavan/api/GitResource.java index 05966b4..5fa989f 100644 --- a/karavan-app/src/main/java/org/apache/camel/karavan/api/GitResource.java +++ b/karavan-app/src/main/java/org/apache/camel/karavan/api/GitResource.java @@ -64,8 +64,8 @@ public class GitResource { @Produces(MediaType.APPLICATION_JSON) @Consumes(MediaType.APPLICATION_JSON) public Project push(@HeaderParam("username") String username, Project project) throws Exception { - Project p = infinispanService.getProject(project.getKey()); - List<ProjectFile> files = infinispanService.getProjectFiles(project.getKey()); + Project p = infinispanService.getProject(project.getProjectId()); + List<ProjectFile> files = infinispanService.getProjectFiles(project.getProjectId()); String commitId = gitService.save(p, files); p.setLastCommit(commitId); infinispanService.saveProject(p); diff --git a/karavan-app/src/main/java/org/apache/camel/karavan/api/ProjectFileResource.java b/karavan-app/src/main/java/org/apache/camel/karavan/api/ProjectFileResource.java index e45a8de..cf40128 100644 --- a/karavan-app/src/main/java/org/apache/camel/karavan/api/ProjectFileResource.java +++ b/karavan-app/src/main/java/org/apache/camel/karavan/api/ProjectFileResource.java @@ -41,10 +41,10 @@ public class ProjectFileResource { @GET @Produces(MediaType.APPLICATION_JSON) - @Path("/{project}") + @Path("/{projectId}") public List<ProjectFile> get(@HeaderParam("username") String username, - @PathParam("project") String project) throws Exception { - return infinispanService.getProjectFiles(project); + @PathParam("projectId") String projectId) throws Exception { + return infinispanService.getProjectFiles(projectId); } @POST diff --git a/karavan-app/src/main/java/org/apache/camel/karavan/api/ProjectResource.java b/karavan-app/src/main/java/org/apache/camel/karavan/api/ProjectResource.java index edc4743..bdd149d 100644 --- a/karavan-app/src/main/java/org/apache/camel/karavan/api/ProjectResource.java +++ b/karavan-app/src/main/java/org/apache/camel/karavan/api/ProjectResource.java @@ -48,7 +48,7 @@ public class ProjectResource { @Produces(MediaType.APPLICATION_JSON) public List<Project> getAll(@HeaderParam("username") String username) throws Exception { return infinispanService.getProjects().stream() - .sorted(Comparator.comparing(Project::getKey)) + .sorted(Comparator.comparing(Project::getProjectId)) .collect(Collectors.toList()); } @@ -87,7 +87,7 @@ public class ProjectResource { // Copy files Map<GroupedKey, ProjectFile> map = infinispanService.getProjectFiles(sourceProject).stream() - .collect(Collectors.toMap(f -> new GroupedKey(project.getKey(), f.getName()), f -> f)); + .collect(Collectors.toMap(f -> new GroupedKey(project.getProjectId(), f.getName()), f -> f)); infinispanService.saveProjectFiles(map); return project; } 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 fed618c..8a2fc6b 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 @@ -3,13 +3,12 @@ package org.apache.camel.karavan.model; import io.smallrye.config.ConfigMapping; import java.util.List; -import java.util.Set; @ConfigMapping(prefix = "karavan.config") public interface KaravanConfiguration { String groupId(); - String defaultRuntime(); + String runtime(); List<Environment> environments(); interface Environment { 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 6a13009..6f0b4cb 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 @@ -1,6 +1,5 @@ package org.apache.camel.karavan.model; -import com.google.common.base.CaseFormat; import org.infinispan.protostream.annotations.ProtoEnumValue; import org.infinispan.protostream.annotations.ProtoFactory; import org.infinispan.protostream.annotations.ProtoField; @@ -9,89 +8,67 @@ public class Project { public static final String CACHE = "projects"; @ProtoField(number = 1) - String groupId; + String projectId; @ProtoField(number = 2) - String artifactId; + String name; @ProtoField(number = 3) - String version; + String description; @ProtoField(number = 4) - String folder; - @ProtoField(number = 5) Project.CamelRuntime runtime; - @ProtoField(number = 6) + @ProtoField(number = 5) String lastCommit; public enum CamelRuntime { @ProtoEnumValue(number = 0, name = "Quarkus") QUARKUS, @ProtoEnumValue(number = 1, name = "Spring") - SPRING + SPRING, + @ProtoEnumValue(number = 2, name = "Main") + MAIN } @ProtoFactory - public Project(String groupId, String artifactId, String version, String folder, CamelRuntime runtime, String lastCommit) { - this.groupId = groupId; - this.artifactId = artifactId; - this.version = version; - this.folder = folder; + public Project(String projectId, String name, String description, CamelRuntime runtime, String lastCommit) { + this.projectId = projectId; + this.name = name; + this.description = description; this.runtime = runtime; this.lastCommit = lastCommit; } - public Project(String groupId, String artifactId, String version, String folder, CamelRuntime runtime) { - this.groupId = groupId; - this.artifactId = artifactId; - this.version = version; - this.folder = folder != null && folder.trim().length() > 0 ? folder : toFolder(artifactId, version); + public Project(String projectId, String name, String description, CamelRuntime runtime) { + this.projectId = projectId; + this.name = name; + this.description = description; this.runtime = runtime; } - public static String toFolder(String artifactId, String version){ - String folder = (artifactId+version).replaceAll("[^A-Za-z0-9 ]", "_"); - return CaseFormat.UPPER_UNDERSCORE.to(CaseFormat.LOWER_CAMEL, folder); - } - - public static String toKey(String groupId, String artifactId, String version){ - return groupId + ":" + artifactId + ":" + version; - } - - public String getKey(){ - return toKey(groupId, artifactId, version); - } public Project() { } - public String getGroupId() { - return groupId; - } - - public void setGroupId(String groupId) { - this.groupId = groupId; - } - - public String getArtifactId() { - return artifactId; + public String getProjectId() { + return projectId; } - public void setArtifactId(String artifactId) { - this.artifactId = artifactId; + public void setProjectId(String projectId) { + this.projectId = projectId; } - public String getVersion() { - return version; + public String getName() { + return name; } - public void setVersion(String version) { - this.version = version; + public void setName(String name) { + this.name = name; } - public String getFolder() { - return folder; + public String getDescription() { + return description; } - public void setFolder(String folder) { - this.folder = folder; + public void setDescription(String description) { + this.description = description; } public CamelRuntime getRuntime() { diff --git a/karavan-app/src/main/java/org/apache/camel/karavan/model/ProjectFile.java b/karavan-app/src/main/java/org/apache/camel/karavan/model/ProjectFile.java index ddd703b..30bb0fe 100644 --- a/karavan-app/src/main/java/org/apache/camel/karavan/model/ProjectFile.java +++ b/karavan-app/src/main/java/org/apache/camel/karavan/model/ProjectFile.java @@ -12,13 +12,13 @@ public class ProjectFile { String code; @ProtoField(number = 3) @ProtoDoc("@Field(index=Index.YES, analyze = Analyze.YES, store = Store.NO)") - String project; + String projectId; @ProtoFactory - public ProjectFile(String name, String code, String project) { + public ProjectFile(String name, String code, String projectId) { this.name = name; this.code = code; - this.project = project; + this.projectId = projectId; } public ProjectFile() { @@ -40,11 +40,11 @@ public class ProjectFile { this.code = code; } - public String getProject() { - return project; + public String getProjectId() { + return projectId; } - public void setProject(String project) { - this.project = project; + public void setProjectId(String projectId) { + this.projectId = projectId; } } diff --git a/karavan-app/src/main/java/org/apache/camel/karavan/service/GeneratorService.java b/karavan-app/src/main/java/org/apache/camel/karavan/service/GeneratorService.java index 3467948..02bf3c8 100644 --- a/karavan-app/src/main/java/org/apache/camel/karavan/service/GeneratorService.java +++ b/karavan-app/src/main/java/org/apache/camel/karavan/service/GeneratorService.java @@ -20,7 +20,6 @@ import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.ObjectMapper; import io.apicurio.datamodels.Library; import io.apicurio.datamodels.openapi.models.OasDocument; -import io.vertx.core.Vertx; import org.apache.camel.CamelContext; import org.apache.camel.generator.openapi.RestDslGenerator; import org.apache.camel.impl.lw.LightweightCamelContext; @@ -29,17 +28,12 @@ import org.eclipse.microprofile.config.inject.ConfigProperty; import org.jboss.logging.Logger; import javax.enterprise.context.ApplicationScoped; -import javax.inject.Inject; @ApplicationScoped public class GeneratorService { - - @ConfigProperty(name = "karavan.folder.integrations") - String integrations; - - @Inject - Vertx vertx; + @ConfigProperty(name = "karavan.config.group-id") + String groupId; private static final Logger LOGGER = Logger.getLogger(GeneratorService.class.getName()); @@ -54,12 +48,14 @@ public class GeneratorService { public String getDefaultApplicationProperties(Project project){ StringBuilder s = new StringBuilder(); - s.append("camel.jbang.gav=").append(project.getKey()).append(System.lineSeparator()); + s.append("camel.jbang.projectId=").append(project.getProjectId()).append(System.lineSeparator()); + s.append("camel.jbang.projectName=").append(project.getName()).append(System.lineSeparator()); + s.append("camel.jbang.projectDescription=").append(project.getDescription()).append(System.lineSeparator()); + s.append("camel.jbang.gav=").append(groupId).append(":").append(project.getProjectId()).append(":").append("1.0.0").append(System.lineSeparator()); s.append("camel.jbang.runtime=").append(project.getRuntime().name().toLowerCase()).append(System.lineSeparator()); - s.append("quarkus.container-image.group=").append(project.getGroupId()).append(System.lineSeparator()); - s.append("quarkus.container-image.name=").append(project.getArtifactId()).append(System.lineSeparator()); - s.append("quarkus.container-image.tag=").append(project.getVersion()).append(System.lineSeparator()); - s.append("quarkus.openshift.route.expose=true").append(System.lineSeparator()); + s.append("quarkus.container-image.group=").append(groupId).append(System.lineSeparator()); + s.append("quarkus.container-image.name=").append(project.getProjectId()).append(System.lineSeparator()); + s.append("quarkus.openshift.route.expose=false").append(System.lineSeparator()); s.append("quarkus.kubernetes-client.trust-certs=true").append(System.lineSeparator()); return s.toString(); } diff --git a/karavan-app/src/main/java/org/apache/camel/karavan/service/GitService.java b/karavan-app/src/main/java/org/apache/camel/karavan/service/GitService.java index 4dbcd60..4b3cd88 100644 --- a/karavan-app/src/main/java/org/apache/camel/karavan/service/GitService.java +++ b/karavan-app/src/main/java/org/apache/camel/karavan/service/GitService.java @@ -78,7 +78,7 @@ public class GitService { } public String save(Project project, List<ProjectFile> files) throws GitAPIException, IOException, URISyntaxException { - LOGGER.info("Save project " + project.getKey()); + LOGGER.info("Save project " + project.getProjectId()); String uuid = UUID.randomUUID().toString(); String folder = vertx.fileSystem().createTempDirectoryBlocking(uuid); LOGGER.infof("Temp folder created: {}", folder); @@ -97,10 +97,10 @@ public class GitService { } private void writeProjectToFolder(String folder, Project project, List<ProjectFile> files) throws IOException { - Files.createDirectories(Paths.get(folder, project.getFolder())); + Files.createDirectories(Paths.get(folder, project.getProjectId())); files.forEach(file -> { try { - Files.writeString(Paths.get(folder, project.getFolder(), file.getName()), file.getCode()); + Files.writeString(Paths.get(folder, project.getProjectId(), file.getName()), file.getCode()); } catch (IOException e) { throw new RuntimeException(e); } diff --git a/karavan-app/src/main/java/org/apache/camel/karavan/service/InfinispanService.java b/karavan-app/src/main/java/org/apache/camel/karavan/service/InfinispanService.java index a6f5e1c..0ae70c0 100644 --- a/karavan-app/src/main/java/org/apache/camel/karavan/service/InfinispanService.java +++ b/karavan-app/src/main/java/org/apache/camel/karavan/service/InfinispanService.java @@ -17,10 +17,14 @@ package org.apache.camel.karavan.service; import io.quarkus.runtime.StartupEvent; +import io.quarkus.runtime.configuration.ProfileManager; import org.apache.camel.karavan.KaravanLifecycleBean; import org.apache.camel.karavan.model.GroupedKey; import org.apache.camel.karavan.model.Project; import org.apache.camel.karavan.model.ProjectFile; +import org.eclipse.microprofile.config.Config; +import org.eclipse.microprofile.config.ConfigProvider; +import org.eclipse.microprofile.config.inject.ConfigProperty; import org.infinispan.Cache; import org.infinispan.client.hotrod.RemoteCache; import org.infinispan.client.hotrod.RemoteCacheManager; @@ -56,6 +60,9 @@ public class InfinispanService { @Inject GeneratorService generatorService; + @ConfigProperty(name = "karavan.config.runtime") + String runtime; + private static final String CACHE_CONFIG = "<distributed-cache name=\"%s\">" + " <encoding media-type=\"application/x-protostream\"/>" + " <groups enabled=\"true\"/>" @@ -77,26 +84,8 @@ public class InfinispanService { projects = cacheManager.administration().getOrCreateCache(Project.CACHE, new XMLStringConfiguration(String.format(CACHE_CONFIG, Project.CACHE))); files = cacheManager.administration().getOrCreateCache(ProjectFile.CACHE, new XMLStringConfiguration(String.format(CACHE_CONFIG, ProjectFile.CACHE))); } - - for (int i = 0; i < 10; i++){ - String groupId = "org.apache.camel.karavan"; - String artifactId = "parcel-demo" + i; - Project p = new Project(groupId, artifactId, "1.0.0", null, Project.CamelRuntime.values()[new Random().nextInt(2)]); - this.saveProject(p); - - files.put(GroupedKey.create(p.getKey(),"new-parcels.yaml"), new ProjectFile("new-parcels.yaml", "flows:", p.getKey())); - files.put(GroupedKey.create(p.getKey(),"parcel-confirmation.yaml"), new ProjectFile("parcel-confirmation.yaml", "rest:", p.getKey())); - files.put(GroupedKey.create(p.getKey(),"CustomProcessor.java"), new ProjectFile("CustomProcessor.java", "import org.apache.camel.BindToRegistry;\n" + - "import org.apache.camel.Exchange;\n" + - "import org.apache.camel.Processor;\n" + - "\n" + - "@BindToRegistry(\"myBean\")\n" + - "public class CustomProcessor implements Processor {\n" + - "\n" + - " public void process(Exchange exchange) throws Exception {\n" + - " exchange.getIn().setBody(\"Hello world\");\n" + - " }\n" + - "}", p.getKey())); + if (ProfileManager.getLaunchMode().isDevOrTest()){ + generateDevProjects(); } } @@ -105,35 +94,33 @@ public class InfinispanService { } public void saveProject(Project project) { - GroupedKey key = GroupedKey.create(project.getKey(), project.getKey()); + GroupedKey key = GroupedKey.create(project.getProjectId(), project.getProjectId()); boolean isNew = !projects.containsKey(key); - if (project.getFolder() == null || project.getFolder().trim().length() == 0) { - project.setFolder(Project.toFolder(project.getArtifactId(), project.getVersion())); - } + project.setRuntime(Project.CamelRuntime.valueOf(runtime)); projects.put(key, project); if (isNew){ String filename = "application.properties"; String code = generatorService.getDefaultApplicationProperties(project); - files.put(new GroupedKey(project.getKey(), filename), new ProjectFile(filename, code, project.getKey())); + files.put(new GroupedKey(project.getProjectId(), filename), new ProjectFile(filename, code, project.getProjectId())); } } - public List<ProjectFile> getProjectFiles(String projectName) { + public List<ProjectFile> getProjectFiles(String projectId) { if (cacheManager == null) { QueryFactory queryFactory = org.infinispan.query.Search.getQueryFactory((Cache<?, ?>) files); - return queryFactory.<ProjectFile>create("FROM org.apache.camel.karavan.model.ProjectFile WHERE project = :project") - .setParameter("project", projectName) + return queryFactory.<ProjectFile>create("FROM org.apache.camel.karavan.model.ProjectFile WHERE projectId = :projectId") + .setParameter("projectId", projectId) .execute().list(); } else { QueryFactory queryFactory = Search.getQueryFactory((RemoteCache<?, ?>) files); - return queryFactory.<ProjectFile>create("FROM karavan.ProjectFile WHERE project = :project") - .setParameter("project", projectName) + return queryFactory.<ProjectFile>create("FROM karavan.ProjectFile WHERE projectId = :projectId") + .setParameter("projectId", projectId) .execute().list(); } } public void saveProjectFile(ProjectFile file) { - files.put(GroupedKey.create(file.getProject(), file.getName()), file); + files.put(GroupedKey.create(file.getProjectId(), file.getName()), file); } public void saveProjectFiles(Map<GroupedKey, ProjectFile> f) { @@ -151,4 +138,26 @@ public class InfinispanService { public Project getProject(String project) { return projects.get(GroupedKey.create(project, project)); } + + private void generateDevProjects(){ + for (int i = 0; i < 10; i++){ + String projectId = "parcel-demo" + i; + Project p = new Project(projectId, "Demo project " + i, "Demo project placeholder for UI testing purposes", Project.CamelRuntime.valueOf(runtime)); + this.saveProject(p); + + files.put(GroupedKey.create(p.getProjectId(),"new-parcels.yaml"), new ProjectFile("new-parcels.yaml", "flows:", p.getProjectId())); + files.put(GroupedKey.create(p.getProjectId(),"parcel-confirmation.yaml"), new ProjectFile("parcel-confirmation.yaml", "rest:", p.getProjectId())); + files.put(GroupedKey.create(p.getProjectId(),"CustomProcessor.java"), new ProjectFile("CustomProcessor.java", "import org.apache.camel.BindToRegistry;\n" + + "import org.apache.camel.Exchange;\n" + + "import org.apache.camel.Processor;\n" + + "\n" + + "@BindToRegistry(\"myBean\")\n" + + "public class CustomProcessor implements Processor {\n" + + "\n" + + " public void process(Exchange exchange) throws Exception {\n" + + " exchange.getIn().setBody(\"Hello world\");\n" + + " }\n" + + "}", p.getProjectId())); + } + } } diff --git a/karavan-app/src/main/resources/application.properties b/karavan-app/src/main/resources/application.properties index 9d953ca..13820c9 100644 --- a/karavan-app/src/main/resources/application.properties +++ b/karavan-app/src/main/resources/application.properties @@ -5,7 +5,6 @@ karavan.folder.kamelets-buildin=kamelets-buildin %dev.karavan.folder.kamelets-buildin=target/classes/kamelets karavan.folder.kamelets-custom=kamelets -karavan.mode=local karavan.folder.integrations=integrations %dev.karavan.folder.integrations=target/classes/integrations @@ -16,8 +15,8 @@ karavan.git.password= karavan.git.main=main # Projects configuration -karavan.config.group-id=com.acme -karavan.config.default-runtime=QUARKUS +karavan.config.group-id=org.camel.karavan.demo +karavan.config.runtime=QUARKUS karavan.config.environments[0].name=dev karavan.config.environments[0].cluster=kubernetes.default.svc karavan.config.environments[1].name=test diff --git a/karavan-app/src/main/webapp/src/Main.tsx b/karavan-app/src/main/webapp/src/Main.tsx index edc2b16..f34cad6 100644 --- a/karavan-app/src/main/webapp/src/Main.tsx +++ b/karavan-app/src/main/webapp/src/Main.tsx @@ -247,7 +247,7 @@ export class Main extends React.Component<Props, State> { onClick={e => this.setState({isModalOpen: false})}>Cancel</Button> ]} onEscapePress={e => this.setState({isModalOpen: false})}> - <div>{"Are you sure you want to delete the project " + this.state.projectToDelete?.getKey() + "?"}</div> + <div>{"Are you sure you want to delete the project " + this.state.projectToDelete?.projectId + "?"}</div> </Modal> {this.state.alerts.map((e: ToastMessage) => ( <Alert key={e.id} className="main-alert" variant={e.variant} title={e.title} diff --git a/karavan-app/src/main/webapp/src/api/KaravanApi.tsx b/karavan-app/src/main/webapp/src/api/KaravanApi.tsx index cb59783..b8616ee 100644 --- a/karavan-app/src/main/webapp/src/api/KaravanApi.tsx +++ b/karavan-app/src/main/webapp/src/api/KaravanApi.tsx @@ -60,7 +60,7 @@ export const KaravanApi = { }, deleteProject: async (project: Project, after: (res: AxiosResponse<any>) => void) => { - axios.delete('/project/' + encodeURI(project.getKey()), + axios.delete('/project/' + encodeURI(project.projectId), {headers:{'username': 'cameleer'}}) .then(res => { after(res); @@ -92,7 +92,7 @@ export const KaravanApi = { }, deleteProjectFile: async (file: ProjectFile, after: (res: AxiosResponse<any>) => void) => { - axios.delete('/file/' + file.project + '/' + file.name, + axios.delete('/file/' + file.projectId + '/' + file.name, {headers:{'username': 'cameleer'}}) .then(res => { after(res); diff --git a/karavan-app/src/main/webapp/src/builder/PropertiesTable.tsx b/karavan-app/src/main/webapp/src/builder/PropertiesTable.tsx index 27d5a88..f59cec6 100644 --- a/karavan-app/src/main/webapp/src/builder/PropertiesTable.tsx +++ b/karavan-app/src/main/webapp/src/builder/PropertiesTable.tsx @@ -100,7 +100,7 @@ export class PropertiesTable extends React.Component<Props, State> { </Thead> <Tbody> {properties.map((property, idx: number) => { - const readOnly = ["camel.jbang.gav", "camel.jbang.runtime"].includes(property.key); + const readOnly = property.key.startsWith("camel.jbang"); return ( <Tr key={property.id}> <Td noPadding width={20} dataLabel="key">{this.getTextInputField(property, "key", readOnly)}</Td> diff --git a/karavan-app/src/main/webapp/src/models/ProjectModels.ts b/karavan-app/src/main/webapp/src/models/ProjectModels.ts index edc033d..89daf48 100644 --- a/karavan-app/src/main/webapp/src/models/ProjectModels.ts +++ b/karavan-app/src/main/webapp/src/models/ProjectModels.ts @@ -1,42 +1,33 @@ export class Project { - groupId: string = ''; - artifactId: string = ''; - version: string = ''; - folder: string = ''; - runtime: string = ''; + projectId: string = ''; + name: string = ''; + description: string = ''; lastCommit: string = ''; - - public constructor(groupId: string, artifactId: string, version: string, folder: string, runtime: string, lastCommit: string); + public constructor(projectId: string, name: string, description: string, lastCommit: string); public constructor(init?: Partial<Project>); public constructor(...args: any[]) { if (args.length === 1){ Object.assign(this, args[0]); return; } else { - this.groupId = args[0]; - this.artifactId = args[1]; - this.version = args[2]; - this.folder = args[3]; - this.runtime = args[4]; - this.lastCommit = args[5]; + this.projectId = args[0]; + this.name = args[1]; + this.description = args[2]; + this.lastCommit = args[3]; return; } } - - getKey():string{ - return this.groupId + ":" + this.artifactId + ":" + this.version; - } } export class ProjectFile { name: string = ''; - project: string = ''; + projectId: string = ''; code: string = ''; - constructor(name: string, project: string, code: string) { + constructor(name: string, projectId: string, code: string) { this.name = name; - this.project = project; + this.projectId = projectId; this.code = code; } } diff --git a/karavan-app/src/main/webapp/src/projects/CreateFileModal.tsx b/karavan-app/src/main/webapp/src/projects/CreateFileModal.tsx index bf5edde..efe47c5 100644 --- a/karavan-app/src/main/webapp/src/projects/CreateFileModal.tsx +++ b/karavan-app/src/main/webapp/src/projects/CreateFileModal.tsx @@ -5,7 +5,7 @@ import { FormGroup, ModalVariant, Form, - ToggleGroupItem, ToggleGroup, TextInputGroupMain, ChipGroup, Chip, TextInputGroupUtilities, TextInputGroup, Text + ToggleGroupItem, ToggleGroup, TextInputGroupMain, TextInputGroupUtilities, TextInputGroup, Text } from '@patternfly/react-core'; import '../designer/karavan.css'; import {KaravanApi} from "../api/KaravanApi"; @@ -38,7 +38,7 @@ export class CreateFileModal extends React.Component<Props, State> { const {name, extension} = this.state; const filename = (extension !== 'java') ? CamelUi.nameFromTitle(name) : CamelUi.javaNameFromTitle(name) if (filename && extension){ - const file = new ProjectFile(filename + '.' + extension, this.props.project.getKey(), ''); + const file = new ProjectFile(filename + '.' + extension, this.props.project.projectId, ''); KaravanApi.postProjectFile(file, res => { if (res.status === 200) { console.log(res) //TODO show notification diff --git a/karavan-app/src/main/webapp/src/projects/ProjectPage.tsx b/karavan-app/src/main/webapp/src/projects/ProjectPage.tsx index f874a18..acdf5ae 100644 --- a/karavan-app/src/main/webapp/src/projects/ProjectPage.tsx +++ b/karavan-app/src/main/webapp/src/projects/ProjectPage.tsx @@ -156,7 +156,7 @@ export class ProjectPage extends React.Component<Props, State> { <div> <Breadcrumb> <BreadcrumbItem to="#" - onClick={event => this.setState({file: undefined})}>{"Project: " + this.props.project?.getKey()}</BreadcrumbItem> + onClick={event => this.setState({file: undefined})}>{"Project: " + this.props.project?.projectId}</BreadcrumbItem> <BreadcrumbItem to="#" isActive>{this.getType(file?.name)}</BreadcrumbItem> </Breadcrumb> <TextContent className="title"> @@ -172,12 +172,12 @@ export class ProjectPage extends React.Component<Props, State> { onRefresh = () => { if (this.props.project) { - KaravanApi.getProject(this.props.project.getKey(), (project: Project) => { + KaravanApi.getProject(this.props.project.projectId, (project: Project) => { this.setState({ project: project }) }); - KaravanApi.getFiles(this.props.project.getKey(), (files: []) => { + KaravanApi.getFiles(this.props.project.projectId, (files: []) => { this.setState({ files: files }) @@ -251,27 +251,18 @@ export class ProjectPage extends React.Component<Props, State> { <FlexItem flex={{default: "flex_1"}}> <DescriptionList isHorizontal> <DescriptionListGroup> - <DescriptionListTerm>Group</DescriptionListTerm> - <DescriptionListDescription>{project?.groupId}</DescriptionListDescription> + <DescriptionListTerm>Project ID</DescriptionListTerm> + <DescriptionListDescription>{project?.projectId}</DescriptionListDescription> </DescriptionListGroup> <DescriptionListGroup> - <DescriptionListTerm>Artifact</DescriptionListTerm> - <DescriptionListDescription>{project?.artifactId}</DescriptionListDescription> + <DescriptionListTerm>Name</DescriptionListTerm> + <DescriptionListDescription>{project?.name}</DescriptionListDescription> </DescriptionListGroup> <DescriptionListGroup> - <DescriptionListTerm>Version</DescriptionListTerm> - <DescriptionListDescription>{project?.version}</DescriptionListDescription> - </DescriptionListGroup> - <DescriptionListGroup> - <DescriptionListTerm>Folder</DescriptionListTerm> - <DescriptionListDescription>{project?.folder}</DescriptionListDescription> - </DescriptionListGroup> - <DescriptionListGroup> - <DescriptionListTerm>Runtime</DescriptionListTerm> - <DescriptionListDescription> - <Badge>{project?.runtime}</Badge> - </DescriptionListDescription> + <DescriptionListTerm>Description</DescriptionListTerm> + <DescriptionListDescription>{project?.description}</DescriptionListDescription> </DescriptionListGroup> + </DescriptionList> </FlexItem> <FlexItem flex={{default: "flex_1"}}> diff --git a/karavan-app/src/main/webapp/src/projects/ProjectsPage.tsx b/karavan-app/src/main/webapp/src/projects/ProjectsPage.tsx index c1bc9c3..7f19ac6 100644 --- a/karavan-app/src/main/webapp/src/projects/ProjectsPage.tsx +++ b/karavan-app/src/main/webapp/src/projects/ProjectsPage.tsx @@ -34,9 +34,9 @@ import PlusIcon from '@patternfly/react-icons/dist/esm/icons/plus-icon'; import {Project} from "../models/ProjectModels"; import {TableComposable, Tbody, Td, Th, Thead, Tr} from "@patternfly/react-table"; import DeleteIcon from "@patternfly/react-icons/dist/js/icons/times-icon"; -import {CamelUtil} from "karavan-core/lib/api/CamelUtil"; import SearchIcon from '@patternfly/react-icons/dist/esm/icons/search-icon'; import CopyIcon from "@patternfly/react-icons/dist/esm/icons/copy-icon"; +import {CamelUi} from "../designer/utils/CamelUi"; interface Props { projects: Project[], @@ -53,11 +53,9 @@ interface State { isCopy: boolean, projectToCopy?: Project, filter: string, - groupId: string, - artifactId: string, - version: string, - folder: string, - runtime: string, + name: string, + description: string, + projectId: string, } export class ProjectsPage extends React.Component<Props, State> { @@ -67,11 +65,9 @@ export class ProjectsPage extends React.Component<Props, State> { isCreateModalOpen: false, isCopy: false, filter: '', - groupId: this.props.config.groupId, - artifactId: '', - version: '', - folder: '', - runtime: this.props.config.defaultRuntime, + name: '', + description: '', + projectId: '', }; tools = () => (<Toolbar id="toolbar-group-types"> @@ -97,28 +93,28 @@ export class ProjectsPage extends React.Component<Props, State> { </TextContent>); closeModal = () => { - this.setState({isCreateModalOpen: false, isCopy: false, groupId: this.props.config.groupId, artifactId:'', version: '', folder: '', runtime: this.props.config.defaultRuntime}); + this.setState({isCreateModalOpen: false, isCopy: false, name: this.props.config.groupId, description:'', projectId: ''}); this.props.onRefresh.call(this); } saveAndCloseCreateModal = () => { - const {groupId, artifactId, version, runtime} = this.state; - const p = new Project(groupId, artifactId, version, '', runtime ? runtime : this.props.config.defaultRuntime, ''); + const {name, description, projectId} = this.state; + const p = new Project(projectId, name, description, ''); this.props.onCreate.call(this, p); - this.setState({isCreateModalOpen: false, isCopy: false, groupId: this.props.config.groupId, artifactId: '', version: '', folder: '', runtime: this.props.config.defaultRuntime}); + this.setState({isCreateModalOpen: false, isCopy: false, name: this.props.config.groupId, description: '', projectId: ''}); } onKeyDown = (event: React.KeyboardEvent<HTMLDivElement>): void => { - if (event.key === 'Enter' && this.state.groupId !== undefined && this.state.artifactId !== undefined && this.state.version !== undefined) { + if (event.key === 'Enter' && this.state.name !== undefined && this.state.description !== undefined && this.state.projectId !== undefined) { this.saveAndCloseCreateModal(); } } createModalForm() { - const {runtime, isCopy, projectToCopy } = this.state; + const {isCopy, projectToCopy, projectId, name} = this.state; return ( <Modal - title={!isCopy ? "Create new project" : "Copy project from " + projectToCopy?.artifactId} + title={!isCopy ? "Create new project" : "Copy project from " + projectToCopy?.projectId} variant={ModalVariant.small} isOpen={this.state.isCreateModalOpen} onClose={this.closeModal} @@ -129,27 +125,21 @@ export class ProjectsPage extends React.Component<Props, State> { ]} > <Form isHorizontal={true} autoComplete="off"> - <FormGroup label="GroupId" fieldId="group" isRequired> - <TextInput className="text-field" type="text" id="group" name="group" - value={this.state.groupId} - onChange={e => this.setState({groupId: e})}/> + <FormGroup label="Name" fieldId="name" isRequired> + <TextInput className="text-field" type="text" id="name" name="name" + value={this.state.name} + onChange={e => this.setState({name: e})}/> </FormGroup> - <FormGroup label="ArtifactId" fieldId="artifact" isRequired> - <TextInput className="text-field" type="text" id="artifact" name="artifact" - value={this.state.artifactId} - onChange={e => this.setState({artifactId: e})}/> + <FormGroup label="Description" fieldId="description" isRequired> + <TextInput className="text-field" type="text" id="description" name="description" + value={this.state.description} + onChange={e => this.setState({description: e})}/> </FormGroup> - <FormGroup label="Version" fieldId="version" isRequired> - <TextInput className="text-field" type="text" id="version" name="version" - value={this.state.version} - onChange={e => this.setState({version: e})}/> - </FormGroup> - <FormGroup label="Runtime" fieldId="runtime" isRequired> - <ToggleGroup aria-label="Runtime"> - {["QUARKUS", "SPRING"].map(value => - <ToggleGroupItem key={value} text={CamelUtil.capitalizeName(value.toLowerCase())} buttonId={value} isSelected={runtime === value} onChange={selected => this.setState({runtime: value})} /> - )} - </ToggleGroup> + <FormGroup label="Project ID" fieldId="projectId" isRequired helperText="Unique project name"> + <TextInput className="text-field" type="text" id="projectId" name="projectId" + value={this.state.projectId} + onFocus={e => this.setState({projectId : projectId === '' ? CamelUi.nameFromTitle(name) : projectId})} + onChange={e => this.setState({projectId: CamelUi.nameFromTitle(e)})}/> </FormGroup> </Form> </Modal> @@ -157,7 +147,7 @@ export class ProjectsPage extends React.Component<Props, State> { } render() { - const projects = this.state.projects.filter(p => p.groupId.includes(this.state.filter) || p.artifactId.includes(this.state.filter)); + const projects = this.state.projects.filter(p => p.name.includes(this.state.filter) || p.description.includes(this.state.filter)); const environments: string[] = this.props.config.environments && Array.isArray(this.props.config.environments) ? Array.from(this.props.config.environments) : []; @@ -171,9 +161,9 @@ export class ProjectsPage extends React.Component<Props, State> { <Thead> <Tr> <Th key='type'>Runtime</Th> - <Th key='group'>GroupId</Th> - <Th key='artifact'>ArtifactId</Th> - <Th key='version'>Version</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'>Deployment</Th> <Th key='action'></Th> @@ -181,17 +171,17 @@ export class ProjectsPage extends React.Component<Props, State> { </Thead> <Tbody> {projects.map(project => ( - <Tr key={project.artifactId}> + <Tr key={project.projectId}> <Td modifier={"fitContent"}> - <Badge className="runtime-badge">{project.runtime}</Badge> + <Badge className="runtime-badge">{this.props.config.runtime}</Badge> </Td> - <Td>{project.groupId}</Td> <Td> <Button style={{padding: '6px'}} variant={"link"} onClick={e=>this.props.onSelect?.call(this, project)}> - {project.artifactId} + {project.projectId} </Button> </Td> - <Td>{project.version}</Td> + <Td>{project.name}</Td> + <Td>{project.description}</Td> <Td isActionCell> <Tooltip content={project.lastCommit} position={"bottom"}> <Badge>{project.lastCommit?.substr(0, 7)}</Badge> diff --git a/karavan-designer/src/builder/PropertiesTable.tsx b/karavan-designer/src/builder/PropertiesTable.tsx index 27d5a88..f59cec6 100644 --- a/karavan-designer/src/builder/PropertiesTable.tsx +++ b/karavan-designer/src/builder/PropertiesTable.tsx @@ -100,7 +100,7 @@ export class PropertiesTable extends React.Component<Props, State> { </Thead> <Tbody> {properties.map((property, idx: number) => { - const readOnly = ["camel.jbang.gav", "camel.jbang.runtime"].includes(property.key); + const readOnly = property.key.startsWith("camel.jbang"); return ( <Tr key={property.id}> <Td noPadding width={20} dataLabel="key">{this.getTextInputField(property, "key", readOnly)}</Td>