Add toolbar to experiment table [SCI-7379]

This commit is contained in:
Anton 2022-11-07 11:49:25 +01:00
parent dd22d53bda
commit 7ceb94ab1f
8 changed files with 177 additions and 15 deletions

View file

@ -1,9 +1,11 @@
/* global I18n GLOBAL_CONSTANTS InfiniteScroll */
const ExperimnetTable = {
var ExperimnetTable = {
permissions: ['editable', 'archivable', 'restorable', 'moveable'],
selectedId: [],
table: '.experiment-table',
render: {},
selectedMyModules: [],
pageSize: GLOBAL_CONSTANTS.DEFAULT_ELEMENTS_PER_PAGE,
loadPlaceholder: function() {
let placeholder = '';
@ -17,10 +19,10 @@ const ExperimnetTable = {
// Checkbox selector
let row = `
<div class="table-body-cell">
<div class="sci-checkbox-container">
<input type="checkbox" class="sci-checkbox">
<span class="sci-checkbox-label"></span>
</div>
<div class="sci-checkbox-container">
<input type="checkbox" class="sci-checkbox my-module-selector" data-my-module="${id}">
<span class="sci-checkbox-label"></span>
</div>
</div>`;
// Task columns
$.each(data, (_i, cell) => {
@ -32,12 +34,77 @@ const ExperimnetTable = {
});
// Menu
row += '<div class="table-body-cell"></div>';
$(`<div class="table-row">${row}</div>`).appendTo(`${this.table} .table-body`);
$(`<div class="table-row" data-id="${id}">${row}</div>`).appendTo(`${this.table} .table-body`);
});
},
checkActionPermission: function(permission) {
let allMyModules;
allMyModules = this.selectedMyModules.every((id) => {
return $(`.table-row[data-id="${id}"]`).data(permission);
});
return allMyModules;
},
initSelectAllCheckbox: function() {
$(this.table).on('click', '.select-all-checkboxes .sci-checkbox', (e1) => {
$.each($('.my-module-selector'), (_i, e2) => {
if (e1.target.checked !== e2.checked) e2.click();
});
});
},
initSelector: function() {
$(this.table).on('click', '.my-module-selector', (e) => {
let checkbox = e.target;
let myModuleId = checkbox.dataset.myModule;
let row = $(`.table-row[data-id="${myModuleId}"]`);
let index = $.inArray(myModuleId, this.selectedMyModules);
// If checkbox is checked and row ID is not in list of selected project IDs
if (checkbox.checked && index === -1) {
$(checkbox).closest('.table-row').addClass('selected');
this.selectedMyModules.push(myModuleId);
// Otherwise, if checkbox is not checked and ID is in list of selected IDs
} else if (!this.checked && index !== -1) {
$(checkbox).closest('.table-row').removeClass('selected');
this.selectedMyModules.splice(index, 1);
}
if (checkbox.checked) {
$.get($(`.table-row[data-id="${myModuleId}"] .my-module-urls`).data('url-permissions'), (result) => {
this.permissions.forEach((permission) => {
row.data(permission, result[permission]);
});
this.updateExperimentToolbar();
});
} else {
this.updateExperimentToolbar();
}
});
},
updateExperimentToolbar: function() {
let experimentToolbar = $('.toolbar-row');
if (this.selectedMyModules.length === 0) {
experimentToolbar.find('.single-object-action, .multiple-object-action').addClass('hidden');
} else if (this.selectedMyModules.length === 1) {
experimentToolbar.find('.single-object-action, .multiple-object-action').removeClass('hidden');
} else {
experimentToolbar.find('.single-object-action').addClass('hidden');
experimentToolbar.find('.multiple-object-action').removeClass('hidden');
}
this.permissions.forEach((permission) => {
if (!this.checkActionPermission(permission)) {
experimentToolbar.find(`.btn[data-for="${permission}"]`).addClass('hidden');
}
});
},
init: function() {
var dataUrl = $(this.table).data('my-modules-url');
this.loadPlaceholder();
this.initSelector();
this.initSelectAllCheckbox();
$.get(dataUrl, (result) => {
$(this.table).find('.table-row').remove();
this.appendRows(result.data);
@ -61,7 +128,11 @@ ExperimnetTable.render.task_name = function(data) {
};
ExperimnetTable.render.id = function(data) {
return data;
let element = $(`<div class="my-module-urls">${data.id}</div>`);
$.each(data.urls, (name, url) => {
element.attr(`data-url-${name}`, url);
});
return element.prop('outerHTML');
};
ExperimnetTable.render.due_date = function(data) {
@ -114,7 +185,10 @@ ExperimnetTable.render.assigned = function(data) {
ExperimnetTable.render.tags = function(data) {
const value = parseInt(data.tags, 10) === 0 ? I18n.t('experiments.table.add_tag') : data.tags;
return `<a href="${data.edit_url}" id="myModuleTags${data.my_module_id}" data-remote="true" class="edit-tags-link">${value}</a>`;
return `<a href="${data.edit_url}"
id="myModuleTags${data.my_module_id}"
data-remote="true"
class="edit-tags-link">${value}</a>`;
};
ExperimnetTable.render.comments = function(data) {

View file

@ -1,9 +1,31 @@
// scss-lint:disable SelectorDepth NestingDepth IdSelector
#experimentTable {
--content-header-size: 5em;
--toolbar-height: 4.5em;
position: relative;
.experiment-table-container {
margin-top: 1em;
overflow-x: scroll;
height: calc(100vh - var(--content-header-size) - var(--navbar-height) - var(--toolbar-height));
overflow: auto;
}
.toolbar-row {
align-items: center;
display: flex;
height: var(--toolbar-height);
.toolbar-left-block {
display: flex;
.btn {
margin-right: .25em;
}
}
.toolbar-right-block {
margin-left: auto;
}
}
.experiment-table {
@ -19,9 +41,9 @@
display: flex;
height: 3em;
padding: 0 .5em;
//position: sticky;
//position: -webkit-sticky;
//top: calc(var(--content-header-size) + var(--navbar-height));
position: sticky;
position: -webkit-sticky;
top: 0;
z-index: 2;
&.select-all-checkboxes {
@ -35,6 +57,7 @@
.table-header {
display: contents;
height: 10px;
&::after {
content: "";

View file

@ -354,6 +354,17 @@ class MyModulesController < ApplicationController
end
end
def permissions
if stale?([@my_module])
render json: {
editable: can_manage_my_module?(@my_module),
moveable: can_move_my_module?(@my_module),
archivable: can_archive_my_module?(@my_module),
restorable: can_restore_my_module?(@my_module)
}
end
end
private
def load_vars

View file

@ -70,7 +70,12 @@ module Experiments
end
def id_presenter(my_module)
my_module.id
{
id: my_module.id,
urls: {
permissions: permissions_my_module_path(my_module)
}
}
end
def due_date_presenter(my_module)

View file

@ -0,0 +1,38 @@
<div class="toolbar-row">
<div class="toolbar-left-block">
<% if can_manage_experiment?(@experiment) %>
<button id="createTask" class="btn btn-primary">
<i class="fas fa-plus"></i>
<%= t("experiments.table.toolbar.new") %>
</button>
<% end %>
<button id="editTask" class="btn btn-light single-object-action hidden" data-for="editable">
<i class="fas fa-pen"></i>
<%= t("experiments.table.toolbar.edit") %>
</button>
<% if can_manage_experiment?(@experiment) %>
<button id="duplicateTask" class="btn btn-light multiple-object-action hidden">
<i class="fas fa-copy"></i>
<%= t("experiments.table.toolbar.duplicate") %>
</button>
<% end %>
<button id="moveTask" class="btn btn-light multiple-object-action hidden" data-for="moveable">
<i class="fas fa-arrow-right"></i>
<%= t("experiments.table.toolbar.move") %>
</button>
<button id="manageTaskAccess" class="btn btn-light single-object-action hidden">
<i class="fas fa-door-open"></i>
<%= t("experiments.table.toolbar.manage_access") %>
</button>
<button id="archiveTask" class="btn btn-light multiple-object-action hidden" data-for="archivable">
<i class="fas fa-archive"></i>
<%= t("experiments.table.toolbar.archive") %>
</button>
</div>
<div class="toolbar-right-block">
<button id="taskDataDisplay" class="btn btn-light">
<i class="fas fa-eye"></i>
<%= t("experiments.table.toolbar.task_data") %>
</button>
</div>
</div>

View file

@ -9,7 +9,7 @@
<div class="content-pane flexible" id="experimentTable">
<%= render partial: 'experiments/show_header' %>
<%= render partial: 'experiments/table_toolbar' %>
<div class="experiment-table-container">
<div class="experiment-table"
style="--columns-count: <%= Experiments::TableViewService::COLUMNS.length%>"

View file

@ -1304,6 +1304,14 @@ en:
assigned_html: 'Assigned to'
tags_html: 'Tags'
comments_html: '<i class="fas fa-comment"></i>'
toolbar:
new: 'New task'
edit: 'Edit'
archive: 'Archive'
move: 'Move'
duplicate: 'Duplicate'
manage_access: 'Manage access'
task_data: 'Task data display'
add_tag: '+ Add tag'
canvas:
archive_confirm: "Are you sure to archive this experiment?"

View file

@ -381,6 +381,9 @@ Rails.application.routes.draw do
# Show action is a popup (JSON) for individual module in full-zoom canvas,
# as well as 'module info' page for single module (HTML)
resources :my_modules, path: '/modules', only: [:show, :update] do
member do
get :permissions
end
resources :my_module_tags, path: '/tags', only: [:index, :create, :destroy] do
collection do
get :search_tags