diff --git a/src/main/java/com/gw/web/ResultBrowserController.java b/src/main/java/com/gw/web/ResultBrowserController.java new file mode 100644 index 000000000..2240391a8 --- /dev/null +++ b/src/main/java/com/gw/web/ResultBrowserController.java @@ -0,0 +1,60 @@ +package com.gw.web; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.core.io.Resource; +import org.springframework.core.io.UrlResource; +import org.springframework.http.HttpHeaders; +import org.springframework.http.ResponseEntity; +import org.springframework.stereotype.Controller; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.ResponseBody; + +import com.gw.utils.BaseTool; + +import java.io.IOException; +import java.net.MalformedURLException; +import java.nio.file.*; +import java.util.stream.Collectors; +import java.util.List; + +@Controller +public class ResultBrowserController { + + @Autowired BaseTool bt; + + // Inject the directory path from application.properties + + // Endpoint to list image files in the directory + @GetMapping("/results") + @ResponseBody + public List listImageFiles() throws IOException { + String resultfolder = bt.getFileTransferFolder(); + Path rootLocation = Paths.get(resultfolder); + return Files.walk(rootLocation, 1) // 1: only files in the current folder + .filter(Files::isRegularFile) + .map(path -> path.getFileName().toString()) // Return file names + .collect(Collectors.toList()); + } + + // Endpoint to serve images by filename + @GetMapping("/results/{filename:.+}") + @ResponseBody + public ResponseEntity serveFile(@PathVariable String filename) { + try { + String resultfolder = bt.getFileTransferFolder(); + Path file = Paths.get(resultfolder).resolve(filename); + Resource resource = new UrlResource(file.toUri()); + if (resource.exists() || resource.isReadable()) { + return ResponseEntity.ok() + .header(HttpHeaders.CONTENT_DISPOSITION, + "inline; filename=\"" + filename + "\"") + .body(resource); + } else { + throw new RuntimeException("Could not read file: " + filename); + } + } catch (MalformedURLException e) { + throw new RuntimeException("Could not read file: " + filename, e); + } + } +} diff --git a/src/main/resources/static/css/main.css b/src/main/resources/static/css/main.css index 2e16b4644..90295a4a8 100644 --- a/src/main/resources/static/css/main.css +++ b/src/main/resources/static/css/main.css @@ -430,4 +430,46 @@ form .progress { transform: translateX(-50%); cursor: pointer; -} \ No newline at end of file +} + +.result-full-height { + height: calc(100%-20px); +} +#result-left-panel { + height: 100%; /* Full height within the parent */ + overflow-y: auto; /* Scrollable when content overflows */ +} +#result-file-list { + max-height: 100vh; /* Limit the height to viewport height */ + overflow-y: auto; /* Scrollable */ + padding: 0; +} +.result-list-group-item { + cursor: pointer; + transition: background-color 0.2s, color 0.2s; +} +.result-list-group-item:hover { + background-color: #007bff; + color: #fff; +} +.result-card { + border-radius: 0.5rem; +} +.result-card-body { + padding: 1.25rem; +} +.result-dark-theme { + background-color: #343a40; + color: #f8f9fa; +} +.result-dark-theme .card { + background-color: #495057; + border: 1px solid #6c757d; +} +.result-dark-theme .list-group-item { + background-color: #495057; + border-color: #6c757d; +} +.result-dark-theme .list-group-item:hover { + background-color: #6c757d; +} diff --git a/src/main/resources/static/js/gw.main.js b/src/main/resources/static/js/gw.main.js index f48773292..df0834eee 100644 --- a/src/main/resources/static/js/gw.main.js +++ b/src/main/resources/static/js/gw.main.js @@ -92,6 +92,8 @@ GW.main = { GW.menu.init(); + GW.result.browser.init(); + //session id is a server side thing and it is not reasonable to get it on the client // var current_jssessionid = GW.main.getJSessionId(); diff --git a/src/main/resources/static/js/gw.result.browser.js b/src/main/resources/static/js/gw.result.browser.js new file mode 100644 index 000000000..194dbad13 --- /dev/null +++ b/src/main/resources/static/js/gw.result.browser.js @@ -0,0 +1,59 @@ + +GW.result.browser = { + + init: function () { + + GW.result.browser.loadFileList(); + + }, + + loadFileList: function() { + $.ajax({ + url: '/Geoweaver/results', + method: 'GET', + success: function(data) { + // Populate the file list + $('#result-file-list').empty(); + data.forEach(function(filename) { + $('#result-file-list').append(` +
  • ${filename}
  • + `); + }); + + // Add click event to each file item + $('.file-item').click(function() { + let selectedFile = $(this).data('filename'); + GW.result.browser.previewFile(selectedFile); + }); + }, + error: function(err) { + console.error("Error fetching file list", err); + } + }); + }, + + previewFile: function(filename) { + // Determine if file is an image or text based on file extension + const isImage = /\.(jpg|jpeg|png|gif)$/.test(filename); + + if (isImage) { + // Display image + $('#image-preview').attr('src', `/Geoweaver/results/${filename}`).show(); + $('#text-preview').hide(); + } else { + // Display text content + $.ajax({ + url: `/Geoweaver/results/${filename}`, + method: 'GET', + success: function(data) { + $('#text-preview').text(data).show(); + $('#image-preview').hide(); + }, + error: function(err) { + console.error("Error fetching file content", err); + } + }); + } + } + +} diff --git a/src/main/resources/templates/fragments/config/scripts.html b/src/main/resources/templates/fragments/config/scripts.html index 0f9ed8cd9..ceab3ad30 100644 --- a/src/main/resources/templates/fragments/config/scripts.html +++ b/src/main/resources/templates/fragments/config/scripts.html @@ -32,6 +32,7 @@ + \ No newline at end of file diff --git a/src/main/resources/templates/fragments/content/workspace.html b/src/main/resources/templates/fragments/content/workspace.html index 231b16eb2..54ce1833a 100644 --- a/src/main/resources/templates/fragments/content/workspace.html +++ b/src/main/resources/templates/fragments/content/workspace.html @@ -20,6 +20,9 @@
    + +
    +

    Please select a host on the left panel or a new host!

    diff --git a/src/main/resources/templates/fragments/content/workspace/result-browser.html b/src/main/resources/templates/fragments/content/workspace/result-browser.html new file mode 100644 index 000000000..3b832c901 --- /dev/null +++ b/src/main/resources/templates/fragments/content/workspace/result-browser.html @@ -0,0 +1,26 @@ + +
    +
    +
    +
    + +
    +
      + + +
    +
    + + +
    +
    +
    + + +
    +
    +
    +
    +
    +
    +
    diff --git a/src/main/resources/templates/fragments/content/workspace/top-menu-bar.html b/src/main/resources/templates/fragments/content/workspace/top-menu-bar.html index b342b8314..3dc2c63a9 100644 --- a/src/main/resources/templates/fragments/content/workspace/top-menu-bar.html +++ b/src/main/resources/templates/fragments/content/workspace/top-menu-bar.html @@ -5,6 +5,9 @@ +