diff --git a/apps/dashboard/app/controllers/concerns/pathable.rb b/apps/dashboard/app/controllers/concerns/directory_utils_concern.rb
similarity index 59%
rename from apps/dashboard/app/controllers/concerns/pathable.rb
rename to apps/dashboard/app/controllers/concerns/directory_utils_concern.rb
index 57947dcea..834d2bb8f 100644
--- a/apps/dashboard/app/controllers/concerns/pathable.rb
+++ b/apps/dashboard/app/controllers/concerns/directory_utils_concern.rb
@@ -1,4 +1,12 @@
-module Pathable
+module DirectoryUtilsConcern
+ # Constants for sorting
+ ASCENDING = true
+ DESCENDING = false
+ # Constants for grouping
+ DIRECTORIES = true
+ FILES = false
+ DEFAULT_SORTING_PARAMS = { col: 'name', direction: ASCENDING, grouped?: true }
+
extend ActiveSupport::Concern
def normalized_path(path)
@@ -33,10 +41,41 @@ def validate_path!
end
end
+ def set_sorting_params(parameters)
+ @sorting_params = {
+ col: parameters[:col],
+ direction: parameters[:direction],
+ grouped?: parameters[:grouped?]
+ }
+ end
+
+ def set_files
+ @files = @path.ls
+ @files = sort_by_column(@files, @sorting_params[:col], @sorting_params[:direction])
+ @files = group_by_type(@files) if @sorting_params[:grouped?]
+ end
+
+ def group_by_type(files)
+ directories = files.select { |file| file[:directory] } + files.select { |file| !file[:directory] }
+ end
+
+ def sort_by_column(files, column, direction)
+ col = column.to_sym
+ sorted_files = files.sort_by do |file|
+ if col == :size
+ file[col].to_i
+ else
+ file[col].to_s.downcase
+ end
+ end
+ return sorted_files if direction == ASCENDING
+ return sorted_files.reverse
+ end
+
def posix_file?
@path.is_a?(PosixFile)
end
-
+
def resolved_path
raise NoMethodError, "Must implement resolved_path in #{self.class.to_s} to use Pathable concern"
end
diff --git a/apps/dashboard/app/controllers/files_controller.rb b/apps/dashboard/app/controllers/files_controller.rb
index 502a9ed40..3edde290d 100644
--- a/apps/dashboard/app/controllers/files_controller.rb
+++ b/apps/dashboard/app/controllers/files_controller.rb
@@ -3,7 +3,7 @@
# The controller for all the files pages /dashboard/files
class FilesController < ApplicationController
include ActionController::Live
- include Pathable
+ include DirectoryUtilsConcern
before_action :strip_sendfile_headers, only: [:fs]
diff --git a/apps/dashboard/app/controllers/projects_controller.rb b/apps/dashboard/app/controllers/projects_controller.rb
index 958186913..5ae3ba77c 100644
--- a/apps/dashboard/app/controllers/projects_controller.rb
+++ b/apps/dashboard/app/controllers/projects_controller.rb
@@ -2,7 +2,7 @@
# The controller for project pages /dashboard/projects.
class ProjectsController < ApplicationController
- include Pathable
+ include DirectoryUtilsConcern
# GET /projects/:id
def show
@@ -11,8 +11,9 @@ def show
parse_path
validate_path!
- @files = @path.ls
-
+ set_sorting_params(show_project_params[:sorting_params] || default_sorting_params)
+ set_files
+
if @project.nil?
respond_to do |format|
message = I18n.t('dashboard.jobs_project_not_found', project_id: project_id)
@@ -34,20 +35,41 @@ def show
end
end
end
-
+
# GET /projects/:project_id/files/*filepath
- def files
- @project = Project.find(files_params[:project_id])
- parse_path(files_params[:filepath])
+ def directory
+ @project = Project.find(directory_params[:project_id])
+ parse_path("#{directory_params[:dir_path]}")
validate_path!
- Rails.logger.debug("\n\n\n==============================================================")
- Rails.logger.debug("ProjectsController#files: request: #{request.methods.sort}")
- Rails.logger.debug("==============================================================\n\n\n")
- @files = @path.ls
-
- render(partial: 'projects/directory', locals: { project_id: @project.id, path: @path, files: @files })
+ set_sorting_params(directory_params[:sorting_params] || DEFAULT_SORTING_PARAMS)
+ set_files
+ render( partial: 'projects/directory',
+ locals: { project: @project,
+ path: @path,
+ files: @files,
+ sorting_params: @sorting_params
+ }
+ )
end
+ def file
+ @project = Project.find(file_params[:project_id])
+ parse_path(file_params[:path])
+ validate_path!
+ @file = File.open(@path.to_s, "r") do |file|
+ file.read
+ end
+
+ render( partial: 'projects/file',
+ locals: {
+ project: @project,
+ path: @path,
+ file: @file,
+ sorting_params: file_params[:sorting_params]
+ }
+ )
+ end
+
# GET /projects
def index
@projects = Project.all
@@ -192,6 +214,10 @@ def resolved_fs
'fs'
end
+ def default_sorting_params
+ DEFAULT_SORTING_PARAMS
+ end
+
def templates
Project.templates.map do |project|
label = project.title
@@ -209,8 +235,12 @@ def project_params
.permit(:name, :directory, :description, :icon, :id, :template)
end
- def files_params
- params.permit(:project_id, :filepath)
+ def directory_params
+ params.permit(:project_id, :format, :dir_path, sorting_params: [:col, :direction, :grouped?])
+ end
+
+ def file_params
+ params.permit(:project_id, :format, :path, :sorting_params)
end
def show_project_params
diff --git a/apps/dashboard/app/helpers/projects_helper.rb b/apps/dashboard/app/helpers/projects_helper.rb
index 87df4858d..7241a4f8f 100644
--- a/apps/dashboard/app/helpers/projects_helper.rb
+++ b/apps/dashboard/app/helpers/projects_helper.rb
@@ -31,4 +31,93 @@ def button_category(status)
status
end
end
+
+ def files_button
+ link_to(
+ ".../projects#{@path.to_s.split('projects')[1]}",
+ files_path(fs: 'fs', filepath: @path),
+ target: '_top',
+ class: 'link-light'
+ ).html_safe
+ end
+
+ #
+ #
+ # <%= "Go To Files: .../projects#{@path.to_s.split('projects')[1]}" %>
+ # <%- if Configuration.project_size_enabled -%>
+ #
+ # <%- end -%>
+ #
+
+ def project_size
+
+ end
+
+ # DRAFT: Remove if not needed
+ # def group_by_type_link
+ # group_link_text = "#{@sorting_params[:grouped?] ? 'Ungroup' : 'Group'}"
+ # group_link_title = @sorting_params[:grouped?] ? 'Ungroup results by type' : 'Group results by type'
+ # link_to(
+ # "Group",
+ # target_path(@sorting_params[:col], !@sorting_params[:grouped?]),
+ # title: "Group results by type",
+ # class: "btn btn-1 btn-primary btn-hover btn-sm align-self-end ml-auto",
+ # data: data_attributes
+ # )
+ # end
+
+ def column_head_link(column)
+ link_to(
+ link_text(column),
+ target_path(column),
+ title: tool_tip,
+ class: "text-dark",
+ data: data_attributes
+ )
+ end
+
+ def direction(column)
+ if column.to_s == @sorting_params[:col]
+ @sorting_params[:direction] == ascending ? descending : ascending
+ else
+ DirectoryUtilsConcern::ASCENDING
+ end
+ end
+
+ def link_text(column)
+ col_title = t("dashboard.#{column.to_s}")
+ if column.to_s == @sorting_params[:col]
+ "#{col_title} #{fa_icon( direction(column) == ascending ? 'sort-up' : 'sort-down', classes: 'fa-md')}".html_safe
+ else
+ "#{col_title} #{fa_icon('sort', classes: 'fa-md')}".html_safe
+ end
+ end
+
+ def target_path(column, grouped = @sorting_params[:grouped?])
+ project_directory_path(
+ { project_id: @project.id,
+ dir_path: @path.to_s,
+ sorting_params: { col: column,
+ direction: direction(column),
+ grouped?: grouped
+ }
+ }
+ )
+ end
+
+ def tool_tip
+ "Show #{@path.basename} directory"
+ end
+
+ def data_attributes
+ { turbo_frame: 'project_directory' }
+ end
+
+ def ascending
+ DirectoryUtilsConcern::ASCENDING
+ end
+
+ def descending
+ DirectoryUtilsConcern::DESCENDING
+ end
end
diff --git a/apps/dashboard/app/javascript/application.js b/apps/dashboard/app/javascript/application.js
index 3b3fc068e..77caf0877 100644
--- a/apps/dashboard/app/javascript/application.js
+++ b/apps/dashboard/app/javascript/application.js
@@ -21,6 +21,8 @@ import 'datatables.net-bs4/js/dataTables.bootstrap4';
import 'datatables.net-select/js/dataTables.select';
import 'datatables.net-plugins/api/processing().mjs';
import "@hotwired/turbo-rails"
+import { Turbo } from "@hotwired/turbo-rails"
+Turbo.session.drive = false
import Rails from '@rails/ujs';
diff --git a/apps/dashboard/app/views/projects/_directory.html.erb b/apps/dashboard/app/views/projects/_directory.html.erb
index 6e719b1ae..7263a15e4 100644
--- a/apps/dashboard/app/views/projects/_directory.html.erb
+++ b/apps/dashboard/app/views/projects/_directory.html.erb
@@ -1,21 +1,27 @@
-<%= turbo_frame_tag "project_files" do %>
-
+<%= turbo_frame_tag "project_directory" do %>
+
+
+ .../projects<%= @path.to_s.split('projects')[1] %>
+
+
+
+
+  <%= files_button %>
+
+
+
+
+ <%= t('dashboard.type') %>
+ <%= column_head_link(:name) %>
+ <%= column_head_link(:size) %>
+ <%= column_head_link(:date) %>
+ <%= column_head_link(:owner) %>
+ Mode
+
+
+
+ <%= render partial: "files", locals: { project: project, path: path, files: files, sorting_params: sorting_params } %>
+
+
+
<% end %>
\ No newline at end of file
diff --git a/apps/dashboard/app/views/projects/_file.html.erb b/apps/dashboard/app/views/projects/_file.html.erb
new file mode 100644
index 000000000..939ab5f01
--- /dev/null
+++ b/apps/dashboard/app/views/projects/_file.html.erb
@@ -0,0 +1,26 @@
+<%= turbo_frame_tag "project_directory" do %>
+
+
+
+
+
+ <%= link_to("",
+ project_directory_path(project_id: @project.id, dir_path: "#{@path.parent}", sorting_params: @sorting_params),
+ class: 'fa fa-window-close align-self-start button buttom-sm text-danger',
+ data: { turbo_frame: "project_directory" }
+ )
+ %> 
+ .../projects<%= @path.to_s.split('projects')[1] %>
+
+
+
+
+
+
+  <%= files_button %>
+
+
+
+<%- end -%>
\ No newline at end of file
diff --git a/apps/dashboard/app/views/projects/_files.html.erb b/apps/dashboard/app/views/projects/_files.html.erb
index 14c39c432..e05f320e0 100644
--- a/apps/dashboard/app/views/projects/_files.html.erb
+++ b/apps/dashboard/app/views/projects/_files.html.erb
@@ -1,54 +1,73 @@
+
+<%- unless path.to_s == project.directory.to_s -%>
-
+
+
+ <%= link_to(
+ "..",
+ project_directory_path(
+ project_id: project.id,
+ dir_path: "#{path.parent}",
+ sorting_params: sorting_params
+ ),
+ title: 'Show parent directory',
+ data: { turbo_frame: "project_directory" }
+ )
+ %>
+
-
- <%= link_to("..", project_files_path(project_id: project_id, filepath: sanitize("#{path}/..")), data: { turbo_frame: "project_files" }) %>
-
-
- <% files.each do |file| %>
-
-
-
-
-
- <%= file[:type] %>
-
-
- <%= link_to(file[:name], project_files_path(project_id: project_id, filepath: sanitize("#{path}/#{file[:name]}")), data: { turbo_frame: "project_files" }) %>
-
-
- Actions
-
-
-
-
-
-
-
-
-
-
-
-
-
- <%= file[:size] %>
-
-
- <%= file[:modified_at] %>
-
-
- <%= file[:owner] %>
-
-
- <%= file[:mode] %>
-
-
- <%- end -%>
\ No newline at end of file
+<%- end -%>
+<% files.each do |file| %>
+
+
+
+
+
+ <%- if file[:directory] -%>
+ <%= link_to(
+ file[:name],
+ project_directory_path(
+ project_id: project.id,
+ dir_path: "#{path}/#{file[:name]}",
+ sorting_params: sorting_params
+ ),
+ title: "Show #{file[:name]} directory",
+ data: { turbo_frame: "project_directory" }
+ )
+ %>
+ <%- else -%>
+ <%= link_to(
+ file[:name],
+ project_file_path(
+ project_id: project.id,
+ path: "#{path}/#{file[:name]}",
+ sorting_params: sorting_params
+ ),
+ title: "Show #{file[:name]}",
+ data: { turbo_frame: "project_directory" }
+ )
+ %>
+ <%- end -%>
+
+
+ <%= file[:size] %>
+
+
+ <%= DateTime.parse(Time.at(file[:date]).to_s).strftime("%F %r") %>
+
+
+ <%= file[:owner] %>
+
+
+ <%= file[:mode] %>
+
+
+<%- end -%>
\ No newline at end of file
diff --git a/apps/dashboard/app/views/projects/_files_column_head.html.erb b/apps/dashboard/app/views/projects/_files_column_head.html.erb
new file mode 100644
index 000000000..8b320d785
--- /dev/null
+++ b/apps/dashboard/app/views/projects/_files_column_head.html.erb
@@ -0,0 +1,14 @@
+<%= link_to(
+ "Name #{fa_icon( sorting_params["direction"] == controller.class::ASCENDING ? 'caret-up' : 'caret-down', classes: nil)}".html_safe,
+ project_directory_path(
+ project_id: project.id,
+ dir_path: path,
+ sorting_params: { col: 'name',
+ direction: sorting_params[:col] == 'name' ? sorting_params[:direction] : controller.class::ASCENDING,
+ grouped?: sorting_params[:grouped?]
+ }
+ ),
+ title: "Show #{path.basename} directory",
+ data: { turbo_frame: "project_directory" },
+ class: "text-dark"
+)%>
\ No newline at end of file
diff --git a/apps/dashboard/app/views/projects/show.html.erb b/apps/dashboard/app/views/projects/show.html.erb
index c5f2380a7..f16de0bc1 100644
--- a/apps/dashboard/app/views/projects/show.html.erb
+++ b/apps/dashboard/app/views/projects/show.html.erb
@@ -20,16 +20,6 @@
-
-
-
<%= "#{@project.name} (Project ID: #{@project.id})" %>
- <%= render partial: 'directory', locals: { project: @project, path: @path, files: @files } %>
+ <%= "#{t('dashboard.project')} #{t('dashboard.directory')}" %>:  <%= @project.id %>
+ <%= render partial: 'directory', locals: { project: @project, path: @path, files: @files, sorting_params: @sorting_params } %>
diff --git a/apps/dashboard/config/locales/en.yml b/apps/dashboard/config/locales/en.yml
index cbe6599f2..c1cd5f866 100644
--- a/apps/dashboard/config/locales/en.yml
+++ b/apps/dashboard/config/locales/en.yml
@@ -322,3 +322,9 @@ en:
project: "Project"
directory: "Directory"
close: "Close"
+ type: "Type"
+ name: "Name"
+ size: "Size"
+ owner: "Owner"
+ date: "Date"
+ mode: "Mode"
diff --git a/apps/dashboard/config/locales/ja_JP.yml b/apps/dashboard/config/locales/ja_JP.yml
index e3b3282fd..09c1c8df5 100644
--- a/apps/dashboard/config/locales/ja_JP.yml
+++ b/apps/dashboard/config/locales/ja_JP.yml
@@ -10,6 +10,15 @@ ja_JP:
edit: "編集する"
show: "見せる"
launch: "起動する"
+ type: 'タイプ'
+ name: '名前'
+ size: "サイズ"
+ owner: "所有者"
+ date: "日付"
+ mode: "モード"
+ project: "プロジェクト"
+ directory: "ディレクトリ"
+
# project: "Project"
# directory: "Directory"
auto_log_location_title: "ログの場所"
\ No newline at end of file
diff --git a/apps/dashboard/config/locales/zh-CN.yml b/apps/dashboard/config/locales/zh-CN.yml
index bb3c798bd..48e5f99a4 100644
--- a/apps/dashboard/config/locales/zh-CN.yml
+++ b/apps/dashboard/config/locales/zh-CN.yml
@@ -151,4 +151,13 @@ zh-CN:
edit: "编辑"
show: "显示"
launch: "启动"
+ type: "类型"
+ name: "名称"
+ size: "大小"
+ owner: "所有者"
+ date: "日期"
+ mode: "模式"
+ project: "项目"
+ directory: "目录"
+
# development_apps_caption: "Sandbox App"
diff --git a/apps/dashboard/config/routes.rb b/apps/dashboard/config/routes.rb
index d5e93352d..00c478ae9 100644
--- a/apps/dashboard/config/routes.rb
+++ b/apps/dashboard/config/routes.rb
@@ -16,7 +16,8 @@
end
end
if Configuration.can_access_files?
- get 'projects/:project_id/files/*filepath' => 'projects#files', as: 'project_files'
+ get 'projects/:project_id/directory' => 'projects#directory', as: 'project_directory'
+ get 'projects/:project_id/file' => 'projects#file', as: 'project_file'
end
end