mirror of
https://github.com/scinote-eln/scinote-web.git
synced 2025-09-21 12:34:39 +08:00
Merge pull request #1876 from aignatov-bio/ai-sci-3624-refactor-marvin-js-over-active-storage
Refactor MarvinJS core over active storage [SCI-3624]
This commit is contained in:
commit
cd40084c82
34 changed files with 439 additions and 520 deletions
1
app/assets/images/icon_small/marvinjs.svg
Normal file
1
app/assets/images/icon_small/marvinjs.svg
Normal file
|
@ -0,0 +1 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><defs><style>.cls-2{fill:#505050}</style></defs><path fill="none" d="M0 0h24v24H0z" id="Trim_Area" data-name="Trim Area"/><g id="Icons"><path class="cls-2" d="M12 2.56l8 4.62v9.64l-8 4.62-8-4.62V7.18zm0-.95L3 6.8v10.4l9 5.19 9-5.19V6.8l-9-5.19z"/><path class="cls-2" d="M5.28 9.52l8.21-4.74-1-.58-7.21 4.16v1.16zM18.51 16V7.67l-1-.57v9.48l1-.58zm-13.23-.95v1.15l6.44 3.72 1-.58-7.44-4.29z"/></g></svg>
|
After Width: | Height: | Size: 461 B |
|
@ -14,7 +14,7 @@
|
|||
_expandAllResults();
|
||||
applyCollapseLinkCallBack();
|
||||
applyCreateWopiFileCallback();
|
||||
Assets.setupAssetsLoading();
|
||||
//Assets.setupAssetsLoading();
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -122,6 +122,7 @@
|
|||
SmartAnnotation.preventPropagation('.atwho-user-popover');
|
||||
TinyMCE.destroyAll();
|
||||
DragNDropSteps.clearFiles();
|
||||
MarvinJsEditor.initNewButton('.new-marvinjs-upload-button');
|
||||
}, 1000);
|
||||
|
||||
})
|
||||
|
@ -375,7 +376,6 @@
|
|||
|
||||
function initCallBacks() {
|
||||
applyCreateWopiFileCallback()
|
||||
if (typeof(MarvinJsEditor.initNewButton) == 'function') MarvinJsEditor.initNewButton('.new-marvinjs-upload-button');
|
||||
applyCheckboxCallBack();
|
||||
applyStepCompletedCallBack();
|
||||
applyEditCallBack();
|
||||
|
@ -601,16 +601,12 @@
|
|||
SmartAnnotation.preventPropagation('.atwho-user-popover');
|
||||
|
||||
tinyMCE.editors.step_description_textarea.remove();
|
||||
|
||||
MarvinJsEditor.initNewButton('.new-marvinjs-upload-button');
|
||||
//Rerender tables
|
||||
$new_step.find("div.step-result-hot-table").each(function() {
|
||||
$(this).handsontable("render");
|
||||
});
|
||||
animateSpinner(null, false);
|
||||
<<<<<<< HEAD
|
||||
Assets.setupAssetsLoading();
|
||||
=======
|
||||
>>>>>>> activestorage_migration
|
||||
DragNDropSteps.clearFiles();
|
||||
FilePreviewModal.init();
|
||||
$.initTooltips();
|
||||
|
|
|
@ -25,10 +25,6 @@ var FilePreviewModal = (function() {
|
|||
name = $(this).find('.attachment-label').text();
|
||||
url = $(this).data('preview-url');
|
||||
downloadUrl = $(this).attr('href');
|
||||
if ($(this).data('asset-type') === 'marvin-sketch') {
|
||||
openMarvinPrevieModal(name, $(this).find('#description'), this);
|
||||
return true;
|
||||
}
|
||||
openPreviewModal(name, url, downloadUrl);
|
||||
return true;
|
||||
});
|
||||
|
@ -412,7 +408,7 @@ var FilePreviewModal = (function() {
|
|||
imageEditor = {};
|
||||
$('#tui-image-editor').html('');
|
||||
$('#fileEditModal').modal('hide');
|
||||
}
|
||||
});
|
||||
|
||||
if (data.mode === 'tinymce') {
|
||||
$.ajax({
|
||||
|
@ -487,6 +483,8 @@ var FilePreviewModal = (function() {
|
|||
modal.find('.file-edit-link').css('display', 'none');
|
||||
}
|
||||
}
|
||||
} else if (data.type === 'marvinjs') {
|
||||
openMarvinEditModal(data, modal);
|
||||
} else {
|
||||
modal.find('.file-edit-link').css('display', 'none');
|
||||
modal.find('.file-preview-container').html(data['preview-icon']);
|
||||
|
@ -570,41 +568,30 @@ var FilePreviewModal = (function() {
|
|||
modal.find('.file-edit-link').css('display', 'none');
|
||||
}
|
||||
|
||||
function openMarvinPrevieModal(name, src, sketch) {
|
||||
var modal = $('#filePreviewModal');
|
||||
var link = modal.find('.file-download-link');
|
||||
var target;
|
||||
clearPrevieModal();
|
||||
|
||||
modal.modal('show');
|
||||
function openMarvinEditModal(data, modal) {
|
||||
modal.find('.file-preview-container')
|
||||
.append($('<img>').attr('src', '').attr('alt', ''));
|
||||
target = modal.find('.file-preview-container').find('img');
|
||||
MarvinJsEditor.create_preview(src, target);
|
||||
MarvinJsEditor.create_download_link(src, link, name);
|
||||
modal.find('.file-name').text(name);
|
||||
$.get(sketch.dataset.updateUrl, function(result) {
|
||||
if (!readOnly && result.editable) {
|
||||
modal.find('.file-edit-link').css('display', '');
|
||||
modal.find('.file-edit-link').off().click(function(ev) {
|
||||
ev.preventDefault();
|
||||
.append($('<img>')
|
||||
.attr('src', data['large-preview-url'])
|
||||
.attr('alt', data.name)
|
||||
.click(function(ev) {
|
||||
ev.stopPropagation();
|
||||
modal.modal('hide');
|
||||
MarvinJsEditor.open({
|
||||
mode: 'edit',
|
||||
data: src.val(),
|
||||
name: name,
|
||||
marvinUrl: sketch.dataset.updateUrl,
|
||||
reloadImage: {
|
||||
src: src,
|
||||
sketch: sketch
|
||||
}
|
||||
});
|
||||
}));
|
||||
if (!readOnly && data.editable) {
|
||||
modal.find('.file-edit-link').css('display', '');
|
||||
modal.find('.file-edit-link').off().click(function(ev) {
|
||||
ev.preventDefault();
|
||||
ev.stopPropagation();
|
||||
modal.modal('hide');
|
||||
MarvinJsEditor.open({
|
||||
mode: 'edit',
|
||||
data: data.description,
|
||||
name: data.name,
|
||||
marvinUrl: data['update-url']
|
||||
});
|
||||
} else {
|
||||
modal.find('.file-edit-link').css('display', 'none');
|
||||
}
|
||||
});
|
||||
});
|
||||
} else {
|
||||
modal.find('.file-edit-link').css('display', 'none');
|
||||
}
|
||||
}
|
||||
|
||||
return Object.freeze({
|
||||
|
|
|
@ -1,12 +1,15 @@
|
|||
/* global TinyMCE, ChemicalizeMarvinJs, MarvinJSUtil, I18n, FilePreviewModal, tinymce */
|
||||
/* global Results, Comments */
|
||||
/* eslint-disable no-param-reassign */
|
||||
/* eslint-disable wrap-iife */
|
||||
/* eslint-disable no-use-before-define */
|
||||
|
||||
|
||||
var marvinJsRemoteLastMrv;
|
||||
var marvinJsRemoteEditor;
|
||||
var MarvinJsEditor;
|
||||
|
||||
MarvinJsEditor = (function() {
|
||||
var MarvinJsEditorApi = (function() {
|
||||
var marvinJsModal = $('#MarvinJsModal');
|
||||
var marvinJsContainer = $('#marvinjs-editor');
|
||||
var marvinJsObject = $('#marvinjs-sketch');
|
||||
|
@ -15,23 +18,6 @@ MarvinJsEditor = (function() {
|
|||
var marvinJsMode = marvinJsContainer.data('marvinjsMode');
|
||||
|
||||
// Facade api actions
|
||||
|
||||
var marvinJsExport = (childFunction, options = {}) => {
|
||||
if (marvinJsMode === 'remote') {
|
||||
remoteExport(childFunction, options);
|
||||
} else {
|
||||
localExport(childFunction, options);
|
||||
}
|
||||
};
|
||||
|
||||
var marvinJsImage = (childFunction, source, options = {}) => {
|
||||
if (marvinJsMode === 'remote') {
|
||||
remoteImage(childFunction, source, options);
|
||||
} else {
|
||||
localImage(childFunction, source, options);
|
||||
}
|
||||
};
|
||||
|
||||
var marvinJsExportImage = (childFuction, options = {}) => {
|
||||
if (marvinJsMode === 'remote') {
|
||||
remoteExportImage(childFuction, options);
|
||||
|
@ -53,25 +39,6 @@ MarvinJsEditor = (function() {
|
|||
|
||||
// Local marvinJS installation
|
||||
|
||||
var localExport = (childFuction, options = {}) => {
|
||||
loadEditor().then(function(sketcherInstance) {
|
||||
sketcherInstance.exportStructure('mrv').then(function(source) {
|
||||
childFuction(source, options);
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
var localImage = (childFuction, source, options = {}) => {
|
||||
loadPackages().then(function(sketcherInstance) {
|
||||
sketcherInstance.onReady(function() {
|
||||
var exporter = createExporter(sketcherInstance, 'image/jpeg');
|
||||
exporter.render(source).then(function(image) {
|
||||
childFuction(source, image, options);
|
||||
});
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
var localExportImage = (childFuction, options = {}) => {
|
||||
loadEditor().then(function(sketcherInstance) {
|
||||
sketcherInstance.exportStructure('mrv').then(function(source) {
|
||||
|
@ -89,10 +56,6 @@ MarvinJsEditor = (function() {
|
|||
|
||||
// Web services installation
|
||||
|
||||
var remoteExport = (childFuction, options = {}) => {
|
||||
childFuction(marvinJsRemoteLastMrv, options);
|
||||
};
|
||||
|
||||
var remoteImage = (childFuction, source, options = {}) => {
|
||||
var params = {
|
||||
carbonLabelVisible: false,
|
||||
|
@ -105,7 +68,7 @@ MarvinJsEditor = (function() {
|
|||
setTimeout(() => { remoteImage(childFuction, source, options); }, 100);
|
||||
return false;
|
||||
}
|
||||
marvinJsRemoteEditor.exportMrvToImageDataUri(source, 'jpeg', params).then(function(image) {
|
||||
marvinJsRemoteEditor.exportMrvToImageDataUri(source, 'image/jpeg', params).then(function(image) {
|
||||
childFuction(source, image, options);
|
||||
});
|
||||
return true;
|
||||
|
@ -120,17 +83,18 @@ MarvinJsEditor = (function() {
|
|||
if (marvinJsMode === 'remote') {
|
||||
if (config.mode === 'new' || config.mode === 'new-tinymce') {
|
||||
marvinJsRemoteEditor.importStructure('mrv', emptySketch);
|
||||
sketchName.val(I18n.t('marvinjs.new_sketch'));
|
||||
sketchName.val('');
|
||||
} else if (config.mode === 'edit') {
|
||||
marvinJsRemoteLastMrv = config.data;
|
||||
marvinJsRemoteEditor.importStructure('mrv', config.data);
|
||||
sketchName.val(config.name);
|
||||
} else if (config.mode === 'edit-tinymce') {
|
||||
$.get(config.marvinUrl, function(result) {
|
||||
marvinJsRemoteLastMrv = config.data;
|
||||
$.get(config.marvinUrl, { object_type: 'TinyMceAsset' }, function(result) {
|
||||
marvinJsRemoteEditor.importStructure('mrv', result.description);
|
||||
sketchName.val(result.name);
|
||||
});
|
||||
}
|
||||
|
||||
marvinJsRemoteEditor.on('molchange', () => {
|
||||
marvinJsRemoteEditor.exportStructure('mrv').then(function(source) {
|
||||
marvinJsRemoteLastMrv = source;
|
||||
|
@ -169,42 +133,16 @@ MarvinJsEditor = (function() {
|
|||
return new marvin.ImageExporter(params);
|
||||
}
|
||||
|
||||
function assignImage(source, data, target) {
|
||||
target.attr('src', data);
|
||||
return data;
|
||||
}
|
||||
|
||||
function TinyMceBuildHTML(json) {
|
||||
var imgstr = "<img src='" + json.image.url + "'";
|
||||
imgstr += " width='300' height='300'";
|
||||
imgstr += " data-mce-token='" + json.image.token + "'";
|
||||
imgstr += " data-source-id='" + json.image.source_id + "'";
|
||||
imgstr += " data-source-type='" + json.image.source_type + "'";
|
||||
imgstr += " alt='description-" + json.image.token + "' />";
|
||||
return imgstr;
|
||||
}
|
||||
|
||||
function saveFunction(source, config) {
|
||||
$.post(config.marvinUrl, {
|
||||
description: source,
|
||||
object_id: config.objectId,
|
||||
object_type: config.objectType,
|
||||
name: sketchName.val()
|
||||
}, function(result) {
|
||||
var newAsset;
|
||||
if (config.objectType === 'Step') {
|
||||
newAsset = $(result.html);
|
||||
newAsset.find('.file-preview-link').css('top', '-300px');
|
||||
newAsset.addClass('new').prependTo($(config.container));
|
||||
setTimeout(function() {
|
||||
newAsset.find('.file-preview-link').css('top', '0px');
|
||||
}, 200);
|
||||
FilePreviewModal.init();
|
||||
}
|
||||
$(marvinJsModal).modal('hide');
|
||||
});
|
||||
}
|
||||
|
||||
function saveTinymceFunction(source, image, config) {
|
||||
function saveFunction(source, image, config) {
|
||||
$.post(config.marvinUrl, {
|
||||
description: source,
|
||||
object_id: config.objectId,
|
||||
|
@ -212,48 +150,49 @@ MarvinJsEditor = (function() {
|
|||
name: sketchName.val(),
|
||||
image: image
|
||||
}, function(result) {
|
||||
var json = tinymce.util.JSON.parse(result);
|
||||
config.editor.execCommand('mceInsertContent', false, TinyMceBuildHTML(json));
|
||||
TinyMCE.updateImages(config.editor);
|
||||
$(marvinJsModal).modal('hide');
|
||||
});
|
||||
}
|
||||
|
||||
function updateFunction(source, config) {
|
||||
$.ajax({
|
||||
url: config.marvinUrl,
|
||||
data: {
|
||||
description: source,
|
||||
name: sketchName.val()
|
||||
},
|
||||
dataType: 'json',
|
||||
type: 'PUT',
|
||||
success: function(json) {
|
||||
$(marvinJsModal).modal('hide');
|
||||
config.reloadImage.src.val(json.description);
|
||||
$(config.reloadImage.sketch).find('.attachment-label').text(json.name);
|
||||
MarvinJsEditor.create_preview(
|
||||
config.reloadImage.src,
|
||||
$(config.reloadImage.sketch).find('img')
|
||||
);
|
||||
var newAsset = $(result.html);
|
||||
var json;
|
||||
if (config.objectType === 'Step') {
|
||||
newAsset.find('.file-preview-link').css('top', '-300px');
|
||||
newAsset.addClass('new').prependTo($(config.container));
|
||||
setTimeout(function() {
|
||||
newAsset.find('.file-preview-link').css('top', '0px');
|
||||
}, 200);
|
||||
} else if (config.objectType === 'Result') {
|
||||
newAsset.prependTo($(config.container));
|
||||
Results.expandResult(newAsset);
|
||||
Comments.init();
|
||||
} else if (config.objectType === 'TinyMceAsset') {
|
||||
json = tinymce.util.JSON.parse(result);
|
||||
config.editor.execCommand('mceInsertContent', false, TinyMceBuildHTML(json));
|
||||
TinyMCE.updateImages(config.editor);
|
||||
}
|
||||
$(marvinJsModal).modal('hide');
|
||||
FilePreviewModal.init();
|
||||
});
|
||||
}
|
||||
|
||||
function updateTinymceFunction(source, image, config) {
|
||||
function updateFunction(source, image, config) {
|
||||
$.ajax({
|
||||
url: config.marvinUrl,
|
||||
data: {
|
||||
description: source,
|
||||
name: sketchName.val(),
|
||||
object_type: 'TinyMceAsset',
|
||||
object_type: config.objectType,
|
||||
image: image
|
||||
},
|
||||
dataType: 'json',
|
||||
type: 'PUT',
|
||||
success: function(json) {
|
||||
config.image[0].src = json.url;
|
||||
$(marvinJsModal).modal('hide');
|
||||
if (config.objectType === 'TinyMceAsset') {
|
||||
config.image[0].src = json.url;
|
||||
config.image[0].dataset.mceSrc = json.url;
|
||||
$(marvinJsModal).modal('hide');
|
||||
} else {
|
||||
$(marvinJsModal).modal('hide');
|
||||
$('#modal_link' + json.id + ' img').attr('src', json.url);
|
||||
$('#modal_link' + json.id + ' .attachment-label').html(json.file_name);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
@ -270,7 +209,6 @@ MarvinJsEditor = (function() {
|
|||
$('#MarvinJsPromoModal').modal('show');
|
||||
return false;
|
||||
}
|
||||
|
||||
if (marvinJsMode === 'remote' && typeof (marvinJsRemoteEditor) === 'undefined') {
|
||||
setTimeout(() => { MarvinJsEditor.open(config); }, 100);
|
||||
return false;
|
||||
|
@ -284,12 +222,14 @@ MarvinJsEditor = (function() {
|
|||
if (config.mode === 'new') {
|
||||
MarvinJsEditor.save(config);
|
||||
} else if (config.mode === 'edit') {
|
||||
config.objectType = 'Asset';
|
||||
MarvinJsEditor.update(config);
|
||||
} else if (config.mode === 'new-tinymce') {
|
||||
config.objectType = 'TinyMceAsset';
|
||||
MarvinJsEditor.save_with_image(config);
|
||||
MarvinJsEditor.save(config);
|
||||
} else if (config.mode === 'edit-tinymce') {
|
||||
MarvinJsEditor.update_tinymce(config);
|
||||
config.objectType = 'TinyMceAsset';
|
||||
MarvinJsEditor.update(config);
|
||||
}
|
||||
});
|
||||
return true;
|
||||
|
@ -312,42 +252,11 @@ MarvinJsEditor = (function() {
|
|||
},
|
||||
|
||||
save: function(config) {
|
||||
marvinJsExport(saveFunction, config);
|
||||
},
|
||||
|
||||
save_with_image: function(config) {
|
||||
marvinJsExportImage(saveTinymceFunction, config);
|
||||
marvinJsExportImage(saveFunction, config);
|
||||
},
|
||||
|
||||
update: function(config) {
|
||||
marvinJsExport(updateFunction, config);
|
||||
},
|
||||
|
||||
update_tinymce: function(config) {
|
||||
marvinJsExportImage(updateTinymceFunction, config);
|
||||
},
|
||||
|
||||
create_preview: function(source, target) {
|
||||
marvinJsImage(assignImage, source.val(), target);
|
||||
},
|
||||
|
||||
create_download_link: function(source, link, filename) {
|
||||
var downloadLink = (mrv, image, option) => {
|
||||
option.link.attr('href', image);
|
||||
option.link.attr('download', option.filename);
|
||||
};
|
||||
marvinJsImage(downloadLink, source.val(), { link: link, filename: filename });
|
||||
},
|
||||
|
||||
delete_sketch: function(url, object) {
|
||||
$.ajax({
|
||||
url: url,
|
||||
dataType: 'json',
|
||||
type: 'DELETE',
|
||||
success: function() {
|
||||
$(object).remove();
|
||||
}
|
||||
});
|
||||
marvinJsExportImage(updateFunction, config);
|
||||
}
|
||||
};
|
||||
});
|
||||
|
@ -366,21 +275,21 @@ MarvinJsEditor = (function() {
|
|||
function openMarvinJs() {
|
||||
MarvinJsEditor.open({
|
||||
mode: 'new-tinymce',
|
||||
marvinUrl: '/marvin_js_assets',
|
||||
marvinUrl: '/tiny_mce_assets/marvinjs',
|
||||
editor: editor
|
||||
});
|
||||
}
|
||||
// Add a button that opens a window
|
||||
editor.addButton('marvinjsplugin', {
|
||||
tooltip: I18n.t('marvinjs.new_button'),
|
||||
icon: 'file-invoice',
|
||||
icon: 'marvinjs',
|
||||
onclick: openMarvinJs
|
||||
});
|
||||
|
||||
// Adds a menu item to the tools menu
|
||||
editor.addMenuItem('marvinjsplugin', {
|
||||
text: I18n.t('marvinjs.new_button'),
|
||||
icon: 'file-invoice',
|
||||
icon: 'marvinjs',
|
||||
context: 'insert',
|
||||
onclick: openMarvinJs
|
||||
});
|
||||
|
@ -397,7 +306,7 @@ MarvinJsEditor = (function() {
|
|||
|
||||
|
||||
$(document).on('turbolinks:load', function() {
|
||||
MarvinJsEditor = MarvinJsEditor();
|
||||
MarvinJsEditor = MarvinJsEditorApi();
|
||||
if (MarvinJsEditor.enabled()) {
|
||||
if ($('#marvinjs-editor')[0].dataset.marvinjsMode === 'remote') {
|
||||
ChemicalizeMarvinJs.createEditor('#marvinjs-sketch').then(function(marvin) {
|
||||
|
|
32
app/assets/javascripts/sitewide/tiny_mce.js
vendored
32
app/assets/javascripts/sitewide/tiny_mce.js
vendored
|
@ -1,5 +1,5 @@
|
|||
|
||||
/* global _ hljs tinyMCE SmartAnnotation MarvinJsEditor FilePreviewModal globalConstants */
|
||||
/* global _ hljs tinyMCE SmartAnnotation MarvinJsEditor globalConstants */
|
||||
|
||||
/* global _ I18n */
|
||||
|
||||
|
@ -30,7 +30,6 @@ var TinyMCE = (function() {
|
|||
$('<div class="tinymce-active-object-handler" style="display:none">'
|
||||
+ '<a class="file-download-link tool-button" href="#" data-turbolinks="false"><i class="mce-ico mce-i-donwload"></i></a>'
|
||||
+ '<span class="file-edit-link tool-button" href="#" data-turbolinks="false"><i class="mce-ico mce-i-pencil"></i></span>'
|
||||
+ '<span class="file-image-editor-link tool-button" href="#" data-turbolinks="false"><i class="mce-ico mce-i-image"></i></span>'
|
||||
+ '</div>').appendTo(editorToolbar.find('.mce-stack-layout'));
|
||||
editorIframe.contents().click(function() {
|
||||
var marvinJsEdit;
|
||||
|
@ -44,20 +43,19 @@ var TinyMCE = (function() {
|
|||
});
|
||||
editorContainer.find('.tinymce-active-object-handler').css('display', 'block');
|
||||
editorContainer.find('.tinymce-active-object-handler .file-download-link')
|
||||
.attr('href', image[0].src)
|
||||
.attr('download', 'tinymce-image');
|
||||
.attr('href', '/tiny_mce_assets/' + image.data('mceToken') + '/download');
|
||||
|
||||
// Edit link
|
||||
editLink = editorContainer.find('.tinymce-active-object-handler .file-edit-link');
|
||||
if (image[0].dataset.sourceId) {
|
||||
if (image[0].dataset.sourceType) {
|
||||
editLink.css('display', 'inline-block');
|
||||
marvinJsEdit = (image[0].dataset.sourceType === 'MarvinJsAsset' && typeof (MarvinJsEditor) !== 'undefined');
|
||||
marvinJsEdit = (image[0].dataset.sourceType === 'marvinjs' && typeof (MarvinJsEditor) !== 'undefined');
|
||||
if (!marvinJsEdit) editLink.css('display', 'none');
|
||||
editLink.on('click', function() {
|
||||
if (marvinJsEdit) {
|
||||
MarvinJsEditor.open({
|
||||
mode: 'edit-tinymce',
|
||||
marvinUrl: '/marvin_js_assets/' + image[0].dataset.sourceId,
|
||||
marvinUrl: '/tiny_mce_assets/' + image[0].dataset.mceToken + '/marvinjs',
|
||||
image: image
|
||||
});
|
||||
}
|
||||
|
@ -66,26 +64,6 @@ var TinyMCE = (function() {
|
|||
editLink.css('display', 'none');
|
||||
editLink.off('click');
|
||||
}
|
||||
|
||||
// imaged editor Link
|
||||
imageEditorLink = editorContainer.find('.tinymce-active-object-handler .file-image-editor-link');
|
||||
if (image[0].dataset.mceToken && image[0].dataset.sourceId) {
|
||||
imageEditorLink.css('display', 'inline-block');
|
||||
imageEditorLink.on('click', function() {
|
||||
FilePreviewModal.imageEditor({
|
||||
'download-url': image[0].src,
|
||||
filename: 'tinymce-image.jpg',
|
||||
mode: 'tinymce',
|
||||
url: '/tiny_mce_assets/' + image[0].dataset.mceToken,
|
||||
quality: 100,
|
||||
'mime-type': 'image/jpeg',
|
||||
image: image[0]
|
||||
});
|
||||
});
|
||||
} else {
|
||||
imageEditorLink.css('display', 'none');
|
||||
imageEditorLink.off('click');
|
||||
}
|
||||
} else {
|
||||
editorContainer.find('.tinymce-active-object-handler').css('display', 'none');
|
||||
}
|
||||
|
|
|
@ -88,7 +88,7 @@
|
|||
form = createElement('form', {
|
||||
action: editor.getParam(
|
||||
'customimageuploader_form_url',
|
||||
'/tinymce_assets'
|
||||
'/tiny_mce_assets'
|
||||
),
|
||||
target: iframe._id,
|
||||
method: 'POST',
|
||||
|
|
|
@ -23,5 +23,6 @@
|
|||
@import "select2.min";
|
||||
@import "extend/perfect-scrollbar";
|
||||
@import "my_modules/protocols/*";
|
||||
@import "my_modules/results/*";
|
||||
@import "protocols/*";
|
||||
@import "hooks/*";
|
||||
|
|
|
@ -41,9 +41,17 @@
|
|||
background: $color-black;
|
||||
border: 0;
|
||||
height: 60px;
|
||||
line-height: 40px;
|
||||
padding: 10px 15px;
|
||||
text-align: center;
|
||||
|
||||
.file-save-link {
|
||||
margin: 0 20px 0 0;
|
||||
}
|
||||
|
||||
.file-name {
|
||||
align-items: center;
|
||||
display: flex;
|
||||
float: left;
|
||||
|
||||
input {
|
||||
|
@ -51,10 +59,10 @@
|
|||
box-shadow: none;
|
||||
color: $color-black;
|
||||
height: 40px;
|
||||
margin-left: 5px;
|
||||
outline: 0;
|
||||
padding: 5px 10px;
|
||||
position: relative;
|
||||
top: -5px;
|
||||
width: 350px;
|
||||
}
|
||||
}
|
||||
|
@ -131,10 +139,28 @@
|
|||
}
|
||||
}
|
||||
|
||||
.mce-i-file-invoice::before {
|
||||
content: "\F570";
|
||||
font-family: "Font Awesome 5 Free";
|
||||
font-weight: 900;
|
||||
line-height: 16px;
|
||||
position: absolute;
|
||||
.new-marvinjs-upload-button {
|
||||
|
||||
.new-marvinjs-upload-icon {
|
||||
display: inline-block;
|
||||
height: 22px;
|
||||
width: 22px;
|
||||
|
||||
img {
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.mce-i-marvinjs::before {
|
||||
background-image: url("icon_small/marvinjs.svg");
|
||||
content: "";
|
||||
display: block;
|
||||
height: 22px;
|
||||
left: -3px;
|
||||
line-height: 16px;
|
||||
position: relative;
|
||||
top: -3px;
|
||||
width: 22px;
|
||||
}
|
||||
|
|
17
app/assets/stylesheets/my_modules/results/index.scss
Normal file
17
app/assets/stylesheets/my_modules/results/index.scss
Normal file
|
@ -0,0 +1,17 @@
|
|||
// scss-lint:disable SelectorDepth
|
||||
// scss-lint:disable NestingDepth
|
||||
// scss-lint:disable SelectorFormat
|
||||
// scss-lint:disable ImportantRule
|
||||
|
||||
@import "constants";
|
||||
@import "mixins";
|
||||
|
||||
#results-toolbar {
|
||||
.help_tooltips {
|
||||
.btn-default {
|
||||
border: 0;
|
||||
color: inherit;
|
||||
margin-left: 10px;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -164,6 +164,10 @@
|
|||
text-align: center;
|
||||
width: 220px;
|
||||
|
||||
.attachment-thumbnail {
|
||||
width: calc(100% - 20px);
|
||||
}
|
||||
|
||||
a {
|
||||
color: inherit;
|
||||
}
|
||||
|
|
|
@ -20,8 +20,7 @@ class AssetsController < ApplicationController
|
|||
def file_preview
|
||||
response_json = {
|
||||
'id' => @asset.id,
|
||||
'type' => (@asset.image? ? 'image' : 'file'),
|
||||
|
||||
'type' => @asset.file.metadata[:asset_type] || (@asset.image? ? 'image' : 'file'),
|
||||
'filename' => truncate(escape_input(@asset.file_name),
|
||||
length: Constants::FILENAME_TRUNCATION_LENGTH),
|
||||
'download-url' => download_asset_path(@asset, timestamp: Time.now.to_i)
|
||||
|
@ -34,15 +33,22 @@ class AssetsController < ApplicationController
|
|||
elsif @assoc.class == RepositoryCell
|
||||
can_manage_repository_rows?(@repository.team)
|
||||
end
|
||||
|
||||
if @asset.image?
|
||||
if ['image/jpeg', 'image/pjpeg'].include? @asset.content_type
|
||||
if response_json['type'] == 'image'
|
||||
if ['image/jpeg', 'image/pjpeg'].include? @asset.file.content_type
|
||||
response_json['quality'] = @asset.file_image_quality || 90
|
||||
end
|
||||
response_json.merge!(
|
||||
'editable' => @asset.editable_image? && can_edit,
|
||||
'mime-type' => @asset.file.content_type,
|
||||
'large-preview-url' => @asset.large_preview
|
||||
'large-preview-url' => rails_representation_url(@asset.large_preview)
|
||||
)
|
||||
elsif response_json['type'] == 'marvinjs'
|
||||
response_json.merge!(
|
||||
'editable' => can_edit,
|
||||
'large-preview-url' => rails_representation_url(@asset.large_preview),
|
||||
'update-url' => marvin_js_asset_path(@asset.id),
|
||||
'description' => @asset.file.metadata[:description],
|
||||
'name' => @asset.file.metadata[:name]
|
||||
)
|
||||
else
|
||||
|
||||
|
|
|
@ -1,82 +1,98 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
class MarvinJsAssetsController < ApplicationController
|
||||
before_action :load_vars, except: :create
|
||||
before_action :load_create_vars, only: :create
|
||||
|
||||
before_action :check_read_permission
|
||||
before_action :check_edit_permission, only: %i(update create)
|
||||
|
||||
def create
|
||||
new_asset = MarvinJsAsset.add_sketch(marvin_params, current_team)
|
||||
if new_asset.object_type == 'Step'
|
||||
result = MarvinJsService.create_sketch(marvin_params, current_user, current_team)
|
||||
if result[:asset] && marvin_params[:object_type] == 'Step'
|
||||
render json: {
|
||||
html: render_to_string(
|
||||
partial: 'assets/marvinjs/marvin_sketch_card.html.erb',
|
||||
locals: { sketch: new_asset, i: 0, assets_count: 0, step: new_asset.object }
|
||||
partial: 'steps/attachments/item.html.erb',
|
||||
locals: { asset: result[:asset],
|
||||
i: 0,
|
||||
assets_count: 0,
|
||||
step: result[:object],
|
||||
order_atoz: 0,
|
||||
order_ztoa: 0 }
|
||||
)
|
||||
}
|
||||
elsif new_asset.object_type == 'TinyMceAsset'
|
||||
tiny_img = TinyMceAsset.find(new_asset.object_id)
|
||||
elsif result[:asset] && marvin_params[:object_type] == 'Result'
|
||||
@my_module = result[:object].my_module
|
||||
render json: {
|
||||
image: {
|
||||
url: view_context.image_url(tiny_img.url(:large)),
|
||||
token: Base62.encode(tiny_img.id),
|
||||
source_id: new_asset.id,
|
||||
source_type: new_asset.class.name
|
||||
}
|
||||
}, content_type: 'text/html'
|
||||
elsif new_asset
|
||||
render json: new_asset
|
||||
html: render_to_string(
|
||||
partial: 'my_modules/result.html.erb',
|
||||
locals: { result: result[:object] }
|
||||
)
|
||||
}, status: :ok
|
||||
elsif result[:asset]
|
||||
render json: result[:asset]
|
||||
else
|
||||
render json: new_asset.errors, status: :unprocessable_entity
|
||||
end
|
||||
end
|
||||
|
||||
def show
|
||||
sketch = current_team.marvin_js_assets.find_by_id(params[:id])
|
||||
if sketch
|
||||
if sketch.object_type == 'Step'
|
||||
editable = can_manage_protocol_in_module?(sketch.object.protocol) ||
|
||||
can_manage_protocol_in_repository?(sketch.object.protocol)
|
||||
render json: {
|
||||
sketch: sketch,
|
||||
editable: editable
|
||||
}
|
||||
else
|
||||
render json: sketch
|
||||
end
|
||||
else
|
||||
render json: { error: t('marvinjs.no_sketches_found') }, status: :unprocessable_entity
|
||||
end
|
||||
end
|
||||
|
||||
def destroy
|
||||
sketch = current_team.marvin_js_assets.find_by_id(params[:id])
|
||||
if sketch.destroy
|
||||
render json: sketch
|
||||
else
|
||||
render json: { error: t('marvinjs.no_sketches_found') }, status: :unprocessable_entity
|
||||
render json: result[:asset].errors, status: :unprocessable_entity
|
||||
end
|
||||
end
|
||||
|
||||
def update
|
||||
sketch = MarvinJsAsset.update_sketch(marvin_params, current_team)
|
||||
if sketch
|
||||
render json: sketch
|
||||
asset = MarvinJsService.update_sketch(marvin_params, current_user, current_team)
|
||||
if asset
|
||||
render json: { url: rails_representation_url(asset.medium_preview), id: asset.id, file_name: asset.file_name }
|
||||
else
|
||||
render json: { error: t('marvinjs.no_sketches_found') }, status: :unprocessable_entity
|
||||
end
|
||||
end
|
||||
|
||||
def team_sketches
|
||||
result = ''
|
||||
sketches = current_team.marvin_js_assets.where.not(object_type: 'TinyMceAsset')
|
||||
sketches.each do |sketch|
|
||||
result += render_to_string(
|
||||
partial: 'shared/marvinjs_modal_sketch.html.erb',
|
||||
locals: { sketch: sketch }
|
||||
)
|
||||
end
|
||||
private
|
||||
|
||||
render json: { html: result, sketches: sketches.pluck(:id) }
|
||||
def load_vars
|
||||
@asset = current_team.assets.find_by_id(params[:id])
|
||||
return render_404 unless @asset
|
||||
|
||||
@assoc ||= @asset.step
|
||||
@assoc ||= @asset.result
|
||||
|
||||
if @assoc.class == Step
|
||||
@protocol = @assoc.protocol
|
||||
elsif @assoc.class == Result
|
||||
@my_module = @assoc.my_module
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
def load_create_vars
|
||||
@assoc = Step.find_by_id(marvin_params[:object_id]) if marvin_params[:object_type] == 'Step'
|
||||
@assoc = MyModule.find_by_id(params[:object_id]) if marvin_params[:object_type] == 'Result'
|
||||
|
||||
if @assoc.class == Step
|
||||
@protocol = @assoc.protocol
|
||||
elsif @assoc.class == MyModule
|
||||
@my_module = @assoc
|
||||
end
|
||||
end
|
||||
|
||||
def check_read_permission
|
||||
if @assoc.class == Step
|
||||
return render_403 unless can_read_protocol_in_module?(@protocol) ||
|
||||
can_read_protocol_in_repository?(@protocol)
|
||||
elsif @assoc.class == Result || @assoc.class == MyModule
|
||||
return render_403 unless can_read_experiment?(@my_module.experiment)
|
||||
else
|
||||
render_403
|
||||
end
|
||||
end
|
||||
|
||||
def check_edit_permission
|
||||
if @assoc.class == Step
|
||||
return render_403 unless can_manage_protocol_in_module?(@protocol) ||
|
||||
can_manage_protocol_in_repository?(@protocol)
|
||||
elsif @assoc.class == Result || @assoc.class == MyModule
|
||||
return render_403 unless can_manage_module?(@my_module)
|
||||
else
|
||||
render_403
|
||||
end
|
||||
end
|
||||
|
||||
def marvin_params
|
||||
params.permit(:id, :description, :object_id, :object_type, :name, :image)
|
||||
|
|
|
@ -1,6 +1,11 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
class TinyMceAssetsController < ApplicationController
|
||||
before_action :load_vars, only: %i(marvinjs_show marvinjs_update download)
|
||||
|
||||
before_action :check_read_permission, only: %i(marvinjs_show marvinjs_update download)
|
||||
before_action :check_edit_permission, only: %i(marvinjs_update)
|
||||
|
||||
def create
|
||||
image = params.fetch(:file) { render_404 }
|
||||
tiny_img = TinyMceAsset.new(team_id: current_team.id, saved: false)
|
||||
|
@ -23,4 +28,91 @@ class TinyMceAssetsController < ApplicationController
|
|||
}, status: :unprocessable_entity
|
||||
end
|
||||
end
|
||||
|
||||
def download
|
||||
if @asset&.image&.attached?
|
||||
redirect_to rails_blob_path(@asset.image, disposition: 'attachment')
|
||||
else
|
||||
render_404
|
||||
end
|
||||
end
|
||||
|
||||
def marvinjs_show
|
||||
asset = current_team.tiny_mce_assets.find_by_id(Base62.decode(params[:id]))
|
||||
return render_404 unless asset
|
||||
|
||||
render json: {
|
||||
name: asset.image.metadata[:name],
|
||||
description: asset.image.metadata[:description]
|
||||
}
|
||||
end
|
||||
|
||||
def marvinjs_create
|
||||
result = MarvinJsService.create_sketch(marvin_params, current_user, current_team)
|
||||
if result[:asset]
|
||||
render json: {
|
||||
image: {
|
||||
url: rails_representation_url(result[:asset].preview),
|
||||
token: Base62.encode(result[:asset].id),
|
||||
source_type: result[:asset].image.metadata[:asset_type]
|
||||
}
|
||||
}, content_type: 'text/html'
|
||||
else
|
||||
render json: result[:asset].errors, status: :unprocessable_entity
|
||||
end
|
||||
end
|
||||
|
||||
def marvinjs_update
|
||||
asset = MarvinJsService.update_sketch(marvin_params, current_user, current_team)
|
||||
if asset
|
||||
render json: { url: rails_representation_url(asset.preview), id: asset.id }
|
||||
else
|
||||
render json: { error: t('marvinjs.no_sketches_found') }, status: :unprocessable_entity
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def load_vars
|
||||
@asset = current_team.tiny_mce_assets.find_by_id(Base62.decode(params[:id]))
|
||||
return render_404 unless @asset
|
||||
|
||||
@assoc = @asset.object
|
||||
|
||||
if @assoc.class == Step
|
||||
@protocol = @assoc.protocol
|
||||
elsif @assoc.class == Protocol
|
||||
@protocol = @assoc
|
||||
elsif @assoc.class == MyModule
|
||||
@my_module = @assoc
|
||||
elsif @assoc.class == ResultText
|
||||
@my_module = @assoc.result.my_module
|
||||
end
|
||||
end
|
||||
|
||||
def check_read_permission
|
||||
if @assoc.class == Step || @assoc.class == Protocol
|
||||
return render_403 unless can_read_protocol_in_module?(@protocol) ||
|
||||
can_read_protocol_in_repository?(@protocol)
|
||||
elsif @assoc.class == ResultText || @assoc.class == MyModule
|
||||
return render_403 unless can_read_experiment?(@my_module.experiment)
|
||||
else
|
||||
render_403
|
||||
end
|
||||
end
|
||||
|
||||
def check_edit_permission
|
||||
if @assoc.class == Step || @assoc.class == Protocol
|
||||
return render_403 unless can_manage_protocol_in_module?(@protocol) ||
|
||||
can_manage_protocol_in_repository?(@protocol)
|
||||
elsif @assoc.class == ResultText || @assoc.class == MyModule
|
||||
return render_403 unless can_manage_module?(@my_module)
|
||||
else
|
||||
render_403
|
||||
end
|
||||
end
|
||||
|
||||
def marvin_params
|
||||
params.permit(:id, :description, :object_id, :object_type, :name, :image)
|
||||
end
|
||||
end
|
||||
|
|
|
@ -10,23 +10,15 @@ module MyModulesHelper
|
|||
end
|
||||
|
||||
def ordered_assets(step)
|
||||
assets = []
|
||||
assets += step.assets
|
||||
assets += step.marvin_js_assets
|
||||
|
||||
view_state = step.current_view_state(current_user)
|
||||
assets.sort! do |a, b|
|
||||
case view_state.state.dig('assets', 'sort')
|
||||
when 'old'
|
||||
b[asset_date_sort_field(b)] <=> a[asset_date_sort_field(a)]
|
||||
when 'atoz'
|
||||
(a[asset_name_sort_field(a)]).downcase <=> (b[asset_name_sort_field(b)]).downcase
|
||||
when 'ztoa'
|
||||
(b[asset_name_sort_field(b)]).downcase <=> (a[asset_name_sort_field(a)]).downcase
|
||||
else
|
||||
a[asset_date_sort_field(a)] <=> b[asset_date_sort_field(b)]
|
||||
end
|
||||
end
|
||||
sort = case view_state.state.dig('assets', 'sort')
|
||||
when 'old' then { created_at: :asc }
|
||||
when 'atoz' then { file_file_name: :asc }
|
||||
when 'ztoa' then { file_file_name: :desc }
|
||||
else { created_at: :desc }
|
||||
end
|
||||
|
||||
step.assets.order(sort)
|
||||
end
|
||||
|
||||
def az_ordered_assets_index(step, asset_id)
|
||||
|
@ -63,22 +55,4 @@ module MyModulesHelper
|
|||
def is_results_page?
|
||||
action_name == 'results'
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def asset_date_sort_field(element)
|
||||
result = {
|
||||
'Asset' => :file_updated_at,
|
||||
'MarvinJsAsset' => :updated_at
|
||||
}
|
||||
result[element.class.name]
|
||||
end
|
||||
|
||||
def asset_name_sort_field(element)
|
||||
result = {
|
||||
'Asset' => :file_file_name,
|
||||
'MarvinJsAsset' => :name
|
||||
}
|
||||
result[element.class.name] || ''
|
||||
end
|
||||
end
|
||||
|
|
|
@ -257,7 +257,7 @@ class Asset < ApplicationRecord
|
|||
end
|
||||
|
||||
def image?
|
||||
content_type == %r{^image/#{Regexp.union(Constants::WHITELISTED_IMAGE_TYPES)}}
|
||||
content_type =~ %r{^image/#{Regexp.union(Constants::WHITELISTED_IMAGE_TYPES)}}
|
||||
end
|
||||
|
||||
def text?
|
||||
|
@ -448,21 +448,7 @@ class Asset < ApplicationRecord
|
|||
!locked? && %r{^image/#{Regexp.union(Constants::WHITELISTED_IMAGE_TYPES_EDITABLE)}} =~ file.content_type
|
||||
end
|
||||
|
||||
<<<<<<< HEAD
|
||||
def generate_base64(style)
|
||||
image = if file.options[:storage].to_sym == :s3
|
||||
URI.parse(url(style)).open.to_a.join
|
||||
else
|
||||
File.open(file.path(style)).to_a.join
|
||||
end
|
||||
encoded_data = Base64.strict_encode64(image)
|
||||
"data:#{file_content_type};base64,#{encoded_data}"
|
||||
end
|
||||
|
||||
protected
|
||||
=======
|
||||
private
|
||||
>>>>>>> activestorage_migration
|
||||
|
||||
def tempdir
|
||||
Rails.root.join('tmp')
|
||||
|
|
|
@ -1,44 +0,0 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
class MarvinJsAsset < ApplicationRecord
|
||||
validates :name, presence: true
|
||||
validates :description, presence: true
|
||||
validates :object_id, presence: true
|
||||
validates :object_type, presence: true
|
||||
|
||||
belongs_to :object, polymorphic: true,
|
||||
optional: true,
|
||||
inverse_of: :marvin_js_assets
|
||||
|
||||
belongs_to :team, inverse_of: :marvin_js_assets, optional: true
|
||||
|
||||
def self.add_sketch(values, team)
|
||||
if values[:object_type] == 'TinyMceAsset'
|
||||
tiny_mce_img = TinyMceAsset.create(
|
||||
object: nil,
|
||||
team_id: team.id,
|
||||
saved: false,
|
||||
image: values[:image],
|
||||
image_file_name: "#{name}.jpg"
|
||||
)
|
||||
values[:object_id] = tiny_mce_img.id
|
||||
end
|
||||
values[:name] = I18n.t('marvinjs.new_sketch') if values[:name].empty?
|
||||
create(values.merge(team_id: team.id).except(:image))
|
||||
end
|
||||
|
||||
def self.update_sketch(values, team)
|
||||
sketch = team.marvin_js_assets.find(values[:id])
|
||||
return false unless sketch
|
||||
|
||||
values[:name] = I18n.t('marvinjs.new_sketch') if values[:name].empty?
|
||||
sketch.update(values.except(:image, :object_type, :id))
|
||||
|
||||
if values[:object_type] == 'TinyMceAsset'
|
||||
image = TinyMceAsset.find(sketch.object_id)
|
||||
image.update(image: values[:image], image_file_name: "#{name}.jpg")
|
||||
return { url: image.url(:large), description: sketch.description }
|
||||
end
|
||||
sketch
|
||||
end
|
||||
end
|
|
@ -25,11 +25,6 @@ class Step < ApplicationRecord
|
|||
has_many :tables, through: :step_tables
|
||||
has_many :report_elements, inverse_of: :step, dependent: :destroy
|
||||
|
||||
has_many :marvin_js_assets,
|
||||
as: :object,
|
||||
class_name: :MarvinJsAsset,
|
||||
dependent: :destroy
|
||||
|
||||
accepts_nested_attributes_for :checklists,
|
||||
reject_if: :all_blank,
|
||||
allow_destroy: true
|
||||
|
@ -41,9 +36,6 @@ class Step < ApplicationRecord
|
|||
attributes['contents'].blank?
|
||||
},
|
||||
allow_destroy: true
|
||||
accepts_nested_attributes_for :marvin_js_assets,
|
||||
reject_if: :all_blank,
|
||||
allow_destroy: true
|
||||
|
||||
after_destroy :cascade_after_destroy
|
||||
before_save :set_last_modified_by
|
||||
|
|
|
@ -41,7 +41,7 @@ class Team < ApplicationRecord
|
|||
has_many :repositories, dependent: :destroy
|
||||
has_many :reports, inverse_of: :team, dependent: :destroy
|
||||
has_many :activities, inverse_of: :team, dependent: :destroy
|
||||
has_many :marvin_js_assets, inverse_of: :team, dependent: :destroy
|
||||
has_many :assets, inverse_of: :team, dependent: :destroy
|
||||
|
||||
attr_accessor :without_templates
|
||||
attr_accessor :without_intro_demo
|
||||
|
|
|
@ -14,11 +14,6 @@ class TinyMceAsset < ApplicationRecord
|
|||
touch: true,
|
||||
optional: true
|
||||
|
||||
has_one :marvin_js_asset,
|
||||
as: :object,
|
||||
class_name: :MarvinJsAsset,
|
||||
dependent: :destroy
|
||||
|
||||
belongs_to :object, polymorphic: true,
|
||||
optional: true,
|
||||
inverse_of: :tiny_mce_assets
|
||||
|
@ -41,10 +36,6 @@ class TinyMceAsset < ApplicationRecord
|
|||
# }
|
||||
validates :estimated_size, presence: true
|
||||
|
||||
def source
|
||||
return marvin_js_asset if marvin_js_asset
|
||||
end
|
||||
|
||||
def self.update_images(object, images)
|
||||
images = JSON.parse(images)
|
||||
current_images = object.tiny_mce_assets.pluck(:id)
|
||||
|
@ -75,8 +66,6 @@ class TinyMceAsset < ApplicationRecord
|
|||
tm_asset.attributes['src'].value = Rails.application.routes.url_helpers.url_for(new_asset.image)
|
||||
tm_asset['class'] = 'img-responsive'
|
||||
end
|
||||
tm_asset.attributes['src'].value = new_asset_url.url
|
||||
tm_asset['class'] = 'img-responsive'
|
||||
end
|
||||
description.css('body').inner_html.to_s
|
||||
end
|
||||
|
@ -107,7 +96,7 @@ class TinyMceAsset < ApplicationRecord
|
|||
asset = find_by_id(id)
|
||||
asset.destroy if asset && !asset.saved
|
||||
end
|
||||
|
||||
|
||||
def self.update_estimated_size(id)
|
||||
asset = find_by_id(id)
|
||||
return unless asset&.image&.attached?
|
||||
|
|
|
@ -1,11 +1,89 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
class MarvinJsService
|
||||
def self.url
|
||||
ENV['MARVINJS_URL']
|
||||
end
|
||||
class << self
|
||||
def url
|
||||
ENV['MARVINJS_URL']
|
||||
end
|
||||
|
||||
def self.enabled?
|
||||
!ENV['MARVINJS_URL'].nil? || !ENV['MARVINJS_API_KEY'].nil?
|
||||
def enabled?
|
||||
!ENV['MARVINJS_URL'].nil? || !ENV['MARVINJS_API_KEY'].nil?
|
||||
end
|
||||
|
||||
def create_sketch(params, current_user, current_team)
|
||||
file = generate_image(params)
|
||||
if params[:object_type] == 'TinyMceAsset'
|
||||
asset = TinyMceAsset.new(team_id: current_team.id)
|
||||
attach_file(asset.image, file, params)
|
||||
asset.save!
|
||||
return { asset: asset }
|
||||
end
|
||||
|
||||
asset = Asset.new(created_by: current_user,
|
||||
last_modified_by: current_user,
|
||||
team_id: current_team.id)
|
||||
attach_file(asset.file, file, params)
|
||||
asset.save!
|
||||
connect_asset(asset, params, current_user)
|
||||
end
|
||||
|
||||
def update_sketch(params, _current_user, current_team)
|
||||
if params[:object_type] == 'TinyMceAsset'
|
||||
asset = current_team.tiny_mce_assets.find(Base62.decode(params[:id]))
|
||||
attachment = asset&.image
|
||||
else
|
||||
asset = current_team.assets.find(params[:id])
|
||||
attachment = asset&.file
|
||||
end
|
||||
return unless attachment
|
||||
|
||||
file = generate_image(params)
|
||||
attach_file(attachment, file, params)
|
||||
asset
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def connect_asset(asset, params, current_user)
|
||||
if params[:object_type] == 'Step'
|
||||
object = params[:object_type].constantize.find(params[:object_id])
|
||||
object.assets << asset
|
||||
elsif params[:object_type] == 'Result'
|
||||
my_module = MyModule.find_by_id(params[:object_id])
|
||||
return unless my_module
|
||||
|
||||
object = Result.create(user: current_user,
|
||||
my_module: my_module,
|
||||
name: prepare_name(params[:name]),
|
||||
asset: asset,
|
||||
last_modified_by: current_user)
|
||||
end
|
||||
{ asset: asset, object: object }
|
||||
end
|
||||
|
||||
def generate_image(params)
|
||||
StringIO.new(Base64.decode64(params[:image].split(',')[1]))
|
||||
end
|
||||
|
||||
def attach_file(asset, file, params)
|
||||
asset.attach(
|
||||
io: file,
|
||||
filename: "#{prepare_name(params[:name])}.jpg",
|
||||
content_type: 'image/jpeg',
|
||||
metadata: {
|
||||
name: prepare_name(params[:name]),
|
||||
description: params[:description],
|
||||
asset_type: 'marvinjs'
|
||||
}
|
||||
)
|
||||
end
|
||||
|
||||
def prepare_name(sketch_name)
|
||||
if !sketch_name.empty?
|
||||
sketch_name
|
||||
else
|
||||
I18n.t('marvinjs.new_sketch')
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -5,6 +5,8 @@
|
|||
data-marvin-url="<%= marvin_js_assets_path %>"
|
||||
data-sketch-container="<%= sketch_container %>"
|
||||
>
|
||||
<span class="fas fa-file-invoice new-marvinjs-upload-icon"></span>
|
||||
<span class="new-marvinjs-upload-icon">
|
||||
<%= image_tag 'icon_small/marvinjs.svg' %>
|
||||
</span>
|
||||
<%= t('marvinjs.new_button') %>
|
||||
</span>
|
|
@ -1,18 +0,0 @@
|
|||
<div class="pseudo-attachment-container" style="order: <%= assets_count - i %>">
|
||||
<%= link_to '',
|
||||
class: 'file-preview-link',
|
||||
id: "marvin_js_sketch_#{sketch.id}",
|
||||
data: { no_turbolink: true, id: true, status: 'asset-present',
|
||||
'preview-url': '',
|
||||
'order-atoz': az_ordered_assets_index(step, sketch.id),
|
||||
'order-ztoa': assets_count - az_ordered_assets_index(step, sketch.id),
|
||||
'order-old': i,
|
||||
'order-new': assets_count - i,
|
||||
'asset-type': 'marvin-sketch',
|
||||
'asset-id': sketch.id,
|
||||
'update_url': marvin_js_asset_path(sketch.id)
|
||||
} do %>
|
||||
<%= render partial: 'assets/marvinjs/marvin_sketch_card_placeholder.html.erb',
|
||||
locals: { edit_page: false, sketch: sketch } %>
|
||||
<% end %>
|
||||
</div>
|
|
@ -1,18 +0,0 @@
|
|||
<div class="attachment-placeholder pull-left" data-marvinjs-sketch="<%= sketch.id %>">
|
||||
<div class="attachment-thumbnail">
|
||||
<img src>
|
||||
<%= hidden_field_tag :description, sketch.description %>
|
||||
</div>
|
||||
<div class="attachment-label"><%= truncate(sketch.name,
|
||||
length: Constants::FILENAME_TRUNCATION_LENGTH) %></div>
|
||||
<div class="spencer-bonnet-modif">
|
||||
<%= t('protocols.steps.attachments.modified_label') %> <%= l(sketch.updated_at, format: :full_date) if sketch.updated_at %>
|
||||
</div>
|
||||
<% if edit_page %>
|
||||
<div class="remove-icon pull-right">
|
||||
<%= ff.remove_nested_fields_link do %>
|
||||
<span class="fas fa-trash"></span>
|
||||
<% end %>
|
||||
</div>
|
||||
<% end %>
|
||||
</div>
|
|
@ -41,6 +41,8 @@
|
|||
<span class="fas fa-paperclip"></span>
|
||||
<span class="hidden-xs"><%= t("my_modules.results.new_asset_result") %></span>
|
||||
</a>
|
||||
<%= render partial: '/assets/marvinjs/create_marvin_sketch_button.html.erb',
|
||||
locals: { element_id: @my_module.id, element_type: 'Result', sketch_container: "#results[data-module-id=#{@my_module.id}]" } %>
|
||||
<%= render partial: "assets/wopi/create_wopi_file_button",
|
||||
locals: { element_id: @my_module.id, element_type: 'Result' } %>
|
||||
</div>
|
||||
|
|
|
@ -11,7 +11,8 @@
|
|||
<div class="modal-header">
|
||||
<button type="button" class="preview-close" data-dismiss="modal"><span class="fas fa-times"></span></button>
|
||||
<span class="file-name">
|
||||
<%= text_field_tag :sketch_name %>
|
||||
<%= t('marvinjs.modal_name_title') %>
|
||||
<%= text_field_tag :sketch_name, '', placeholder: t('marvinjs.structure_placeholder') %>
|
||||
</span>
|
||||
<p class="file-save-link"><span class="fas fa-save"></span> <%= t('SaveClose')%></p>
|
||||
</div>
|
||||
|
|
|
@ -24,12 +24,6 @@
|
|||
<%= t("protocols.steps.new.tab_tables") %>
|
||||
</a>
|
||||
</li>
|
||||
<li role="presentation" id="new-step-sketch-tab">
|
||||
<a href="#new-step-sketch" data-toggle="tab" data-no-turbolink="true">
|
||||
<span class="fas fa-file-invoice"></span>
|
||||
<%= t('marvinjs.checmical_drawing') %>
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
<div class="tab-content">
|
||||
<div class="tab-pane active" role="tabpanel" id="new-step-main">
|
||||
|
@ -90,13 +84,4 @@
|
|||
<%= t("protocols.steps.new.add_table") %>
|
||||
<% end %>
|
||||
</div>
|
||||
<div class="tab-pane" role="tabpanel" id="new-step-sketch">
|
||||
<div class="sketch-container">
|
||||
<%= f.nested_fields_for :marvin_js_assets do |ff| %>
|
||||
<% next unless ff.object.description %>
|
||||
<%= render partial: 'assets/marvinjs/marvin_sketch_card_placeholder.html.erb',
|
||||
locals: { sketch: ff.object, edit_page: true, ff: ff} %>
|
||||
<% end %>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -44,13 +44,8 @@
|
|||
<% assets.each_with_index do |asset, i| %>
|
||||
<% order_atoz = az_ordered_assets_index(step, asset.id) %>
|
||||
<% order_ztoa = assets.length - az_ordered_assets_index(step, asset.id) %>
|
||||
<% if asset.class.name == 'Asset' %>
|
||||
<%= render partial: 'steps/attachments/item.html.erb',
|
||||
locals: { asset: asset, i: i, assets_count: assets.length, step: step, order_atoz: order_atoz, order_ztoa: order_ztoa } %>
|
||||
<% elsif asset.class.name == 'MarvinJsAsset' %>
|
||||
<%= render partial: 'assets/marvinjs/marvin_sketch_card.html.erb',
|
||||
locals: { sketch: asset, i:i, assets_count: assets.count, step: step} %>
|
||||
<% end %>
|
||||
<%= render partial: 'steps/attachments/item.html.erb',
|
||||
locals: { asset: asset, i: i, assets_count: assets.length, step: step, order_atoz: order_atoz, order_ztoa: order_ztoa } %>
|
||||
<% end %>
|
||||
</div>
|
||||
<hr>
|
||||
|
|
|
@ -1765,10 +1765,11 @@ en:
|
|||
complete_title: "Complete Step"
|
||||
uncomplete_title: "Uncomplete Step"
|
||||
attachments:
|
||||
sort_new: "Newest first ↓"
|
||||
sort_old: "Oldest first ↑"
|
||||
sort_atoz: "Name ↓"
|
||||
sort_ztoa: "Name ↑"
|
||||
sort:
|
||||
new_html: "Newest first ↓"
|
||||
old_html: "Oldest first ↑"
|
||||
atoz_html: "Name ↓"
|
||||
ztoa_html: "Name ↑"
|
||||
new:
|
||||
add_step_title: "Add new step"
|
||||
tab_checklists: "Checklists"
|
||||
|
@ -2154,9 +2155,8 @@ en:
|
|||
visibility: "https://support.scinote.net/hc/en-us/articles/360004627472"
|
||||
manage_columns: "https://support.scinote.net/hc/en-us/articles/360004695831"
|
||||
marvinjs:
|
||||
new_sketch: "New sketch"
|
||||
new_button: "New chemical drawing"
|
||||
checmical_drawing: "Chemical drawings"
|
||||
team_drawings: "Team drawings"
|
||||
task: "Task"
|
||||
no_sketches_found: "No sketches found"
|
||||
new_sketch: "New structure"
|
||||
new_button: "New structure"
|
||||
structure_placeholder: "Click here to enter structure name"
|
||||
modal_name_title: "Structure name:"
|
||||
checmical_drawing: "Chemical drawings"
|
|
@ -449,8 +449,16 @@ Rails.application.routes.draw do
|
|||
end
|
||||
|
||||
# tinyMCE image uploader endpoint
|
||||
resources :tiny_mce_assets, only: [:update]
|
||||
post '/tinymce_assets', to: 'tiny_mce_assets#create', as: :tiny_mce_assets
|
||||
resources :tiny_mce_assets, only: [:create] do
|
||||
member do
|
||||
get :download
|
||||
get :marvinjs, to: 'tiny_mce_assets#marvinjs_show'
|
||||
put :marvinjs, to: 'tiny_mce_assets#marvinjs_update'
|
||||
end
|
||||
collection do
|
||||
post :marvinjs, to: 'tiny_mce_assets#marvinjs_create'
|
||||
end
|
||||
end
|
||||
|
||||
resources :results, only: [:update, :destroy] do
|
||||
resources :result_comments,
|
||||
|
@ -580,10 +588,6 @@ Rails.application.routes.draw do
|
|||
|
||||
# We cannot use 'resources :assets' because assets is a reserved route
|
||||
# in Rails (assets pipeline) and causes funky behavior
|
||||
<<<<<<< HEAD
|
||||
get 'files/:id/present', to: 'assets#file_present', as: 'file_present_asset'
|
||||
=======
|
||||
>>>>>>> activestorage_migration
|
||||
get 'files/:id/preview',
|
||||
to: 'assets#file_preview',
|
||||
as: 'asset_file_preview'
|
||||
|
|
|
@ -1,15 +0,0 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
class CreateMarvinJsAssets < ActiveRecord::Migration[5.1]
|
||||
def change
|
||||
create_table :marvin_js_assets do |t|
|
||||
t.bigint :team_id
|
||||
t.string :description
|
||||
t.references :object, polymorphic: true
|
||||
|
||||
t.timestamps
|
||||
end
|
||||
|
||||
change_column :marvin_js_assets, :id, :bigint
|
||||
end
|
||||
end
|
|
@ -1,7 +0,0 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
class AddNameToMarvinJsAssets < ActiveRecord::Migration[5.1]
|
||||
def change
|
||||
add_column :marvin_js_assets, :name, :string
|
||||
end
|
||||
end
|
11
db/schema.rb
11
db/schema.rb
|
@ -201,17 +201,6 @@ ActiveRecord::Schema.define(version: 2019_06_13_134100) do
|
|||
t.index ["restored_by_id"], name: "index_experiments_on_restored_by_id"
|
||||
end
|
||||
|
||||
create_table "marvin_js_assets", force: :cascade do |t|
|
||||
t.bigint "team_id"
|
||||
t.string "description"
|
||||
t.string "object_type"
|
||||
t.bigint "object_id"
|
||||
t.datetime "created_at", null: false
|
||||
t.datetime "updated_at", null: false
|
||||
t.string "name"
|
||||
t.index ["object_type", "object_id"], name: "index_marvin_js_assets_on_object_type_and_object_id"
|
||||
end
|
||||
|
||||
create_table "my_module_groups", force: :cascade do |t|
|
||||
t.datetime "created_at", null: false
|
||||
t.datetime "updated_at", null: false
|
||||
|
|
|
@ -1,9 +0,0 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
FactoryBot.define do
|
||||
factory :marvin_js_asset do
|
||||
team_id 1
|
||||
description 'MyString'
|
||||
object ''
|
||||
end
|
||||
end
|
Loading…
Add table
Reference in a new issue