Add clickable breadcrumbs above the folder names on the Team Project page [SCI-5171]

This commit is contained in:
Oleksii Kriuchykhin 2020-11-24 15:42:06 +01:00
parent fcb82fd0d2
commit 78e050ccc0
11 changed files with 76 additions and 12 deletions

View file

@ -367,6 +367,15 @@
}
}
$('#wrapper').on('click', '.project-folder-link', function(event) {
event.preventDefault();
event.stopPropagation();
let viewContainer = $('#cards-wrapper');
viewContainer.data('projects-cards-url', $(this).data('projectsCardsUrl'));
history.replaceState({}, '', this.href);
refreshCurrentView();
});
/**
* Initializes cards view
*/
@ -511,8 +520,10 @@
search: projectsViewSearch
},
success: function(data) {
$('#breadcrumbs-wrapper').html(data.breadcrumbs_html);
viewContainer.data('projects-cards-url', data.projects_cards_url);
viewContainer.find('.card').remove();
viewContainer.append(data.html);
viewContainer.append(data.cards_html);
init();
},
error: function() {

View file

@ -19,6 +19,11 @@ $color-module-hover: $brand-primary;
}
}
// Breadcrumbs
.projects-breadcrumbs {
padding: .5em 1em;
}
/* Secondary navigation */
.navbar-nav {

View file

@ -7,6 +7,7 @@ class ProjectsController < ApplicationController
before_action :switch_team_with_param, only: :index
before_action :load_vars, only: %i(show edit update notifications experiment_archive)
before_action :load_current_folder, only: %i(index cards)
before_action :load_projects_tree, only: %i(sidebar show experiment_archive index)
before_action :check_view_permissions, only: %i(show notifications experiment_archive)
before_action :check_create_permissions, only: %i(create)
@ -24,21 +25,20 @@ class ProjectsController < ApplicationController
end
def cards
if params[:project_folder_id].present?
current_folder = current_team.project_folders.find_by(id: params[:project_folder_id])
end
overview_service = ProjectsOverviewService.new(current_team, current_user, current_folder, params)
overview_service = ProjectsOverviewService.new(current_team, current_user, @current_folder, params)
if params[:search].present?
render json: {
html: render_to_string(
cards_html: render_to_string(
partial: 'projects/index/team_projects_grouped_by_folder.html.erb',
locals: { projects_by_folder: overview_service.grouped_by_folder_project_cards }
)
}
else
render json: {
html: render_to_string(
projects_cards_url: @current_folder ? project_folder_cards_url(@current_folder) : cards_projects_url,
breadcrumbs_html: @current_folder ? render_to_string(partial: 'projects/index/breadcrumbs.html.erb') : '',
cards_html: render_to_string(
partial: 'projects/index/team_projects.html.erb',
locals: { cards: overview_service.project_and_folder_cards }
)
@ -254,6 +254,12 @@ class ProjectsController < ApplicationController
render_404 unless @project
end
def load_current_folder
if current_team && params[:project_folder_id].present?
@current_folder = current_team.project_folders.find_by(id: params[:project_folder_id])
end
end
def load_projects_tree
# Switch to correct team
current_team_switch(@project.team) unless @project.nil? || @project.new_record?

View file

@ -59,6 +59,23 @@ class ProjectFolder < ApplicationRecord
new_query.order(:parent_folder_id)
end
def parent_folders
outer_folders_sql =
'WITH RECURSIVE outer_project_folders(id, parent_folder_id, selected_folders_ids) AS (
SELECT id, parent_folder_id, ARRAY[id]
FROM project_folders
WHERE team_id = ? AND id = ?
UNION ALL
SELECT project_folders.id, project_folders.parent_folder_id, selected_folders_ids || project_folders.id
FROM outer_project_folders
JOIN project_folders ON project_folders.id = outer_project_folders.parent_folder_id
WHERE NOT project_folders.id = ANY(selected_folders_ids)
)
SELECT id FROM outer_project_folders ORDER BY selected_folders_ids'.gsub(/\n|\t/, ' ').gsub(/ +/, ' ')
ProjectFolder.where("project_folders.id IN (#{outer_folders_sql})", team.id, id)
end
def inner_projects
project_folders.map do |inner_folder|
projects + inner_folder.inner_projects

View file

@ -42,7 +42,8 @@ class ProjectsOverviewService
end
def project_and_folder_cards
cards = filter_project_records(fetch_project_records) + filter_project_folder_records(fetch_project_folder_records)
cards = filter_project_records(fetch_project_records.where(project_folder: @current_folder)) +
filter_project_folder_records(fetch_project_folder_records.where(parent_folder: @current_folder))
mixed_sort_records(cards)
end

View file

@ -8,6 +8,9 @@
<span class="fas fa-chevron-right"></span>
</div>
</div>
<div id="breadcrumbs-wrapper">
<%= yield :breadcrumbs %>
</div>
<%= yield :secondary_navigation %>
<div class="container-fluid <%= yield :container_class %>" id="fluid-content">
<%= yield %>

View file

@ -2,8 +2,10 @@
<% if current_team %>
<%= render partial: "shared/sidebar", locals: { page: 'project' } %>
<% content_for :breadcrumbs do %>
<%= render partial: "projects/index/breadcrumbs" if @current_folder %>
<% end %>
<%= render partial: "shared/secondary_navigation" %>
<span style="display: none;" data-hook="projects-index-html"></span>
<%= render partial: 'projects/index/modals/new' %>
@ -13,7 +15,7 @@
<div class="projects-container">
<%= render partial: 'projects/index/toolbar' %>
<div class="cards-wrapper" id="cards-wrapper" data-projects-cards-url="<%= cards_projects_url %>">
<div class="cards-wrapper" id="cards-wrapper" data-projects-cards-url="<%= @current_folder ? project_folder_cards_url(@current_folder) : cards_projects_url %>">
<div class="table-header">
<div class="table-header-cell select-all-checkboxes">
<div class="sci-checkbox-container">

View file

@ -0,0 +1,14 @@
<div class="projects-breadcrumbs">
<%= link_to(t('projects.index.breadcrumbs_root'),
projects_path,
class: 'project-folder-link',
data: { projects_cards_url: cards_projects_url }) %>
<span>/</span>
<% @current_folder.parent_folders.each do |project_folder| %>
<%= link_to(project_folder.name,
project_folder_path(project_folder),
class: 'project-folder-link',
data: { projects_cards_url: project_folder_cards_url(project_folder) }) %>
<span>/</span>
<% end %>
</div>

View file

@ -9,7 +9,10 @@
<i class="fas fa-folder"></i>
</div>
<div class="name">
<%= folder.name %>
<%= link_to(folder.name,
project_folder_path(folder),
class: 'project-folder-link',
data: { projects_cards_url: project_folder_cards_url(folder) }) %>
</div>
<div class="description">
<%= t('projects.index.folder.description', projects_count: folder.projects_count, folders_count: folder.folders_count) %>

View file

@ -284,6 +284,7 @@ en:
projects:
index:
head_title: "Projects"
breadcrumbs_root: "Projects"
archive: "Archive"
archived: "Archived"
active: "Active"

View file

@ -297,12 +297,13 @@ Rails.application.routes.draw do
get 'users/edit', to: 'user_projects#index_edit'
collection do
get 'cards'
get 'cards', to: 'projects#cards'
get 'users_filter'
end
end
resources :project_folders, only: [] do
get '/', to: 'projects#index'
get 'cards', to: 'projects#cards'
end