mirror of
https://github.com/scinote-eln/scinote-web.git
synced 2025-01-27 10:08:11 +08:00
Add assign items modal and update modal for task inventories
This commit is contained in:
parent
10fdd0c1c7
commit
34d6e903a4
22 changed files with 551 additions and 162 deletions
|
@ -1,11 +1,22 @@
|
|||
/* eslint-disable no-param-reassign */
|
||||
/* global DataTableHelpers PerfectScrollbar FilePreviewModal animateSpinner */
|
||||
/* global DataTableHelpers PerfectScrollbar FilePreviewModal animateSpinner HelperModule */
|
||||
|
||||
|
||||
|
||||
var MyModuleRepositories = (function() {
|
||||
const FULL_VIEW_MODAL = $('#myModuleRepositoryFullViewModal');
|
||||
const UPDATE_REPOSITORY_MODAL = $('#updateRepositoryRecordModal');
|
||||
var SIMPLE_TABLE;
|
||||
var FULL_VIEW_TABLE;
|
||||
var FULL_VIEW_TABLE_SCROLLBAR;
|
||||
var SELECTED_ROWS = {};
|
||||
|
||||
function reloadRepositoriesList() {
|
||||
var repositoriesContainer = $('#assigned-items-container');
|
||||
$.get(repositoriesContainer.data('repositories-list-url'), function(result) {
|
||||
repositoriesContainer.html(result.html);
|
||||
});
|
||||
}
|
||||
|
||||
function tableColumns(tableContainer, skipCheckbox = false) {
|
||||
var columns = $(tableContainer).data('default-table-columns');
|
||||
|
@ -28,9 +39,20 @@ var MyModuleRepositories = (function() {
|
|||
|
||||
function fullViewColumnDefs() {
|
||||
let columnDefs = [{
|
||||
targets: 0,
|
||||
visible: false
|
||||
}];
|
||||
targets: 0,
|
||||
visible: true,
|
||||
searchable: false,
|
||||
orderable: false,
|
||||
className: 'dt-body-center',
|
||||
sWidth: '1%',
|
||||
render: function(data) {
|
||||
var checked = data ? 'checked' : '';
|
||||
return `<div class="sci-checkbox-container">
|
||||
<input class='repository-row-selector sci-checkbox' type='checkbox' ${checked}>
|
||||
<span class='sci-checkbox-label'></span>
|
||||
</div>`;
|
||||
}
|
||||
}];
|
||||
|
||||
if (FULL_VIEW_MODAL.find('.table').data('type') === 'live') {
|
||||
columnDefs.push({
|
||||
|
@ -100,8 +122,9 @@ var MyModuleRepositories = (function() {
|
|||
});
|
||||
}
|
||||
|
||||
function renderFullViewTable(tableContainer) {
|
||||
function renderFullViewTable(tableContainer, options = {}) {
|
||||
if (FULL_VIEW_TABLE) FULL_VIEW_TABLE.destroy();
|
||||
SELECTED_ROWS = {};
|
||||
FULL_VIEW_TABLE_SCROLLBAR = false;
|
||||
FULL_VIEW_TABLE = $(tableContainer).DataTable({
|
||||
dom: "R<'main-actions hidden'<'toolbar'><'filter-container'f>>t<'pagination-row hidden'<'pagination-info'li><'pagination-actions'p>>",
|
||||
|
@ -116,21 +139,25 @@ var MyModuleRepositories = (function() {
|
|||
ajax: {
|
||||
url: $(tableContainer).data('source'),
|
||||
data: function(d) {
|
||||
d.assigned = 'assigned';
|
||||
if (options.assigned) d.assigned = 'assigned';
|
||||
d.view_mode = true;
|
||||
},
|
||||
global: false,
|
||||
type: 'POST'
|
||||
},
|
||||
columns: tableColumns(tableContainer, true),
|
||||
columns: tableColumns(tableContainer, options.skipCheckbox),
|
||||
columnDefs: fullViewColumnDefs(),
|
||||
|
||||
fnInitComplete: function() {
|
||||
var dataTableWrapper = $(tableContainer).closest('.dataTables_wrapper');
|
||||
DataTableHelpers.initLengthApearance(dataTableWrapper);
|
||||
DataTableHelpers.initSearchField(dataTableWrapper);
|
||||
dataTableWrapper.find('.main-actions, .pagination-row').removeClass('hidden');
|
||||
|
||||
$('.table-container .toolbar').html($('#repositoryToolbarButtonsTemplate').html());
|
||||
if (options.assign_mode) {
|
||||
renderFullViewActionButtons();
|
||||
} else {
|
||||
$('.table-container .toolbar').html($('#repositoryToolbarButtonsTemplate').html());
|
||||
}
|
||||
},
|
||||
|
||||
drawCallback: function() {
|
||||
|
@ -148,12 +175,21 @@ var MyModuleRepositories = (function() {
|
|||
);
|
||||
}
|
||||
},
|
||||
|
||||
stateLoadCallback: function(settings, callback) {
|
||||
var loadStateUrl = $(tableContainer).data('load-state-url');
|
||||
$.post(loadStateUrl, function(json) {
|
||||
json.state.columns[0].visible = false;
|
||||
callback(json.state);
|
||||
});
|
||||
},
|
||||
|
||||
rowCallback: function(row) {
|
||||
var checkbox = $(row).find('.repository-row-selector');
|
||||
if (SELECTED_ROWS[row.id]) {
|
||||
$(row).addClass('selected');
|
||||
checkbox.attr('checked', !checkbox.attr('checked'));
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
@ -184,7 +220,6 @@ var MyModuleRepositories = (function() {
|
|||
|
||||
function reloadTable(tableUrl) {
|
||||
animateSpinner(null, true);
|
||||
if (FULL_VIEW_TABLE) FULL_VIEW_TABLE.destroy();
|
||||
$.get(tableUrl, (data) => {
|
||||
FULL_VIEW_MODAL.find('.table-container').html(data.html);
|
||||
renderFullViewTable(FULL_VIEW_MODAL.find('.table'));
|
||||
|
@ -193,6 +228,34 @@ var MyModuleRepositories = (function() {
|
|||
});
|
||||
}
|
||||
|
||||
function initSelectAllCheckbox() {
|
||||
FULL_VIEW_MODAL.on('click', 'input.select-all', function() {
|
||||
var selectAllCheckbox = $(this);
|
||||
var rows = FULL_VIEW_MODAL.find('.dataTables_scrollBody tbody tr');
|
||||
$.each(rows, function(i, row) {
|
||||
var checkbox = $(row).find('.repository-row-selector');
|
||||
if (checkbox.prop('checked') === selectAllCheckbox.prop('checked')) return;
|
||||
|
||||
checkbox.prop('checked', !checkbox.prop('checked'));
|
||||
selectFullViewRow(row);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
function refreshSelectAllCheckbox() {
|
||||
var checkboxes = FULL_VIEW_MODAL.find('.dataTables_scrollBody .repository-row-selector');
|
||||
var selectedCheckboxes = FULL_VIEW_MODAL.find('.dataTables_scrollBody .repository-row-selector:checked');
|
||||
var selectAllCheckbox = FULL_VIEW_MODAL.find('input.select-all');
|
||||
selectAllCheckbox.prop('indeterminate', false);
|
||||
if (selectedCheckboxes.length === 0) {
|
||||
selectAllCheckbox.prop('checked', false);
|
||||
} else if (selectedCheckboxes.length === checkboxes.length) {
|
||||
selectAllCheckbox.prop('checked', true);
|
||||
} else {
|
||||
selectAllCheckbox.prop('indeterminate', true);
|
||||
}
|
||||
}
|
||||
|
||||
function initSimpleTable() {
|
||||
$('#assigned-items-container').on('show.bs.collapse', '.assigned-repository-container', function() {
|
||||
var repositoryContainer = $(this);
|
||||
|
@ -255,7 +318,7 @@ var MyModuleRepositories = (function() {
|
|||
FULL_VIEW_MODAL.modal('show');
|
||||
$.get($(this).data('table-url'), (data) => {
|
||||
FULL_VIEW_MODAL.find('.table-container').html(data.html);
|
||||
renderFullViewTable(FULL_VIEW_MODAL.find('.table'));
|
||||
renderFullViewTable(FULL_VIEW_MODAL.find('.table'), { assigned: true, skipCheckbox: true });
|
||||
});
|
||||
e.stopPropagation();
|
||||
});
|
||||
|
@ -270,12 +333,153 @@ var MyModuleRepositories = (function() {
|
|||
});
|
||||
}
|
||||
|
||||
function selectFullViewRow(row) {
|
||||
var id = row.id;
|
||||
|
||||
if (!SELECTED_ROWS[id]) {
|
||||
SELECTED_ROWS[id] = {
|
||||
row_name: $(row).find('.record-info-link').text(),
|
||||
assigned: $(row).find('.repository-row-selector').prop('checked')
|
||||
};
|
||||
} else {
|
||||
delete SELECTED_ROWS[id];
|
||||
}
|
||||
|
||||
$(row).toggleClass('selected');
|
||||
|
||||
if (Object.keys(SELECTED_ROWS).length) {
|
||||
$('#assignRepositoryRecords, #updateRepositoryRecords').attr('disabled', false);
|
||||
} else {
|
||||
$('#assignRepositoryRecords, #updateRepositoryRecords').attr('disabled', true);
|
||||
}
|
||||
|
||||
refreshSelectAllCheckbox();
|
||||
}
|
||||
|
||||
function renderFullViewActionButtons() {
|
||||
var toolbar = FULL_VIEW_MODAL.find('.dataTables_wrapper .toolbar');
|
||||
toolbar.empty();
|
||||
if (FULL_VIEW_MODAL.data('rows-count') === 0) {
|
||||
toolbar.append($('#my-module-repository-full-view-assign-button').html());
|
||||
} else {
|
||||
toolbar.append($('#my-module-repository-full-view-update-button').html());
|
||||
}
|
||||
}
|
||||
|
||||
function updateFullViewRowsCount(value) {
|
||||
FULL_VIEW_MODAL.data('rows-count', value);
|
||||
FULL_VIEW_MODAL.find('.assigned-repository-title').attr('data-rows-count', `[${value}]`);
|
||||
}
|
||||
|
||||
function initRepoistoryAssignView() {
|
||||
$('.repositories-dropdown-menu').on('click', '.repository', function(e) {
|
||||
var assignUrlModal = $(this).data('assign-url-modal');
|
||||
var updateUrlModal = $(this).data('update-url-modal');
|
||||
var repositoryNameObject = $(this).find('.name').clone().addClass('assigned-repository-title');
|
||||
|
||||
FULL_VIEW_MODAL.find('.repository-name').html(repositoryNameObject);
|
||||
FULL_VIEW_MODAL.data('rows-count', $(this).data('rows-count'));
|
||||
FULL_VIEW_MODAL.modal('show');
|
||||
$.get($(this).data('table-url'), (data) => {
|
||||
FULL_VIEW_MODAL.find('.modal-body').html(data.html);
|
||||
FULL_VIEW_MODAL.data('assign-url-modal', assignUrlModal);
|
||||
FULL_VIEW_MODAL.data('update-url-modal', updateUrlModal);
|
||||
renderFullViewTable(FULL_VIEW_MODAL.find('.table'), { assign_mode: true });
|
||||
});
|
||||
e.stopPropagation();
|
||||
});
|
||||
|
||||
FULL_VIEW_MODAL.on('click', '.table tbody tr', function() {
|
||||
var checkbox = $(this).find('.repository-row-selector');
|
||||
checkbox.prop('checked', !checkbox.prop('checked'));
|
||||
selectFullViewRow(this);
|
||||
}).on('click', '.table tbody tr .repository-row-selector', function(e) {
|
||||
selectFullViewRow($(this).closest('tr')[0]);
|
||||
e.stopPropagation();
|
||||
}).on('click', '#assignRepositoryRecords', function() {
|
||||
openAssignRecordsModal();
|
||||
}).on('click', '#updateRepositoryRecords', function() {
|
||||
openUpdateRecordsModal();
|
||||
});
|
||||
|
||||
UPDATE_REPOSITORY_MODAL.on('click', '.downstream-action', function() {
|
||||
submitUpdateRepositoryRecord({ downstream: true });
|
||||
}).on('click', '.task-action', function() {
|
||||
submitUpdateRepositoryRecord({ downstream: false });
|
||||
});
|
||||
}
|
||||
|
||||
function openUpdateRecordsModal() {
|
||||
var updateUrl = FULL_VIEW_MODAL.data('update-url-modal');
|
||||
$.get(updateUrl, { selected_rows: SELECTED_ROWS }, function(data) {
|
||||
var assignList;
|
||||
var assignListScrollbar;
|
||||
var unassignList;
|
||||
var unassignListScrollbar;
|
||||
UPDATE_REPOSITORY_MODAL.find('.modal-content').html(data.html);
|
||||
UPDATE_REPOSITORY_MODAL.data('update-url', data.update_url);
|
||||
assignList = UPDATE_REPOSITORY_MODAL.find('.rows-to-assign .rows-list')[0];
|
||||
unassignList = UPDATE_REPOSITORY_MODAL.find('.rows-to-unassign .rows-list')[0];
|
||||
UPDATE_REPOSITORY_MODAL.modal('show');
|
||||
if (assignList) assignListScrollbar = new PerfectScrollbar(assignList);
|
||||
if (unassignList) unassignListScrollbar = new PerfectScrollbar(unassignList);
|
||||
});
|
||||
}
|
||||
|
||||
function openAssignRecordsModal() {
|
||||
var assignUrl = FULL_VIEW_MODAL.data('assign-url-modal');
|
||||
$.get(assignUrl, { selected_rows: SELECTED_ROWS }, function(data) {
|
||||
UPDATE_REPOSITORY_MODAL.find('.modal-content').html(data.html);
|
||||
UPDATE_REPOSITORY_MODAL.data('update-url', data.update_url);
|
||||
UPDATE_REPOSITORY_MODAL.modal('show');
|
||||
});
|
||||
}
|
||||
|
||||
function submitUpdateRepositoryRecord(options = {}) {
|
||||
var rowsToAssign = [];
|
||||
var rowsToUnassign = [];
|
||||
$.each(Object.keys(SELECTED_ROWS), function(i, rowId) {
|
||||
if (SELECTED_ROWS[rowId].assigned) {
|
||||
rowsToAssign.push(rowId);
|
||||
} else {
|
||||
rowsToUnassign.push(rowId);
|
||||
}
|
||||
});
|
||||
$.ajax({
|
||||
url: UPDATE_REPOSITORY_MODAL.data('update-url'),
|
||||
type: 'PATCH',
|
||||
dataType: 'json',
|
||||
data: {
|
||||
rows_to_assign: rowsToAssign,
|
||||
rows_to_unassign: rowsToUnassign,
|
||||
downstream: options.downstream
|
||||
},
|
||||
success: function(data) {
|
||||
UPDATE_REPOSITORY_MODAL.modal('hide');
|
||||
HelperModule.flashAlertMsg(data.flash, 'success');
|
||||
SELECTED_ROWS = {};
|
||||
FULL_VIEW_TABLE.ajax.reload(null, false);
|
||||
reloadRepositoriesList();
|
||||
updateFullViewRowsCount(data.rows_count);
|
||||
renderFullViewActionButtons();
|
||||
},
|
||||
error: function(data) {
|
||||
UPDATE_REPOSITORY_MODAL.modal('hide');
|
||||
HelperModule.flashAlertMsg(data.responseJSON.flash, 'danger');
|
||||
SELECTED_ROWS = {};
|
||||
FULL_VIEW_TABLE.ajax.reload(null, false);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
return {
|
||||
init: () => {
|
||||
initSimpleTable();
|
||||
initRepositoryFullView();
|
||||
initRepositoriesDropdown();
|
||||
initVersionsSidebarActions();
|
||||
initRepoistoryAssignView();
|
||||
initSelectAllCheckbox();
|
||||
}
|
||||
};
|
||||
}());
|
||||
|
|
|
@ -640,19 +640,6 @@ var RepositoryDatatable = (function(global) {
|
|||
});
|
||||
};
|
||||
|
||||
global.openAssignRecordsModal = function() {
|
||||
$.post(
|
||||
$('#assignRepositoryRecords').data('assign-url-modal'),
|
||||
{ selected_rows: rowsSelected }
|
||||
).done(
|
||||
function(data) {
|
||||
$(data.html).appendTo('body').promise().done(function() {
|
||||
$('#assignRepositoryRecordModal').modal('show');
|
||||
});
|
||||
}
|
||||
);
|
||||
};
|
||||
|
||||
global.hideAssignUnasignModal = function(id) {
|
||||
$(id).modal('hide').promise().done(
|
||||
function() {
|
||||
|
@ -661,28 +648,6 @@ var RepositoryDatatable = (function(global) {
|
|||
);
|
||||
};
|
||||
|
||||
global.submitAssignRepositoryRecord = function(option) {
|
||||
animateSpinner();
|
||||
$.ajax({
|
||||
url: $('#assignRepositoryRecordModal').data('assign-url'),
|
||||
type: 'POST',
|
||||
dataType: 'json',
|
||||
data: { selected_rows: rowsSelected, downstream: (option === 'downstream') },
|
||||
success: function(data) {
|
||||
hideAssignUnasignModal('#assignRepositoryRecordModal');
|
||||
HelperModule.flashAlertMsg(data.flash, 'success');
|
||||
resetTableView();
|
||||
clearRowSelection();
|
||||
},
|
||||
error: function(data) {
|
||||
hideAssignUnasignModal('#assignRepositoryRecordModal');
|
||||
HelperModule.flashAlertMsg(data.responseJSON.flash, 'danger');
|
||||
resetTableView();
|
||||
clearRowSelection();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
global.openUnassignRecordsModal = function() {
|
||||
$.post(
|
||||
$('#unassignRepositoryRecords').data('unassign-url'),
|
||||
|
|
|
@ -64,6 +64,7 @@
|
|||
|
||||
.repository {
|
||||
@include font-button;
|
||||
cursor: pointer;
|
||||
display: flex;
|
||||
padding: 8px 16px;
|
||||
|
||||
|
|
|
@ -259,6 +259,11 @@
|
|||
}
|
||||
|
||||
.dataTables_scrollBody {
|
||||
|
||||
tbody tr.selected {
|
||||
background: $brand-warning-light;
|
||||
}
|
||||
|
||||
.assigned-column {
|
||||
position: relative;
|
||||
|
||||
|
@ -362,3 +367,46 @@
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
.update-repository-record-modal {
|
||||
.rows-list-container {
|
||||
display: flex;
|
||||
margin: 0 -10px;
|
||||
|
||||
.header {
|
||||
font-weight: bold;
|
||||
|
||||
.fas {
|
||||
margin-right: 3px;
|
||||
}
|
||||
}
|
||||
|
||||
.rows-list {
|
||||
background: $color-concrete;
|
||||
height: 170px;
|
||||
list-style: none;
|
||||
overflow: hidden;
|
||||
padding-left: 16px;
|
||||
position: relative;
|
||||
|
||||
li {
|
||||
margin: 6px 0;
|
||||
}
|
||||
}
|
||||
|
||||
.rows-to-assign,
|
||||
.rows-to-unassign {
|
||||
flex-grow: 1;
|
||||
margin: 0 10px;
|
||||
}
|
||||
|
||||
.rows-to-assign .header .fas {
|
||||
color: $brand-success;
|
||||
}
|
||||
|
||||
.rows-to-unassign .header .fas {
|
||||
color: $brand-danger;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
|
@ -2,10 +2,21 @@
|
|||
// scss-lint:disable NestingDepth QualifyingElement
|
||||
|
||||
.dataTables_wrapper {
|
||||
|
||||
.main-actions {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
|
||||
.toolbar {
|
||||
flex-grow: 1;
|
||||
}
|
||||
}
|
||||
|
||||
.pagination-row {
|
||||
align-items: center;
|
||||
background-color: $color-white;
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
height: 68px;
|
||||
width: 100%;
|
||||
|
||||
|
|
|
@ -1,10 +1,14 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
class MyModuleRepositoriesController < ApplicationController
|
||||
include ApplicationHelper
|
||||
|
||||
before_action :load_my_module
|
||||
before_action :load_repository, except: %i(repositories_dropdown_list)
|
||||
before_action :load_repository, except: %i(repositories_dropdown_list repositories_list_html)
|
||||
before_action :check_my_module_view_permissions
|
||||
before_action :check_repository_view_permissions, except: %i(repositories_dropdown_list)
|
||||
before_action :check_repository_view_permissions, except: %i(repositories_dropdown_list repositories_list_html)
|
||||
|
||||
before_action :check_assign_repository_records_permissions, only: :update
|
||||
|
||||
def index_dt
|
||||
@draw = params[:draw].to_i
|
||||
|
@ -14,7 +18,8 @@ class MyModuleRepositoriesController < ApplicationController
|
|||
|
||||
@datatable_params = {
|
||||
view_mode: params[:view_mode],
|
||||
skip_custom_columns: params[:skip_custom_columns]
|
||||
skip_custom_columns: params[:skip_custom_columns],
|
||||
my_module: @my_module
|
||||
}
|
||||
@all_rows_count = datatable_service.all_count
|
||||
@columns_mappings = datatable_service.mappings
|
||||
|
@ -28,6 +33,69 @@ class MyModuleRepositoriesController < ApplicationController
|
|||
render 'repository_rows/index.json'
|
||||
end
|
||||
|
||||
def update
|
||||
if params[:rows_to_assign]
|
||||
assign_service = RepositoryRows::MyModuleAssigningService.call(my_module: @my_module,
|
||||
repository: @repository,
|
||||
user: current_user,
|
||||
params: params)
|
||||
end
|
||||
if params[:rows_to_unassign]
|
||||
unassign_service = RepositoryRows::MyModuleUnassigningService.call(my_module: @my_module,
|
||||
repository: @repository,
|
||||
user: current_user,
|
||||
params: params)
|
||||
end
|
||||
|
||||
if (params[:rows_to_assign].nil? || assign_service.succeed?) &&
|
||||
(params[:rows_to_unassign].nil? || unassign_service.succeed?)
|
||||
flash = update_flash_message(assign_service, unassign_service)
|
||||
status = :ok
|
||||
else
|
||||
flash = t('my_modules.repository.flash.update_error')
|
||||
status = :bad_request
|
||||
end
|
||||
|
||||
respond_to do |format|
|
||||
format.json do
|
||||
render json: { flash: flash, rows_count: @my_module.repository_rows_count(@repository) }, status: status
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def update_repository_records_modal
|
||||
selected_rows = params[:selected_rows]
|
||||
modal = render_to_string(
|
||||
partial: 'my_modules/modals/update_repository_records_modal_content.html.erb',
|
||||
locals: { my_module: @my_module,
|
||||
repository: @repository,
|
||||
selected_rows: selected_rows }
|
||||
)
|
||||
render json: {
|
||||
html: modal,
|
||||
update_url: my_module_my_module_repository_path(@my_module, @repository)
|
||||
}, status: :ok
|
||||
end
|
||||
|
||||
def assign_repository_records_modal
|
||||
selected_rows = params[:selected_rows]
|
||||
modal = render_to_string(
|
||||
partial: 'my_modules/modals/assign_repository_records_modal_content.html.erb',
|
||||
locals: { my_module: @my_module,
|
||||
repository: @repository,
|
||||
selected_rows: selected_rows }
|
||||
)
|
||||
render json: {
|
||||
html: modal,
|
||||
update_url: my_module_my_module_repository_path(@my_module, @repository)
|
||||
}, status: :ok
|
||||
end
|
||||
|
||||
def repositories_list_html
|
||||
@assigned_repositories = @my_module.assigned_repositories
|
||||
render json: { html: render_to_string(partial: 'my_modules/repositories/repositories_list') }
|
||||
end
|
||||
|
||||
def full_view_table
|
||||
render json: {
|
||||
html: render_to_string(partial: 'my_modules/repositories/full_view_table')
|
||||
|
@ -59,4 +127,38 @@ class MyModuleRepositoriesController < ApplicationController
|
|||
def check_repository_view_permissions
|
||||
render_403 unless can_read_repository?(@repository)
|
||||
end
|
||||
|
||||
def check_assign_repository_records_permissions
|
||||
render_403 unless module_page? &&
|
||||
can_assign_repository_rows_to_module?(@my_module)
|
||||
end
|
||||
|
||||
def update_flash_message(assign_service, unassign_service)
|
||||
assigned_count = params[:rows_to_assign]&.count
|
||||
unassigned_count = params[:rows_to_unassign]&.count
|
||||
|
||||
if params[:downstream] == 'true'
|
||||
if assigned_count && unassigned_count
|
||||
t('my_modules.repository.flash.assign_and_unassign_from_task_and_downstream_html',
|
||||
assigned_items: assigned_count,
|
||||
unassigned_items: unassigned_count)
|
||||
elsif assigned_count
|
||||
t('my_modules.repository.flash.assign_to_task_and_downstream_html',
|
||||
assigned_items: assigned_count)
|
||||
elsif unassigned_count
|
||||
t('my_modules.repository.flash.unassign_from_task_and_downstream_html',
|
||||
unassigned_items: unassigned_count)
|
||||
end
|
||||
elsif assigned_count && unassigned_count
|
||||
t('my_modules.repository.flash.assign_and_unassign_from_task_html',
|
||||
assigned_items: assigned_count,
|
||||
unassigned_items: unassigned_count)
|
||||
elsif assigned_count
|
||||
t('my_modules.repository.flash.assign_to_task_html',
|
||||
assigned_items: assigned_count)
|
||||
elsif unassigned_count
|
||||
t('my_modules.repository.flash.unassign_from_task_html',
|
||||
unassigned_items: unassigned_count)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -6,7 +6,8 @@ module ApplicationHelper
|
|||
include InputSanitizeHelper
|
||||
|
||||
def module_page?
|
||||
controller_name == 'my_modules'
|
||||
controller_name == 'my_modules' ||
|
||||
controller_name == 'my_module_repositories'
|
||||
end
|
||||
|
||||
def experiment_page?
|
||||
|
|
|
@ -3,7 +3,13 @@
|
|||
module RepositoryDatatableHelper
|
||||
include InputSanitizeHelper
|
||||
|
||||
|
||||
def prepare_row_columns(repository_rows, repository, columns_mappings, team, options = {})
|
||||
|
||||
if options[:my_module]
|
||||
assigned_rows = options[:my_module].repository_rows.where(repository: repository).pluck(:id)
|
||||
end
|
||||
|
||||
repository_rows.map do |record|
|
||||
row = {
|
||||
'DT_RowId': record.id,
|
||||
|
@ -32,6 +38,8 @@ module RepositoryDatatableHelper
|
|||
)
|
||||
end
|
||||
|
||||
row['0'] = assigned_rows.include? record.id if options[:my_module]
|
||||
|
||||
unless options[:skip_custom_columns]
|
||||
# Add custom columns
|
||||
record.repository_cells.each do |cell|
|
||||
|
|
|
@ -47,7 +47,7 @@ module RepositoryRows
|
|||
"ON repository_rows.id = my_module_repository_rows.repository_row_id "\
|
||||
"AND my_module_repository_rows.my_module_id = #{my_module.id.to_i}")
|
||||
.where(my_module_repository_rows: { id: nil })
|
||||
.where(id: @params[:selected_rows])
|
||||
.where(id: @params[:rows_to_assign])
|
||||
|
||||
return [] unless unassigned_rows.any?
|
||||
|
||||
|
|
|
@ -18,7 +18,7 @@ module RepositoryRows
|
|||
def call
|
||||
return self unless valid?
|
||||
|
||||
ActiveRecord::Base.transaction do
|
||||
#ActiveRecord::Base.transaction do
|
||||
if params[:downstream] == 'true'
|
||||
@my_module.downstream_modules.each do |downstream_module|
|
||||
unassign_repository_rows_from_my_module(downstream_module)
|
||||
|
@ -26,10 +26,10 @@ module RepositoryRows
|
|||
else
|
||||
unassign_repository_rows_from_my_module(@my_module)
|
||||
end
|
||||
rescue StandardError => e
|
||||
@errors[e.record.class.name.underscore] = e.record.errors.full_messages
|
||||
raise ActiveRecord::Rollback
|
||||
end
|
||||
#rescue StandardError => e
|
||||
# @errors[e.record.class.name.underscore] = e.record.errors.full_messages
|
||||
# raise ActiveRecord::Rollback
|
||||
#end
|
||||
|
||||
self
|
||||
end
|
||||
|
@ -44,8 +44,11 @@ module RepositoryRows
|
|||
def unassign_repository_rows_from_my_module(my_module)
|
||||
unassigned_names = my_module.my_module_repository_rows
|
||||
.joins(:repository_row)
|
||||
.where(repository_rows: { repository: @repository, id: params[:selected_rows] })
|
||||
.select('*, repository_rows.name AS name')
|
||||
.where(repository_row_id: params[:rows_to_unassign])
|
||||
.where(repository_rows: { repository: @repository })
|
||||
.select('my_module_id,
|
||||
my_module_repository_rows.id,
|
||||
repository_rows.name AS name')
|
||||
.destroy_all
|
||||
.pluck(:name)
|
||||
|
||||
|
@ -53,7 +56,7 @@ module RepositoryRows
|
|||
|
||||
# update row last_modified_by
|
||||
my_module.repository_rows
|
||||
.where(repository: @repository, id: params[:selected_rows])
|
||||
.where(repository: @repository, id: params[:rows_to_unassign])
|
||||
.update_all(last_modified_by_id: @user.id)
|
||||
|
||||
Activities::CreateActivityService.call(activity_type: :unassign_repository_record,
|
||||
|
|
|
@ -1,37 +0,0 @@
|
|||
<div id="assignRepositoryRecordModal"
|
||||
class="modal"
|
||||
tabindex="-1"
|
||||
role="dialog"
|
||||
data-dismiss="modal"
|
||||
data-assign-url="<%= assign_repository_records_my_module_path(@my_module)%>">
|
||||
<div class="modal-dialog">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header">
|
||||
<button type="button"
|
||||
class="close"
|
||||
data-dismiss="modal"
|
||||
aria-label="Close"
|
||||
onclick="hideAssignUnasignModal('#assignRepositoryRecordModal')"><span aria-hidden="true">×</span></button>
|
||||
<h4 class="modal-title">
|
||||
<%=t 'my_modules.modals.assign_repository_record.title',
|
||||
repository_name: repository.name,
|
||||
my_module_name: my_module.name %>
|
||||
</h4>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
<p><%=t 'my_modules.modals.assign_repository_record.message', size: selected_rows.size %></p>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<a class="btn btn-default" data-dismiss="modal" onclick="hideAssignUnasignModal('#assignRepositoryRecordModal')">
|
||||
<%=t 'general.cancel' %>
|
||||
</a>
|
||||
<a class="btn btn-primary" onclick="submitAssignRepositoryRecord()">
|
||||
<%=t 'Module' %>
|
||||
</a>
|
||||
<a class="btn btn-primary" onclick="submitAssignRepositoryRecord('downstream')">
|
||||
<%=t 'my_modules.modals.assign_repository_record.task_and_downstream' %>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
|
@ -0,0 +1,25 @@
|
|||
<div class="modal-header">
|
||||
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
|
||||
<span aria-hidden="true">×</span>
|
||||
</button>
|
||||
<h4 class="modal-title">
|
||||
<%=t 'my_modules.modals.assign_repository_record.title',
|
||||
repository_name: repository.name,
|
||||
my_module_name: my_module.name %>
|
||||
</h4>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
<p><%=t 'my_modules.modals.assign_repository_record.message', size: selected_rows.keys.count %></p>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<a class="btn btn-light" data-dismiss="modal">
|
||||
<i class="fas fa-times"></i>
|
||||
<%= t 'general.cancel' %>
|
||||
</a>
|
||||
<a class="btn btn-secondary downstream-action">
|
||||
<%= t 'my_modules.modals.assign_repository_record.task_and_downstream' %>
|
||||
</a>
|
||||
<a class="btn btn-primary task-action">
|
||||
<%= t 'my_modules.modals.assign_repository_record.task' %>
|
||||
</a>
|
||||
</div>
|
|
@ -1,36 +0,0 @@
|
|||
<div id="unassignRepositoryRecordModal"
|
||||
class="modal"
|
||||
tabindex="-1"
|
||||
role="dialog"
|
||||
data-dismiss="modal"
|
||||
data-unassign-url="<%= unassign_repository_records_my_module_path(@my_module)%>">
|
||||
<div class="modal-dialog">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header">
|
||||
<button type="button"
|
||||
class="close"
|
||||
data-dismiss="modal"
|
||||
aria-label="Close"
|
||||
onclick="hideAssignUnasignModal('#unassignRepositoryRecordModal')"><span aria-hidden="true">×</span></button>
|
||||
<h4 class="modal-title">
|
||||
<%=t 'my_modules.modals.assign_repository_record.unassign_title',
|
||||
repository_name: repository.name,
|
||||
my_module_name: my_module.name %>
|
||||
</h4>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
<p><%=t 'my_modules.modals.assign_repository_record.unassign_message', size: selected_rows.size %></p>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<a class="btn btn-default" data-dismiss="modal" onclick="hideAssignUnasignModal('#unassignRepositoryRecordModal')">
|
||||
<%=t 'general.cancel' %>
|
||||
</a>
|
||||
<a class="btn btn-primary" onclick="submitUnassignRepositoryRecord()">
|
||||
<%=t 'Module' %>
|
||||
</a>
|
||||
<a class="btn btn-primary" onclick="submitUnassignRepositoryRecord('downstream')">
|
||||
<%=t 'my_modules.modals.assign_repository_record.task_and_downstream' %>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
|
@ -0,0 +1,6 @@
|
|||
<div id="updateRepositoryRecordModal" class="modal update-repository-record-modal" tabindex="-1" role="dialog" data-dismiss="modal">
|
||||
<div class="modal-dialog">
|
||||
<div class="modal-content">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
|
@ -0,0 +1,56 @@
|
|||
<%
|
||||
rows_to_assign = selected_rows.select{|k, v| v[:assigned] == "true"}
|
||||
rows_to_unassign = selected_rows.select{|k, v| v[:assigned] == "false"}
|
||||
%>
|
||||
<div class="modal-header">
|
||||
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
|
||||
<span aria-hidden="true">×</span>
|
||||
</button>
|
||||
<h4 class="modal-title">
|
||||
<%=t 'my_modules.modals.update_repository_record.title',
|
||||
repository_name: repository.name,
|
||||
my_module_name: my_module.name %>
|
||||
</h4>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
<p><%=t 'my_modules.modals.update_repository_record.message', size: selected_rows.keys.count %></p>
|
||||
<div class="rows-list-container">
|
||||
<% if rows_to_assign.keys.count.positive? %>
|
||||
<div class="rows-to-assign">
|
||||
<p class="header">
|
||||
<i class="fas fa-plus"></i>
|
||||
Items newly assigned
|
||||
</p>
|
||||
<ul class="rows-list">
|
||||
<% rows_to_assign.each do |row_id, row| %>
|
||||
<li><%= row[:row_name] %></li>
|
||||
<% end %>
|
||||
</ul>
|
||||
</div>
|
||||
<% end %>
|
||||
<% if rows_to_unassign.keys.count.positive? %>
|
||||
<div class="rows-to-unassign">
|
||||
<p class="header">
|
||||
<i class="fas fa-minus"></i>
|
||||
Items that will be removed
|
||||
</p>
|
||||
<ul class="rows-list">
|
||||
<% rows_to_unassign.each do |row_id, row| %>
|
||||
<li><%= row[:row_name] %></li>
|
||||
<% end %>
|
||||
</ul>
|
||||
</div>
|
||||
<% end %>
|
||||
</div>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<a class="btn btn-light" data-dismiss="modal">
|
||||
<%=t 'general.cancel' %>
|
||||
</a>
|
||||
<a class="btn btn-secondary downstream-action" >
|
||||
<%=t 'my_modules.modals.update_repository_record.task_and_downstream' %>
|
||||
</a>
|
||||
<a class="btn btn-primary task-action">
|
||||
<%=t 'my_modules.modals.update_repository_record.task' %>
|
||||
</a>
|
||||
</div>
|
|
@ -60,9 +60,12 @@
|
|||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="collapse panel-group" id="assigned-items-container">
|
||||
<div class="collapse panel-group" id="assigned-items-container"
|
||||
data-repositories-list-url="<%= repositories_list_html_my_module_my_module_repositories_path(@my_module) %>">
|
||||
<%= render partial: "my_modules/repositories/repositories_list" %>
|
||||
</div>
|
||||
<%= render partial: "my_modules/repositories/full_view_modal" %>
|
||||
<%= render partial: "my_modules/modals/update_repository_records_modal" %>
|
||||
</div>
|
||||
<!-- Protocol -->
|
||||
<div class="task-section">
|
||||
|
@ -104,3 +107,4 @@
|
|||
<%= stylesheet_link_tag 'datatables' %>
|
||||
<%= javascript_include_tag("my_modules/protocols") %>
|
||||
<%= javascript_pack_tag 'emoji_button' %>
|
||||
<%= javascript_include_tag("my_modules/repositories") %>
|
||||
|
|
|
@ -34,3 +34,15 @@
|
|||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<template id="my-module-repository-full-view-assign-button">
|
||||
<button type="button" class="btn btn-primary" id="assignRepositoryRecords" disabled>
|
||||
<%= t 'repositories.assign_records_to_module' %>
|
||||
</button>
|
||||
</template>
|
||||
|
||||
<template id="my-module-repository-full-view-update-button">
|
||||
<button type="button" class="btn btn-primary" id="updateRepositoryRecords" disabled>
|
||||
<%= t 'general.update' %>
|
||||
</button>
|
||||
</template>
|
|
@ -9,7 +9,12 @@
|
|||
>
|
||||
<thead>
|
||||
<tr>
|
||||
<th class="never"></th>
|
||||
<th id="checkbox">
|
||||
<div class="sci-checkbox-container">
|
||||
<input value="1" type="checkbox" class="sci-checkbox select-all">
|
||||
<span class="sci-checkbox-label"></span>
|
||||
</div>
|
||||
</th>
|
||||
<th id="assigned"><%= t("repositories.table.assigned") %></th>
|
||||
<th id="row-id"><%= t("repositories.table.id") %></th>
|
||||
<th id="row-name"><%= t("repositories.table.row_name") %></th>
|
||||
|
|
|
@ -1,12 +1,16 @@
|
|||
<% @repositories.each do |repository| %>
|
||||
<% assigned_items_count = @my_module.repository_rows_count(repository) %>
|
||||
<li class="repository">
|
||||
<li class="repository"
|
||||
data-table-url="<%= full_view_table_my_module_my_module_repository_path(@my_module, repository) %>"
|
||||
data-assign-url-modal="<%= assign_repository_records_modal_my_module_my_module_repository_path(@my_module, repository) %>"
|
||||
data-update-url-modal="<%= update_repository_records_modal_my_module_my_module_repository_path(@my_module, repository)%>" data-repository-id="<%= repository.id %>"
|
||||
data-rows-count="<%= assigned_items_count %>" >
|
||||
<% if repository.shared_with?(current_team) %>
|
||||
<span class="shared-icon">
|
||||
<i class="fas fa-users"></i>
|
||||
</span>
|
||||
<% end %>
|
||||
<span class="name"><%= escape_input(repository.name) %></span>
|
||||
<span class="name" data-rows-count="[<%= assigned_items_count %>]"><%= escape_input(repository.name) %></span>
|
||||
<% if assigned_items_count.positive? %>
|
||||
<span class="assigned-items">
|
||||
<i class="fas fa-file-signature"></i>
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
<% @assigned_repositories.each do |repository| %>
|
||||
<div class="assigned-repository panel">
|
||||
<div class="assigned-repository panel" data-repository-id="<%= repository.id %>">
|
||||
<a class="assigned-repository-caret collapsed"
|
||||
role="button"
|
||||
data-toggle="collapse"
|
||||
|
@ -39,7 +39,3 @@
|
|||
<tbody></tbody>
|
||||
</table>
|
||||
</template>
|
||||
|
||||
<%= render partial: "my_modules/repositories/full_view_modal" %>
|
||||
|
||||
<%= javascript_include_tag("my_modules/repositories") %>
|
||||
|
|
|
@ -808,13 +808,26 @@ en:
|
|||
versions_sidebar_button: 'View versions'
|
||||
create_button: 'Create snapshot'
|
||||
created_by: 'by %{full_name}'
|
||||
flash:
|
||||
assign_to_task_html: "Successfully assigned <strong>%{assigned_items}</strong> item(s) to the task."
|
||||
assign_to_task_and_downstream_html: "Successfully assigned <strong>%{assigned_items}</strong> item(s) to the task and downstream tasks."
|
||||
unassign_from_task_html: "Successfully unassigned <strong>%{unassigned_items}</strong> item(s) from the task."
|
||||
unassign_from_task_and_downstream_html: "Successfully unassigned <strong>%{unassigned_items}</strong> item(s) from the task and downstream tasks."
|
||||
assign_and_unassign_from_task_html: "Successfully assigned <strong>%{assigned_items}</strong> and unassigned <strong>%{unassigned_items}</strong> item(s) from the task."
|
||||
assign_and_unassign_from_task_and_downstream_html: "Successfully assigned <strong>%{assigned_items}</strong> and unassigned <strong>%{unassigned_items}</strong> item(s) from the task and downstream tasks."
|
||||
update_error: "There was an error in updating your item(s)."
|
||||
|
||||
modals:
|
||||
update_repository_record:
|
||||
title: "Update %{repository_name} items to %{my_module_name} task"
|
||||
message: "Do you want to update %{size} items only from this task, or update them from this task & downstream tasks in the workflow also?"
|
||||
task: 'Update task'
|
||||
task_and_downstream: 'Update task & downstream'
|
||||
assign_repository_record:
|
||||
title: 'Assign %{repository_name} items to task %{my_module_name}'
|
||||
message: Do you want to assign %{size} items only to this task, or assign them to this task & downstream tasks in the workflow as well?
|
||||
task_and_downstream: 'Task & Downstream'
|
||||
unassign_title: "Unassign %{repository_name} items from task %{my_module_name}"
|
||||
unassign_message: "Do you want to unassign %{size} items only from this task, or unassign them from this task & downstream tasks in the workflow as well?"
|
||||
task: 'Assign to task'
|
||||
task_and_downstream: 'Assign to task & downstream'
|
||||
unshared_inventory:
|
||||
title_html: The inventory <b>%{inventory_name}</b> is no longer shared with your team.
|
||||
body_html: This inventory has been ushared with your team by the inventory’s owner. To view the item/s that are assigned to your task/s contact the <b>%{team_name}</b> team administrator <b>%{admin_name}</b> (<b>%{admin_email}</b>).
|
||||
|
@ -1195,11 +1208,6 @@ en:
|
|||
contains_other_records_flash: "%{records_number} item(s) successfully deleted. %{other_records_number} of the selected item(s) were created by other users and were not deleted."
|
||||
no_records_selected_flash: "There were no selected items."
|
||||
no_deleted_records_flash: "No items were deleted. %{other_records_number} of the selected items were created by other users and were not deleted."
|
||||
assigned_records_flash: "Successfully assigned item(s) <strong>%{records}</strong> to task"
|
||||
assigned_records_downstream_flash: "Successfully assigned item(s) <strong>%{records}</strong> to task and downstream tasks"
|
||||
unassigned_records_flash: "Successfully unassigned item(s) <strong>%{records}</strong> from task"
|
||||
no_records_assigned_flash: "No items were assigned to task"
|
||||
no_records_unassigned_flash: "No items were unassigned from task"
|
||||
default_column: 'Name'
|
||||
copy_records_report: "%{number} item(s) successfully copied."
|
||||
multiple_share_service:
|
||||
|
|
|
@ -384,25 +384,28 @@ Rails.application.routes.draw do
|
|||
path: '/comments',
|
||||
only: [:index, :create, :edit, :update, :destroy]
|
||||
|
||||
get :repositories_dropdown_list, to: 'my_module_repositories#repositories_dropdown_list'
|
||||
|
||||
resources :repositories, only: [] do
|
||||
resources :repositories, controller: 'my_module_repositories', only: :update do
|
||||
member do
|
||||
get :full_view_table, to: 'my_module_repositories#full_view_table', as: :full_view_table
|
||||
post :index_dt, to: 'my_module_repositories#index_dt', as: :index_dt
|
||||
get :full_view_table
|
||||
post :index_dt
|
||||
get :assign_repository_records_modal
|
||||
get :update_repository_records_modal
|
||||
end
|
||||
|
||||
resources :repository_snapshots, controller: 'my_module_repository_snapshots',
|
||||
as: :snapshots,
|
||||
only: %i(create destroy) do
|
||||
collection do
|
||||
get :repositories_dropdown_list
|
||||
get :repositories_list_html
|
||||
end
|
||||
|
||||
resources :snapshots, controller: 'my_module_repository_snapshots', only: %i(create destroy) do
|
||||
member do
|
||||
get :full_view_table, to: 'my_module_repository_snapshots#full_view_table'
|
||||
post :index_dt, to: 'my_module_repository_snapshots#index_dt'
|
||||
get :full_view_table
|
||||
post :index_dt
|
||||
end
|
||||
end
|
||||
|
||||
get :full_view_versions_sidebar, to: 'my_module_repository_snapshots#full_view_versions_sidebar',
|
||||
as: :full_view_versions_sidebar
|
||||
collection do
|
||||
get :full_view_versions_sidebar
|
||||
end
|
||||
end
|
||||
|
||||
# resources :sample_my_modules, path: '/samples_index', only: [:index]
|
||||
|
|
Loading…
Reference in a new issue