mirror of
https://github.com/scinote-eln/scinote-web.git
synced 2024-11-10 17:36:33 +08:00
Add edit renderer for Assets
This commit is contained in:
parent
3ab1967703
commit
ee5c2ac93d
7 changed files with 276 additions and 22 deletions
|
@ -0,0 +1,54 @@
|
|||
/*
|
||||
global ActiveStorage Promise
|
||||
*/
|
||||
/* eslint-disable no-unused-vars */
|
||||
|
||||
var Asset = (function() {
|
||||
function uploadFiles($fileInputs, directUploadUrl) {
|
||||
let filesToUploadCntr = 0;
|
||||
let filesUploadedCntr = 0;
|
||||
let filesForUpload = [];
|
||||
|
||||
$fileInputs.each(function(_, f) {
|
||||
let $f = $(f);
|
||||
if ($f.val()) {
|
||||
filesToUploadCntr += 1;
|
||||
filesForUpload.push($f);
|
||||
}
|
||||
});
|
||||
|
||||
return new Promise((resolve, reject) => {
|
||||
if (filesToUploadCntr === 0) {
|
||||
resolve('done');
|
||||
return;
|
||||
}
|
||||
|
||||
$(filesForUpload).each(function(_, $el) {
|
||||
let upload = new ActiveStorage.DirectUpload($el[0].files[0], directUploadUrl);
|
||||
|
||||
upload.create(function(error, blob) {
|
||||
if (error) {
|
||||
reject(error);
|
||||
} else {
|
||||
$el
|
||||
.prev('.file-hidden-field-container')
|
||||
.html(`<input type="hidden"
|
||||
form="${$el.attr('form')}"
|
||||
name="repository_cells[${$el.data('col-id')}]"
|
||||
value="${blob.signed_id}"/>`);
|
||||
|
||||
filesUploadedCntr += 1;
|
||||
if (filesUploadedCntr === filesToUploadCntr) {
|
||||
resolve('done');
|
||||
}
|
||||
}
|
||||
});
|
||||
return true;
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
return {
|
||||
uploadFiles: uploadFiles
|
||||
};
|
||||
}());
|
|
@ -17,7 +17,27 @@ $.fn.dataTable.render.editRowName = function(formId, cell) {
|
|||
};
|
||||
|
||||
$.fn.dataTable.render.editRepositoryAssetValue = function(formId, columnId, cell) {
|
||||
return '';
|
||||
let $cell = $(cell.node());
|
||||
let empty = $cell.is(':empty');
|
||||
let fileName = $cell.find('a.file-preview-link').text();
|
||||
|
||||
$cell.html(`
|
||||
<div class="file-editing">
|
||||
<div class="file-hidden-field-container hidden"></div>
|
||||
<input class=""
|
||||
id="repository_file_${columnId}"
|
||||
form="${formId}"
|
||||
type="file"
|
||||
data-col-id="${columnId}"
|
||||
data-is-empty="${empty}"
|
||||
value=""
|
||||
data-type="RepositoryAssetValue">
|
||||
<div class="file-upload-button ${empty ? 'new-file' : ''}">
|
||||
<label for="repository_file_${columnId}">Select File (Max 300 MB)...</label>
|
||||
<span class="icon"><i class="fas fa-paperclip"></i></span><span class="label-asset">${fileName}</span>
|
||||
<span class="delete-action fas fa-trash"> </span>
|
||||
</div>
|
||||
</div>`);
|
||||
};
|
||||
|
||||
$.fn.dataTable.render.editRepositoryTextValue = function(formId, columnId, cell) {
|
||||
|
|
|
@ -250,7 +250,8 @@ var RepositoryDatatable = (function(global) {
|
|||
|
||||
function initSaveButton() {
|
||||
TABLE_WRAPPER.on('click', '#saveRecord', function() {
|
||||
$(TABLE_ID).find('.repository-row-edit-form').submit();
|
||||
var $table = $(TABLE_ID);
|
||||
RepositoryDatatableRowEditor.validateAndSubmit($table);
|
||||
});
|
||||
}
|
||||
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
/*
|
||||
globals HelperModule animateSpinner SmartAnnotation
|
||||
globals HelperModule animateSpinner SmartAnnotation Asset
|
||||
*/
|
||||
/* eslint-disable no-unused-vars */
|
||||
|
||||
var RepositoryDatatableRowEditor = (function() {
|
||||
const NAME_COLUMN_ID = 'row-name';
|
||||
|
@ -18,27 +19,80 @@ var RepositoryDatatableRowEditor = (function() {
|
|||
});
|
||||
}
|
||||
|
||||
function validateAndSubmit($table) {
|
||||
let $form = $table.find('.repository-row-edit-form');
|
||||
let $row = $form.closest('tr');
|
||||
let valid = true;
|
||||
let directUrl = $table.data('direct-upload-url');
|
||||
let $files = $row.find('input[type=file]');
|
||||
$row.find('.has-error').removeClass('has-error').find('span').remove();
|
||||
|
||||
// Validations here
|
||||
$row.find('input').each(function() {
|
||||
let dataType = $(this).data('type');
|
||||
if (!dataType) return;
|
||||
|
||||
valid = $.fn.dataTable.render[dataType + 'Validator']($(this));
|
||||
if (!valid) return false;
|
||||
});
|
||||
|
||||
if (!valid) return false;
|
||||
|
||||
// DirectUpload here
|
||||
let uploadPromise = Asset.uploadFiles($files, directUrl);
|
||||
|
||||
// Submission here
|
||||
uploadPromise
|
||||
.then(function() {
|
||||
animateSpinner(null, true);
|
||||
$form.submit();
|
||||
return false;
|
||||
}).catch((reason) => {
|
||||
alert(reason);
|
||||
return false;
|
||||
});
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
function initAssetCellActions($row) {
|
||||
let fileInputs = $row.find('input[type=file]');
|
||||
let deleteButtons = $row.find('.file-upload-button>span.delete-action');
|
||||
|
||||
fileInputs.on('change', function() {
|
||||
let $input = $(this);
|
||||
let $fileBtn = $input.next('.file-upload-button');
|
||||
let $label = $fileBtn.find('.label-asset');
|
||||
|
||||
$label.text($input[0].files[0].name);
|
||||
$fileBtn.removeClass('new-file');
|
||||
});
|
||||
|
||||
|
||||
deleteButtons.on('click', function() {
|
||||
let $fileBtn = $(this).parent();
|
||||
let $input = $fileBtn.prev('input[type=file]');
|
||||
let $label = $fileBtn.find('.label-asset');
|
||||
|
||||
$fileBtn.addClass('new-file');
|
||||
$label.text('');
|
||||
$input.val('');
|
||||
|
||||
if (!$input.data('is-empty')) { // set hidden field for deletion only if original value has been set on rendering
|
||||
$input
|
||||
.prev('.file-hidden-field-container')
|
||||
.html(`<input type="hidden"
|
||||
form="${$input.attr('form')}"
|
||||
name="repository_cells[${$input.data('col-id')}]"
|
||||
value="-1"/>`);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
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');
|
||||
|
@ -139,13 +193,16 @@ var RepositoryDatatableRowEditor = (function() {
|
|||
});
|
||||
|
||||
initSmartAnnotation($row);
|
||||
initAssetCellActions($row);
|
||||
|
||||
TABLE.columns.adjust();
|
||||
}
|
||||
|
||||
return Object.freeze({
|
||||
initFormSubmitAction: initFormSubmitAction,
|
||||
validateAndSubmit: validateAndSubmit,
|
||||
switchRowToEditMode: switchRowToEditMode,
|
||||
addNewRow: addNewRow
|
||||
});
|
||||
}());
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* global GLOBAL_CONSTANTS textValidator */
|
||||
/* global GLOBAL_CONSTANTS textValidator I18n */
|
||||
|
||||
$.fn.dataTable.render.RowNameValidator = function($input) {
|
||||
return textValidator(undefined, $input, 1, GLOBAL_CONSTANTS.NAME_MAX_LENGTH);
|
||||
|
@ -15,3 +15,17 @@ $.fn.dataTable.render.RepositoryListValueValidator = function() {
|
|||
$.fn.dataTable.render.RepositoryStatusValueValidator = function() {
|
||||
return true;
|
||||
};
|
||||
|
||||
$.fn.dataTable.render.RepositoryAssetValueValidator = function($input) {
|
||||
let file = $input[0].files[0];
|
||||
if (!file) return true;
|
||||
|
||||
let valid = (file.size < GLOBAL_CONSTANTS.FILE_MAX_SIZE_MB * 1024 * 1024);
|
||||
if (valid) return true;
|
||||
|
||||
let errorMessage = I18n.t('general.file.size_exceeded', { file_size: GLOBAL_CONSTANTS.FILE_MAX_SIZE_MB });
|
||||
let $btn = $input.next('.file-upload-button');
|
||||
$btn.addClass('error');
|
||||
$btn.attr('data-error-text', errorMessage);
|
||||
return false;
|
||||
};
|
||||
|
|
|
@ -65,6 +65,10 @@
|
|||
.repository-status-value-icon {
|
||||
margin-right: 5px;
|
||||
}
|
||||
|
||||
.dropdown-selector-container {
|
||||
width: 150px;
|
||||
}
|
||||
}
|
||||
|
||||
.repository-cog {
|
||||
|
@ -158,10 +162,114 @@
|
|||
}
|
||||
|
||||
.file-preview-link {
|
||||
min-width: 140px;
|
||||
padding-left: 5px;
|
||||
}
|
||||
}
|
||||
|
||||
.file-editing {
|
||||
width: 200px;
|
||||
|
||||
.file-upload-button {
|
||||
background-color: $color-white;
|
||||
border: solid 1px;
|
||||
border-radius: 3px;
|
||||
height: 34px;
|
||||
line-height: 32px;
|
||||
position: relative;
|
||||
|
||||
&.new-file {
|
||||
.icon {
|
||||
display: none;
|
||||
}
|
||||
|
||||
label {
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
&:hover {
|
||||
.fa-trash {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.icon {
|
||||
display: inline-block;
|
||||
text-align: center;
|
||||
width: 34px;
|
||||
}
|
||||
|
||||
.label-asset {
|
||||
display: inline-block;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
width: calc(100% - 44px);
|
||||
}
|
||||
|
||||
.fa-trash {
|
||||
background-color: $color-white;
|
||||
cursor: pointer;
|
||||
display: none;
|
||||
line-height: 32px;
|
||||
position: absolute;
|
||||
right: 0;
|
||||
text-align: center;
|
||||
top: 0;
|
||||
width: 34px;
|
||||
z-index: 3;
|
||||
}
|
||||
|
||||
&:hover {
|
||||
.fa-trash {
|
||||
display: inline-block;
|
||||
}
|
||||
}
|
||||
|
||||
&.error {
|
||||
border-color: $brand-danger;
|
||||
margin-bottom: 10px;
|
||||
|
||||
&::after {
|
||||
background-color: $color-white;
|
||||
bottom: 0;
|
||||
color: $brand-danger;
|
||||
content: "\f071";
|
||||
font-family: "Font Awesome 5 Free";
|
||||
font-weight: 501;
|
||||
line-height: 32px;
|
||||
position: absolute;
|
||||
right: 0;
|
||||
text-align: center;
|
||||
width: 34px;
|
||||
}
|
||||
|
||||
&::before {
|
||||
bottom: -15px;
|
||||
color: $brand-danger;
|
||||
content: attr(data-error-text);
|
||||
left: 0;
|
||||
line-height: 15px;
|
||||
position: absolute;
|
||||
width: 100%;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
input[type=file] {
|
||||
display: none;
|
||||
}
|
||||
|
||||
label {
|
||||
display: none;
|
||||
font-weight: normal;
|
||||
margin-left: 10px;
|
||||
}
|
||||
}
|
||||
|
||||
.toolbarButtonsDatatable {
|
||||
.view-only-label {
|
||||
opacity: .6;
|
||||
|
|
|
@ -158,7 +158,7 @@ class RepositoryRowsController < ApplicationController
|
|||
existing.delete
|
||||
end
|
||||
elsif existing.value_type == 'RepositoryAssetValue'
|
||||
existing.value.destroy && next if remove_file_columns_params.include?(key)
|
||||
existing.value.destroy && next if value == '-1'
|
||||
if existing.value.asset.update(file: value)
|
||||
existing.value.asset.created_by = current_user
|
||||
existing.value.asset.last_modified_by = current_user
|
||||
|
|
Loading…
Reference in a new issue