mirror of
https://github.com/scinote-eln/scinote-web.git
synced 2025-02-26 16:53:12 +08:00
Add repository list view
This commit is contained in:
parent
be8c7e01e2
commit
aee75a2f83
10 changed files with 259 additions and 190 deletions
|
@ -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(
|
||||
'<span class="help-block">' + XHR.responseJSON.message + '</span>'
|
||||
);
|
||||
}
|
||||
|
||||
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 `<div class="sci-checkbox-container">
|
||||
<input class='repository-row-selector sci-checkbox' type='checkbox'>
|
||||
<span class='sci-checkbox-label'></span>
|
||||
</div>`;
|
||||
}
|
||||
$(`#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 `<a href="${row.repositoryUrl}">${value}</a>`;
|
||||
}
|
||||
}],
|
||||
|
||||
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');
|
||||
}());
|
||||
|
|
|
@ -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(
|
||||
'<span class="help-block">' + XHR.responseJSON.message + '</span>'
|
||||
);
|
||||
}
|
||||
|
||||
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("<span class='help-block'>" +
|
||||
data.responseJSON.message + '</span>');
|
||||
});
|
||||
|
||||
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));
|
||||
|
|
|
@ -36,7 +36,7 @@
|
|||
}
|
||||
|
||||
$('.navbar-secondary').one("transitionend",function(event) {
|
||||
$('.navbar-secondary').trigger(sideBarEvent);
|
||||
$('#sidebar-wrapper').trigger(sideBarEvent);
|
||||
})
|
||||
}
|
||||
|
||||
|
|
25
app/assets/stylesheets/shared/content_pane.scss
Normal file
25
app/assets/stylesheets/shared/content_pane.scss
Normal file
|
@ -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 {
|
||||
|
||||
}
|
||||
}
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
|
23
app/helpers/repositories_datatable_helper.rb
Normal file
23
app/helpers/repositories_datatable_helper.rb
Normal file
|
@ -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
|
|
@ -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
|
||||
%>
|
||||
<div class="content-pane">
|
||||
<div class="jumbotron text-center" style="margin-top:12%">
|
||||
<strong><%=t 'libraries.index.no_libraries.text' %></strong>
|
||||
<div class="content-pane flexible">
|
||||
<div class="content-header">
|
||||
<h1>Inventories</h1>
|
||||
</div>
|
||||
<div class="content-body">
|
||||
</div>
|
||||
<template id="activeRepositoriesListTable">
|
||||
<table id="repositoriesList" class="table"
|
||||
data-source="<%= team_repositories_path(current_team, format: :json) %>"
|
||||
>
|
||||
<thead>
|
||||
<tr>
|
||||
<th>
|
||||
<div class="sci-checkbox-container">
|
||||
<input value="1" type="checkbox" class="sci-checkbox">
|
||||
<span class="sci-checkbox-label"></span>
|
||||
</div>
|
||||
</th>
|
||||
<th>Name</th>
|
||||
<th>No. of items</th>
|
||||
<th>Shared</th>
|
||||
<th>Ownership</th>
|
||||
<th>Added on</th>
|
||||
<th>Added by</th>
|
||||
</tr>
|
||||
</thead>
|
||||
</table>
|
||||
</template>
|
||||
<template id="activeRepositoriesListButtons">
|
||||
<% if can_create_repositories?(current_team) %>
|
||||
<h2><strong><%=t 'libraries.index.no_libraries.title' %><strong></h2>
|
||||
<br />
|
||||
<a class="btn btn-primary btn-lg create-new-repository"
|
||||
data-remote="true"
|
||||
href="<%= create_modal_team_repositories_path(current_team) %>">
|
||||
data-remote="true"
|
||||
href="<%= create_modal_team_repositories_path(current_team) %>">
|
||||
<span class="fas fa-plus"></span>
|
||||
<span class="hidden-xs"><%= t('libraries.index.no_libraries.create_new_button') %></span>
|
||||
</a>
|
||||
<% else %>
|
||||
<p class="no-permission-title"><strong><%=t 'libraries.index.no_libraries.no_permission_title' %></strong></p>
|
||||
<% end %>
|
||||
</div>
|
||||
</template>
|
||||
</div>
|
||||
<% end %>
|
||||
|
||||
<%= javascript_include_tag "repositories/index" %>
|
||||
<%= stylesheet_link_tag 'datatables' %>
|
||||
|
|
|
@ -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' %>
|
||||
|
||||
|
|
Loading…
Reference in a new issue