diff --git a/app/assets/javascripts/projects/index.js b/app/assets/javascripts/projects/index.js index ca0d522ca..3850dfbf2 100644 --- a/app/assets/javascripts/projects/index.js +++ b/app/assets/javascripts/projects/index.js @@ -28,10 +28,16 @@ var exportProjectsModalBody = null; var exportProjectsBtn = null; var exportProjectsSubmit = null; - - var projectsViewSearch; var projectsChanged = false; - var projectsCurrentSort; + + let projectsCurrentSort; + let projectsViewSearch; + let createdOnFromFilter; + let createdOnToFilter; + let membersFilter; + let lookInsideFolders; + let archivedOnFromFilter; + let archivedOnToFilter; // Arrays with selected project and folder IDs shared between both views var selectedProjects = []; @@ -483,7 +489,13 @@ data: { filter: $('.projects-index').data('mode'), sort: projectsCurrentSort, - search: projectsViewSearch + search: projectsViewSearch, + members: membersFilter, + created_on_from: createdOnFromFilter, + created_on_to: createdOnToFilter, + folders_search: lookInsideFolders, + archived_on_from: archivedOnFromFilter, + archived_on_to: archivedOnToFilter }, success: function(data) { $('#breadcrumbs-wrapper').html(data.breadcrumbs_html); @@ -537,14 +549,14 @@ }); } - function initProjectsFilter() { + function initProjectsFilters() { let $projectsFilter = $('.projects-index .projects-filters'); let $membersFilter = $('.members-filter', $projectsFilter); let $foldersCB = $('#folder_search', $projectsFilter); - let $createdOnStartFilter = $('#createdOnStartDate', $projectsFilter); - let $createdOnEndFilter = $('#createdOnEndDate', $projectsFilter); - let $archivedOnStartFilter = $('#archivedOnStartDate', $projectsFilter); - let $archivedOnEndFilter = $('#archivedOnEndDate', $projectsFilter); + let $createdOnFromFilter = $('#createdOnFromDate', $projectsFilter); + let $createdOnToFilter = $('#createdOnToDate', $projectsFilter); + let $archivedOnFromFilter = $('#archivedOnFromDate', $projectsFilter); + let $archivedOnToFilter = $('#archivedOnToDate', $projectsFilter); let $textFilter = $('#textSearchFilterInput', $projectsFilter); dropdownSelector.init($membersFilter, { @@ -629,9 +641,17 @@ console.error(error); } - $('.projects-filters').dropdown('toggle'); + $(e.target).closest('.dropdown').removeClass('open'); - loadCardsView(); + + createdOnFromFilter = $createdOnFromFilter.val(); + createdOnToFilter = $createdOnToFilter.val(); + membersFilter = dropdownSelector.getValues($('.members-filter')); + lookInsideFolders = $foldersCB.prop('checked'); + archivedOnFromFilter = $archivedOnFromFilter.val(); + archivedOnToFilter = $archivedOnToFilter.val(); + + refreshCurrentView(); }); // Clear filters @@ -640,10 +660,10 @@ e.preventDefault(); dropdownSelector.clearData($membersFilter); - if ($createdOnStartFilter.data('DateTimePicker')) $createdOnStartFilter.data('DateTimePicker').clear(); - if ($createdOnEndFilter.data('DateTimePicker')) $createdOnEndFilter.data('DateTimePicker').clear(); - if ($archivedOnStartFilter.data('DateTimePicker')) $archivedOnStartFilter.data('DateTimePicker').clear(); - if ($archivedOnEndFilter.data('DateTimePicker')) $archivedOnEndFilter.data('DateTimePicker').clear(); + if ($createdOnFromFilter.data('DateTimePicker')) $createdOnFromFilter.data('DateTimePicker').clear(); + if ($createdOnToFilter.data('DateTimePicker')) $createdOnToFilter.data('DateTimePicker').clear(); + if ($archivedOnFromFilter.data('DateTimePicker')) $archivedOnFromFilter.data('DateTimePicker').clear(); + if ($archivedOnToFilter.data('DateTimePicker')) $archivedOnToFilter.data('DateTimePicker').clear(); $foldersCB.prop('checked', false); $textFilter.val(''); }); @@ -665,5 +685,5 @@ initProjectsViewModeSwitch(); initSorting(); loadCardsView(); - initProjectsFilter(); + initProjectsFilters(); }(window)); diff --git a/app/controllers/projects_controller.rb b/app/controllers/projects_controller.rb index 81f30fc74..393def6b1 100644 --- a/app/controllers/projects_controller.rb +++ b/app/controllers/projects_controller.rb @@ -29,7 +29,7 @@ class ProjectsController < ApplicationController def cards overview_service = ProjectsOverviewService.new(current_team, current_user, @current_folder, params) - if params[:search].present? + if filters_included? render json: { cards_html: render_to_string( partial: 'projects/index/team_projects_grouped_by_folder.html.erb', @@ -281,6 +281,11 @@ class ProjectsController < ApplicationController @current_sort = 'new' if @current_sort.include?('arch') && action_name != 'experiment_archive' end + def filters_included? + %i(search created_on_from created_on_to members archived_on_from archived_on_to folders_search) + .any? { |param_name| params.dig(param_name).present? } + end + def log_activity(type_of, message_items = {}) message_items = { project: @project.id }.merge(message_items) diff --git a/app/services/projects_overview_service.rb b/app/services/projects_overview_service.rb index ed594c28b..d3a210d2b 100644 --- a/app/services/projects_overview_service.rb +++ b/app/services/projects_overview_service.rb @@ -8,13 +8,28 @@ class ProjectsOverviewService @params = params @view_state = @team.current_view_state(@user) + # Default state changed, reset invalid state + unless @view_state.valid? + @view_state.destroy + @view_state = @team.current_view_state(@user) + end + + # Update view_mode if changed if @view_state.state.dig('projects', 'view_mode') != @params[:filter] && %w(active archived).include?(@params[:filter]) @view_state.state['projects']['view_mode'] = @params[:filter] @view_state.save! end - @view_mode = @view_state.state.dig('projects', 'view_mode') + + # Update sort if chanhed + @sort = @view_state.state.dig('projects', @view_mode, 'sort') + if @params[:sort] && @sort != @params[:sort] && + %w(new old atoz ztoa archived_first archived_last).include?(@params[:sort]) + @view_state.state['projects'].merge!(Hash[@view_mode, { 'sort': @params[:sort] }.stringify_keys]) + @view_state.save! + @sort = @view_state.state.dig('projects', @view_mode, 'sort') + end end def project_cards @@ -35,13 +50,24 @@ class ProjectsOverviewService def grouped_by_folder_project_cards project_records = - if @current_folder.present? - fetch_project_records.where(project_folder: ProjectFolder.inner_folders(@team, @current_folder)) - else + if @current_folder + folders = if @params[:folders_search] == 'true' + ProjectFolder.inner_folders(@team, @current_folder).or(ProjectFolder.where(id: @current_folder.id)) + else + ProjectFolder.where(id: @current_folder.id) + end + + fetch_project_records.where(project_folder: folders) + elsif @params[:folders_search] == 'true' + folders = ProjectFolder.inner_folders(@team, nil).or(ProjectFolder.where(id: nil)) fetch_project_records + else + folders = ProjectFolder.where(id: nil) + fetch_project_records.where(project_folder: nil, team: @team) end + project_records = sort_records(filter_project_records(project_records)).includes(:project_folder).to_a - folder_records = ProjectFolder.inner_folders(@team, @current_folder).includes(:parent_folder).to_a + folder_records = folders.includes(:parent_folder).to_a sorted_results_by_folder = {} build_folder_content(@current_folder, folder_records, project_records, sorted_results_by_folder) @@ -120,6 +146,14 @@ class ProjectsOverviewService records = records.where(archived: true) if @params[:filter] == 'archived' records = records.where(archived: false) if @params[:filter] == 'active' records = records.where_attributes_like('projects.name', @params[:search]) if @params[:search].present? + records = records.where_attributes_like('projects.name', @params[:search]) if @params[:search].present? + records = records.where('user_projects.user_id IN (?)', @params[:members]) if @params[:members]&.any? + records = records.where('projects.created_at > ?', @params[:created_on_from]) if @params[:created_on_from].present? + records = records.where('projects.created_at < ?', @params[:created_on_to]) if @params[:created_on_to].present? + records = records.where('projects.archived_on < ?', @params[:archived_on_to]) if @params[:archived_on_to].present? + if @params[:archived_on_from].present? + records = records.where('projects.archived_on > ?', @params[:archived_on_from]) + end records end @@ -131,14 +165,7 @@ class ProjectsOverviewService end def sort_records(records) - cards_state = @view_state.state.dig('projects', 'cards') - if @params[:sort] && cards_state['sort'] != @params[:sort] && %w(new old atoz ztoa).include?(@params[:sort]) - cards_state['sort'] = @params[:sort] - @view_state.state['projects']['cards'] = cards_state - end - @view_state.save! if @view_state.changed? - - case cards_state['sort'] + case @sort when 'new' records.order(created_at: :desc) when 'old' @@ -157,19 +184,7 @@ class ProjectsOverviewService end def mixed_sort_records(records) - sort = @view_state.state.dig('projects', @view_mode, 'sort') - - if @params[:sort] && sort != @params[:sort] && - %w(new old atoz ztoa archived_first archived_last).include?(@params[:sort]) - @view_state.state['projects'].merge!(Hash[@view_mode, { 'sort': @params[:sort] }.stringify_keys]) - end - - if @view_state.changed? - @view_state.save! - sort = @view_state.state.dig('projects', @view_mode, 'sort') - end - - case sort + case @sort when 'new' records.sort_by(&:created_at).reverse! when 'old' diff --git a/app/views/projects/index/_header.html.erb b/app/views/projects/index/_header.html.erb index b30541a17..fc1327576 100644 --- a/app/views/projects/index/_header.html.erb +++ b/app/views/projects/index/_header.html.erb @@ -34,7 +34,7 @@