mirror of
https://github.com/scinote-eln/scinote-web.git
synced 2024-12-26 09:42:46 +08:00
Refactor inventory edit mode [SCI-4070]
This commit is contained in:
parent
e8fdfe7111
commit
338b710d81
13 changed files with 764 additions and 897 deletions
|
@ -44,6 +44,7 @@
|
|||
//= require protocols/header
|
||||
//= require marvinjslauncher
|
||||
//= require_directory ./repositories/renderers
|
||||
//= require_directory ./repositories/validators
|
||||
//= require turbolinks
|
||||
|
||||
|
||||
|
|
|
@ -1,396 +1,260 @@
|
|||
/* global Promise _ ActiveStorage RepositoryItemEditForm */
|
||||
|
||||
//= require sugar.min
|
||||
//= require jquerymy-1.2.14.min
|
||||
|
||||
(function(global) {
|
||||
'use strict';
|
||||
|
||||
/**
|
||||
* RepositoryItemEditForm generates the html inputs for
|
||||
* repository item and returns the form data object
|
||||
*
|
||||
* @param {Object} itemData - repository item data fetched from the API
|
||||
* @param {Object} repositoryItemElement - row node in the table
|
||||
*/
|
||||
global.RepositoryItemEditForm = function(itemData, repositoryItemElement) {
|
||||
this.itemData = itemData;
|
||||
this.repositoryItemElement = repositoryItemElement;
|
||||
this.formData = this.composeFormData(itemData);
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates the input fields
|
||||
*
|
||||
* @param {Object} table - datatable.js object
|
||||
* @returns {undefinded}
|
||||
*/
|
||||
RepositoryItemEditForm.prototype.renderForm = function(table) {
|
||||
var colIndex = getColumnIndex(table, '#row-name');
|
||||
var cells = this.itemData.repository_row.repository_cells;
|
||||
var listColumns = this.itemData.repository_row.repository_column_items;
|
||||
var formData = this.formData;
|
||||
|
||||
if (colIndex) {
|
||||
$(this.repositoryItemElement).children('td').eq(colIndex)
|
||||
.html(changeToInputField('repository_row',
|
||||
'name',
|
||||
this.itemData.repository_row.name,
|
||||
'rowName'));
|
||||
}
|
||||
|
||||
$(this.repositoryItemElement).children('td').each(function(i) {
|
||||
var td = $(this);
|
||||
var rawIndex = table.column.index('fromVisible', i);
|
||||
var colHeader = table.column(rawIndex).header();
|
||||
|
||||
if ($(colHeader).hasClass('repository-column')) {
|
||||
var type = $(colHeader).attr('data-type');
|
||||
var colHeaderId = $(colHeader).attr('id');
|
||||
var cell = cells[colHeaderId] || '';
|
||||
td.html(changeToFormField('repository_cell',
|
||||
colHeaderId,
|
||||
type,
|
||||
cell,
|
||||
listColumns));
|
||||
addSelectedFile(type, colHeaderId);
|
||||
appendNewElementToFormData(cell, colHeaderId, formData);
|
||||
}
|
||||
});
|
||||
initializeDataBinding(this.repositoryItemElement, formData);
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse received data in to a from object
|
||||
*
|
||||
* @param {Object} itemData - json representations of repository item
|
||||
*
|
||||
* @returns {Object}
|
||||
*/
|
||||
RepositoryItemEditForm.prototype.composeFormData = function(itemData) {
|
||||
var formBindingsData = {};
|
||||
formBindingsData['rowName'] = itemData.repository_row.name;
|
||||
$.each(itemData.repository_row.repository_cells, function(i, cell) {
|
||||
var tableCellId = 'colId-' + cell.cell_column_id;
|
||||
if(cell.type === 'RepositoryAssetValue') {
|
||||
formBindingsData[tableCellId] = new File([""], cell.value.file_name);
|
||||
} else {
|
||||
formBindingsData[tableCellId] = cell.value;
|
||||
}
|
||||
});
|
||||
return formBindingsData;
|
||||
}
|
||||
|
||||
/**
|
||||
* Handles select picker default value
|
||||
*
|
||||
* @param {Object} node
|
||||
* @returns {undefinded}
|
||||
*/
|
||||
RepositoryItemEditForm.prototype.initializeSelectpickerValues = function(node) {
|
||||
$($(node).find('.bootstrap-select')).each(function(_, dropdown) {
|
||||
var selectedValue = $($(dropdown).find('select')[0]).data('selected-value');
|
||||
var selectPicker = $($(dropdown).find('select')[0]);
|
||||
var value = '-1'
|
||||
$(dropdown).find('option').each(function(_, option) {
|
||||
$(option).removeAttr('selected');
|
||||
if($(option).val() === selectedValue.toString()) {
|
||||
$(option).attr('selected', true);
|
||||
value = $(option).attr('value');
|
||||
}
|
||||
});
|
||||
$(dropdown).parent().attr("list_item_id", value);
|
||||
selectPicker.val(value);
|
||||
selectPicker.selectpicker('refresh');
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a FormData object with the repository row data ready to be
|
||||
* sended on the server
|
||||
*
|
||||
* @param {Object} tableID
|
||||
* @param {Object} selectedRecord
|
||||
*
|
||||
* @returns (Object)
|
||||
*/
|
||||
RepositoryItemEditForm.prototype.parseToFormObject = function(tableID, selectedRecord) {
|
||||
var formData = this.formData;
|
||||
var formDataObj = new FormData();
|
||||
var removeFileColumns = [];
|
||||
var filesToUploadCntr = 0;
|
||||
var filesUploadedCntr = 0;
|
||||
const directUploadUrl = $(tableID).data('directUploadUrl');
|
||||
|
||||
formDataObj.append('request_url', $(tableID).data('current-uri'));
|
||||
formDataObj.append('repository_row_id', $(selectedRecord).attr('id'));
|
||||
|
||||
return new Promise((resolve, reject) => {
|
||||
$(_.keys(this.formData)).each(function(_, element) {
|
||||
var value = formData[element];
|
||||
if (element === 'rowName') {
|
||||
formDataObj.append('repository_row_name', value);
|
||||
} else {
|
||||
let colId = element.replace('colId-', '');
|
||||
let $el = $('#' + element);
|
||||
// don't save anything if element is not visible
|
||||
if ($el.length === 0) {
|
||||
return;
|
||||
}
|
||||
if ($el.attr('type') === 'file') {
|
||||
// handle deleting of element
|
||||
if ($el.attr('remove') === 'true') {
|
||||
removeFileColumns.push(colId);
|
||||
formDataObj.append('repository_cells[' + colId + ']', null);
|
||||
} else if ($el[0].files.length > 0) {
|
||||
filesToUploadCntr += 1;
|
||||
}
|
||||
} else if (value.length >= 0) {
|
||||
formDataObj.append('repository_cells[' + colId + ']', value);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
formDataObj.append('remove_file_columns', JSON.stringify(removeFileColumns));
|
||||
|
||||
// No files for upload, so return earlier
|
||||
if (filesToUploadCntr === 0) {
|
||||
resolve(formDataObj);
|
||||
return;
|
||||
}
|
||||
|
||||
// Second run, just for files
|
||||
$(_.keys(this.formData)).each(function(_, element) {
|
||||
let $el = $('#' + element);
|
||||
let colId = element.replace('colId-', '');
|
||||
|
||||
if ($el.attr('type') === 'file' && $el.attr('remove') !== 'true') {
|
||||
let upload = new ActiveStorage.DirectUpload($el[0].files[0], directUploadUrl);
|
||||
|
||||
upload.create(function(error, blob) {
|
||||
if (error) {
|
||||
reject(error);
|
||||
} else {
|
||||
formDataObj.append('repository_cells[' + colId + ']', blob.signed_id);
|
||||
filesUploadedCntr += 1;
|
||||
|
||||
if (filesUploadedCntr === filesToUploadCntr) {
|
||||
resolve(formDataObj);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* |-----------------|
|
||||
* | Private methods |
|
||||
* |-----------------|
|
||||
*/
|
||||
|
||||
/**
|
||||
* Takes object and surrounds it with input
|
||||
*
|
||||
* @param {Object} object
|
||||
* @param {String} name
|
||||
* @param {String} value
|
||||
* @param {String} id
|
||||
*
|
||||
* @returns (String)
|
||||
*/
|
||||
function changeToInputField(object, name, value, id) {
|
||||
return "<div class='form-group'><input class='form-control' data-object='"
|
||||
+ object + "' name='" + name + "' value='" + value + "' id='" + id + "'></input></div>";
|
||||
}
|
||||
|
||||
/**
|
||||
* Takes object and creates an input file field, contains a hidden
|
||||
* input field which is triggered on button click and we get the uploaded
|
||||
* file from there.
|
||||
*
|
||||
* @param {Object} object
|
||||
* @param {String} name
|
||||
* @param {String} value
|
||||
* @param {String} id
|
||||
*
|
||||
* @returns (String)
|
||||
*/
|
||||
function changeToInputFileField(object, name, value, id) {
|
||||
var fileName = (value.file_name) ? value.file_name : I18n.t('general.file.no_file_chosen');
|
||||
var buttonLabel = I18n.t('general.file.choose');
|
||||
var html = "<div class='repository-input-file-field'>" +
|
||||
"<div class='form-group'><div><input type='file' name='" + name + "' id='" +
|
||||
id + "' style='display:none' /><button class='btn btn-default' " +
|
||||
"data-object='" + object + "' name='" + name + "' value='" + value +
|
||||
"' data-id='" + id + "'>" + buttonLabel +
|
||||
"</button></div><div><p class='file-name-label'>" + truncateLongString(fileName, 20) +
|
||||
"</p></div>";
|
||||
if(value.file_name) {
|
||||
html += "<div><a data-action='removeAsset' ";
|
||||
html += "onClick='clearFileInput(this)'><i class='fas fa-times'></i></a>";
|
||||
} else {
|
||||
html += "<div><a data-action='removeAsset' onClick='clearFileInput(this)' ";
|
||||
html += "style='display:none'><i class='fas fa-times'></i></a>";
|
||||
}
|
||||
html += "</div></div></div>";
|
||||
|
||||
return html;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the colum index
|
||||
*
|
||||
* @param {Object} table
|
||||
* @param {String} id
|
||||
*
|
||||
* @returns (Boolean | Number)
|
||||
*/
|
||||
function getColumnIndex(table, id) {
|
||||
if(id < 0)
|
||||
return false;
|
||||
return table.column(id).index('visible');
|
||||
}
|
||||
|
||||
/**
|
||||
* Genrates list items dropdown element
|
||||
*
|
||||
* @param {Array} options
|
||||
* @param {String} current_value
|
||||
* @param {Number} columnId
|
||||
* @param {String} id
|
||||
*
|
||||
* @returns (String)
|
||||
*/
|
||||
function _listItemDropdown(options, current_value, columnId, id) {
|
||||
var val = undefined;
|
||||
var html = '<select id="' + id + '" class="form-control selectpicker repository-dropdown" ';
|
||||
html += 'data-selected-value="" data-abs-min-length="2" data-live-search="true" ';
|
||||
html += 'data-container="body" column_id="' + columnId +'">';
|
||||
html += '<option value="-1"></option>';
|
||||
$.each(options, function(index, value) {
|
||||
var selected = '';
|
||||
if (current_value === value[1]) {
|
||||
selected = 'selected';
|
||||
val = value[0];
|
||||
}
|
||||
html += '<option value="' + value[0] + '" ' + selected + '>';
|
||||
html += value[1] + '</option>';
|
||||
});
|
||||
html += '</select>';
|
||||
return (val) ? $(html).attr('data-selected-value', val)[0] : html;
|
||||
}
|
||||
|
||||
/**
|
||||
* Takes an object and creates custom html element
|
||||
*
|
||||
* @param {String} object
|
||||
* @param {String} name
|
||||
* @param {String} column_type
|
||||
* @param {Object} cell
|
||||
* @param {Object} listColumns
|
||||
*
|
||||
* @returns (String)
|
||||
*/
|
||||
function changeToFormField(object, name, column_type, cell, listColumns) {
|
||||
var cellId = generateInputFieldReference(name);
|
||||
var value = cell.value || '';
|
||||
if (column_type === 'RepositoryListValue') {
|
||||
var column = _.findWhere(listColumns,
|
||||
{ column_id: parseInt(name, 10) });
|
||||
var list_items = column.list_items || cell.list_items;
|
||||
return _listItemDropdown(list_items, value, parseInt(name, 10), cellId);
|
||||
} else if (column_type === 'RepositoryAssetValue') {
|
||||
return changeToInputFileField('repository_cell_file', name, value, cellId);
|
||||
} else {
|
||||
return changeToInputField(object, name, value, cellId);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Append the change listener to file field
|
||||
*
|
||||
* @param {String} type
|
||||
* @param {String} name
|
||||
*
|
||||
* @returns {undefined}
|
||||
*/
|
||||
function addSelectedFile(type, name) {
|
||||
var button = $('button[data-id="' +
|
||||
generateInputFieldReference(name) +
|
||||
'"]');
|
||||
if (type === 'RepositoryAssetValue') {
|
||||
var fileInput = $(button.parent().find('input[type="file"]')[0]);
|
||||
button.on('click', function(ev) {
|
||||
ev.preventDefault();
|
||||
ev.stopPropagation();
|
||||
fileInput.trigger('click');
|
||||
initFileHandler(fileInput);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle extraction of file from the input field
|
||||
*
|
||||
* @param {Object} $inputField
|
||||
*
|
||||
* @returns {undefined}
|
||||
*/
|
||||
function initFileHandler($inputField) {
|
||||
$inputField.on('change', function() {
|
||||
var input = $(this);
|
||||
var $label = $($(this).closest('.repository-input-file-field')
|
||||
.find('.file-name-label')[0]);
|
||||
var file = this.files[0];
|
||||
if (file) {
|
||||
$label.text(truncateLongString(file.name, 20));
|
||||
input.attr('remove', false);
|
||||
$($label.closest('.repository-input-file-field')
|
||||
.find('[data-action="removeAsset"]')[0]).show();
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* Initializes the data binding for form object
|
||||
*
|
||||
* @param {Object} rowNode
|
||||
* @param {Object} data
|
||||
*
|
||||
* @returns {undefined}
|
||||
*/
|
||||
function initializeDataBinding(rowNode, data) {
|
||||
var uiBindings = {};
|
||||
$.each(_.keys(data), function(i, element) {
|
||||
uiBindings['#' + element] = element;
|
||||
})
|
||||
$(rowNode).my({ui: uiBindings}, data);
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates the input tag id that will be used in the formData object
|
||||
*
|
||||
* @param {String} columnId
|
||||
*
|
||||
* @returns {String}
|
||||
*/
|
||||
function generateInputFieldReference(columnId) {
|
||||
return 'colId-' + columnId;
|
||||
}
|
||||
|
||||
/**
|
||||
* Appends aditional fields to form data object
|
||||
* @param {Object} cell
|
||||
* @param {String} columnId
|
||||
* @param {Object} formData
|
||||
*
|
||||
* @returns {undefined}
|
||||
*/
|
||||
function appendNewElementToFormData(cell, columnId, formData) {
|
||||
if (!cell.repository_cell_id) {
|
||||
formData[generateInputFieldReference(columnId)] = undefined;
|
||||
}
|
||||
}
|
||||
}(window));
|
||||
// /* global Promise _ ActiveStorage RepositoryItemEditForm */
|
||||
//
|
||||
// //= require sugar.min
|
||||
// //= require jquerymy-1.2.14.min
|
||||
//
|
||||
// (function(global) {
|
||||
// 'use strict';
|
||||
//
|
||||
// /**
|
||||
// * Creates a FormData object with the repository row data ready to be
|
||||
// * sended on the server
|
||||
// *
|
||||
// * @param {Object} tableID
|
||||
// * @param {Object} selectedRecord
|
||||
// *
|
||||
// * @returns (Object)
|
||||
// */
|
||||
// RepositoryItemEditForm.prototype.parseToFormObject = function(tableID, selectedRecord) {
|
||||
// var formData = this.formData;
|
||||
// var formDataObj = new FormData();
|
||||
// var removeFileColumns = [];
|
||||
// var filesToUploadCntr = 0;
|
||||
// var filesUploadedCntr = 0;
|
||||
// const directUploadUrl = $(tableID).data('directUploadUrl');
|
||||
//
|
||||
// formDataObj.append('request_url', $(tableID).data('current-uri'));
|
||||
// formDataObj.append('repository_row_id', $(selectedRecord).attr('id'));
|
||||
//
|
||||
// return new Promise((resolve, reject) => {
|
||||
// $(_.keys(this.formData)).each(function(_, element) {
|
||||
// var value = formData[element];
|
||||
// if (element === 'rowName') {
|
||||
// formDataObj.append('repository_row_name', value);
|
||||
// } else {
|
||||
// let colId = element.replace('colId-', '');
|
||||
// let $el = $('#' + element);
|
||||
// // don't save anything if element is not visible
|
||||
// if ($el.length === 0) {
|
||||
// return;
|
||||
// }
|
||||
// if ($el.attr('type') === 'file') {
|
||||
// // handle deleting of element
|
||||
// if ($el.attr('remove') === 'true') {
|
||||
// removeFileColumns.push(colId);
|
||||
// formDataObj.append('repository_cells[' + colId + ']', null);
|
||||
// } else if ($el[0].files.length > 0) {
|
||||
// filesToUploadCntr += 1;
|
||||
// }
|
||||
// } else if (value.length >= 0) {
|
||||
// formDataObj.append('repository_cells[' + colId + ']', value);
|
||||
// }
|
||||
// }
|
||||
// });
|
||||
//
|
||||
// formDataObj.append('remove_file_columns', JSON.stringify(removeFileColumns));
|
||||
//
|
||||
// // No files for upload, so return earlier
|
||||
// if (filesToUploadCntr === 0) {
|
||||
// resolve(formDataObj);
|
||||
// return;
|
||||
// }
|
||||
//
|
||||
// // Second run, just for files
|
||||
// $(_.keys(this.formData)).each(function(_, element) {
|
||||
// let $el = $('#' + element);
|
||||
// let colId = element.replace('colId-', '');
|
||||
//
|
||||
// if ($el.attr('type') === 'file' && $el.attr('remove') !== 'true') {
|
||||
// let upload = new ActiveStorage.DirectUpload($el[0].files[0], directUploadUrl);
|
||||
//
|
||||
// upload.create(function(error, blob) {
|
||||
// if (error) {
|
||||
// reject(error);
|
||||
// } else {
|
||||
// formDataObj.append('repository_cells[' + colId + ']', blob.signed_id);
|
||||
// filesUploadedCntr += 1;
|
||||
//
|
||||
// if (filesUploadedCntr === filesToUploadCntr) {
|
||||
// resolve(formDataObj);
|
||||
// }
|
||||
// }
|
||||
// });
|
||||
// }
|
||||
// });
|
||||
// });
|
||||
// };
|
||||
//
|
||||
// /**
|
||||
// * Takes object and creates an input file field, contains a hidden
|
||||
// * input field which is triggered on button click and we get the uploaded
|
||||
// * file from there.
|
||||
// *
|
||||
// * @param {Object} object
|
||||
// * @param {String} name
|
||||
// * @param {String} value
|
||||
// * @param {String} id
|
||||
// *
|
||||
// * @returns (String)
|
||||
// */
|
||||
// function changeToInputFileField(object, name, value, id) {
|
||||
// var fileName = (value.file_name) ? value.file_name : I18n.t('general.file.no_file_chosen');
|
||||
// var buttonLabel = I18n.t('general.file.choose');
|
||||
// var html = "<div class='repository-input-file-field'>" +
|
||||
// "<div class='form-group'><div><input type='file' name='" + name + "' id='" +
|
||||
// id + "' style='display:none' /><button class='btn btn-default' " +
|
||||
// "data-object='" + object + "' name='" + name + "' value='" + value +
|
||||
// "' data-id='" + id + "'>" + buttonLabel +
|
||||
// "</button></div><div><p class='file-name-label'>" + truncateLongString(fileName, 20) +
|
||||
// "</p></div>";
|
||||
// if(value.file_name) {
|
||||
// html += "<div><a data-action='removeAsset' ";
|
||||
// html += "onClick='clearFileInput(this)'><i class='fas fa-times'></i></a>";
|
||||
// } else {
|
||||
// html += "<div><a data-action='removeAsset' onClick='clearFileInput(this)' ";
|
||||
// html += "style='display:none'><i class='fas fa-times'></i></a>";
|
||||
// }
|
||||
// html += "</div></div></div>";
|
||||
//
|
||||
// return html;
|
||||
// }
|
||||
//
|
||||
// /**
|
||||
// * Returns the colum index
|
||||
// *
|
||||
// * @param {Object} table
|
||||
// * @param {String} id
|
||||
// *
|
||||
// * @returns (Boolean | Number)
|
||||
// */
|
||||
// function getColumnIndex(table, id) {
|
||||
// if(id < 0)
|
||||
// return false;
|
||||
// return table.column(id).index('visible');
|
||||
// }
|
||||
//
|
||||
// /**
|
||||
// * Genrates list items dropdown element
|
||||
// *
|
||||
// * @param {Array} options
|
||||
// * @param {String} current_value
|
||||
// * @param {Number} columnId
|
||||
// * @param {String} id
|
||||
// *
|
||||
// * @returns (String)
|
||||
// */
|
||||
// function _listItemDropdown(options, current_value, columnId, id) {
|
||||
// var val = undefined;
|
||||
// var html = '<select id="' + id + '" class="form-control selectpicker repository-dropdown" ';
|
||||
// html += 'data-selected-value="" data-abs-min-length="2" data-live-search="true" ';
|
||||
// html += 'data-container="body" column_id="' + columnId +'">';
|
||||
// html += '<option value="-1"></option>';
|
||||
// $.each(options, function(index, value) {
|
||||
// var selected = '';
|
||||
// if (current_value === value[1]) {
|
||||
// selected = 'selected';
|
||||
// val = value[0];
|
||||
// }
|
||||
// html += '<option value="' + value[0] + '" ' + selected + '>';
|
||||
// html += value[1] + '</option>';
|
||||
// });
|
||||
// html += '</select>';
|
||||
// return (val) ? $(html).attr('data-selected-value', val)[0] : html;
|
||||
// }
|
||||
//
|
||||
// /**
|
||||
// * Takes an object and creates custom html element
|
||||
// *
|
||||
// * @param {String} object
|
||||
// * @param {String} name
|
||||
// * @param {String} column_type
|
||||
// * @param {Object} cell
|
||||
// * @param {Object} listColumns
|
||||
// *
|
||||
// * @returns (String)
|
||||
// */
|
||||
// function changeToFormField(object, name, column_type, cell, listColumns) {
|
||||
// var cellId = generateInputFieldReference(name);
|
||||
// var value = cell.value || '';
|
||||
// if (column_type === 'RepositoryListValue') {
|
||||
// var column = _.findWhere(listColumns,
|
||||
// { column_id: parseInt(name, 10) });
|
||||
// var list_items = column.list_items || cell.list_items;
|
||||
// return _listItemDropdown(list_items, value, parseInt(name, 10), cellId);
|
||||
// } else if (column_type === 'RepositoryAssetValue') {
|
||||
// return changeToInputFileField('repository_cell_file', name, value, cellId);
|
||||
// } else {
|
||||
// return changeToInputField(object, name, value, cellId);
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// /**
|
||||
// * Append the change listener to file field
|
||||
// *
|
||||
// * @param {String} type
|
||||
// * @param {String} name
|
||||
// *
|
||||
// * @returns {undefined}
|
||||
// */
|
||||
// function addSelectedFile(type, name) {
|
||||
// var button = $('button[data-id="' +
|
||||
// generateInputFieldReference(name) +
|
||||
// '"]');
|
||||
// if (type === 'RepositoryAssetValue') {
|
||||
// var fileInput = $(button.parent().find('input[type="file"]')[0]);
|
||||
// button.on('click', function(ev) {
|
||||
// ev.preventDefault();
|
||||
// ev.stopPropagation();
|
||||
// fileInput.trigger('click');
|
||||
// initFileHandler(fileInput);
|
||||
// });
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// /**
|
||||
// * Handle extraction of file from the input field
|
||||
// *
|
||||
// * @param {Object} $inputField
|
||||
// *
|
||||
// * @returns {undefined}
|
||||
// */
|
||||
// function initFileHandler($inputField) {
|
||||
// $inputField.on('change', function() {
|
||||
// var input = $(this);
|
||||
// var $label = $($(this).closest('.repository-input-file-field')
|
||||
// .find('.file-name-label')[0]);
|
||||
// var file = this.files[0];
|
||||
// if (file) {
|
||||
// $label.text(truncateLongString(file.name, 20));
|
||||
// input.attr('remove', false);
|
||||
// $($label.closest('.repository-input-file-field')
|
||||
// .find('[data-action="removeAsset"]')[0]).show();
|
||||
// }
|
||||
// })
|
||||
// }
|
||||
//
|
||||
// /**
|
||||
// * Generates the input tag id that will be used in the formData object
|
||||
// *
|
||||
// * @param {String} columnId
|
||||
// *
|
||||
// * @returns {String}
|
||||
// */
|
||||
// function generateInputFieldReference(columnId) {
|
||||
// return 'colId-' + columnId;
|
||||
// }
|
||||
//
|
||||
// /**
|
||||
// * Appends aditional fields to form data object
|
||||
// * @param {Object} cell
|
||||
// * @param {String} columnId
|
||||
// * @param {Object} formData
|
||||
// *
|
||||
// * @returns {undefined}
|
||||
// */
|
||||
// function appendNewElementToFormData(cell, columnId, formData) {
|
||||
// if (!cell.repository_cell_id) {
|
||||
// formData[generateInputFieldReference(columnId)] = undefined;
|
||||
// }
|
||||
// }
|
||||
// }(window));
|
||||
|
|
|
@ -0,0 +1,32 @@
|
|||
$.fn.dataTable.render.editRowName = function(formId, cell) {
|
||||
let $cell = $(cell.node());
|
||||
let text = $cell.find('a').first().text();
|
||||
|
||||
$cell.html(`
|
||||
<div class="form-group">
|
||||
<input class="form-control editing"
|
||||
form="${formId}"
|
||||
type="text"
|
||||
name="repository_row_name"
|
||||
value="${text}"
|
||||
data-type="RowName">
|
||||
</div>
|
||||
`);
|
||||
};
|
||||
|
||||
$.fn.dataTable.render.editRepositoryAssetValue = function(formId, columnId, cell) {
|
||||
return '';
|
||||
};
|
||||
|
||||
$.fn.dataTable.render.editRepositoryTextValue = function(formId, columnId, cell) {
|
||||
SmartAnnotation.init(cell);
|
||||
return '';
|
||||
};
|
||||
|
||||
$.fn.dataTable.render.editRepositoryListValue = function(formId, columnId, cell) {
|
||||
return '';
|
||||
};
|
||||
|
||||
$.fn.dataTable.render.editRepositoryStatusValue = function(formId, columnId, cell) {
|
||||
return '';
|
||||
};
|
|
@ -0,0 +1,24 @@
|
|||
$.fn.dataTable.render.newRowName = function(formId) {
|
||||
return `<input form="${formId}"
|
||||
type="text"
|
||||
name="repository_row_name"
|
||||
class="editing"
|
||||
value=""
|
||||
data-type="RowName">`;
|
||||
};
|
||||
|
||||
$.fn.dataTable.render.newRepositoryAssetValue = function(formId, columnId) {
|
||||
return '';
|
||||
};
|
||||
|
||||
$.fn.dataTable.render.newRepositoryTextValue = function(formId, columnId) {
|
||||
return '';
|
||||
};
|
||||
|
||||
$.fn.dataTable.render.newRepositoryListValue = function(formId, columnId) {
|
||||
return '';
|
||||
};
|
||||
|
||||
$.fn.dataTable.render.newRepositoryStatusValue = function(formId, columnId) {
|
||||
return '';
|
||||
};
|
|
@ -1,31 +1,27 @@
|
|||
/*
|
||||
globals I18n _ SmartAnnotation FilePreviewModal truncateLongString animateSpinner Promise
|
||||
ActiveStorage HelperModule animateLoading RepositoryItemEditForm onClickCancel
|
||||
hideAssignUnasignModal
|
||||
HelperModule animateLoading onClickCancel
|
||||
hideAssignUnasignModal RepositoryDatatableRowEditor
|
||||
*/
|
||||
|
||||
//= require jquery-ui/widgets/sortable
|
||||
//= require repositories/forms/repository_item_edit.js
|
||||
//= require repositories/row_editor.js
|
||||
|
||||
|
||||
var RepositoryDatatable = (function(global) {
|
||||
'use strict';
|
||||
|
||||
var TABLE_ID = '';
|
||||
var TABLE_WRAPPER = $('.repository-table');
|
||||
var TABLE = null;
|
||||
var SCINOTE_REPOSITORY_EDITED_ROWS = []; // an array of edited rows
|
||||
var EDITABLE = false;
|
||||
|
||||
var rowsSelected = [];
|
||||
|
||||
// Tells whether we're currently viewing or editing table
|
||||
var currentMode = 'viewMode';
|
||||
|
||||
// Tells what action will execute by pressing on save button (update/create)
|
||||
var saveAction = 'update';
|
||||
var selectedRecord;
|
||||
|
||||
// Helps saving correct table state
|
||||
var myData;
|
||||
var loadFirstTime = true;
|
||||
// var selectedRecord;
|
||||
|
||||
// Tells whether to filter only assigned repository records
|
||||
var viewAssigned;
|
||||
|
@ -50,22 +46,11 @@ var RepositoryDatatable = (function(global) {
|
|||
return value;
|
||||
});
|
||||
|
||||
function changeToViewMode() {
|
||||
currentMode = 'viewMode';
|
||||
// Table specific stuff
|
||||
TABLE.button(0).enable(true);
|
||||
FilePreviewModal.init();
|
||||
}
|
||||
|
||||
function changeToEditMode() {
|
||||
currentMode = 'editMode';
|
||||
// Table specific stuff
|
||||
TABLE.button(0).enable(false);
|
||||
}
|
||||
|
||||
// Enable/disable edit button
|
||||
function updateButtons() {
|
||||
if (currentMode === 'viewMode') {
|
||||
$('#saveCancel').hide();
|
||||
$('#editDeleteCopy').show();
|
||||
$('#addRepositoryRecord').removeClass('disabled').prop('disabled', false);
|
||||
$('.dataTables_length select').prop('disabled', false);
|
||||
$('#repository-acitons-dropdown').removeClass('disabled').prop('disabled', false);
|
||||
|
@ -108,6 +93,8 @@ var RepositoryDatatable = (function(global) {
|
|||
$('#unassignRepositoryRecords').removeClass('disabled').prop('disabled', false);
|
||||
}
|
||||
} else if (currentMode === 'editMode') {
|
||||
$('#editDeleteCopy').hide();
|
||||
$('#saveCancel').show();
|
||||
$('#repository-acitons-dropdown').addClass('disabled').prop('disabled', true);
|
||||
$('.dataTables_length select').prop('disabled', true);
|
||||
$('#addRepositoryRecord').addClass('disabled').prop('disabled', true);
|
||||
|
@ -124,6 +111,28 @@ var RepositoryDatatable = (function(global) {
|
|||
}
|
||||
}
|
||||
|
||||
function clearRowSelection() {
|
||||
$('.dt-body-center .repository-row-selector').prop('checked', false);
|
||||
$('.dt-body-center .repository-row-selector').closest('tr').removeClass('selected');
|
||||
rowsSelected = [];
|
||||
}
|
||||
|
||||
function changeToViewMode() {
|
||||
currentMode = 'viewMode';
|
||||
// Table specific stuff
|
||||
TABLE.button(0).enable(true);
|
||||
FilePreviewModal.init();
|
||||
updateButtons();
|
||||
}
|
||||
|
||||
function changeToEditMode() {
|
||||
currentMode = 'editMode';
|
||||
// Table specific stuff
|
||||
TABLE.button(0).enable(false);
|
||||
clearRowSelection();
|
||||
updateButtons();
|
||||
}
|
||||
|
||||
// Updates "Select all" control in a data table
|
||||
function updateDataTableSelectAllCtrl() {
|
||||
var $table = TABLE.table().node();
|
||||
|
@ -170,23 +179,9 @@ var RepositoryDatatable = (function(global) {
|
|||
return html;
|
||||
}
|
||||
|
||||
function addSelectedFile(type, cell, input) {
|
||||
if (type === 'RepositoryAssetValue') {
|
||||
if (cell.value != null) {
|
||||
const dT = new ClipboardEvent('').clipboardData // Firefox workaround exploiting https://bugzilla.mozilla.org/show_bug.cgi?id=1422655
|
||||
|| new DataTransfer(); // specs compliant (as of March 2018 only Chrome)
|
||||
dT.items.add(new File([_], cell.value.file_name));
|
||||
input.files = dT.files;
|
||||
}
|
||||
$(input).on('change', function() {
|
||||
this.dataset.changed = 'true';
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
function initRowSelection() {
|
||||
// Handle clicks on checkbox
|
||||
$('.dt-body-center .repository-row-selector').change(function(e) {
|
||||
$('.dt-body-center .repository-row-selector').change(function(ev) {
|
||||
var $row;
|
||||
var data;
|
||||
var rowId;
|
||||
|
@ -219,21 +214,77 @@ var RepositoryDatatable = (function(global) {
|
|||
|
||||
updateDataTableSelectAllCtrl();
|
||||
|
||||
e.stopPropagation();
|
||||
ev.stopPropagation();
|
||||
updateButtons();
|
||||
// Update number of selected records info
|
||||
$('#selected_info').html(' (' + rowsSelected.length + ' entries selected)');
|
||||
});
|
||||
|
||||
// Handle click on "Select all" control
|
||||
$('.dataTables_scrollHead input[name="select_all"]').change(function(e) {
|
||||
$('.dataTables_scrollHead input[name="select_all"]').change(function(ev) {
|
||||
if (this.checked) {
|
||||
$('.repository-row-selector:not(:checked)').trigger('click');
|
||||
} else {
|
||||
$('.repository-row-selector:checked').trigger('click');
|
||||
}
|
||||
// Prevent click event from propagating to parent
|
||||
e.stopPropagation();
|
||||
ev.stopPropagation();
|
||||
});
|
||||
}
|
||||
|
||||
function checkAvailableColumns() {
|
||||
$.ajax({
|
||||
url: $(TABLE_ID).data('available-columns'),
|
||||
type: 'GET',
|
||||
dataType: 'json',
|
||||
success: function(data) {
|
||||
var columnsIds = data.columns;
|
||||
var presentColumns = $(TABLE_ID).data('repository-columns-ids');
|
||||
if (!_.isEqual(columnsIds.sort(), presentColumns.sort())) {
|
||||
alert($(TABLE_ID).data('columns-changed'));
|
||||
animateSpinner();
|
||||
location.reload();
|
||||
}
|
||||
},
|
||||
error: function() {
|
||||
location.reload();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function initItemEditIcon() {
|
||||
$(TABLE_ID).on('click', '.repository-row-edit-icon', function(ev) {
|
||||
let rowId = $(ev.target).closest('tr').attr('id');
|
||||
let row = TABLE.row(`#${rowId}`);
|
||||
|
||||
$(row.node()).find('.repository-row-selector').trigger('click');
|
||||
|
||||
checkAvailableColumns();
|
||||
|
||||
$(TABLE_ID).find('.repository-row-edit-icon').remove();
|
||||
|
||||
RepositoryDatatableRowEditor.switchRowToEditMode(row);
|
||||
changeToEditMode();
|
||||
});
|
||||
}
|
||||
|
||||
function initSaveButton() {
|
||||
TABLE_WRAPPER.on('click', '#saveRecord', function() {
|
||||
$(TABLE_ID).find('.repository-row-edit-form').submit();
|
||||
});
|
||||
}
|
||||
|
||||
function initCancelButton() {
|
||||
TABLE_WRAPPER.on('click', '#cancelSave', function() {
|
||||
if ($('#assigned').text().length === 0) {
|
||||
TABLE.column(1).visible(false);
|
||||
}
|
||||
TABLE.ajax.reload(function() {
|
||||
initRowSelection();
|
||||
}, false);
|
||||
changeToViewMode();
|
||||
SmartAnnotation.closePopup();
|
||||
animateSpinner(null, false);
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -244,10 +295,10 @@ var RepositoryDatatable = (function(global) {
|
|||
}
|
||||
|
||||
// Takes object and surrounds it with input
|
||||
function changeToInputField(object, name, value) {
|
||||
return "<div class='form-group'><input class='form-control' data-object='"
|
||||
+ object + "' name='" + name + "' value='" + value + "'></input></div>";
|
||||
}
|
||||
// function changeToInputField(object, name, value) {
|
||||
// return "<div class='form-group'><input class='form-control' data-object='"
|
||||
// + object + "' name='" + name + "' value='" + value + "'></input></div>";
|
||||
// }
|
||||
|
||||
// Takes object and surrounds it with input
|
||||
function changeToInputFileField(object, name, value) {
|
||||
|
@ -357,13 +408,6 @@ var RepositoryDatatable = (function(global) {
|
|||
});
|
||||
}
|
||||
|
||||
// Return td element with content
|
||||
function createTdElement(content) {
|
||||
var td = document.createElement('td');
|
||||
td.innerHTML = content;
|
||||
return td;
|
||||
}
|
||||
|
||||
function initialListItemsRequest(columnId) {
|
||||
var massageResponse = [];
|
||||
$.ajax({
|
||||
|
@ -443,22 +487,16 @@ var RepositoryDatatable = (function(global) {
|
|||
}
|
||||
|
||||
// Clear all has-error tags
|
||||
function clearAllErrors() {
|
||||
// Remove any validation errors
|
||||
$(selectedRecord)
|
||||
.find('.has-error')
|
||||
.removeClass('has-error')
|
||||
.find('span')
|
||||
.remove();
|
||||
// Remove any alerts
|
||||
$('#alert-container').find('div').remove();
|
||||
}
|
||||
|
||||
function clearRowSelection() {
|
||||
$('.dt-body-center .repository-row-selector').prop('checked', false);
|
||||
$('.dt-body-center .repository-row-selector').closest('tr').removeClass('selected');
|
||||
rowsSelected = [];
|
||||
}
|
||||
// function clearAllErrors() {
|
||||
// // Remove any validation errors
|
||||
// $(selectedRecord)
|
||||
// .find('.has-error')
|
||||
// .removeClass('has-error')
|
||||
// .find('span')
|
||||
// .remove();
|
||||
// // Remove any alerts
|
||||
// $('#alert-container').find('div').remove();
|
||||
// }
|
||||
|
||||
function dataTableInit() {
|
||||
viewAssigned = 'assigned';
|
||||
|
@ -471,6 +509,7 @@ var RepositoryDatatable = (function(global) {
|
|||
sScrollXInner: '100%',
|
||||
scrollY: '64vh',
|
||||
scrollCollapse: true,
|
||||
order: [[2, 'asc']],
|
||||
colReorder: {
|
||||
fixedColumnsLeft: 2,
|
||||
realtime: false
|
||||
|
@ -499,7 +538,14 @@ var RepositoryDatatable = (function(global) {
|
|||
targets: 1,
|
||||
searchable: false,
|
||||
orderable: true,
|
||||
sWidth: '1%'
|
||||
sWidth: '1%',
|
||||
render: function(data) {
|
||||
let content = data;
|
||||
if (EDITABLE) {
|
||||
content = '<i class="repository-row-edit-icon fas fa-pencil-alt"></i>' + content;
|
||||
}
|
||||
return content;
|
||||
}
|
||||
}, {
|
||||
// Name column is clickable
|
||||
targets: 3,
|
||||
|
@ -522,21 +568,16 @@ var RepositoryDatatable = (function(global) {
|
|||
},
|
||||
rowCallback: function(row, data) {
|
||||
// Get row ID
|
||||
var rowId = data.DT_RowId;
|
||||
let 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);
|
||||
$(row).addClass('selected');
|
||||
}
|
||||
},
|
||||
order: $(TABLE_ID).data('default-order'),
|
||||
columns: (function() {
|
||||
var columns = $(TABLE_ID).data('default-table-columns');
|
||||
var customColumns = $(TABLE_ID).find('thead th[data-type]');
|
||||
for (let i = 0; i < columns.length; i += 1) {
|
||||
columns[i].data = String(i);
|
||||
columns[i].defaultContent = '';
|
||||
}
|
||||
customColumns.each((i, column) => {
|
||||
columns.push({
|
||||
visible: true,
|
||||
|
@ -547,10 +588,9 @@ var RepositoryDatatable = (function(global) {
|
|||
});
|
||||
return columns;
|
||||
}()),
|
||||
fnDrawCallback: function() {
|
||||
drawCallback: function() {
|
||||
animateSpinner(this, false);
|
||||
changeToViewMode();
|
||||
updateButtons();
|
||||
updateDataTableSelectAllCtrl();
|
||||
FilePreviewModal.init();
|
||||
// Prevent row toggling when selecting user smart annotation link
|
||||
|
@ -565,101 +605,66 @@ var RepositoryDatatable = (function(global) {
|
|||
animateSpinner(this);
|
||||
$('.record-info-link').off('click');
|
||||
},
|
||||
stateLoadCallback: function() {
|
||||
// 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
|
||||
stateLoadCallback: function(settings, callback) {
|
||||
var repositoryId = $(TABLE_ID).data('repository-id');
|
||||
$.ajax({
|
||||
url: '/repositories/' + repositoryId + '/state_load',
|
||||
data: {},
|
||||
async: false,
|
||||
dataType: 'json',
|
||||
type: 'POST',
|
||||
success: function(json) {
|
||||
myData = json.state;
|
||||
|
||||
// Fix the order - convert it from index-keyed JS object that
|
||||
// is returned from the server state into true JS array;
|
||||
// e.g. {0: [2, 'asc'], 1: [3, 'desc']}
|
||||
// is converted into [[2, 'asc'], [3, 'desc']]
|
||||
myData.order = _.toArray(myData.order);
|
||||
callback(json.state);
|
||||
}
|
||||
});
|
||||
return myData;
|
||||
},
|
||||
stateSaveCallback: function(settings, data) {
|
||||
var stateData = data;
|
||||
// Send an Ajax request to the server with the state object
|
||||
var repositoryId = $(TABLE_ID).data('repository-id');
|
||||
// Save correct data
|
||||
if (loadFirstTime === true) {
|
||||
stateData = myData;
|
||||
}
|
||||
let repositoryId = $(TABLE_ID).data('repository-id');
|
||||
|
||||
$.ajax({
|
||||
url: '/repositories/' + repositoryId + '/state_save',
|
||||
data: { state: stateData },
|
||||
contentType: 'application/json',
|
||||
data: JSON.stringify({ state: data }),
|
||||
dataType: 'json',
|
||||
type: 'POST'
|
||||
});
|
||||
loadFirstTime = false;
|
||||
},
|
||||
fnInitComplete: function(oSettings) {
|
||||
// First two columns are fixed
|
||||
TABLE.column(0).visible(true);
|
||||
TABLE.column(1).visible(true);
|
||||
|
||||
// Reload correct column order and visibility (if you refresh page)
|
||||
for (let i = 2; i < TABLE.columns()[0].length; i += 1) {
|
||||
let visibility = false;
|
||||
if (myData.columns && myData.columns[i]) {
|
||||
visibility = myData.columns[i].visible;
|
||||
}
|
||||
if (typeof (visibility) === 'string') {
|
||||
visibility = (visibility === 'true');
|
||||
}
|
||||
TABLE.column(i).visible(visibility);
|
||||
TABLE.setColumnSearchable(i, visibility);
|
||||
}
|
||||
|
||||
// Re-order table as per loaded state
|
||||
if (myData.order) {
|
||||
TABLE.order(myData.order);
|
||||
TABLE.draw();
|
||||
}
|
||||
|
||||
// Datatables triggers this action about 3 times
|
||||
// sometimes on the first iteration the oSettings._colReorder is null
|
||||
// and the fnOrder rises an error that breaks the table
|
||||
// here I added a null guard for that case.
|
||||
// @todo we need to find out why the tables are loaded multiple times
|
||||
if (oSettings._colReorder) {
|
||||
oSettings._colReorder.fnOrder(myData.ColReorder);
|
||||
}
|
||||
fnInitComplete: function() {
|
||||
initRowSelection();
|
||||
bindExportActions();
|
||||
disableCheckboxToggleOnAssetDownload();
|
||||
FilePreviewModal.init();
|
||||
initHeaderTooltip();
|
||||
|
||||
// Append button to inner toolbar in table
|
||||
$('div.toolbarButtonsDatatable').appendTo('div.toolbar');
|
||||
$('div.toolbarButtonsDatatable').show();
|
||||
|
||||
// Append buttons for task inventory
|
||||
$('div.toolbarButtons').appendTo('div.toolbar');
|
||||
$('div.toolbarButtons').show();
|
||||
|
||||
if (EDITABLE) {
|
||||
RepositoryDatatableRowEditor.initFormSubmitAction(TABLE);
|
||||
initItemEditIcon();
|
||||
initSaveButton();
|
||||
initCancelButton();
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
// hack to replace filter placeholder
|
||||
$('.dataTables_filter .form-control').attr('placeholder', $('.dataTables_filter label').text())
|
||||
$('.dataTables_filter label').contents().filter(function(){
|
||||
$('.dataTables_filter .form-control').attr('placeholder', $('.dataTables_filter label').text());
|
||||
$('.dataTables_filter label').contents().filter(function() {
|
||||
return this.nodeType === 3;
|
||||
}).remove();
|
||||
|
||||
// Handle click on table cells with checkboxes
|
||||
$(TABLE_ID).on('click', 'tbody td', function(e) {
|
||||
if ($(e.target).is('.repository-row-selector')) {
|
||||
// Skip if clicking on selector checkbox
|
||||
return;
|
||||
}
|
||||
if (!$(e.target).is('.record-info-link')) {
|
||||
// Skip if clicking on samples info link
|
||||
$(this).parent().find('.repository-row-selector').trigger('click');
|
||||
}
|
||||
$(TABLE_ID).on('click', 'tbody td', function(ev) {
|
||||
// Skip if clicking on selector checkbox, edit icon or link
|
||||
if ($(ev.target).is('.repository-row-selector, .repository-row-edit-icon, a')) return;
|
||||
|
||||
$(this).parent().find('.repository-row-selector').trigger('click');
|
||||
});
|
||||
|
||||
TABLE.on('column-reorder', function() {
|
||||
|
@ -681,107 +686,15 @@ var RepositoryDatatable = (function(global) {
|
|||
// Append buttons for task inventory
|
||||
$('div.toolbarButtons').appendTo('div.toolbar');
|
||||
$('div.toolbarButtons').show();
|
||||
}, 10);
|
||||
}, 100);
|
||||
|
||||
return TABLE;
|
||||
}
|
||||
|
||||
function checkAvailableColumns() {
|
||||
$.ajax({
|
||||
url: $(TABLE_ID).data('available-columns'),
|
||||
type: 'GET',
|
||||
dataType: 'json',
|
||||
success: function(data) {
|
||||
var columnsIds = data.columns;
|
||||
var presentColumns = $(TABLE_ID).data('repository-columns-ids');
|
||||
if (!_.isEqual(columnsIds.sort(), presentColumns.sort())) {
|
||||
alert($(TABLE_ID).data('columns-changed'));
|
||||
animateSpinner();
|
||||
location.reload();
|
||||
}
|
||||
},
|
||||
error: function() {
|
||||
location.reload();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// Restore previous table
|
||||
global.onClickCancel = function() {
|
||||
if ($('#assigned').text().length === 0) {
|
||||
TABLE.column(1).visible(false);
|
||||
}
|
||||
TABLE.ajax.reload(function() {
|
||||
initRowSelection();
|
||||
}, false);
|
||||
changeToViewMode();
|
||||
updateButtons();
|
||||
SmartAnnotation.closePopup();
|
||||
SCINOTE_REPOSITORY_EDITED_ROWS = [];
|
||||
animateSpinner(null, false);
|
||||
};
|
||||
|
||||
global.onClickAddRecord = function() {
|
||||
var tr = document.createElement('tr');
|
||||
|
||||
checkAvailableColumns();
|
||||
RepositoryDatatableRowEditor.addNewRow(TABLE);
|
||||
changeToEditMode();
|
||||
updateButtons();
|
||||
|
||||
saveAction = 'create';
|
||||
|
||||
if (TABLE.column(1).visible() === false) {
|
||||
TABLE.column(1).visible(true);
|
||||
}
|
||||
$('table' + TABLE_ID + ' thead tr').children('th').each(function() {
|
||||
var th = $(this);
|
||||
var td;
|
||||
var input;
|
||||
if ($(th).attr('id') === 'checkbox') {
|
||||
td = createTdElement('');
|
||||
$(td).html($('#saveRecord').clone());
|
||||
tr.appendChild(td);
|
||||
} else if ($(th).attr('id') === 'assigned') {
|
||||
td = createTdElement('');
|
||||
$(td).html($('#cancelSave').clone());
|
||||
tr.appendChild(td);
|
||||
} else if ($(th).attr('id') === 'row-name') {
|
||||
input = changeToInputField('repository_row', 'name', '');
|
||||
tr.appendChild(createTdElement(input));
|
||||
} else if ($(th).hasClass('repository-column')
|
||||
&& $(th).attr('data-type') === 'RepositoryTextValue') {
|
||||
input = changeToInputField('repository_cell', th.attr('id'), '');
|
||||
tr.appendChild(createTdElement(input));
|
||||
} else if ($(th).hasClass('repository-column')
|
||||
&& $(th).attr('data-type') === 'RepositoryListValue') {
|
||||
input = initialListItemsRequest($(th).attr('id'));
|
||||
tr.appendChild(createTdElement(input));
|
||||
} else if ($(th).hasClass('repository-column')
|
||||
&& $(th).attr('data-type') === 'RepositoryAssetValue') {
|
||||
input = changeToInputFileField('repository_cell_file', th.attr('id'), '');
|
||||
td = createTdElement(input);
|
||||
tr.appendChild(td);
|
||||
addSelectedFile($(th).attr('data-type'), '', $(td).find('input')[0]);
|
||||
} else {
|
||||
// Column we don't care for, just add empty td
|
||||
tr.appendChild(createTdElement(''));
|
||||
}
|
||||
});
|
||||
|
||||
$('table' + TABLE_ID).prepend(tr);
|
||||
selectedRecord = tr;
|
||||
|
||||
// initialize smart annotation
|
||||
_.each($('[data-object="repository_cell"]'), function(el) {
|
||||
if (_.isUndefined($(el).data('atwho'))) {
|
||||
SmartAnnotation.init(el);
|
||||
}
|
||||
});
|
||||
|
||||
// Init selectpicker
|
||||
initSelectPicker();
|
||||
// Adjust columns width in table header
|
||||
adjustTableHeader();
|
||||
};
|
||||
|
||||
global.onClickToggleAssignedRecords = function() {
|
||||
|
@ -903,10 +816,10 @@ var RepositoryDatatable = (function(global) {
|
|||
rowsSelected = [];
|
||||
onClickCancel();
|
||||
},
|
||||
error: function(e) {
|
||||
if (e.status === 403) {
|
||||
error: function(ev) {
|
||||
if (ev.status === 403) {
|
||||
HelperModule.flashAlertMsg(
|
||||
I18n.t('repositories.js.permission_error'), e.responseJSON.style
|
||||
I18n.t('repositories.js.permission_error'), ev.responseJSON.style
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -925,10 +838,10 @@ var RepositoryDatatable = (function(global) {
|
|||
rowsSelected = [];
|
||||
onClickCancel();
|
||||
},
|
||||
error: function(e) {
|
||||
if (e.status === 403) {
|
||||
error: function(ev) {
|
||||
if (ev.status === 403) {
|
||||
HelperModule.flashAlertMsg(
|
||||
I18n.t('repositories.js.permission_error'), e.responseJSON.style
|
||||
I18n.t('repositories.js.permission_error'), ev.responseJSON.style
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -937,232 +850,96 @@ var RepositoryDatatable = (function(global) {
|
|||
|
||||
// Edit record
|
||||
global.onClickEdit = function() {
|
||||
var row;
|
||||
var node;
|
||||
var rowData;
|
||||
|
||||
checkAvailableColumns();
|
||||
|
||||
if (rowsSelected.length !== 1) {
|
||||
return;
|
||||
}
|
||||
|
||||
row = TABLE.row('#' + rowsSelected[0]);
|
||||
node = row.node();
|
||||
rowData = row.data();
|
||||
let row = TABLE.row('#' + rowsSelected[0]);
|
||||
|
||||
$(node).find('td input').trigger('click');
|
||||
selectedRecord = node;
|
||||
$(TABLE_ID).find('.repository-row-edit-icon').remove();
|
||||
|
||||
clearAllErrors();
|
||||
changeToEditMode();
|
||||
updateButtons();
|
||||
saveAction = 'update';
|
||||
|
||||
$.ajax({
|
||||
url: rowData.recordEditUrl,
|
||||
type: 'GET',
|
||||
dataType: 'json',
|
||||
success: function(data) {
|
||||
var editForm = new RepositoryItemEditForm(data, node);
|
||||
|
||||
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());
|
||||
$(node).children('td').eq(1).html($('#cancelSave').clone());
|
||||
|
||||
editForm.renderForm(TABLE);
|
||||
initSelectPicker();
|
||||
editForm.initializeSelectpickerValues(node);
|
||||
|
||||
// initialize smart annotation
|
||||
_.each($('[data-object="repository_cell"]'), function(el) {
|
||||
if (_.isUndefined($(el).data('atwho'))) {
|
||||
SmartAnnotation.init(el);
|
||||
}
|
||||
});
|
||||
// Adjust columns width in table header
|
||||
adjustTableHeader();
|
||||
updateButtons();
|
||||
|
||||
SCINOTE_REPOSITORY_EDITED_ROWS.push(editForm);
|
||||
},
|
||||
error: function(e) {
|
||||
if (e.status === 403) {
|
||||
HelperModule.flashAlertMsg(
|
||||
I18n.t('repositories.js.permission_error'), e.responseJSON.style
|
||||
);
|
||||
changeToViewMode();
|
||||
updateButtons();
|
||||
}
|
||||
}
|
||||
});
|
||||
RepositoryDatatableRowEditor.switchRowToEditMode(row);
|
||||
adjustTableHeader();
|
||||
};
|
||||
|
||||
function submitForm(url, formData) {
|
||||
var type;
|
||||
if (saveAction === 'update') {
|
||||
type = 'PUT';
|
||||
} else {
|
||||
type = 'POST';
|
||||
}
|
||||
$.ajax({
|
||||
url: url,
|
||||
type: type,
|
||||
dataType: 'json',
|
||||
data: formData,
|
||||
processData: false,
|
||||
contentType: false,
|
||||
success: function(data) {
|
||||
HelperModule.flashAlertMsg(data.flash, 'success');
|
||||
SmartAnnotation.closePopup();
|
||||
SCINOTE_REPOSITORY_EDITED_ROWS = [];
|
||||
onClickCancel();
|
||||
animateSpinner(null, false);
|
||||
},
|
||||
error: function(e) {
|
||||
var data = e.responseJSON;
|
||||
animateSpinner(null, false);
|
||||
SmartAnnotation.closePopup();
|
||||
clearAllErrors();
|
||||
|
||||
if (e.status === 404) {
|
||||
HelperModule.flashAlertMsg(
|
||||
I18n.t('repositories.js.not_found_error'), 'danger'
|
||||
);
|
||||
changeToViewMode();
|
||||
updateButtons();
|
||||
} else if (e.status === 403) {
|
||||
HelperModule.flashAlertMsg(
|
||||
I18n.t('repositories.js.permission_error'), 'danger'
|
||||
);
|
||||
changeToViewMode();
|
||||
updateButtons();
|
||||
} else if (e.status === 400) {
|
||||
if (data.default_fields) {
|
||||
let defaultFields = data.default_fields;
|
||||
|
||||
// Validate record name
|
||||
if (defaultFields.name) {
|
||||
let input = $(selectedRecord).find('input[name = name]');
|
||||
|
||||
if (input) {
|
||||
input.closest('.form-group').addClass('has-error');
|
||||
input.parent().append("<span class='help-block'>" + defaultFields.name + '<br /></span>');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Validate custom cells
|
||||
$.each(data.repository_cells || [], function(_, val) {
|
||||
$.each(val, function(key, val2) {
|
||||
let input = $(selectedRecord).find('input[name=' + key + ']');
|
||||
if (input) {
|
||||
let message = Array.isArray(val2.data) ? val2.data[0] : val2.data;
|
||||
// handle custom input field
|
||||
if (input.attr('type') === 'file') {
|
||||
let container = input.closest('.repository-input-file-field');
|
||||
$(container.find('.form-group')[0]).addClass('has-error');
|
||||
container.addClass('has-error');
|
||||
container.append("<span class='help-block'>" + message + '<br /></span>');
|
||||
} else {
|
||||
input.closest('.form-group').addClass('has-error');
|
||||
input.parent().append("<span class='help-block'>" + message + '<br /></span>');
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function buildNewFormData() {
|
||||
return new Promise((resolve, reject) => {
|
||||
var node = selectedRecord;
|
||||
var formData = new FormData();
|
||||
var filesToUploadCntr = 0;
|
||||
var filesUploadedCntr = 0;
|
||||
const directUploadUrl = $(TABLE_ID).data('directUploadUrl');
|
||||
|
||||
// First fetch all the data in input fields
|
||||
formData.append('request_url', $(TABLE_ID).data('current-uri'));
|
||||
formData.append('repository_row_id', $(selectedRecord).attr('id'));
|
||||
|
||||
// Direct record attributes
|
||||
// Record name
|
||||
formData.append('repository_row_name', $('td input[data-object = repository_row]').val());
|
||||
|
||||
// Custom cells text type
|
||||
$(node).find('td input[data-object = repository_cell]').each(function() {
|
||||
// Send data only and only if cell is not empty
|
||||
if ($(this).val().trim()) {
|
||||
formData.append('repository_cells[' + $(this).attr('name') + ']', $(this).val());
|
||||
}
|
||||
});
|
||||
|
||||
// Custom cells list type
|
||||
$(node).find('td[column_id]').each(function(index, el) {
|
||||
var value = $(el).attr('list_item_id');
|
||||
formData.append('repository_cells[' + $(el).attr('column_id') + ']', value);
|
||||
});
|
||||
|
||||
// Custom cells file type, first run, count files ready for upload
|
||||
$(node).find('td input[data-object = repository_cell_file]').each(function() {
|
||||
// Send data only and only if cell is not empty
|
||||
if ($(this)[0].files.length === 1) {
|
||||
filesToUploadCntr += 1;
|
||||
}
|
||||
});
|
||||
|
||||
// No files for upload, so return earlier
|
||||
if (filesToUploadCntr === 0) {
|
||||
resolve(formData);
|
||||
return;
|
||||
}
|
||||
|
||||
// Custom cells file type, second run, upload files
|
||||
$(node).find('td input[data-object = repository_cell_file]').each(function() {
|
||||
// Send data only and only if cell is not empty
|
||||
if ($(this)[0].files.length === 1) {
|
||||
let upload = new ActiveStorage.DirectUpload($(this)[0].files[0], directUploadUrl);
|
||||
let colId = $(this).attr('name');
|
||||
|
||||
upload.create(function(error, blob) {
|
||||
if (error) {
|
||||
reject(error);
|
||||
} else {
|
||||
formData.append('repository_cells[' + colId + ']', blob.signed_id);
|
||||
filesUploadedCntr += 1;
|
||||
|
||||
if (filesUploadedCntr === filesToUploadCntr) {
|
||||
resolve(formData);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
// Save record
|
||||
global.onClickSave = function() {
|
||||
animateSpinner(null, true);
|
||||
if (saveAction === 'update') {
|
||||
let row = TABLE.row(selectedRecord);
|
||||
let rowData = row.data();
|
||||
SCINOTE_REPOSITORY_EDITED_ROWS[0].parseToFormObject(
|
||||
TABLE_ID, selectedRecord
|
||||
).then(formData => {
|
||||
submitForm(rowData.recordUpdateUrl, formData);
|
||||
});
|
||||
} else if (saveAction === 'create') {
|
||||
buildNewFormData().then(formData => {
|
||||
submitForm($('table' + TABLE_ID).data('create-record'), formData);
|
||||
});
|
||||
}
|
||||
};
|
||||
// function submitForm(url, formData) {
|
||||
// var type;
|
||||
// if (saveAction === 'update') {
|
||||
// type = 'PUT';
|
||||
// } else {
|
||||
// type = 'POST';
|
||||
// }
|
||||
// $.ajax({
|
||||
// url: url,
|
||||
// type: type,
|
||||
// dataType: 'json',
|
||||
// data: formData,
|
||||
// processData: false,
|
||||
// contentType: false,
|
||||
// success: function(data) {
|
||||
// HelperModule.flashAlertMsg(data.flash, 'success');
|
||||
// SmartAnnotation.closePopup();
|
||||
// SCINOTE_REPOSITORY_EDITED_ROWS = [];
|
||||
// onClickCancel();
|
||||
// animateSpinner(null, false);
|
||||
// },
|
||||
// error: function(ev) {
|
||||
// var data = ev.responseJSON;
|
||||
// animateSpinner(null, false);
|
||||
// SmartAnnotation.closePopup();
|
||||
// clearAllErrors();
|
||||
//
|
||||
// if (ev.status === 404) {
|
||||
// HelperModule.flashAlertMsg(
|
||||
// I18n.t('repositories.js.not_found_error'), 'danger'
|
||||
// );
|
||||
// changeToViewMode();
|
||||
// } else if (ev.status === 403) {
|
||||
// HelperModule.flashAlertMsg(
|
||||
// I18n.t('repositories.js.permission_error'), 'danger'
|
||||
// );
|
||||
// changeToViewMode();
|
||||
// } else if (ev.status === 400) {
|
||||
// if (data.default_fields) {
|
||||
// let defaultFields = data.default_fields;
|
||||
//
|
||||
// // Validate record name
|
||||
// if (defaultFields.name) {
|
||||
// let input = $(selectedRecord).find('input[name = name]');
|
||||
//
|
||||
// if (input) {
|
||||
// input.closest('.form-group').addClass('has-error');
|
||||
// input.parent().append("<span class='help-block'>" + defaultFields.name + '<br /></span>');
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// // Validate custom cells
|
||||
// $.each(data.repository_cells || [], function(_, val) {
|
||||
// $.each(val, function(key, val2) {
|
||||
// let input = $(selectedRecord).find('input[name=' + key + ']');
|
||||
// if (input) {
|
||||
// let message = Array.isArray(val2.data) ? val2.data[0] : val2.data;
|
||||
// // handle custom input field
|
||||
// if (input.attr('type') === 'file') {
|
||||
// let container = input.closest('.repository-input-file-field');
|
||||
// $(container.find('.form-group')[0]).addClass('has-error');
|
||||
// container.addClass('has-error');
|
||||
// container.append("<span class='help-block'>" + message + '<br /></span>');
|
||||
// } else {
|
||||
// input.closest('.form-group').addClass('has-error');
|
||||
// input.parent().append("<span class='help-block'>" + message + '<br /></span>');
|
||||
// }
|
||||
// }
|
||||
// });
|
||||
// });
|
||||
// }
|
||||
// }
|
||||
// });
|
||||
// }
|
||||
|
||||
// Delete record
|
||||
global.onClickDelete = function() {
|
||||
|
@ -1343,6 +1120,7 @@ var RepositoryDatatable = (function(global) {
|
|||
|
||||
function init(id) {
|
||||
TABLE_ID = id;
|
||||
EDITABLE = $(TABLE_ID).data('editable');
|
||||
TABLE = dataTableInit();
|
||||
initDropdown();
|
||||
}
|
||||
|
|
146
app/assets/javascripts/repositories/row_editor.js
Normal file
146
app/assets/javascripts/repositories/row_editor.js
Normal file
|
@ -0,0 +1,146 @@
|
|||
/*
|
||||
globals HelperModule animateSpinner SmartAnnotation
|
||||
*/
|
||||
|
||||
var RepositoryDatatableRowEditor = (function() {
|
||||
const NAME_COLUMN_ID = 'row-name';
|
||||
const TABLE_ROW = '<tr></tr>';
|
||||
const TABLE_CELL = '<td></td>';
|
||||
|
||||
var TABLE;
|
||||
|
||||
// Initialize SmartAnnotation
|
||||
function initSmartAnnotation($row) {
|
||||
$row.find('[data-object="repository_cell"]').each(function(el) {
|
||||
if (el.data('atwho')) {
|
||||
SmartAnnotation.init(el);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function initFormSubmitAction(table) {
|
||||
TABLE = table;
|
||||
let $table = $(TABLE.table().node());
|
||||
|
||||
$table.on('ajax:beforeSend', '.repository-row-edit-form', function() {
|
||||
let $row = $(this).closest('tr');
|
||||
let valid = true;
|
||||
|
||||
$row.find('.has-error').removeClass('has-error').find('span').remove();
|
||||
|
||||
$row.find('input').each(function() {
|
||||
let dataType = $(this).data('type');
|
||||
if (!dataType) return;
|
||||
|
||||
valid = $.fn.dataTable.render[dataType + 'Validator']($(this));
|
||||
});
|
||||
if (!valid) return false;
|
||||
|
||||
animateSpinner(null, true);
|
||||
});
|
||||
|
||||
$table.on('ajax:success', '.repository-row-edit-form', function(ev, data) {
|
||||
TABLE.ajax.reload();
|
||||
HelperModule.flashAlertMsg(data.flash, 'success');
|
||||
});
|
||||
|
||||
$table.on('ajax:error', '.repository-row-edit-form', function(ev, data) {
|
||||
HelperModule.flashAlertMsg(data.responseJSON.flash, 'danger');
|
||||
});
|
||||
|
||||
$table.on('ajax:complete', '.repository-row-edit-form', function() {
|
||||
animateSpinner(null, false);
|
||||
});
|
||||
}
|
||||
|
||||
function addNewRow(table) {
|
||||
TABLE = table;
|
||||
|
||||
let $row = $(TABLE_ROW);
|
||||
const formId = 'repositoryNewRowForm';
|
||||
let actionUrl = $(TABLE.table().node()).data('createRecord');
|
||||
let rowForm = $(`
|
||||
<form id="${formId}"
|
||||
class="repository-row-edit-form"
|
||||
action="${actionUrl}"
|
||||
method="post"
|
||||
data-remote="true">
|
||||
</form>
|
||||
`);
|
||||
|
||||
$row.prepend(rowForm);
|
||||
|
||||
// First two columns are always present and visible
|
||||
$row.append($(TABLE_CELL));
|
||||
$row.append($(TABLE_CELL));
|
||||
|
||||
table.columns().every(function() {
|
||||
let column = this;
|
||||
let $header = $(column.header());
|
||||
|
||||
if (column.index() < 2) return;
|
||||
if (!column.visible()) return;
|
||||
|
||||
let columnId = $header.attr('id');
|
||||
|
||||
if (columnId === NAME_COLUMN_ID) {
|
||||
$row.append($(TABLE_CELL).html($.fn.dataTable.render.newRowName(formId)));
|
||||
} else {
|
||||
let dataType = $header.data('type');
|
||||
if (dataType) {
|
||||
$row.append($(TABLE_CELL).html($.fn.dataTable.render['new' + dataType](formId, columnId)));
|
||||
} else {
|
||||
$row.append($(TABLE_CELL));
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
$(TABLE.table().node()).find('tbody').prepend($row);
|
||||
|
||||
initSmartAnnotation($row);
|
||||
|
||||
TABLE.columns.adjust();
|
||||
}
|
||||
|
||||
function switchRowToEditMode(row) {
|
||||
let $row = $(row.node());
|
||||
let itemId = row.id();
|
||||
let formId = `repositoryRowForm${itemId}`;
|
||||
let rowForm = $(`
|
||||
<form id="${formId}"
|
||||
class="repository-row-edit-form"
|
||||
action="${row.data().recordUpdateUrl}"
|
||||
method="patch"
|
||||
data-remote="true"
|
||||
data-row-id="${itemId}">
|
||||
<input name="id" type="hidden" value="${itemId}" />
|
||||
</form>
|
||||
`);
|
||||
|
||||
$row.prepend(rowForm);
|
||||
|
||||
TABLE.cells(row.index(), row.columns().eq(0)).every(function() {
|
||||
let columnId = $(TABLE.columns(this.index().column).header()).attr('id');
|
||||
let cell = this;
|
||||
|
||||
if (columnId === NAME_COLUMN_ID) {
|
||||
$.fn.dataTable.render.editRowName(formId, cell);
|
||||
} else {
|
||||
let dataType = $(this.column().header()).data('type');
|
||||
if (dataType) $.fn.dataTable.render['edit' + dataType](formId, columnId, cell);
|
||||
}
|
||||
|
||||
return true;
|
||||
});
|
||||
|
||||
initSmartAnnotation($row);
|
||||
|
||||
TABLE.columns.adjust();
|
||||
}
|
||||
|
||||
return Object.freeze({
|
||||
initFormSubmitAction: initFormSubmitAction,
|
||||
switchRowToEditMode: switchRowToEditMode,
|
||||
addNewRow: addNewRow
|
||||
});
|
||||
}());
|
|
@ -0,0 +1,5 @@
|
|||
/* global GLOBAL_CONSTANTS textValidator */
|
||||
|
||||
$.fn.dataTable.render.RowNameValidator = function($input) {
|
||||
return textValidator(undefined, $input, 1, GLOBAL_CONSTANTS.NAME_MAX_LENGTH);
|
||||
};
|
|
@ -83,6 +83,28 @@
|
|||
}
|
||||
}
|
||||
|
||||
.repository-table {
|
||||
tbody {
|
||||
tr:hover {
|
||||
background-color: $color-concrete;
|
||||
}
|
||||
|
||||
.editing {
|
||||
border: 1px solid;
|
||||
}
|
||||
|
||||
.repository-row-edit-icon {
|
||||
opacity: 0;
|
||||
padding-right: 10px;
|
||||
}
|
||||
|
||||
tr:hover .repository-row-edit-icon {
|
||||
cursor: pointer;
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.new-input-file-field-div {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
|
|
|
@ -56,14 +56,6 @@ module RepositoryDatatableHelper
|
|||
can_manage_repository_rows?(repository)
|
||||
end
|
||||
|
||||
# The order must be converted from Ruby Hash into a JS array -
|
||||
# because arrays in JS are in truth regular JS objects with indexes as keys
|
||||
def default_table_order_as_js_array
|
||||
Constants::REPOSITORY_TABLE_DEFAULT_STATE[:order].keys.sort.map do |k|
|
||||
Constants::REPOSITORY_TABLE_DEFAULT_STATE[:order][k]
|
||||
end.to_s
|
||||
end
|
||||
|
||||
def default_table_columns
|
||||
Constants::REPOSITORY_TABLE_DEFAULT_STATE[:columns].keys.sort.map do |k|
|
||||
col = Constants::REPOSITORY_TABLE_DEFAULT_STATE[:columns][k]
|
||||
|
|
|
@ -18,14 +18,17 @@ class RepositoryTableStateService
|
|||
loaded.state['order'] &&
|
||||
loaded.state['columns'] &&
|
||||
loaded.state['ColReorder'] &&
|
||||
loaded.state.dig('columns', '1', 'visible') == 'true' &&
|
||||
loaded.state.dig('columns', '3', 'visible') == 'true'
|
||||
loaded.state.dig('columns', 1, 'visible') == true &&
|
||||
loaded.state.dig('columns', 3, 'visible') == true
|
||||
loaded
|
||||
end
|
||||
|
||||
def update_state(state)
|
||||
saved_state = load_state
|
||||
state[:order][0] = [3, 'asc'] if state.dig(:order, 0, 0).to_i < 2
|
||||
|
||||
return if saved_state.state.except('time') == state.except('time')
|
||||
|
||||
saved_state.update(state: state)
|
||||
end
|
||||
|
||||
|
@ -33,7 +36,7 @@ class RepositoryTableStateService
|
|||
# Destroy any state object before recreating a new one
|
||||
RepositoryTableState.where(user: @user, repository: @repository).destroy_all
|
||||
|
||||
return RepositoryTableState.create(
|
||||
RepositoryTableState.create(
|
||||
user: @user,
|
||||
repository: @repository,
|
||||
state: generate_default_state
|
||||
|
@ -47,9 +50,7 @@ class RepositoryTableStateService
|
|||
Constants::REPOSITORY_TABLE_DEFAULT_STATE[:length]
|
||||
|
||||
# This state should be strings-only
|
||||
state = HashUtil.deep_stringify_keys_and_values(
|
||||
Constants::REPOSITORY_TABLE_DEFAULT_STATE
|
||||
)
|
||||
state = Constants::REPOSITORY_TABLE_DEFAULT_STATE.with_indifferent_access
|
||||
repository.repository_columns.each_with_index do |_, index|
|
||||
real_index = default_columns_num + index
|
||||
state['columns'][real_index.to_s] =
|
||||
|
|
|
@ -17,9 +17,9 @@
|
|||
data-columns-delete-text="<%= I18n.t('repositories.columns_delete') %>"
|
||||
data-available-columns="<%= repository_available_columns_path(repository) %>"
|
||||
data-columns-changed="<%= I18n.t('repositories.columns_changed') %>"
|
||||
data-default-order="<%= default_table_order_as_js_array %>"
|
||||
data-default-table-columns="<%= default_table_columns %>"
|
||||
data-list-items-path="<%= Rails.application.routes.url_helpers.repository_list_items_path %>">
|
||||
data-list-items-path="<%= Rails.application.routes.url_helpers.repository_list_items_path %>"
|
||||
data-editable="<%= can_manage_repository_rows?(repository) %>">
|
||||
<thead>
|
||||
<tr>
|
||||
<th id="checkbox"><input name="select_all" value="1" type="checkbox"></th>
|
||||
|
|
|
@ -103,17 +103,6 @@
|
|||
</div>
|
||||
</div>
|
||||
|
||||
<div class="btn-group inline" id="saveCancel" data-toggle="buttons" style="display:none">
|
||||
<button type="button" class="btn btn-success" id="saveRecord" onclick="onClickSave()">
|
||||
<span class="fas fa-save"></span>
|
||||
<%= t("repositories.save_record") %>
|
||||
</button>
|
||||
<button type="button" class="btn btn-default" id="cancelSave" onclick="onClickCancel()">
|
||||
<span class="fas fa-times visible-xs-inline"></span>
|
||||
<span class="hidden-xs"><%= t("repositories.cancel_save") %></span>
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<!-- These buttons are appended to table in javascript, after table initialization -->
|
||||
<div class="toolbarButtonsDatatable" style="display:none">
|
||||
|
||||
|
@ -128,21 +117,34 @@
|
|||
<% end %>
|
||||
|
||||
<% if can_manage_repository_rows?(@repository) %>
|
||||
<button type="button" class="btn btn-default editAdd" id="editRepositoryRecord" onclick="onClickEdit()" disabled>
|
||||
<span class="fas fa-pencil-alt"></span>
|
||||
<span class="hidden-xs-custom"><%= t("repositories.edit_record") %></span>
|
||||
</button>
|
||||
<button type="button" class="btn btn-default"
|
||||
id="deleteRepositoryRecordsButton" onclick="onClickDelete()" disabled>
|
||||
<span class="fas fa-trash"></span>
|
||||
<span class="hidden-xs-custom"><%= t'repositories.delete_record' %></span>
|
||||
<%= submit_tag I18n.t('repositories.delete_record'), :class => "hidden
|
||||
delete_repository_records_submit" %>
|
||||
</button>
|
||||
<button type="button" class="btn btn-default copyRow" id="copyRepositoryRecords" onclick="onClickCopyRepositoryRecords()" disabled>
|
||||
<span class="fas fa-copy"></span>
|
||||
<span class="hidden-xs-custom"><%= t("repositories.copy_record") %></span>
|
||||
</button>
|
||||
<span id="editDeleteCopy" data-toggle="buttons" style="display:none">
|
||||
<button type="button" class="btn btn-default editAdd" id="editRepositoryRecord" onclick="onClickEdit()" disabled>
|
||||
<span class="fas fa-pencil-alt"></span>
|
||||
<span class="hidden-xs-custom"><%= t("repositories.edit_record") %></span>
|
||||
</button>
|
||||
<button type="button" class="btn btn-default"
|
||||
id="deleteRepositoryRecordsButton" onclick="onClickDelete()" disabled>
|
||||
<span class="fas fa-trash"></span>
|
||||
<span class="hidden-xs-custom"><%= t'repositories.delete_record' %></span>
|
||||
<%= submit_tag I18n.t('repositories.delete_record'), :class => "hidden
|
||||
delete_repository_records_submit" %>
|
||||
</button>
|
||||
<button type="button" class="btn btn-default copyRow" id="copyRepositoryRecords" onclick="onClickCopyRepositoryRecords()" disabled>
|
||||
<span class="fas fa-copy"></span>
|
||||
<span class="hidden-xs-custom"><%= t("repositories.copy_record") %></span>
|
||||
</button>
|
||||
</span>
|
||||
|
||||
<span id="saveCancel" data-toggle="buttons" style="display:none">
|
||||
<button type="button" class="btn btn-success" id="saveRecord">
|
||||
<span class="fas fa-save"></span>
|
||||
<%= t("repositories.save_record") %>
|
||||
</button>
|
||||
<button type="button" class="btn btn-default" id="cancelSave">
|
||||
<span class="fas fa-times-circle"></span>
|
||||
<%= t("repositories.cancel_save") %>
|
||||
</button>
|
||||
</span>
|
||||
<% elsif @repository.shared_with?(current_team) %>
|
||||
<p class="view-only-label"><%= t('repositories.index.view_only_permission_label') %></p>
|
||||
<% end %>
|
||||
|
|
|
@ -947,7 +947,7 @@ class Constants
|
|||
time: 0,
|
||||
start: 0,
|
||||
length: 6,
|
||||
order: { 0 => [2, 'asc'] }, # Default sorting by 'ID' column
|
||||
order: [[2, 'asc']], # Default sorting by 'ID' column
|
||||
search: { search: '',
|
||||
smart: true,
|
||||
regex: false,
|
||||
|
|
Loading…
Reference in a new issue