Add assign items modal and update modal for task inventories

This commit is contained in:
aignatov-bio 2020-04-22 17:55:22 +02:00
parent 10fdd0c1c7
commit 34d6e903a4
22 changed files with 551 additions and 162 deletions

View file

@ -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();
}
};
}());

View file

@ -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'),

View file

@ -64,6 +64,7 @@
.repository {
@include font-button;
cursor: pointer;
display: flex;
padding: 8px 16px;

View file

@ -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;
}
}
}

View file

@ -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%;

View file

@ -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

View file

@ -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?

View file

@ -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|

View file

@ -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?

View file

@ -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,

View file

@ -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>

View file

@ -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>

View file

@ -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>

View file

@ -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>

View file

@ -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>

View file

@ -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") %>

View file

@ -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>

View file

@ -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>

View file

@ -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>

View file

@ -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") %>

View file

@ -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 inventorys 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:

View file

@ -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]