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/28 17:35:59 UTC

[camel-karavan] 03/10: ProjectFiles last update timestamp

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 c6342026df17638da3f9a26b0237f775f29ddf09
Author: Marat Gubaidullin <ma...@gmail.com>
AuthorDate: Sat Nov 19 14:15:07 2022 -0500

    ProjectFiles last update timestamp
---
 .../apache/camel/karavan/api/ProjectFileResource.java   |  3 ++-
 .../org/apache/camel/karavan/model/ProjectFile.java     | 15 ++++++++++++++-
 .../org/apache/camel/karavan/service/ImportService.java |  7 ++++---
 .../apache/camel/karavan/service/InfinispanService.java | 11 +++++++++--
 .../src/main/webui/src/projects/CreateFileModal.tsx     |  2 +-
 .../src/main/webui/src/projects/ProjectFilesTable.tsx   | 17 +++++++++++++++--
 karavan-app/src/main/webui/src/projects/ProjectInfo.tsx |  5 +++--
 .../src/main/webui/src/projects/ProjectModels.ts        |  4 +++-
 karavan-app/src/main/webui/src/projects/ProjectPage.tsx |  6 +++---
 karavan-app/src/main/webui/src/projects/UploadModal.tsx |  2 +-
 10 files changed, 55 insertions(+), 17 deletions(-)

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 b1b48ed..5069200 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
@@ -32,6 +32,7 @@ import javax.ws.rs.Produces;
 import javax.ws.rs.core.MediaType;
 import java.net.URLDecoder;
 import java.nio.charset.StandardCharsets;
+import java.time.Instant;
 import java.util.List;
 
 @Path("/api/file")
