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 dbfcf4fcd9fcc09feae646c86bbdbd044d6b78ff Author: Marat Gubaidullin <[email protected]> AuthorDate: Mon Dec 4 18:08:23 2023 -0500 Fix #934 --- .../camel/karavan/api/ProjectGitResource.java | 17 +++++-- .../org/apache/camel/karavan/git/GitService.java | 9 +--- .../camel/karavan/service/ProjectService.java | 22 ++++----- .../src/main/webui/src/api/KaravanApi.tsx | 10 ++-- .../src/main/webui/src/api/ProjectService.ts | 19 +++++++- .../src/main/webui/src/api/ProjectStore.ts | 2 + .../main/webui/src/project/files/FilesToolbar.tsx | 53 ++++++++++++++++++++-- 7 files changed, 100 insertions(+), 32 deletions(-) diff --git a/karavan-web/karavan-app/src/main/java/org/apache/camel/karavan/api/ProjectGitResource.java b/karavan-web/karavan-app/src/main/java/org/apache/camel/karavan/api/ProjectGitResource.java index 948b88a2..efcdfbff 100644 --- a/karavan-web/karavan-app/src/main/java/org/apache/camel/karavan/api/ProjectGitResource.java +++ b/karavan-web/karavan-app/src/main/java/org/apache/camel/karavan/api/ProjectGitResource.java @@ -19,14 +19,18 @@ package org.apache.camel.karavan.api; import jakarta.inject.Inject; import jakarta.ws.rs.*; import jakarta.ws.rs.core.MediaType; +import jakarta.ws.rs.core.Response; import org.apache.camel.karavan.infinispan.model.Project; import org.apache.camel.karavan.service.ProjectService; +import org.jboss.logging.Logger; import java.util.HashMap; @Path("/api/git") public class ProjectGitResource { + private static final Logger LOGGER = Logger.getLogger(ProjectGitResource.class.getName()); + @Inject ProjectService projectService; @@ -37,11 +41,18 @@ public class ProjectGitResource { return projectService.commitAndPushProject(params.get("projectId"), params.get("message")); } - @GET + @PUT @Produces(MediaType.APPLICATION_JSON) @Consumes(MediaType.APPLICATION_JSON) @Path("/{projectId}") - public Project pull(@PathParam("projectId") String projectId) throws Exception { - return projectService.importProject(projectId); + public Response pull(@PathParam("projectId") String projectId) { + try { + projectService.importProject(projectId); + return Response.ok().build(); + } catch (Exception e) { + LOGGER.error(e.getMessage()); + return Response.serverError().entity(e.getMessage()).build(); + } + } } \ No newline at end of file diff --git a/karavan-web/karavan-app/src/main/java/org/apache/camel/karavan/git/GitService.java b/karavan-web/karavan-app/src/main/java/org/apache/camel/karavan/git/GitService.java index 010750a2..779e0edb 100644 --- a/karavan-web/karavan-app/src/main/java/org/apache/camel/karavan/git/GitService.java +++ b/karavan-web/karavan-app/src/main/java/org/apache/camel/karavan/git/GitService.java @@ -166,13 +166,8 @@ public class GitService { return new ArrayList<>(0); } - public GitRepo readProjectFromRepository(String projectId) { - Git git = null; - try { - git = getGit(true, vertx.fileSystem().createTempDirectoryBlocking(UUID.randomUUID().toString())); - } catch (Exception e) { - LOGGER.error("Error", e); - } + public GitRepo readProjectFromRepository(String projectId) throws GitAPIException, IOException, URISyntaxException { + Git git = getGit(true, vertx.fileSystem().createTempDirectoryBlocking(UUID.randomUUID().toString())); return readProjectsFromRepository(git, projectId).get(0); } diff --git a/karavan-web/karavan-app/src/main/java/org/apache/camel/karavan/service/ProjectService.java b/karavan-web/karavan-app/src/main/java/org/apache/camel/karavan/service/ProjectService.java index fca9c3c1..eeeb6c08 100644 --- a/karavan-web/karavan-app/src/main/java/org/apache/camel/karavan/service/ProjectService.java +++ b/karavan-web/karavan-app/src/main/java/org/apache/camel/karavan/service/ProjectService.java @@ -288,15 +288,10 @@ public class ProjectService implements HealthCheck { } } - public Project importProject(String projectId) { + public Project importProject(String projectId) throws Exception { LOGGER.info("Import project from Git " + projectId); - try { - GitRepo repo = gitService.readProjectFromRepository(projectId); - return importProjectFromRepo(repo); - } catch (Exception e) { - LOGGER.error("Error during project import", e); - return null; - } + GitRepo repo = gitService.readProjectFromRepository(projectId); + return importProjectFromRepo(repo); } private Project importProjectFromRepo(GitRepo repo) { @@ -318,9 +313,14 @@ public class ProjectService implements HealthCheck { public Project getProjectFromRepo(GitRepo repo) { String folderName = repo.getName(); String propertiesFile = codeService.getPropertiesFile(repo); - String projectName = codeService.getProjectName(propertiesFile); - String projectDescription = codeService.getProjectDescription(propertiesFile); - return new Project(folderName, projectName, projectDescription, repo.getCommitId(), repo.getLastCommitTimestamp()); + if (propertiesFile != null) { + String projectName = codeService.getProjectName(propertiesFile); + String projectDescription = codeService.getProjectDescription(propertiesFile); + return new Project(folderName, projectName, projectDescription, repo.getCommitId(), repo.getLastCommitTimestamp()); + } else { + return new Project(folderName, folderName, folderName, repo.getCommitId(), repo.getLastCommitTimestamp()); + } + } public Project commitAndPushProject(String projectId, String message) throws Exception { diff --git a/karavan-web/karavan-app/src/main/webui/src/api/KaravanApi.tsx b/karavan-web/karavan-app/src/main/webui/src/api/KaravanApi.tsx index 8f584d93..00b3441f 100644 --- a/karavan-web/karavan-app/src/main/webui/src/api/KaravanApi.tsx +++ b/karavan-web/karavan-app/src/main/webui/src/api/KaravanApi.tsx @@ -294,14 +294,12 @@ export class KaravanApi { }); } - static async pull(projectId: string, after: (res: AxiosResponse<any>) => void) { - instance.get('/api/git/' + projectId) + static async pull(projectId: string, after: (res: AxiosResponse<any> | any) => void) { + instance.put('/api/git/' + projectId) .then(res => { - if (res.status === 200) { - after(res.data); - } + after(res); }).catch(err => { - console.log(err); + after(err); }); } diff --git a/karavan-web/karavan-app/src/main/webui/src/api/ProjectService.ts b/karavan-web/karavan-app/src/main/webui/src/api/ProjectService.ts index 3c1588bc..11f4d89b 100644 --- a/karavan-web/karavan-app/src/main/webui/src/api/ProjectService.ts +++ b/karavan-web/karavan-app/src/main/webui/src/api/ProjectService.ts @@ -127,15 +127,30 @@ export class ProjectService { }; KaravanApi.push(params, res => { if (res.status === 200 || res.status === 201) { - useProjectStore.setState({isPushing: false}) ProjectService.refreshProject(project.projectId); ProjectService.refreshProjectData(project.projectId); } else { - // Todo notification + EventBus.sendAlert("Error pushing", (res as any)?.response?.data, 'danger') } + useProjectStore.setState({isPushing: false}) }); } + public static pullProject(projectId: string) { + useProjectStore.setState({isPulling: true}) + KaravanApi.pull(projectId, res => { + console.log(res); + if (res.status === 200 || res.status === 201) { + useProjectStore.setState({isPulling: false}) + ProjectService.refreshProject(projectId); + ProjectService.refreshProjectData(projectId); + } else { + EventBus.sendAlert("Error pulling", (res as any)?.response?.data, 'danger') + } + useProjectStore.setState({isPulling: false}) + }); + } + public static reloadKamelets() { KaravanApi.getKamelets(yamls => { const kamelets: string[] = []; diff --git a/karavan-web/karavan-app/src/main/webui/src/api/ProjectStore.ts b/karavan-web/karavan-app/src/main/webui/src/api/ProjectStore.ts index 23d90b90..02a65dd0 100644 --- a/karavan-web/karavan-app/src/main/webui/src/api/ProjectStore.ts +++ b/karavan-web/karavan-app/src/main/webui/src/api/ProjectStore.ts @@ -107,6 +107,7 @@ export const useProjectsStore = createWithEqualityFn<ProjectsState>((set) => ({ }), shallow) interface ProjectState { + isPulling: boolean, isPushing: boolean, isRunning: boolean, images: string [], @@ -131,6 +132,7 @@ export const useProjectStore = createWithEqualityFn<ProjectState>((set) => ({ operation: 'none', tabIndex: 'files', isPushing: false, + isPulling: false, isRunning: false, setProject: (project: Project, operation: "create" | "select" | "delete"| "none" | "copy") => { set((state: ProjectState) => ({ diff --git a/karavan-web/karavan-app/src/main/webui/src/project/files/FilesToolbar.tsx b/karavan-web/karavan-app/src/main/webui/src/project/files/FilesToolbar.tsx index 9acb08b9..2b22b917 100644 --- a/karavan-web/karavan-app/src/main/webui/src/project/files/FilesToolbar.tsx +++ b/karavan-web/karavan-app/src/main/webui/src/project/files/FilesToolbar.tsx @@ -16,6 +16,7 @@ */ import React, {useEffect, useState} from 'react'; import { + Alert, Button, Flex, FlexItem, @@ -41,8 +42,9 @@ import RefreshIcon from "@patternfly/react-icons/dist/esm/icons/sync-alt-icon"; export function FileToolbar () { const [commitMessageIsOpen, setCommitMessageIsOpen] = useState(false); + const [pullIsOpen, setPullIsOpen] = useState(false); const [commitMessage, setCommitMessage] = useState(''); - const [project, isPushing] = useProjectStore((state) => [state.project, state.isPushing], shallow ) + const [project, isPushing, isPulling] = useProjectStore((s) => [s.project, s.isPushing, s.isPulling], shallow ) const {files} = useFilesStore(); const [file, editAdvancedProperties, setEditAdvancedProperties, setAddProperty, setFile] = useFileStore((s) => [s.file, s.editAdvancedProperties, s.setEditAdvancedProperties, s.setAddProperty, s.setFile], shallow ) @@ -56,6 +58,11 @@ export function FileToolbar () { ProjectService.pushProject(project, commitMessage); } + function pull () { + setPullIsOpen(false); + ProjectService.pullProject(project.projectId); + } + function canAddFiles(): boolean { return !['templates', 'services'].includes(project.projectId); } @@ -63,12 +70,12 @@ export function FileToolbar () { function getCommitModal() { return ( <Modal - title="Commit" + title="Commit and push" variant={ModalVariant.small} isOpen={commitMessageIsOpen} onClose={() => setCommitMessageIsOpen(false)} actions={[ - <Button key="confirm" variant="primary" onClick={() => push()}>Save</Button>, + <Button key="confirm" variant="primary" onClick={() => push()}>Commit and push</Button>, <Button key="cancel" variant="secondary" onClick={() => setCommitMessageIsOpen(false)}>Cancel</Button> ]} > @@ -82,6 +89,30 @@ export function FileToolbar () { ) } + function getPullModal() { + return ( + <Modal + title="Pull" + titleIconVariant={"danger"} + variant={ModalVariant.small} + isOpen={pullIsOpen} + onClose={() => setPullIsOpen(false)} + actions={[ + <Button key="confirm" variant="danger" isDanger onClick={() => pull()}>Pull</Button>, + <Button key="cancel" variant="primary" onClick={() => setPullIsOpen(false)}>Cancel</Button> + ]} + > + <div> + <Alert customIcon={<PushIcon />} + isInline + variant="danger" + title="Pulling code from git rewrites all non-commited code in the project!" + /> + </div> + </Modal> + ) + } + function needCommit(): boolean { return project ? files.filter(f => f.lastUpdate > project.lastCommitTimestamp).length > 0 : false; } @@ -137,6 +168,21 @@ export function FileToolbar () { </Tooltip> </FlexItem>} <FlexItem>{getLastUpdatePanel()}</FlexItem> + <FlexItem> + <Tooltip content="Pull from git" position={"bottom-end"}> + <Button isLoading={isPulling ? true : undefined} + size="sm" + variant={"secondary"} + isDanger + className="project-button" + icon={!isPulling ? <PushIcon/> : <div></div>} + onClick={() => { + setPullIsOpen(true); + }}> + {isPulling ? "..." : "Pull"} + </Button> + </Tooltip> + </FlexItem> <FlexItem> <Tooltip content="Commit and push to git" position={"bottom-end"}> <Button isLoading={isPushing ? true : undefined} @@ -161,5 +207,6 @@ export function FileToolbar () { onClick={e => setFile("upload")}>Upload</Button> </FlexItem>} {getCommitModal()} + {getPullModal()} </Flex> }
