From aee75a2f838ddb5ae2daac4b70e602eaee453647 Mon Sep 17 00:00:00 2001 From: aignatov-bio Date: Mon, 1 Jun 2020 10:24:03 +0200 Subject: [PATCH] Add repository list view --- app/assets/javascripts/repositories/index.js | 205 ++++-------------- app/assets/javascripts/repositories/show.js | 124 ++++++++++- app/assets/javascripts/sidebar_toggle.js.erb | 2 +- .../stylesheets/shared/content_pane.scss | 25 +++ app/assets/stylesheets/shared/datatable.scss | 7 + app/assets/stylesheets/themes/scinote.scss | 6 - app/controllers/repositories_controller.rb | 9 +- app/helpers/repositories_datatable_helper.rb | 23 ++ app/views/repositories/index.html.erb | 47 ++-- app/views/repositories/show.html.erb | 1 - 10 files changed, 259 insertions(+), 190 deletions(-) create mode 100644 app/assets/stylesheets/shared/content_pane.scss create mode 100644 app/helpers/repositories_datatable_helper.rb diff --git a/app/assets/javascripts/repositories/index.js b/app/assets/javascripts/repositories/index.js index daf7cbecf..c135596e9 100644 --- a/app/assets/javascripts/repositories/index.js +++ b/app/assets/javascripts/repositories/index.js @@ -1,172 +1,51 @@ -//= require repositories/import/records_importer.js - -/* - global animateSpinner repositoryRecordsImporter getParam - RepositoryDatatable PerfectScrollbar HelperModule -*/ - -(function(global) { +/* global DataTableHelpers */ +(function() { 'use strict'; - global.pageReload = function() { - animateSpinner(); - location.reload(); - }; + var REPOSITORIES_TABLE; - function handleErrorSubmit(XHR) { - var formGroup = $('#form-records-file').find('.form-group'); - formGroup.addClass('has-error'); - formGroup.find('.help-block').remove(); - formGroup.append( - '' + XHR.responseJSON.message + '' - ); - } - - function handleSuccessfulSubmit(data) { - $('#modal-import-records').modal('hide'); - $(data.html).appendTo('body').promise().done(function() { - $('#parse-records-modal') - .modal('show') - .on('hidden.bs.modal', function() { - animateSpinner(); - location.reload(); - }); - repositoryRecordsImporter(); - }); - } - - function initParseRecordsModal() { - var form = $('#form-records-file'); - var submitBtn = form.find('input[type="submit"]'); - submitBtn.on('click', function(event) { - var data = new FormData(); - event.preventDefault(); - event.stopPropagation(); - data.append('file', document.getElementById('file').files[0]); - data.append('team_id', document.getElementById('team_id').value); - $.ajax({ - type: 'POST', - url: form.attr('action'), - data: data, - success: handleSuccessfulSubmit, - error: handleErrorSubmit, - processData: false, - contentType: false - }); - }); - } - - function initImportRecordsModal() { - $('#importRecordsButton').off().on('click', function() { - $('#modal-import-records').modal('show'); - initParseRecordsModal(); - }); - } - - function loadRepositoryTab() { - var param = getParam('repository'); - $('#repository-tabs a').on('click', function(e) { - var pane = $(this); - e.preventDefault(); - $.ajax({ - url: $(this).attr('data-url'), - type: 'GET', - dataType: 'json', - success: function(data) { - var tabBody = $(pane.context.hash).find('.tab-content-body'); - tabBody.html(data.html); - pane.tab('show').promise().done(function(el) { - initImportRecordsModal(); - RepositoryDatatable.destroy(); - RepositoryDatatable.init(el.attr('data-repo-table')); - }); - }, - error: function() { - // TODO - } - }); - }); - - // on page load - if (param) { - // load selected tab - $('a[href="#custom_repo_' + param + '"]').click(); - } else { - // load first tab content - $('#repository-tabs a:first').click(); - } - - // clean tab content - $('a[data-toggle="tab"]').on('hide.bs.tab', function() { - $('.tab-content-body').html(''); - }); - } - - function initShareModal() { - var form = $('.share-repo-modal').find('form'); - var sharedCBs = form.find("input[name='share_team_ids[]']"); - var permissionCBs = form.find("input[name='write_permissions[]']"); - var permissionChanges = form.find("input[name='permission_changes']"); - var submitBtn = form.find('input[type="submit"]'); - var selectAllCheckbox = form.find('.all-teams .sci-checkbox'); - - form.find('.teams-list').find('input.sci-checkbox, .permission-selector') - .toggleClass('hidden', selectAllCheckbox.is(':checked')); - form.find('.all-teams .sci-toggle-checkbox') - .toggleClass('hidden', !selectAllCheckbox.is(':checked')) - .attr('disabled', !selectAllCheckbox.is(':checked')); - - selectAllCheckbox.change(function() { - form.find('.teams-list').find('input.sci-checkbox, .permission-selector') - .toggleClass('hidden', this.checked); - form.find('.all-teams .sci-toggle-checkbox').toggleClass('hidden', !this.checked) - .attr('disabled', !this.checked); - }); - - sharedCBs.change(function() { - var selectedTeams = form.find('.teams-list .sci-checkbox:checked').length; - form.find('#select_all_teams').prop('indeterminate', selectedTeams > 0); - $('#editable_' + this.value).toggleClass('hidden', !this.checked) - .attr('disabled', !this.checked); - }); - - if (form.find('.teams-list').length) new PerfectScrollbar(form.find('.teams-list')[0]); - - permissionCBs.change(function() { - var changes = JSON.parse(permissionChanges.val()); - changes[this.value] = 'true'; - permissionChanges.val(JSON.stringify(changes)); - }); - - submitBtn.on('click', function(event) { - event.preventDefault(); - $.ajax({ - type: 'POST', - url: form.attr('action'), - data: form.serialize(), - success: function(data) { - if (data.warnings) { - alert(data.warnings); + function initRepositoriesDataTable(tableContainer) { + if (REPOSITORIES_TABLE) REPOSITORIES_TABLE.destroy(); + $('.content-body').html($('#activeRepositoriesListTable').html()); + $.get($(tableContainer).data('source'), function(data) { + REPOSITORIES_TABLE = $(tableContainer).DataTable({ + aaData: data, + dom: "R<'main-actions hidden'<'toolbar'><'filter-container'f>>t<'pagination-row hidden'<'pagination-info'li><'pagination-actions'p>>", + processing: true, + pageLength: 25, + sScrollX: '100%', + sScrollXInner: '100%', + order: [[1, 'asc']], + destroy: true, + columnDefs: [{ + targets: 0, + visible: true, + searchable: false, + orderable: false, + render: function() { + return `
+ + +
`; } - $(`#slide-panel li.active .repository-share-status, - #repository-toolbar .repository-share-status - `).toggleClass('hidden', !data.status); - HelperModule.flashAlertMsg(form.data('success-message'), 'success'); - $('.share-repo-modal').modal('hide'); - }, - error: function(data) { - alert(data.responseJSON.errors); - $('.share-repo-modal').modal('hide'); + }, { + targets: 1, + render: function(value, type, row) { + return `${value}`; + } + }], + + fnInitComplete: function() { + var dataTableWrapper = $(tableContainer).closest('.dataTables_wrapper'); + DataTableHelpers.initLengthApearance(dataTableWrapper); + DataTableHelpers.initSearchField(dataTableWrapper); + $('.content-body .toolbar').html($('#activeRepositoriesListButtons').html()); + dataTableWrapper.find('.main-actions, .pagination-row').removeClass('hidden'); + $('.create-new-repository').initializeModal('#create-repo-modal'); } }); }); } - $('#shareRepoBtn').on('ajax:success', function() { - initShareModal(); - }); - - $('.create-new-repository').initializeModal('#create-repo-modal'); - loadRepositoryTab(); - initImportRecordsModal(); -}(window)); + initRepositoriesDataTable('#repositoriesList'); +}()); diff --git a/app/assets/javascripts/repositories/show.js b/app/assets/javascripts/repositories/show.js index 55ec41b4c..f1f206721 100644 --- a/app/assets/javascripts/repositories/show.js +++ b/app/assets/javascripts/repositories/show.js @@ -1,6 +1,40 @@ -(function() { +//= require repositories/import/records_importer.js + +/* + global animateSpinner repositoryRecordsImporter + RepositoryDatatable PerfectScrollbar HelperModule +*/ + +(function(global) { 'use strict'; + global.pageReload = function() { + animateSpinner(); + location.reload(); + }; + + function handleErrorSubmit(XHR) { + var formGroup = $('#form-records-file').find('.form-group'); + formGroup.addClass('has-error'); + formGroup.find('.help-block').remove(); + formGroup.append( + '' + XHR.responseJSON.message + '' + ); + } + + function handleSuccessfulSubmit(data) { + $('#modal-import-records').modal('hide'); + $(data.html).appendTo('body').promise().done(function() { + $('#parse-records-modal') + .modal('show') + .on('hidden.bs.modal', function() { + animateSpinner(); + location.reload(); + }); + repositoryRecordsImporter(); + }); + } + function initTable() { RepositoryDatatable.destroy(); RepositoryDatatable.init('#' + $('.repository-table table').attr('id')); @@ -8,7 +42,9 @@ } function initParseRecordsModal() { - $('#form-records-file').on('ajax:success', function(ev, data) { + var form = $('#form-records-file'); + var submitBtn = form.find('input[type="submit"]'); + form.on('ajax:success', function(ev, data) { $('#modal-import-records').modal('hide'); $(data.html).appendTo('body').promise().done(function() { $('#parse-records-modal') @@ -25,6 +61,23 @@ $(this).find('.form-group').append("" + data.responseJSON.message + ''); }); + + submitBtn.on('click', function(event) { + var data = new FormData(); + event.preventDefault(); + event.stopPropagation(); + data.append('file', document.getElementById('file').files[0]); + data.append('team_id', document.getElementById('team_id').value); + $.ajax({ + type: 'POST', + url: form.attr('action'), + data: data, + success: handleSuccessfulSubmit, + error: handleErrorSubmit, + processData: false, + contentType: false + }); + }); } function initImportRecordsModal() { @@ -34,6 +87,71 @@ }); } + function initShareModal() { + var form = $('.share-repo-modal').find('form'); + var sharedCBs = form.find("input[name='share_team_ids[]']"); + var permissionCBs = form.find("input[name='write_permissions[]']"); + var permissionChanges = form.find("input[name='permission_changes']"); + var submitBtn = form.find('input[type="submit"]'); + var selectAllCheckbox = form.find('.all-teams .sci-checkbox'); + + form.find('.teams-list').find('input.sci-checkbox, .permission-selector') + .toggleClass('hidden', selectAllCheckbox.is(':checked')); + form.find('.all-teams .sci-toggle-checkbox') + .toggleClass('hidden', !selectAllCheckbox.is(':checked')) + .attr('disabled', !selectAllCheckbox.is(':checked')); + + selectAllCheckbox.change(function() { + form.find('.teams-list').find('input.sci-checkbox, .permission-selector') + .toggleClass('hidden', this.checked); + form.find('.all-teams .sci-toggle-checkbox').toggleClass('hidden', !this.checked) + .attr('disabled', !this.checked); + }); + + sharedCBs.change(function() { + var selectedTeams = form.find('.teams-list .sci-checkbox:checked').length; + form.find('#select_all_teams').prop('indeterminate', selectedTeams > 0); + $('#editable_' + this.value).toggleClass('hidden', !this.checked) + .attr('disabled', !this.checked); + }); + + if (form.find('.teams-list').length) new PerfectScrollbar(form.find('.teams-list')[0]); + + permissionCBs.change(function() { + var changes = JSON.parse(permissionChanges.val()); + changes[this.value] = 'true'; + permissionChanges.val(JSON.stringify(changes)); + }); + + submitBtn.on('click', function(event) { + event.preventDefault(); + $.ajax({ + type: 'POST', + url: form.attr('action'), + data: form.serialize(), + success: function(data) { + if (data.warnings) { + alert(data.warnings); + } + $(`#slide-panel li.active .repository-share-status, + #repository-toolbar .repository-share-status + `).toggleClass('hidden', !data.status); + HelperModule.flashAlertMsg(form.data('success-message'), 'success'); + $('.share-repo-modal').modal('hide'); + }, + error: function(data) { + alert(data.responseJSON.errors); + $('.share-repo-modal').modal('hide'); + } + }); + }); + } + + $('#shareRepoBtn').on('ajax:success', function() { + initShareModal(); + }); + + $('.create-new-repository').initializeModal('#create-repo-modal'); initImportRecordsModal(); initTable(); -}()); +}(window)); diff --git a/app/assets/javascripts/sidebar_toggle.js.erb b/app/assets/javascripts/sidebar_toggle.js.erb index 0b4ef6b83..344c7ec56 100644 --- a/app/assets/javascripts/sidebar_toggle.js.erb +++ b/app/assets/javascripts/sidebar_toggle.js.erb @@ -36,7 +36,7 @@ } $('.navbar-secondary').one("transitionend",function(event) { - $('.navbar-secondary').trigger(sideBarEvent); + $('#sidebar-wrapper').trigger(sideBarEvent); }) } diff --git a/app/assets/stylesheets/shared/content_pane.scss b/app/assets/stylesheets/shared/content_pane.scss new file mode 100644 index 000000000..f90f7aee1 --- /dev/null +++ b/app/assets/stylesheets/shared/content_pane.scss @@ -0,0 +1,25 @@ +.content-pane { + background-color: $color-white; + margin: 20px 0; + padding: 25px 20px; + + &.flexible { + margin: 0; + padding: 0 .5em; + } + + .content-header { + align-items: center; + border-bottom: $border-default; + display: flex; + height: 5em; + + h1 { + margin: 0; + } + } + + .content-body { + + } +} diff --git a/app/assets/stylesheets/shared/datatable.scss b/app/assets/stylesheets/shared/datatable.scss index bf5c57d86..b354ca9c6 100644 --- a/app/assets/stylesheets/shared/datatable.scss +++ b/app/assets/stylesheets/shared/datatable.scss @@ -6,12 +6,19 @@ .main-actions { display: flex; flex-wrap: wrap; + padding: 1em 0; .toolbar { flex-grow: 1; } } + .dataTables_scrollHead { + .dataTable { + margin-top: 0 !important; + } + } + .pagination-row { align-items: center; display: flex; diff --git a/app/assets/stylesheets/themes/scinote.scss b/app/assets/stylesheets/themes/scinote.scss index 93cc686ab..56f9abf8e 100644 --- a/app/assets/stylesheets/themes/scinote.scss +++ b/app/assets/stylesheets/themes/scinote.scss @@ -74,12 +74,6 @@ table { padding-top: 50px; } -.content-pane { - background-color: $color-white; - margin: 20px 0; - padding: 25px 20px; -} - .spacer { margin-left: 0.5em; margin-right: 0.5em; diff --git a/app/controllers/repositories_controller.rb b/app/controllers/repositories_controller.rb index 9e0eb9f42..9380ae2ac 100644 --- a/app/controllers/repositories_controller.rb +++ b/app/controllers/repositories_controller.rb @@ -6,6 +6,7 @@ class RepositoriesController < ApplicationController include ActionView::Context include IconsHelper include TeamsHelper + include RepositoriesDatatableHelper before_action :switch_team_with_param, only: :show before_action :load_repository, except: %i(index create create_modal) @@ -21,8 +22,12 @@ class RepositoriesController < ApplicationController layout 'fluid' def index - redirect_to repository_path(@repositories.first) and return unless @repositories.length.zero? && current_team - render 'repositories/index' + respond_to do |format| + format.html do; end + format.json do + render json: prepare_repositories_datatable(@repositories, current_team, params) + end + end end def show diff --git a/app/helpers/repositories_datatable_helper.rb b/app/helpers/repositories_datatable_helper.rb new file mode 100644 index 000000000..b420d293d --- /dev/null +++ b/app/helpers/repositories_datatable_helper.rb @@ -0,0 +1,23 @@ +# frozen_string_literal: true + +module RepositoriesDatatableHelper + include InputSanitizeHelper + + def prepare_repositories_datatable(repositories, team, _config) + result = [] + repositories = repositories.includes(:repository_rows, :team, :created_by) + repositories.each do |repository| + result.push( + 'DT_RepositoryId': repository.id, + '1': escape_input(repository.name), + '2': repository.repository_rows.size, + '3': repository.shared_with?(team), + '4': escape_input(repository.team.name), + '5': I18n.l(repository.created_at, format: :full), + '6': escape_input(repository.created_by.full_name), + 'repositoryUrl': repository_path(repository) + ) + end + result + end +end diff --git a/app/views/repositories/index.html.erb b/app/views/repositories/index.html.erb index 43ddbabbc..3c34a25ad 100644 --- a/app/views/repositories/index.html.erb +++ b/app/views/repositories/index.html.erb @@ -3,27 +3,46 @@ <% if current_team %> <%= render partial: "sidebar", locals: { repositories: @repositories } %> - <% - # show only if no repositories present. If the team will have them we will - # handle this in left side navigation bar - %> -
-
- <%=t 'libraries.index.no_libraries.text' %> +
+
+

Inventories

+
+
+
+ +
<% end %> <%= javascript_include_tag "repositories/index" %> +<%= stylesheet_link_tag 'datatables' %> diff --git a/app/views/repositories/show.html.erb b/app/views/repositories/show.html.erb index fe1e3b6ca..fef8d686a 100644 --- a/app/views/repositories/show.html.erb +++ b/app/views/repositories/show.html.erb @@ -128,7 +128,6 @@ <%= javascript_include_tag 'repositories/edit' %> <%= javascript_include_tag 'repositories/repository_datatable' %> <%= javascript_include_tag "repositories/show" %> -<%= javascript_include_tag "repositories/index" %> <%= javascript_pack_tag 'custom/inputmask' %> <%= javascript_pack_tag 'emoji_button' %>