@@ -82,7 +83,7 @@ public class ProjectFileResource {
         infinispanService.saveProjectFile(file);
         if (generateRest) {
             String yaml = codeService.generate(file.getName(), file.getCode(), generateRoutes);
-            ProjectFile integration = new ProjectFile(integrationName, yaml, file.getProjectId());
+            ProjectFile integration = new ProjectFile(integrationName, yaml, file.getProjectId(), Instant.now().toEpochMilli());
             infinispanService.saveProjectFile(integration);
             return file;
         }
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 30bb0fe..6732b91 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
@@ -4,6 +4,8 @@ import org.infinispan.protostream.annotations.ProtoDoc;
 import org.infinispan.protostream.annotations.ProtoFactory;
 import org.infinispan.protostream.annotations.ProtoField;
 
+import java.time.Instant;
+
 public class ProjectFile {
     public static final String CACHE = "project_files";
     @ProtoField(number = 1)
@@ -13,12 +15,15 @@ public class ProjectFile {
     @ProtoField(number = 3)
     @ProtoDoc("@Field(index=Index.YES, analyze = Analyze.YES, store = Store.NO)")
     String projectId;
+    @ProtoField(number = 4)
+    Long lastUpdate;
 
     @ProtoFactory
-    public ProjectFile(String name, String code, String projectId) {
+    public ProjectFile(String name, String code, String projectId, Long lastUpdate) {
         this.name = name;
         this.code = code;
         this.projectId = projectId;
+        this.lastUpdate = lastUpdate;
     }
 
     public ProjectFile() {
@@ -47,4 +52,12 @@ public class ProjectFile {
     public void setProjectId(String projectId) {
         this.projectId = projectId;
     }
+
+    public Long getLastUpdate() {
+        return lastUpdate;
+    }
+
+    public void setLastUpdate(Long lastUpdate) {
+        this.lastUpdate = lastUpdate;
+    }
 }
diff --git a/karavan-app/src/main/java/org/apache/camel/karavan/service/ImportService.java b/karavan-app/src/main/java/org/apache/camel/karavan/service/ImportService.java
index 05cbe5d..e59d423 100644
--- a/karavan-app/src/main/java/org/apache/camel/karavan/service/ImportService.java
+++ b/karavan-app/src/main/java/org/apache/camel/karavan/service/ImportService.java
@@ -25,6 +25,7 @@ import org.jboss.logging.Logger;
 
 import javax.enterprise.context.ApplicationScoped;
 import javax.inject.Inject;
+import java.time.Instant;
 import java.util.Arrays;
 import java.util.List;
 import java.util.Map;
@@ -67,7 +68,7 @@ public class ImportService {
                 infinispanService.saveProject(project, true);
 
                 p.getItem2().forEach((key, value) -> {
-                    ProjectFile file = new ProjectFile(key, value, folderName);
+                    ProjectFile file = new ProjectFile(key, value, folderName, Instant.now().toEpochMilli());
                     infinispanService.saveProjectFile(file);
                 });
             });
@@ -87,7 +88,7 @@ public class ImportService {
                 infinispanService.saveProject(templates, true);
 
                 codeService.getApplicationPropertiesTemplates().forEach((name, value) -> {
-                    ProjectFile file = new ProjectFile(name, value, Project.NAME_TEMPLATES);
+                    ProjectFile file = new ProjectFile(name, value, Project.NAME_TEMPLATES, Instant.now().toEpochMilli());
                     infinispanService.saveProjectFile(file);
                 });
             }
@@ -109,7 +110,7 @@ public class ImportService {
                 repo.forEach(p -> {
                     String name = p.getItem1();
                     String yaml = p.getItem2();
-                    ProjectFile file = new ProjectFile(name, yaml, Project.NAME_KAMELETS);
+                    ProjectFile file = new ProjectFile(name, yaml, Project.NAME_KAMELETS, Instant.now().toEpochMilli());
                     infinispanService.saveProjectFile(file);
                 });
             }
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 b7ae729..adc641e 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
@@ -41,6 +41,8 @@ import org.jboss.logging.Logger;
 
 import javax.enterprise.context.ApplicationScoped;
 import javax.inject.Inject;
+import java.time.Instant;
+import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
 import java.util.stream.Collectors;
@@ -127,7 +129,7 @@ public class InfinispanService {
         if (isNew && !imported){
             String filename = "application.properties";
             String code = codeService.getApplicationProperties(project);
-            files.put(new GroupedKey(project.getProjectId(), filename), new ProjectFile(filename, code, project.getProjectId()));
+            files.put(new GroupedKey(project.getProjectId(), filename), new ProjectFile(filename, code, project.getProjectId(), Instant.now().toEpochMilli()));
         }
     }
 
@@ -144,11 +146,16 @@ public class InfinispanService {
         }
     }
     public void saveProjectFile(ProjectFile file) {
+        file.setLastUpdate(Instant.now().toEpochMilli());
         files.put(GroupedKey.create(file.getProjectId(), file.getName()), file);
     }
 
     public void saveProjectFiles(Map<GroupedKey, ProjectFile> f) {
-        files.putAll(f);
+        Map<GroupedKey, ProjectFile> files = new HashMap<>(f.size());
+        f.forEach((groupedKey, projectFile) -> {
+            projectFile.setLastUpdate(Instant.now().toEpochMilli());
+        });
+        files.putAll(files);
     }
 
     public void deleteProject(String project) {
diff --git a/karavan-app/src/main/webui/src/projects/CreateFileModal.tsx b/karavan-app/src/main/webui/src/projects/CreateFileModal.tsx
index 47d7cda..dd37da8 100644
--- a/karavan-app/src/main/webui/src/projects/CreateFileModal.tsx
+++ b/karavan-app/src/main/webui/src/projects/CreateFileModal.tsx
@@ -45,7 +45,7 @@ export class CreateFileModal extends React.Component<Props, State> {
             ? CamelDefinitionYaml.integrationToYaml(Integration.createNew(name, 'plain'))
             : '';
         if (filename && extension){
-            const file = new ProjectFile(filename + '.' + extension, this.props.project.projectId, code);
+            const file = new ProjectFile(filename + '.' + extension, this.props.project.projectId, code, Date.now());
             KaravanApi.postProjectFile(file, res => {
                 if (res.status === 200) {
                     // console.log(res) //TODO show notification
diff --git a/karavan-app/src/main/webui/src/projects/ProjectFilesTable.tsx b/karavan-app/src/main/webui/src/projects/ProjectFilesTable.tsx
index f1269e4..e185ae6 100644
--- a/karavan-app/src/main/webui/src/projects/ProjectFilesTable.tsx
+++ b/karavan-app/src/main/webui/src/projects/ProjectFilesTable.tsx
@@ -60,14 +60,24 @@ export class ProjectFilesTable extends React.Component<Props, State> {
 
     public state: State = {};
 
+    getDate(lastUpdate: number):string {
+        if (lastUpdate) {
+            const date = new Date(lastUpdate);
+            return date.toDateString() + ' ' + date.toLocaleTimeString();
+        } else {
+            return "N/A"
+        }
+    }
+
     render() {
         const {files, onOpenDeleteConfirmation, onSelect} = this.props;
         return (
             <TableComposable aria-label="Files" variant={"compact"} className={"table"}>
                 <Thead>
                     <Tr>
-                        <Th key='type' width={10}>Type</Th>
-                        <Th key='filename' width={50}>Filename</Th>
+                        <Th key='type' width={20}>Type</Th>
+                        <Th key='filename' width={40}>Filename</Th>
+                        <Th key='lastUpdate' width={30}>Updated</Th>
                         <Th key='action'></Th>
                     </Tr>
                 </Thead>
@@ -84,6 +94,9 @@ export class ProjectFilesTable extends React.Component<Props, State> {
                                     {file.name}
                                 </Button>
                             </Td>
+                            <Td>
+                                {this.getDate(file.lastUpdate)}
+                            </Td>
                             <Td modifier={"fitContent"}>
                                 {file.projectId !== 'templates' &&
                                     <Button style={{padding: '0'}} variant={"plain"}
diff --git a/karavan-app/src/main/webui/src/projects/ProjectInfo.tsx b/karavan-app/src/main/webui/src/projects/ProjectInfo.tsx
index 79df4ca..91aa2a9 100644
--- a/karavan-app/src/main/webui/src/projects/ProjectInfo.tsx
+++ b/karavan-app/src/main/webui/src/projects/ProjectInfo.tsx
@@ -7,7 +7,7 @@ import {
     DescriptionListGroup,
     DescriptionListDescription,
     Card,
-    CardBody, Spinner, Tooltip, Flex, FlexItem, Divider, LabelGroup, Label, Modal
+    CardBody, Spinner, Tooltip, Flex, FlexItem, Divider, LabelGroup, Label, Modal, GridItem, Grid
 } from '@patternfly/react-core';
 import '../designer/karavan.css';
 import {KaravanApi} from "../api/KaravanApi";
@@ -417,6 +417,7 @@ export class ProjectInfo extends React.Component<Props, State> {
         return (
             <Card className="project-info">
                 <CardBody>
+
                     <Flex direction={{default: "row"}}
                           style={{height: "200px"}}
                           justifyContent={{default: "justifyContentSpaceBetween"}}>
@@ -424,7 +425,7 @@ export class ProjectInfo extends React.Component<Props, State> {
                             {this.getProjectDescription()}
                         </FlexItem>
                         <Divider orientation={{default: "vertical"}}/>
-                        <FlexItem flex={{default: "flex_1"}}>
+                        <FlexItem flex={{default: "flex_2"}}>
                             {this.getEnvPanel("dev")}
                         </FlexItem>
                     </Flex>
diff --git a/karavan-app/src/main/webui/src/projects/ProjectModels.ts b/karavan-app/src/main/webui/src/projects/ProjectModels.ts
index 5764869..f7e8db0 100644
--- a/karavan-app/src/main/webui/src/projects/ProjectModels.ts
+++ b/karavan-app/src/main/webui/src/projects/ProjectModels.ts
@@ -75,11 +75,13 @@ export class ProjectFile {
     name: string = '';
     projectId: string = '';
     code: string = '';
+    lastUpdate: number;
 
-    constructor(name: string, projectId: string, code: string) {
+    constructor(name: string, projectId: string, code: string, lastUpdate: number) {
         this.name = name;
         this.projectId = projectId;
         this.code = code;
+        this.lastUpdate = lastUpdate;
     }
 }
 
diff --git a/karavan-app/src/main/webui/src/projects/ProjectPage.tsx b/karavan-app/src/main/webui/src/projects/ProjectPage.tsx
index f19e053..01cdbe0 100644
--- a/karavan-app/src/main/webui/src/projects/ProjectPage.tsx
+++ b/karavan-app/src/main/webui/src/projects/ProjectPage.tsx
@@ -272,15 +272,15 @@ export class ProjectPage extends React.Component<Props, State> {
     showLogs = (type: 'container' | 'pipeline', name: string, environment: string) => {
         const filename = name + ".log";
         const code = '';
-        this.setState({file: new ProjectFile(filename, this.props.project.projectId, code)});
+        this.setState({file: new ProjectFile(filename, this.props.project.projectId, code, Date.now())});
         if (type === 'pipeline') {
             KaravanApi.getPipelineLog(environment, name, (res: any) => {
                 if (Array.isArray(res) && Array.from(res).length > 0)
-                    this.setState({file: new ProjectFile(filename, this.props.project.projectId, res.at(0).log)});
+                    this.setState({file: new ProjectFile(filename, this.props.project.projectId, res.at(0).log, Date.now())});
             });
         } else if (type === 'container') {
             KaravanApi.getContainerLog(environment, name, (res: any) => {
-                this.setState({file: new ProjectFile(filename, this.props.project.projectId, res)});
+                this.setState({file: new ProjectFile(filename, this.props.project.projectId, res, Date.now())});
             });
         }
 
diff --git a/karavan-app/src/main/webui/src/projects/UploadModal.tsx b/karavan-app/src/main/webui/src/projects/UploadModal.tsx
index 7fb778a..fae83f8 100644
--- a/karavan-app/src/main/webui/src/projects/UploadModal.tsx
+++ b/karavan-app/src/main/webui/src/projects/UploadModal.tsx
@@ -43,7 +43,7 @@ export class UploadModal extends React.Component<Props, State> {
 
     saveAndCloseModal = () => {
         const state = this.state;
-        const file = new ProjectFile(state.filename, this.props.projectId, state.data);
+        const file = new ProjectFile(state.filename, this.props.projectId, state.data, Date.now());
         if (this.state.type === "integration"){
             KaravanApi.postProjectFile(file, res => {
                 if (res.status === 200) {