From c74fa3c244ce1c391bb153586c75d1a99088502b Mon Sep 17 00:00:00 2001 From: Oleksii Kriuchykhin Date: Tue, 12 May 2020 16:26:44 +0200 Subject: [PATCH] Make snapshots selectable [SCI-4596] --- .../javascripts/my_modules/repositories.js | 48 +++++++- .../stylesheets/my_modules/repositories.scss | 4 + .../my_module_repositories_controller.rb | 19 +-- ..._module_repository_snapshots_controller.rb | 45 ++++--- app/helpers/my_modules_helper.rb | 37 +++--- app/helpers/repository_datatable_helper.rb | 32 +++-- app/models/my_module.rb | 15 ++- app/models/repository_snapshot.rb | 11 ++ .../repositories/_full_view_version.html.erb | 4 +- .../_full_view_versions_sidebar.html.erb | 8 +- .../repositories/_repositories_list.html.erb | 15 +-- .../_repository_row_info_modal.html.erb | 114 +++++++++--------- .../simple_view_index.json.jbuilder | 8 ++ .../snapshot_index.json.jbuilder | 5 +- config/locales/en.yml | 8 ++ config/routes.rb | 4 + ...20200331183640_add_repository_snapshots.rb | 14 ++- db/structure.sql | 1 + 18 files changed, 258 insertions(+), 134 deletions(-) create mode 100644 app/views/repository_rows/simple_view_index.json.jbuilder diff --git a/app/assets/javascripts/my_modules/repositories.js b/app/assets/javascripts/my_modules/repositories.js index 64c1fde4d..82d099663 100644 --- a/app/assets/javascripts/my_modules/repositories.js +++ b/app/assets/javascripts/my_modules/repositories.js @@ -88,12 +88,12 @@ var MyModuleRepositories = (function() { function renderSimpleTable(tableContainer) { if (SIMPLE_TABLE) SIMPLE_TABLE.destroy(); SIMPLE_TABLE = $(tableContainer).DataTable({ - dom: "Rt<'pagination-row'<'pagination-actions'p>>", + dom: "Rt<'pagination-row'<'version-label'><'pagination-actions'p>>", processing: true, serverSide: true, responsive: true, pageLength: 5, - order: [[3, 'asc']], + order: [[1, 'asc']], sScrollY: '100%', sScrollX: '100%', sScrollXInner: '100%', @@ -103,14 +103,16 @@ var MyModuleRepositories = (function() { data: function(d) { d.assigned = 'assigned'; d.view_mode = true; - d.skip_custom_columns = true; + d.simple_view = true; }, global: false, type: 'POST' }, - columns: tableColumns(tableContainer), + columns: [ + { data: '1' } + ], columnDefs: [{ - targets: 3, + targets: 1, render: function(data, type, row) { return "" + data + ''; @@ -119,6 +121,7 @@ var MyModuleRepositories = (function() { drawCallback: function() { var repositoryContainer = $(this).closest('.assigned-repository-container'); repositoryContainer.find('.table.dataTable').removeClass('hidden'); + repositoryContainer.find('.version-label').html(tableContainer.data('version-label')); SIMPLE_TABLE.columns.adjust(); } }); @@ -202,6 +205,12 @@ var MyModuleRepositories = (function() { let currentId = FULL_VIEW_MODAL.find('.table').data('id'); versionsSidebar.find('.list-group-item').removeClass('active'); versionsSidebar.find(`[data-id="${currentId}"]`).addClass('active'); + + if (!versionsSidebar.find(`[data-id="${currentId}"]`).data('selected')) { + $('#setDefaultVersionButton').removeClass('hidden'); + } else { + $('#setDefaultVersionButton').addClass('hidden'); + } } function reloadTable(tableUrl) { @@ -259,8 +268,9 @@ var MyModuleRepositories = (function() { function initSimpleTable() { $('#assigned-items-container').on('show.bs.collapse', '.assigned-repository-container', function() { var repositoryContainer = $(this); - var repositoryTemplate = $($('#my-module-repository-simple-template').html()); + var repositoryTemplate = $($('#myModuleRepositorySimpleTemplate').html()); repositoryTemplate.attr('data-source', $(this).data('repository-url')); + repositoryTemplate.attr('data-version-label', $(this).data('footer-label')); repositoryContainer.html(repositoryTemplate); renderSimpleTable(repositoryTemplate); }); @@ -344,6 +354,32 @@ var MyModuleRepositories = (function() { FULL_VIEW_TABLE.columns.adjust(); e.stopPropagation(); }); + + FULL_VIEW_MODAL.on('click', '#setDefaultVersionButton', function(e) { + let data; + animateSpinner(null, true); + + if (FULL_VIEW_MODAL.find('.table').data('type') === 'live') { + data = { repository_snapshot_id: -1 }; + } else { + data = { repository_snapshot_id: FULL_VIEW_MODAL.find('.table').data('id') }; + } + + $.ajax({ + url: $(this).data('select-path'), + type: 'POST', + dataType: 'json', + data: data, + success: function() { + let versionsList = FULL_VIEW_MODAL.find('.repository-versions-list'); + versionsList.find('.list-group-item').data('selected', false); + versionsList.find('.list-group-item.active').data('selected', true); + $('#setDefaultVersionButton').addClass('hidden'); + animateSpinner(null, false); + } + }); + e.stopPropagation(); + }); } function initRepositoryFullView() { diff --git a/app/assets/stylesheets/my_modules/repositories.scss b/app/assets/stylesheets/my_modules/repositories.scss index d70a26e71..06f05a0e3 100644 --- a/app/assets/stylesheets/my_modules/repositories.scss +++ b/app/assets/stylesheets/my_modules/repositories.scss @@ -379,6 +379,10 @@ display: none; } + .default-version-button { + bottom: 5em; + } + &:hover { background-color: $color-alto; diff --git a/app/controllers/my_module_repositories_controller.rb b/app/controllers/my_module_repositories_controller.rb index d1b28d9c6..a9170902d 100644 --- a/app/controllers/my_module_repositories_controller.rb +++ b/app/controllers/my_module_repositories_controller.rb @@ -17,19 +17,22 @@ class MyModuleRepositoriesController < ApplicationController @datatable_params = { view_mode: params[:view_mode], - skip_custom_columns: params[:skip_custom_columns], my_module: @my_module } @all_rows_count = datatable_service.all_count @columns_mappings = datatable_service.mappings - @repository_rows = datatable_service.repository_rows - .preload(:repository_columns, - :created_by, - repository_cells: @repository.cell_preload_includes) - .page(page) - .per(per_page) + if params[:simple_view] + repository_rows = datatable_service.repository_rows + rows_view = 'repository_rows/simple_view_index.json' + else + repository_rows = datatable_service.repository_rows.preload(:repository_columns, + :created_by, + repository_cells: @repository.cell_preload_includes) + rows_view = 'repository_rows/index.json' + end + @repository_rows = repository_rows.page(page).per(per_page) - render 'repository_rows/index.json' + render rows_view end def update diff --git a/app/controllers/my_module_repository_snapshots_controller.rb b/app/controllers/my_module_repository_snapshots_controller.rb index 9733431b8..5c5fe3d03 100644 --- a/app/controllers/my_module_repository_snapshots_controller.rb +++ b/app/controllers/my_module_repository_snapshots_controller.rb @@ -3,9 +3,9 @@ class MyModuleRepositorySnapshotsController < ApplicationController before_action :load_my_module before_action :load_repository - before_action :load_repository_snapshot, except: %i(create full_view_versions_sidebar) - before_action :check_view_permissions, except: %i(create destroy) - before_action :check_manage_permissions, only: %i(create destroy) + before_action :load_repository_snapshot, except: %i(create full_view_versions_sidebar select) + before_action :check_view_permissions, except: %i(create destroy select) + before_action :check_manage_permissions, only: %i(create destroy select) def index_dt @draw = params[:draw].to_i @@ -13,20 +13,21 @@ class MyModuleRepositorySnapshotsController < ApplicationController page = (params[:start].to_i / per_page) + 1 datatable_service = RepositorySnapshotDatatableService.new(@repository_snapshot, params, current_user, @my_module) - @datatable_params = { - view_mode: params[:view_mode], - skip_custom_columns: params[:skip_custom_columns] - } @all_rows_count = datatable_service.all_count @columns_mappings = datatable_service.mappings - @repository_rows = datatable_service.repository_rows - .preload(:repository_columns, - :created_by, - repository_cells: @repository_snapshot.cell_preload_includes) - .page(page) - .per(per_page) + if params[:simple_view] + repository_rows = datatable_service.repository_rows + rows_view = 'repository_rows/simple_view_index.json' + else + repository_rows = datatable_service.repository_rows + .preload(:repository_columns, + :created_by, + repository_cells: @repository_snapshot.cell_preload_includes) + rows_view = 'repository_rows/snapshot_index.json' + end + @repository_rows = repository_rows.page(page).per(per_page) - render 'repository_rows/snapshot_index.json' + render rows_view end def create @@ -75,6 +76,20 @@ class MyModuleRepositorySnapshotsController < ApplicationController render json: { html: render_to_string(partial: 'my_modules/repositories/full_view_versions_sidebar') } end + def select + if params[:repository_snapshot_id].to_i == -1 + @my_module.repository_snapshots.where(original_repository: @repository).update(selected: nil) + else + repository_snapshot = @my_module.repository_snapshots.find_by(id: params[:repository_snapshot_id]) + return render_404 unless repository_snapshot + + @my_module.repository_snapshots.where(original_repository: @repository).update(selected: nil) + repository_snapshot.update!(selected: true) + end + + render json: {} + end + private def load_my_module @@ -98,6 +113,6 @@ class MyModuleRepositorySnapshotsController < ApplicationController end def check_manage_permissions - render_403 unless can_read_experiment?(@my_module.experiment) + render_403 unless can_manage_module?(@my_module) end end diff --git a/app/helpers/my_modules_helper.rb b/app/helpers/my_modules_helper.rb index 9e6c1d420..c7e4fd71c 100644 --- a/app/helpers/my_modules_helper.rb +++ b/app/helpers/my_modules_helper.rb @@ -56,21 +56,28 @@ module MyModulesHelper action_name == 'results' end - def grouped_by_prj_exp(my_modules) - ungrouped_tasks = my_modules.joins(experiment: :project) - .select('experiments.name as experiment_name, - experiments.archived as experiment_archived, - projects.name as project_name, - projects.archived as project_archived, - my_modules.*') - ungrouped_tasks.group_by { |i| [i[:project_name], i[:experiment_name]] }.map do |group, tasks| - { - project_name: group[0], - project_archived: tasks[0]&.project_archived, - experiment_name: group[1], - experiment_archived: tasks[0]&.experiment_archived, - tasks: tasks - } + def assigned_repository_full_view_table_path(my_module, repository) + if repository.is_a?(RepositorySnapshot) + return full_view_table_my_module_repository_snapshot_path(my_module, repository.original_repository, repository) end + + full_view_table_my_module_repository_path(my_module, repository) + end + + def assigned_repository_simple_view_index_path(my_module, repository) + if repository.is_a?(RepositorySnapshot) + return index_dt_my_module_repository_snapshot_path(my_module, repository.original_repository, repository) + end + + index_dt_my_module_repository_path(my_module, repository) + end + + def assigned_repository_simple_view_footer_label(repository) + if repository.is_a?(RepositorySnapshot) + return t('my_modules.repository.snapshots.simple_view.snapshot_bottom_label', + date_time: l(repository.updated_at, format: :full)) + end + + t('my_modules.repository.snapshots.simple_view.live_bottom_label') end end diff --git a/app/helpers/repository_datatable_helper.rb b/app/helpers/repository_datatable_helper.rb index b27dfd8ba..b4a05bc9b 100644 --- a/app/helpers/repository_datatable_helper.rb +++ b/app/helpers/repository_datatable_helper.rb @@ -34,18 +34,27 @@ module RepositoryDatatableHelper row['0'] = record[:row_assigned] if options[:my_module] - unless options[:skip_custom_columns] - # Add custom columns - record.repository_cells.each do |cell| - row[columns_mappings[cell.repository_column.id]] = - display_cell_value(cell, team) - end + # Add custom columns + record.repository_cells.each do |cell| + row[columns_mappings[cell.repository_column.id]] = + display_cell_value(cell, team) end + row end end - def prepare_snapshot_row_columns(repository_rows, columns_mappings, team, options = {}) + def prepare_simple_view_row_columns(repository_rows) + repository_rows.map do |record| + { + 'DT_RowId': record.id, + '1': escape_input(record.name), + 'recordInfoUrl': Rails.application.routes.url_helpers.repository_row_path(record.id) + } + end + end + + def prepare_snapshot_row_columns(repository_rows, columns_mappings, team) repository_rows.map do |record| row = { 'DT_RowId': record.id, @@ -56,12 +65,11 @@ module RepositoryDatatableHelper 'recordInfoUrl': Rails.application.routes.url_helpers.repository_row_path(record.id) } - unless options[:skip_custom_columns] - # Add custom columns - record.repository_cells.each do |cell| - row[columns_mappings[cell.repository_column.id]] = display_cell_value(cell, team) - end + # Add custom columns + record.repository_cells.each do |cell| + row[columns_mappings[cell.repository_column.id]] = display_cell_value(cell, team) end + row end end diff --git a/app/models/my_module.rb b/app/models/my_module.rb index 86503139b..7e40140dd 100644 --- a/app/models/my_module.rb +++ b/app/models/my_module.rb @@ -54,7 +54,6 @@ class MyModule < ApplicationRecord inverse_of: :my_module, dependent: :destroy has_many :repository_rows, through: :my_module_repository_rows has_many :repository_snapshots, - class_name: 'RepositorySnapshot', dependent: :destroy, inverse_of: :my_module has_many :user_my_modules, inverse_of: :my_module, dependent: :destroy @@ -201,7 +200,19 @@ class MyModule < ApplicationRecord end def assigned_repositories - Repository.where(id: repository_rows.select('DISTINCT(repository_id)')) + team = experiment.project.team + selected_snapshots = repository_snapshots.joins(:repository_rows) + .where(selected: true) + .group(:parent_id, :id) + live_repositories = team.repositories + .joins(repository_rows: :my_module_repository_rows) + .where(my_module_repository_rows: { my_module_id: id }) + .where.not(id: selected_snapshots.select(:parent_id)) + .group(:id) + + selector = 'repositories.*, COUNT(repository_rows.id) AS assigned_rows_count' + + live_repositories.select(selector) + selected_snapshots.select(selector) end def unassigned_users diff --git a/app/models/repository_snapshot.rb b/app/models/repository_snapshot.rb index e5951bda4..b24ad1454 100644 --- a/app/models/repository_snapshot.rb +++ b/app/models/repository_snapshot.rb @@ -8,8 +8,19 @@ class RepositorySnapshot < RepositoryBase validates :name, presence: true, length: { maximum: Constants::NAME_MAX_LENGTH } validates :status, presence: true + validate :only_one_selected_for_my_module def default_columns_count Constants::REPOSITORY_SNAPSHOT_TABLE_DEFAULT_STATE['length'] end + + private + + def only_one_selected_for_my_module + return unless selected + + if my_module.repository_snapshots.where(original_repository: original_repository, selected: true).any? + errors.add(:selected, I18n.t('activerecord.errors.models.repository_snapshot.attributes.selected.already_taken')) + end + end end diff --git a/app/views/my_modules/repositories/_full_view_version.html.erb b/app/views/my_modules/repositories/_full_view_version.html.erb index 3cc59e152..312b1077e 100644 --- a/app/views/my_modules/repositories/_full_view_version.html.erb +++ b/app/views/my_modules/repositories/_full_view_version.html.erb @@ -1,4 +1,6 @@ -
diff --git a/app/views/my_modules/repositories/_full_view_versions_sidebar.html.erb b/app/views/my_modules/repositories/_full_view_versions_sidebar.html.erb index c517310d1..d82d374b0 100644 --- a/app/views/my_modules/repositories/_full_view_versions_sidebar.html.erb +++ b/app/views/my_modules/repositories/_full_view_versions_sidebar.html.erb @@ -6,7 +6,7 @@
diff --git a/app/views/my_modules/repositories/_repositories_list.html.erb b/app/views/my_modules/repositories/_repositories_list.html.erb index 1034b9d01..907c64664 100644 --- a/app/views/my_modules/repositories/_repositories_list.html.erb +++ b/app/views/my_modules/repositories/_repositories_list.html.erb @@ -7,33 +7,30 @@ data-parent="#assigned-items-container" > - + <%= repository.name %>
- +
<% end %> -