Merge pull request #745 from ZmagoD/zd_SCI_1485

refactor repositories js files [fixes SCI-1485]
This commit is contained in:
Zmago Devetak 2017-07-19 11:17:52 +02:00 committed by GitHub
commit 7b898666da
8 changed files with 883 additions and 842 deletions

View file

@ -46,8 +46,10 @@
success: function (data) {
var tabBody = $(pane.context.hash).find(".tab-content-body");
tabBody.html(data.html);
pane.tab('show').promise().done(function() {
pane.tab('show').promise().done(function(el) {
initImportRecordsModal();
RepositoryDatatable.destroy()
RepositoryDatatable.init(el.attr('data-repo-table'));
});
},
error: function (error) {

View file

@ -0,0 +1,10 @@
(function() {
'use strict';
// initialze repository datatable
$(document).ready(function() {
RepositoryDatatable.destroy()
RepositoryDatatable.init($('#content').attr('data-repo-id'));
onClickToggleAssignedRecords();
});
})();

View file

@ -1,5 +1,11 @@
//= require jquery-ui/sortable
var RepositoryDatatable = (function(global) {
'use strict';
var TABLE_ID = '';
var TABLE = {};
// Extend datatables API with searchable options
// (http://stackoverflow.com/questions/39912395/datatables-dynamically-set-columns-searchable)
$.fn.dataTable.Api.register('isColumnSearchable()', function(colSelector) {
@ -31,7 +37,6 @@ var selectedRecord;
var myData;
var loadFirstTime = true;
var table;
var originalHeader;
// Tells whether to filter only assigned repository records
@ -39,9 +44,9 @@ var viewAssigned;
function dataTableInit() {
// Make a copy of original repository table header
originalHeader = $('#repository-table thead').children().clone();
originalHeader = $(TABLE_ID + ' thead').children().clone();
viewAssigned = 'assigned';
table = $('#repository-table').DataTable({
TABLE = $(TABLE_ID).DataTable({
order: [[2, 'desc']],
dom: "R<'row'<'col-sm-9-custom toolbar'l><'col-sm-3-custom'f>>tpi",
stateSave: true,
@ -57,7 +62,7 @@ function dataTableInit() {
},
destroy: true,
ajax: {
url: $('#repository-table').data('source'),
url: $(TABLE_ID).data('source'),
data: function(d) {
d.assigned = viewAssigned;
},
@ -82,7 +87,6 @@ function dataTableInit() {
rowCallback: function(row, data) {
// Get row ID
var rowId = data.DT_RowId;
// If row ID is in the list of selected row IDs
if ($.inArray(rowId, rowsSelected) !== -1) {
$(row).find('input[type="checkbox"]').prop('checked', true);
@ -90,7 +94,7 @@ function dataTableInit() {
}
},
columns: (function() {
var numOfColumns = $('#repository-table').data('num-columns');
var numOfColumns = $(TABLE_ID).data('num-columns');
var columns = [];
for (var i = 0; i < numOfColumns; i++) {
var visible = (i <= 4);
@ -108,7 +112,7 @@ function dataTableInit() {
animateSpinner(this, false);
changeToViewMode();
updateButtons();
updateDataTableSelectAllCtrl(table);
updateDataTableSelectAllCtrl();
// Prevent row toggling when selecting user smart annotation link
SmartAnnotation.preventPropagation('.atwho-user-popover');
@ -127,7 +131,7 @@ function dataTableInit() {
// Send an Ajax request to the server to get the data. Note that
// this is a synchronous request since the data is expected back from the
// function
var repositoryId = $('#repository-table').data('repository-id');
var repositoryId = $(TABLE_ID).data('repository-id');
$.ajax({
url: '/repositories/' + repositoryId + '/state_load',
data: {},
@ -142,7 +146,7 @@ function dataTableInit() {
},
stateSaveCallback: function(settings, data) {
// Send an Ajax request to the server with the state object
var repositoryId = $('#repository-table').data('repository-id');
var repositoryId = $(TABLE_ID).data('repository-id');
// Save correct data
if (loadFirstTime === true) {
data = myData;
@ -159,9 +163,9 @@ function dataTableInit() {
fnInitComplete: function(oSettings) {
// Reload correct column order and visibility (if you refresh page)
// First two columns are fixed
table.column(0).visible(true);
table.column(1).visible(true);
for (var i = 2; i < table.columns()[0].length; i++) {
TABLE.column(0).visible(true);
TABLE.column(1).visible(true);
for (var i = 2; i < TABLE.columns()[0].length; i++) {
var visibility = false;
if (myData.columns[i]) {
visibility = myData.columns[i].visible;
@ -169,15 +173,16 @@ function dataTableInit() {
if (typeof (visibility) === 'string') {
visibility = (visibility === 'true');
}
table.column(i).visible(visibility);
table.setColumnSearchable(i, visibility);
TABLE.column(i).visible(visibility);
TABLE.setColumnSearchable(i, visibility);
}
oSettings._colReorder.fnOrder(myData.ColReorder);
table.on('mousedown', function() {
TABLE.on('mousedown', function() {
$('#repository-columns-dropdown').removeClass('open');
});
initHeaderTooltip();
initRowSelection();
bindExportActions();
}
});
@ -186,7 +191,7 @@ function dataTableInit() {
$('div.toolbarButtons').show();
// Handle click on table cells with checkboxes
$('#repository-table').on('click', 'tbody td', function(e) {
$(TABLE_ID).on('click', 'tbody td', function(e) {
if ($(e.target).is('.repository-row-selector')) {
// Skip if clicking on selector checkbox
return;
@ -194,7 +199,7 @@ function dataTableInit() {
$(this).parent().find('.repository-row-selector').trigger('click');
});
table.on('column-reorder', function() {
TABLE.on('column-reorder', function() {
initRowSelection();
});
@ -202,19 +207,18 @@ function dataTableInit() {
animateLoading();
});
return table;
}
table = dataTableInit();
// Timeout for table header scrolling
setTimeout(function() {
table.columns.adjust();
TABLE.columns.adjust();
}, 10);
return TABLE;
}
// Enables noSearchHidden plugin
$.fn.dataTable.defaults.noSearchHidden = true;
function bindExportActions() {
$('form#form-export').submit(function() {
var form = this;
@ -224,7 +228,7 @@ $('form#form-export').submit(function() {
$(form).find('input[name=header_ids\\[\\]]').remove();
// Append visible column information
$('.active table#repository-table thead tr th').each(function() {
$('.active table' + TABLE_ID + ' thead tr th').each(function() {
var th = $(this);
var val;
switch ($(th).attr('id')) {
@ -258,6 +262,8 @@ $('form#form-export').submit(function() {
});
}
});
}
function appendInput(form, val, name) {
$(form).append(
@ -276,7 +282,7 @@ function initRowSelection() {
}
// Get row ID
var $row = $(this).closest('tr');
var data = table.row($row).data();
var data = TABLE.row($row).data();
var rowId = data.DT_RowId;
// Determine whether row ID is in the list of selected row IDs
@ -296,7 +302,7 @@ function initRowSelection() {
$row.removeClass('selected');
}
updateDataTableSelectAllCtrl(table);
updateDataTableSelectAllCtrl();
e.stopPropagation();
updateButtons();
@ -317,9 +323,9 @@ function initRowSelection() {
}
// Updates "Select all" control in a data table
function updateDataTableSelectAllCtrl(table) {
var $table = table.table().node();
var $header = table.table().header();
function updateDataTableSelectAllCtrl() {
var $table = TABLE.table().node();
var $header = TABLE.table().header();
var $chkboxAll = $('.repository-row-selector', $table);
var $chkboxChecked = $('.repository-row-selector:checked', $table);
var chkboxSelectAll = $('input[name="select_all"]', $header).get(0);
@ -360,9 +366,9 @@ function initHeaderTooltip() {
var width = 200;
// set tooltip params in the table body
if ( $(this).parents('#repository-table').length ) {
offsetLeft = $('#repository-table').offset().left + 100;
width = $('#repository-table').width() - 200;
if ($(this).parents(TABLE_ID).length) {
offsetLeft = $(TABLE_ID).offset().left + 100;
width = $(TABLE_ID).width() - 200;
}
$('body').append($tooltip);
$tooltip.css('background-color', '#d2d2d2');
@ -385,16 +391,16 @@ function initHeaderTooltip() {
});
}
function onClickAddRecord() {
global.onClickAddRecord = function() {
changeToEditMode();
updateButtons();
saveAction = 'create';
var tr = document.createElement('tr');
if (table.column(1).visible() === false) {
table.column(1).visible(true);
if (TABLE.column(1).visible() === false) {
TABLE.column(1).visible(true);
}
$('table#repository-table thead tr').children('th').each(function() {
$('table' + TABLE_ID + ' thead tr').children('th').each(function() {
var th = $(this);
var td;
var input;
@ -417,7 +423,7 @@ function onClickAddRecord() {
tr.appendChild(createTdElement(''));
}
});
$('table#repository-table').prepend(tr);
$('table' + TABLE_ID).prepend(tr);
selectedRecord = tr;
// initialize smart annotation
@ -430,7 +436,7 @@ function onClickAddRecord() {
adjustTableHeader();
}
(function onClickToggleAssignedRecords() {
global.onClickToggleAssignedRecords = function() {
$('.repository-assign-group > .btn').click(function() {
$('.btn-group > .btn').removeClass('active btn-primary');
$('.btn-group > .btn').addClass('btn-default');
@ -439,19 +445,19 @@ function onClickAddRecord() {
$('#assigned-repo-records').on('click', function() {
viewAssigned = 'assigned';
table.ajax.reload(function() {
TABLE.ajax.reload(function() {
initRowSelection();
}, false);
});
$('#all-repo-records').on('click', function() {
viewAssigned = 'all';
table.ajax.reload(function() {
TABLE.ajax.reload(function() {
initRowSelection();
}, false);
});
})();
};
function onClickAssignRecords() {
global.onClickAssignRecords = function() {
animateSpinner();
$.ajax({
url: $('#assignRepositoryRecords').data('assign-url'),
@ -471,7 +477,7 @@ function onClickAssignRecords() {
});
}
function onClickUnassignRecords() {
global.onClickUnassignRecords = function() {
animateSpinner();
$.ajax({
url: $('#unassignRepositoryRecords').data('unassign-url'),
@ -491,10 +497,10 @@ function onClickUnassignRecords() {
});
}
function onClickDeleteRecord() {
global.onClickDeleteRecord = function() {
animateSpinner();
$.ajax({
url: $('table#repository-table').data('delete-record'),
url: $('table' + TABLE_ID).data('delete-record'),
type: 'POST',
dataType: 'json',
data: {selected_rows: rowsSelected},
@ -514,12 +520,12 @@ function onClickDeleteRecord() {
}
// Edit record
function onClickEdit() {
global.onClickEdit = function() {
if (rowsSelected.length !== 1) {
return;
}
var row = table.row('#' + rowsSelected[0]);
var row = TABLE.row('#' + rowsSelected[0]);
var node = row.node();
var rowData = row.data();
@ -536,8 +542,8 @@ function onClickEdit() {
type: 'GET',
dataType: 'json',
success: function(data) {
if (table.column(1).visible() === false) {
table.column(1).visible(true);
if (TABLE.column(1).visible() === false) {
TABLE.column(1).visible(true);
}
// Show save and cancel buttons in first two columns
$(node).children('td').eq(0).html($('#saveRecord').clone());
@ -555,8 +561,8 @@ function onClickEdit() {
var cells = data.repository_row.repository_cells;
$(node).children('td').each(function(i) {
var td = $(this);
var rawIndex = table.column.index('fromVisible', i);
var colHeader = table.column(rawIndex).header();
var rawIndex = TABLE.column.index('fromVisible', i);
var colHeader = TABLE.column(rawIndex).header();
if ($(colHeader).hasClass('repository-column')) {
// Check if cell on this record exists
var cell = cells[$(colHeader).attr('id')];
@ -594,11 +600,11 @@ function onClickEdit() {
}
// Save record
function onClickSave() {
global.onClickSave = function() {
var node;
var rowData;
if (saveAction === 'update') {
var row = table.row(selectedRecord);
var row = TABLE.row(selectedRecord);
node = row.node();
rowData = row.data();
} else if (saveAction === 'create') {
@ -606,7 +612,7 @@ function onClickSave() {
}
// First fetch all the data in input fields
var data = {
request_url: $('#repository-table').data('current-uri'),
request_url: $(TABLE_ID).data('current-uri'),
repository_row_id: $(selectedRecord).attr('id'),
repository_row: {},
repository_cells: {}
@ -631,7 +637,7 @@ function onClickSave() {
type = 'PUT';
} else {
type = 'POST';
url = $('table#repository-table').data('create-record');
url = $('table' + TABLE_ID).data('create-record');
}
$.ajax({
url: url,
@ -785,11 +791,11 @@ function clearRowSelection() {
}
// Restore previous table
function onClickCancel() {
global.onClickCancel = function() {
if ($('#assigned').text().length === 0) {
table.column(1).visible(false);
TABLE.column(1).visible(false);
}
table.ajax.reload(function() {
TABLE.ajax.reload(function() {
initRowSelection();
}, false);
changeToViewMode();
@ -812,7 +818,7 @@ function getColumnIndex(id) {
if (id < 0) {
return false;
}
return table.column(id).index('visible');
return TABLE.column(id).index('visible');
}
// Takes object and surrounds it with input
@ -830,34 +836,31 @@ function createTdElement(content) {
// Adjust columns width in table header
function adjustTableHeader() {
table.columns.adjust();
TABLE.columns.adjust();
$('.dropdown-menu').parent()
.on('shown.bs.dropdown hidden.bs.dropdown', function() {
table.columns.adjust();
TABLE.columns.adjust();
});
}
function changeToViewMode() {
currentMode = 'viewMode';
// Table specific stuff
table.button(0).enable(true);
TABLE.button(0).enable(true);
}
function changeToEditMode() {
currentMode = 'editMode';
// Table specific stuff
table.button(0).enable(false);
TABLE.button(0).enable(false);
initHeaderTooltip();
}
/*
* Repository columns dropdown
*/
(function(table) {
'use strict';
var dropdown = $('#repository-columns-dropdown');
var dropdownList = $('#repository-columns-list');
var dropdown, dropdownList;
function createNewColumn() {
// Make an Ajax request to repository_columns_controller
@ -893,11 +896,11 @@ function changeToEditMode() {
$('div.toolbarButtons').hide();
// Destroy datatable
table.destroy();
TABLE.destroy();
// Add number of columns
$('#repository-table').data('num-columns',
$('#repository-table').data('num-columns') + 1);
$(TABLE_ID).data('num-columns',
$(TABLE_ID).data('num-columns') + 1);
// Add column to table (=table header)
originalHeader.append(
'<th class="repository-column" id="' + data.id + '" ' +
@ -909,13 +912,13 @@ function changeToEditMode() {
// Remove all event handlers as we re-initialize them later with
// new table
$('#repository-table').off();
$('#repository-table thead').empty();
$('#repository-table thead').append(originalHeader);
$(TABLE_ID).off();
$(TABLE_ID +' thead').empty();
$(TABLE_ID + ' thead').append(originalHeader);
// Re-initialize datatable
table = dataTableInit();
table.on('init.dt', function() {
TABLE = dataTableInit();
TABLE.on('init.dt', function() {
loadColumnsNames();
dropdownOverflow();
});
@ -961,10 +964,10 @@ function changeToEditMode() {
var scrollPosition = dropdownList.scrollTop();
// Clear the list
dropdownList.find('li[data-position]').remove();
_.each(table.columns().header(), function(el, index) {
_.each(TABLE.columns().header(), function(el, index) {
if (index > 1) {
var colIndex = $(el).attr('data-column-index');
var visible = table.column(colIndex).visible();
var visible = TABLE.column(colIndex).visible();
var editable = $(el).is('[data-editable]');
var deletable = $(el).is('[data-deletable]');
@ -994,19 +997,19 @@ function changeToEditMode() {
'form-control" style="display: none;" />' +
'<span class="pull-right controls">' +
'<span class="ok glyphicon glyphicon-ok" style="display: none;" ' +
'title="' + $('#repository-table').data('save-text') + '"></span>' +
'title="' + $(TABLE_ID).data('save-text') + '"></span>' +
'<span class="cancel glyphicon glyphicon-remove" ' +
'style="display: none;" ' +
'title="' + $('#repository-table').data('cancel-text') +
'title="' + $(TABLE_ID).data('cancel-text') +
'"></span>' +
'<span class="vis glyphicon ' + visClass + '" title="' +
$('#repository-table').data('columns-visibility-text') + '">' +
$(TABLE_ID).data('columns-visibility-text') + '">' +
'</span> ' +
'<span class="edit glyphicon glyphicon-pencil ' + editClass +
'" title="' + $('#repository-table').data('edit-text') +
'" title="' + $(TABLE_ID).data('edit-text') +
'"></span>' +
'<span class="del glyphicon glyphicon-trash ' + delClass +
'" title="' + $('#repository-table').data('columns-delete-text') +
'" title="' + $(TABLE_ID).data('columns-delete-text') +
'"></span>' +
'</span><br></span></li>';
dropdownList.append(html);
@ -1038,27 +1041,27 @@ function changeToEditMode() {
event.stopPropagation();
var self = $(this);
var li = self.closest('li');
var column = table.column(li.attr('data-position'));
var column = TABLE.column(li.attr('data-position'));
if (column.visible()) {
self.addClass('glyphicon-eye-close');
self.removeClass('glyphicon-eye-open');
li.addClass('col-invisible');
column.visible(false);
table.setColumnSearchable(column.index(), false);
TABLE.setColumnSearchable(column.index(), false);
} else {
self.addClass('glyphicon-eye-open');
self.removeClass('glyphicon-eye-close');
li.removeClass('col-invisible');
column.visible(true);
table.setColumnSearchable(column.index(), true);
TABLE.setColumnSearchable(column.index(), true);
initHeaderTooltip();
}
// Re-filter/search if neccesary
var searchText = $('div.dataTables_filter input').val();
if (!_.isEmpty(searchText)) {
table.search(searchText).draw();
TABLE.search(searchText).draw();
}
initRowSelection();
});
@ -1070,7 +1073,7 @@ function changeToEditMode() {
cancel: '.new-repository-column',
axis: 'y',
update: function() {
var reorderer = table.colReorder;
var reorderer = TABLE.colReorder;
var listIds = [];
// We skip first two columns
listIds.push(0, 1);
@ -1107,7 +1110,7 @@ function changeToEditMode() {
dropdownList.sortable('enable');
$(li).clearFormErrors();
text.html(generateColumnNameTooltip(newName));
$(table.columns().header()).filter('#' + id)
$(TABLE.columns().header()).filter('#' + id)
.html(generateColumnNameTooltip(newName));
originalHeader.find('#' + id).html(newName);
cancelEditMode();
@ -1291,28 +1294,28 @@ function changeToEditMode() {
$('div.toolbarButtons').hide();
// Destroy datatable
table.destroy();
TABLE.destroy();
// Subtract number of columns
$('#repository-table').data(
$(TABLE_ID).data(
'num-columns',
$('#repository-table').data('num-columns') - 1
$(TABLE_ID).data('num-columns') - 1
);
// Remove column from table (=table header) & rows
var th = originalHeader.find('#' + id);
var index = th.index();
th.remove();
$('#repository-table tbody td:nth-child(' + (index + 1) + ')').remove();
$(TABLE_ID + ' tbody td:nth-child(' + (index + 1) + ')').remove();
// Remove all event handlers as we re-initialize them later with
// new table
$('#repository-table').off();
$('#repository-table thead').empty();
$('#repository-table thead').append(originalHeader);
$(TABLE_ID).off();
$(TABLE_ID + ' thead').empty();
$(TABLE_ID + ' thead').append(originalHeader);
// Re-initialize datatable
table = dataTableInit();
TABLE = dataTableInit();
loadColumnsNames();
// Hide modal
@ -1344,7 +1347,7 @@ function changeToEditMode() {
}
function generateColumnNameTooltip(name) {
var maxLength = $('#repository-table').data('max-dropdown-length');
var maxLength = $(TABLE_ID).data('max-dropdown-length');
if ($.trim(name).length > maxLength) {
return '<div class="modal-tooltip">' +
truncateLongString(name, maxLength) +
@ -1355,7 +1358,9 @@ function changeToEditMode() {
// initialze dropdown after the table is loaded
function initDropdown() {
table.on('init.dt', function() {
TABLE.on('init.dt', function() {
dropdown = $('#repository-columns-dropdown');
dropdownList = $('#repository-columns-list');
initNewColumnForm();
initSorting();
toggleColumnVisibility();
@ -1372,5 +1377,19 @@ function changeToEditMode() {
});
}
function init(id) {
TABLE_ID = id;
TABLE = dataTableInit();
initDropdown();
})(table);
}
function destroy() {
TABLE = {};
TABLE_ID = '';
}
return Object.freeze({
init: init,
destroy: destroy
});
})(window);

View file

@ -31,7 +31,8 @@
<% end %>
</div>
<div id="content">
<div id="content"
data-repo-id="#repository-table-<%= @repository.id %>">
<%= render partial: "repositories/repository_table",
locals: {
repository: @repository,
@ -40,3 +41,7 @@
}
%>
</div>
<%= stylesheet_link_tag 'datatables' %>
<%= javascript_include_tag 'repositories/repository_datatable' %>
<%= javascript_include_tag 'repositories/my_module_repository' %>

View file

@ -1,5 +1,5 @@
<div class="repository-table">
<table id="repository-table" class="table"
<table id="repository-table-<%= repository.id %>" class="table"
data-current-uri="<%= request.original_url %>"
data-repository-id="<%= repository.id %>"
data-source="<%= repository_index_link %>"
@ -35,6 +35,3 @@
<tbody></tbody>
</table>
</div>
<%= stylesheet_link_tag 'datatables' %>
<%= javascript_include_tag('repositories/repository_datatable') %>

View file

@ -10,6 +10,7 @@
<li role="presentation">
<a href="#custom_repo_<%= repo.id %>"
data-toggle="tab"
data-repo-table="#repository-table-<%= repo.id %>"
aria-controls="custom_repo_<%= repo.id %>"
data-url="<%=team_repository_show_tab_path(current_team, repo)%>"
title="<%=repo.name%>"><%= truncate(repo.name, length: Constants::NAME_TRUNCATION_LENGTH) %></a>
@ -53,4 +54,6 @@
</div>
<% end %>
<%= stylesheet_link_tag 'datatables' %>
<%= javascript_include_tag 'repositories/repository_datatable' %>
<%= javascript_include_tag "repositories/index", "data-turbolinks-track" => true %>

View file

@ -203,7 +203,10 @@
<ul class="dropdown-menu repositories-dropdown-menu" aria-labelledby="repositoriesDropdownMenuLink">
<% @my_module.experiment.project.team.repositories.order(created_at: :asc).each do |repository| %>
<li>
<a class="dropdown-item" href="<%= repository_my_module_url(id: @my_module, repository_id: repository) %>" title="<%= repository.name %>">
<a class="dropdown-item"
href="<%= repository_my_module_url(id: @my_module, repository_id: repository) %>"
title="<%= repository.name %>"
data-no-turbolink="true">
<%= truncate(repository.name) %>
</a>
</li>

View file

@ -76,6 +76,8 @@ Rails.application.config.assets.precompile += %w(repositories/index.js)
Rails.application.config.assets.precompile += %w(repositories/edit.js)
Rails.application.config.assets.precompile +=
%w(repositories/repository_datatable.js)
Rails.application.config.assets.precompile +=
%w(repositories/my_module_repository.js)
# Libraries needed for Handsontable formulas
Rails.application.config.assets.precompile += %w(lodash.js)