mirror of
https://github.com/scinote-eln/scinote-web.git
synced 2025-02-27 09:13:46 +08:00
Merge branch 'features/inventory-archiving' into ml-sci-4689
This commit is contained in:
commit
75f2a49cc4
14 changed files with 247 additions and 74 deletions
|
@ -4,10 +4,11 @@
|
|||
|
||||
var REPOSITORIES_TABLE;
|
||||
|
||||
function initRepositoriesDataTable(tableContainer) {
|
||||
if (REPOSITORIES_TABLE) REPOSITORIES_TABLE.destroy();
|
||||
$('.content-body').html($('#activeRepositoriesListTable').html());
|
||||
$.get($(tableContainer).data('source'), function(data) {
|
||||
function initRepositoriesDataTable(tableContainer, archived = false) {
|
||||
var tableTemplate = archived ? $('#archivedRepositoriesListTable').html() : $('#activeRepositoriesListTable').html();
|
||||
$.get($(tableTemplate).data('source'), function(data) {
|
||||
if (REPOSITORIES_TABLE) REPOSITORIES_TABLE.destroy();
|
||||
$('.content-body').html(tableTemplate);
|
||||
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>>",
|
||||
|
@ -39,7 +40,7 @@
|
|||
var dataTableWrapper = $(tableContainer).closest('.dataTables_wrapper');
|
||||
DataTableHelpers.initLengthApearance(dataTableWrapper);
|
||||
DataTableHelpers.initSearchField(dataTableWrapper);
|
||||
$('.content-body .toolbar').html($('#activeRepositoriesListButtons').html());
|
||||
$('.content-body .toolbar').html($('#repositoriesListButtons').html());
|
||||
dataTableWrapper.find('.main-actions, .pagination-row').removeClass('hidden');
|
||||
$('.create-new-repository').initializeModal('#create-repo-modal');
|
||||
}
|
||||
|
@ -47,5 +48,29 @@
|
|||
});
|
||||
}
|
||||
|
||||
function reloadSidebar() {
|
||||
var slidePanel = $('#slide-panel');
|
||||
var archived;
|
||||
if ($('.repositories-index').hasClass('archived')) archived = true;
|
||||
$.get(slidePanel.data('sidebar-url'), { archived: archived }, function(data) {
|
||||
slidePanel.html(data.html);
|
||||
});
|
||||
}
|
||||
|
||||
function initRepositoryViewSwitcher() {
|
||||
var viewSwitch = $('.view-switch');
|
||||
viewSwitch.on('click', '.view-switch-archived', function() {
|
||||
$('.repositories-index').toggleClass('archived active');
|
||||
initRepositoriesDataTable('#repositoriesList', true);
|
||||
reloadSidebar();
|
||||
});
|
||||
viewSwitch.on('click', '.view-switch-active', function() {
|
||||
$('.repositories-index').toggleClass('archived active');
|
||||
initRepositoriesDataTable('#repositoriesList');
|
||||
reloadSidebar();
|
||||
});
|
||||
}
|
||||
|
||||
initRepositoriesDataTable('#repositoriesList');
|
||||
initRepositoryViewSwitcher();
|
||||
}());
|
||||
|
|
13
app/assets/stylesheets/repository/index.scss
Normal file
13
app/assets/stylesheets/repository/index.scss
Normal file
|
@ -0,0 +1,13 @@
|
|||
.repositories-index {
|
||||
&.active {
|
||||
[data-view-mode="archived"] {
|
||||
display: none
|
||||
}
|
||||
}
|
||||
|
||||
&.archived {
|
||||
[data-view-mode="active"] {
|
||||
display: none
|
||||
}
|
||||
}
|
||||
}
|
|
@ -17,6 +17,37 @@
|
|||
h1 {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.view-switch {
|
||||
margin-left: auto;
|
||||
|
||||
.caret {
|
||||
margin: 8px 0 8px 8px;
|
||||
}
|
||||
&.open {
|
||||
.caret {
|
||||
transform: rotateX(180deg)
|
||||
}
|
||||
}
|
||||
|
||||
.dropdown-menu {
|
||||
@include font-button;
|
||||
min-width: 250px;
|
||||
|
||||
li {
|
||||
cursor: pointer;
|
||||
padding: 1em;
|
||||
|
||||
.button-icon {
|
||||
margin-right: .5em;
|
||||
}
|
||||
|
||||
&:hover {
|
||||
background: $color-concrete;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.content-body {
|
||||
|
|
|
@ -9,10 +9,10 @@ class RepositoriesController < ApplicationController
|
|||
include RepositoriesDatatableHelper
|
||||
|
||||
before_action :switch_team_with_param, only: :show
|
||||
before_action :load_repository, except: %i(index create create_modal)
|
||||
before_action :load_repositories, only: %i(index show)
|
||||
before_action :check_view_all_permissions, only: :index
|
||||
before_action :check_view_permissions, except: %i(index create_modal create update destroy parse_sheet import_records)
|
||||
before_action :load_repository, except: %i(index create create_modal sidebar)
|
||||
before_action :load_repositories, only: %i(index show sidebar)
|
||||
before_action :check_view_all_permissions, only: %i(index sidebar)
|
||||
before_action :check_view_permissions, except: %i(index create_modal create update destroy parse_sheet import_records sidebar)
|
||||
before_action :check_manage_permissions, only: %i(destroy destroy_modal rename_modal update)
|
||||
before_action :check_share_permissions, only: :share_modal
|
||||
before_action :check_create_permissions, only: %i(create_modal create)
|
||||
|
@ -30,6 +30,15 @@ class RepositoriesController < ApplicationController
|
|||
end
|
||||
end
|
||||
|
||||
def sidebar
|
||||
render json: {
|
||||
html: render_to_string(partial: 'repositories/sidebar_list.html.erb', locals: {
|
||||
repositories: @repositories,
|
||||
archived: params[:archived]
|
||||
})
|
||||
}
|
||||
end
|
||||
|
||||
def show
|
||||
@display_edit_button = can_create_repository_rows?(@repository)
|
||||
@display_delete_button = can_delete_repository_rows?(@repository)
|
||||
|
@ -342,6 +351,11 @@ class RepositoriesController < ApplicationController
|
|||
|
||||
def load_repositories
|
||||
@repositories = Repository.accessible_by_teams(current_team).order('repositories.created_at ASC')
|
||||
@repositories = if params[:archived]
|
||||
@repositories.archived
|
||||
else
|
||||
@repositories.active
|
||||
end
|
||||
end
|
||||
|
||||
def set_inline_name_editing
|
||||
|
|
|
@ -5,7 +5,7 @@ module RepositoriesDatatableHelper
|
|||
|
||||
def prepare_repositories_datatable(repositories, team, _config)
|
||||
result = []
|
||||
repositories = repositories.includes(:repository_rows, :team, :created_by)
|
||||
repositories = repositories.includes(:repository_rows, :team, :created_by, :archived_by)
|
||||
repositories.each do |repository|
|
||||
result.push(
|
||||
'DT_RepositoryId': repository.id,
|
||||
|
@ -15,6 +15,8 @@ module RepositoriesDatatableHelper
|
|||
'4': escape_input(repository.team.name),
|
||||
'5': I18n.l(repository.created_at, format: :full),
|
||||
'6': escape_input(repository.created_by.full_name),
|
||||
'7': (I18n.l(repository.archived_on, format: :full) if repository.archived_on),
|
||||
'8': escape_input(repository.archived_by&.full_name),
|
||||
'repositoryUrl': repository_path(repository)
|
||||
)
|
||||
end
|
||||
|
|
|
@ -9,7 +9,7 @@ class RepositoryBase < ApplicationRecord
|
|||
|
||||
belongs_to :team
|
||||
belongs_to :created_by, foreign_key: :created_by_id, class_name: 'User'
|
||||
belongs_to :archived_by, foreign_key: :archived_by_id, class_name: 'User', inverse_of: :repository, optional: true
|
||||
belongs_to :archived_by, foreign_key: :archived_by_id, class_name: 'User', inverse_of: :archived_repositories, optional: true
|
||||
has_many :repository_columns, foreign_key: :repository_id, inverse_of: :repository, dependent: :destroy
|
||||
has_many :repository_rows, foreign_key: :repository_id, inverse_of: :repository, dependent: :destroy
|
||||
has_many :repository_table_states, foreign_key: :repository_id, inverse_of: :repository, dependent: :destroy
|
||||
|
|
|
@ -1,32 +1,6 @@
|
|||
<%= content_for :sidebar do %>
|
||||
<div id="slide-panel" class="visible">
|
||||
<div id="repo-tree" class="tree">
|
||||
<ul class="sidebar-root">
|
||||
<% if can_create_repositories?(current_team) %>
|
||||
<li class="branch">
|
||||
<span class="tree-link no-indent">
|
||||
<a class="btn btn-secondary create-new-repository" data-remote="true"
|
||||
href="<%= create_modal_team_repositories_path(current_team) %>">
|
||||
<i class="fas fa-plus"></i>
|
||||
<%= t('libraries.index.no_libraries.create_new_button') %>
|
||||
</a>
|
||||
</span>
|
||||
</li>
|
||||
<% end %>
|
||||
<% repositories.each do |repository| %>
|
||||
<li class="branch <%= 'active parent_li' if current_page?(repository_path(repository)) %>" >
|
||||
<span class="tree-link no-indent" title="<%= repository.name %>">
|
||||
<%= link_to repository_path(repository),
|
||||
class: current_page?(repository_path(repository)) ? 'disabled line-wrap' : 'line-wrap',
|
||||
data: { 'no-turbolink' => 'true', type: 'repository', id: repository.id } do %>
|
||||
<%= repository.name %>
|
||||
<%= inventory_shared_status_icon(repository, current_team) %>
|
||||
<% end %>
|
||||
</span>
|
||||
</li>
|
||||
<% end %>
|
||||
</ul>
|
||||
</div>
|
||||
<div id="slide-panel" class="visible" data-sidebar-url="<%= sidebar_repositories_path %>">
|
||||
<%= render partial: "sidebar_list", locals: { repositories: repositories, archived: false} %>
|
||||
</div>
|
||||
<% end %>
|
||||
|
||||
|
|
27
app/views/repositories/_sidebar_list.html.erb
Normal file
27
app/views/repositories/_sidebar_list.html.erb
Normal file
|
@ -0,0 +1,27 @@
|
|||
<div id="repo-tree" class="tree">
|
||||
<ul class="sidebar-root">
|
||||
<% if can_create_repositories?(current_team) && !archived %>
|
||||
<li class="branch">
|
||||
<span class="tree-link no-indent">
|
||||
<a class="btn btn-secondary create-new-repository" data-remote="true"
|
||||
href="<%= create_modal_team_repositories_path(current_team) %>">
|
||||
<i class="fas fa-plus"></i>
|
||||
<%= t('libraries.index.no_libraries.create_new_button') %>
|
||||
</a>
|
||||
</span>
|
||||
</li>
|
||||
<% end %>
|
||||
<% repositories.each do |repository| %>
|
||||
<li class="branch <%= 'active parent_li' if current_page?(repository_path(repository)) %>" >
|
||||
<span class="tree-link no-indent" title="<%= repository.name %>">
|
||||
<%= link_to repository_path(repository),
|
||||
class: current_page?(repository_path(repository)) ? 'disabled line-wrap' : 'line-wrap',
|
||||
data: { 'no-turbolink' => 'true', type: 'repository', id: repository.id } do %>
|
||||
<%= repository.name %>
|
||||
<%= inventory_shared_status_icon(repository, current_team) %>
|
||||
<% end %>
|
||||
</span>
|
||||
</li>
|
||||
<% end %>
|
||||
</ul>
|
||||
</div>
|
|
@ -3,46 +3,109 @@
|
|||
|
||||
<% if current_team %>
|
||||
<%= render partial: "sidebar", locals: { repositories: @repositories } %>
|
||||
<div class="content-pane flexible">
|
||||
<div class="content-pane flexible active repositories-index">
|
||||
<div class="content-header">
|
||||
<h1><%= t('libraries.index.head_title') %></h1>
|
||||
<h1 data-view-mode="active"><%= t('libraries.index.head_title') %></h1>
|
||||
<h1 data-view-mode="archived"><%= t('libraries.index.head_title_archived') %></h1>
|
||||
<%= render layout: "shared/view_switch" do %>
|
||||
<li class="view-switch-archived" data-view-mode="active">
|
||||
<i class="fas fa-archive button-icon"></i>
|
||||
<%= t('libraries.index.switch_view.archived') %>
|
||||
</li>
|
||||
<li class="view-switch-active" data-view-mode="archived">
|
||||
<i class="fas fa-rocket button-icon"></i>
|
||||
<%= t('libraries.index.switch_view.active') %>
|
||||
</li>
|
||||
<% end %>
|
||||
</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><%= t('libraries.index.table.name') %></th>
|
||||
<th><%= t('libraries.index.table.number_of_items') %></th>
|
||||
<th><%= t('libraries.index.table.shared') %></th>
|
||||
<th><%= t('libraries.index.table.shared') %></th>
|
||||
<th>Added on</th>
|
||||
<th>Added by</th>
|
||||
</tr>
|
||||
</thead>
|
||||
</table>
|
||||
</template>
|
||||
<template id="activeRepositoriesListButtons">
|
||||
<% if can_create_repositories?(current_team) %>
|
||||
<a class="btn btn-primary btn-lg create-new-repository"
|
||||
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>
|
||||
<% end %>
|
||||
</template>
|
||||
</div>
|
||||
<% end %>
|
||||
|
||||
<!-- Active table template -->
|
||||
<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><%= t('libraries.index.table.name') %></th>
|
||||
<th><%= t('libraries.index.table.number_of_items') %></th>
|
||||
<th><%= t('libraries.index.table.shared') %></th>
|
||||
<th><%= t('libraries.index.table.ownership') %></th>
|
||||
<th><%= t('libraries.index.table.added_on') %></th>
|
||||
<th><%= t('libraries.index.table.added_by') %></th>
|
||||
</tr>
|
||||
</thead>
|
||||
</table>
|
||||
</template>
|
||||
|
||||
|
||||
<!-- Archived table template -->
|
||||
<template id="archivedRepositoriesListTable">
|
||||
<table id="repositoriesList" class="table"
|
||||
data-source="<%= team_repositories_path(current_team, archived: true, 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><%= t('libraries.index.table.name') %></th>
|
||||
<th><%= t('libraries.index.table.number_of_items') %></th>
|
||||
<th><%= t('libraries.index.table.shared') %></th>
|
||||
<th><%= t('libraries.index.table.ownership') %></th>
|
||||
<th><%= t('libraries.index.table.added_on') %></th>
|
||||
<th><%= t('libraries.index.table.added_by') %></th>
|
||||
<th><%= t('libraries.index.table.archived_on') %></th>
|
||||
<th><%= t('libraries.index.table.archived_by') %></th>
|
||||
</tr>
|
||||
</thead>
|
||||
</table>
|
||||
</template>
|
||||
|
||||
<!-- Repositories action buttons -->
|
||||
<template id="repositoriesListButtons">
|
||||
<% if can_create_repositories?(current_team) %>
|
||||
<a class="btn btn-primary btn-lg create-new-repository"
|
||||
data-remote="true"
|
||||
data-view-mode="active"
|
||||
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>
|
||||
<% end %>
|
||||
<a class="btn btn-light" data-view-mode="active" href="#">
|
||||
<span class="fas fa-pencil-alt"></span>
|
||||
<%= t('libraries.index.buttons.edit') %>
|
||||
</a>
|
||||
<a class="btn btn-light" data-view-mode="active" href="#">
|
||||
<span class="fas fa-copy"></span>
|
||||
<%= t('libraries.index.buttons.duplicate') %>
|
||||
</a>
|
||||
<a class="btn btn-light" data-view-mode="active" href="#">
|
||||
<span class="fas fa-archive"></span>
|
||||
<%= t('libraries.index.buttons.archive') %>
|
||||
</a>
|
||||
<a class="btn btn-light" data-view-mode="archived" href="#">
|
||||
<span class="fas fa-undo"></span>
|
||||
<%= t('libraries.index.buttons.restore') %>
|
||||
</a>
|
||||
<a class="btn btn-light" data-view-mode="archived" href="#">
|
||||
<span class="fas fa-trash"></span>
|
||||
<%= t('libraries.index.buttons.delete') %>
|
||||
</a>
|
||||
</template>
|
||||
|
||||
<%= javascript_include_tag "repositories/index" %>
|
||||
<%= stylesheet_link_tag 'datatables' %>
|
||||
|
|
9
app/views/shared/_view_switch.html.erb
Normal file
9
app/views/shared/_view_switch.html.erb
Normal file
|
@ -0,0 +1,9 @@
|
|||
<div class="dropdown view-switch">
|
||||
<a href="#" class="btn btn-light view-switch-button" id="viewSwitchButton" data-toggle="dropdown" aria-haspopup="true" aria-expanded="true">
|
||||
<span><%= t('general.view') %></span>
|
||||
<span class="caret pull-right"></span>
|
||||
</a>
|
||||
<ul class="dropdown-menu dropdown-menu-right" aria-labelledby="viewSwitchButton">
|
||||
<%= yield %>
|
||||
</ul>
|
||||
</div>
|
|
@ -1312,6 +1312,7 @@ en:
|
|||
error_flash: "Something went wrong! Please try again later."
|
||||
index:
|
||||
head_title: "Inventories"
|
||||
head_title_archived: "Archived Inventories"
|
||||
table:
|
||||
name: "Name"
|
||||
number_of_items: "No. of items"
|
||||
|
@ -1319,6 +1320,17 @@ en:
|
|||
ownership: "Ownership"
|
||||
added_on: "Added on"
|
||||
added_by: "Added by"
|
||||
archived_on: "Archived on"
|
||||
archived_by: "Archived by"
|
||||
switch_view:
|
||||
active: Show active inventories
|
||||
archived: Show archived inventories
|
||||
buttons:
|
||||
edit: "Edit"
|
||||
duplicate: "Duplicate"
|
||||
archive: "Archive"
|
||||
restore: "Restore"
|
||||
delete: "Delete"
|
||||
no_libraries:
|
||||
create_new_button: "New Inventory"
|
||||
show:
|
||||
|
@ -2234,6 +2246,7 @@ en:
|
|||
other: "tasks"
|
||||
public: "public"
|
||||
private: "private"
|
||||
view: "View"
|
||||
search: "Search"
|
||||
file:
|
||||
choose: "Choose File"
|
||||
|
|
|
@ -643,6 +643,7 @@ Rails.application.routes.draw do
|
|||
end
|
||||
|
||||
collection do
|
||||
get :sidebar
|
||||
post 'available_rows', to: 'repository_rows#available_rows', defaults: { format: 'json' }
|
||||
end
|
||||
|
||||
|
|
|
@ -7235,3 +7235,4 @@ INSERT INTO "schema_migrations" (version) VALUES
|
|||
('20200604210943');
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -19,7 +19,7 @@ describe RepositoriesController, type: :controller do
|
|||
action
|
||||
parsed_response = JSON.parse(response.body)
|
||||
expect(parsed_response[0].keys).to contain_exactly(
|
||||
'DT_RepositoryId', '1', '2', '3', '4', '5', '6', 'repositoryUrl'
|
||||
'DT_RepositoryId', '1', '2', '3', '4', '5', '6', '7', '8', 'repositoryUrl'
|
||||
)
|
||||
end
|
||||
end
|
||||
|
|
Loading…
Reference in a new issue