mirror of
https://github.com/scinote-eln/scinote-web.git
synced 2024-09-21 07:26:15 +08:00
Add MarvinJS to Result and TinyMce MarvinJS refactor
This commit is contained in:
parent
ba1d6d45ca
commit
3339c1fbbf
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();
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -375,7 +375,6 @@
|
|||
|
||||
function initCallBacks() {
|
||||
applyCreateWopiFileCallback()
|
||||
if (typeof(MarvinJsEditor.initNewButton) == 'function') MarvinJsEditor.initNewButton('.new-marvinjs-upload-button');
|
||||
applyCheckboxCallBack();
|
||||
applyStepCompletedCallBack();
|
||||
applyEditCallBack();
|
||||
|
@ -601,7 +600,7 @@
|
|||
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");
|
||||
|
|
|
@ -572,7 +572,7 @@ var FilePreviewModal = (function() {
|
|||
modal.find('.file-preview-container')
|
||||
.append($('<img>')
|
||||
.attr('src', data['large-preview-url'])
|
||||
.attr('alt', data.file_name)
|
||||
.attr('alt', data.name)
|
||||
.click(function(ev) {
|
||||
ev.stopPropagation();
|
||||
}));
|
||||
|
|
|
@ -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');
|
||||
|
@ -87,7 +90,7 @@ MarvinJsEditor = (function() {
|
|||
sketchName.val(config.name);
|
||||
} else if (config.mode === 'edit-tinymce') {
|
||||
marvinJsRemoteLastMrv = config.data;
|
||||
$.get(config.marvinUrl, function(result) {
|
||||
$.get(config.marvinUrl, { object_type: 'TinyMceAsset' }, function(result) {
|
||||
marvinJsRemoteEditor.importStructure('mrv', result.description);
|
||||
sketchName.val(result.name);
|
||||
});
|
||||
|
@ -132,6 +135,7 @@ MarvinJsEditor = (function() {
|
|||
|
||||
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 + "'";
|
||||
|
@ -147,17 +151,20 @@ MarvinJsEditor = (function() {
|
|||
name: sketchName.val(),
|
||||
image: image
|
||||
}, function(result) {
|
||||
var newAsset;
|
||||
var newAsset = $(result.html);
|
||||
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();
|
||||
} else if (config.objectType === 'Result') {
|
||||
newAsset.prependTo($(config.container));
|
||||
Results.expandResult(newAsset);
|
||||
Comments.init();
|
||||
}
|
||||
$(marvinJsModal).modal('hide');
|
||||
FilePreviewModal.init();
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -223,7 +230,6 @@ MarvinJsEditor = (function() {
|
|||
$('#MarvinJsPromoModal').modal('show');
|
||||
return false;
|
||||
}
|
||||
|
||||
if (marvinJsMode === 'remote' && typeof (marvinJsRemoteEditor) === 'undefined') {
|
||||
setTimeout(() => { MarvinJsEditor.open(config); }, 100);
|
||||
return false;
|
||||
|
@ -314,14 +320,14 @@ MarvinJsEditor = (function() {
|
|||
// 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
|
||||
});
|
||||
|
@ -338,7 +344,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) {
|
||||
|
|
25
app/assets/javascripts/sitewide/tiny_mce.js
vendored
25
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;
|
||||
|
@ -51,7 +50,7 @@ var TinyMCE = (function() {
|
|||
editLink = editorContainer.find('.tinymce-active-object-handler .file-edit-link');
|
||||
if (image[0].dataset.sourceId) {
|
||||
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) {
|
||||
|
@ -66,26 +65,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');
|
||||
}
|
||||
|
|
|
@ -23,5 +23,6 @@
|
|||
@import "select2.min";
|
||||
@import "extend/perfect-scrollbar";
|
||||
@import "my_modules/protocols/*";
|
||||
@import "my_modules/results/*";
|
||||
@import "protocols/*";
|
||||
@import "hooks/*";
|
||||
|
|
|
@ -131,10 +131,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 {
|
||||
content: "";
|
||||
background-image: url(icon_small/marvinjs.svg);
|
||||
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;
|
||||
}
|
||||
|
|
|
@ -1,29 +1,51 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
class MarvinJsAssetsController < ApplicationController
|
||||
def show
|
||||
asset = current_team.tiny_mce_assets.find_by_id(params[:id]) if params[:object_type] == 'TinyMceAsset'
|
||||
return render_404 unless asset
|
||||
|
||||
render json: {
|
||||
name: asset.image.metadata[:name],
|
||||
description: asset.image.metadata[:description]
|
||||
}
|
||||
end
|
||||
|
||||
def create
|
||||
new_asset = MarvinJsService.create_sketch(marvin_params, current_user)
|
||||
if marvin_params[:object_type] == 'Step'
|
||||
result = MarvinJsService.create_sketch(marvin_params, current_user)
|
||||
if result[:asset] && marvin_params[:object_type] == 'Step'
|
||||
render json: {
|
||||
html: render_to_string(
|
||||
partial: 'steps/attachments/item.html.erb',
|
||||
locals: { asset: new_asset, i: 0, assets_count: 0, step: new_asset.step, order_atoz: 0, order_ztoa: 0 }
|
||||
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)
|
||||
# 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
|
||||
elsif result[:asset] && marvin_params[:object_type] == 'Result'
|
||||
@my_module = result[:object].my_module
|
||||
render json: {
|
||||
html: render_to_string(
|
||||
partial: 'my_modules/result.html.erb',
|
||||
locals: { result: result[:object] }
|
||||
)
|
||||
}, status: :ok
|
||||
elsif result[:asset] && marvin_params[:object_type] == 'TinyMceAsset'
|
||||
render json: {
|
||||
image: {
|
||||
url: result[:asset].preview,
|
||||
token: Base62.encode(result[:asset].id),
|
||||
source_id: result[:asset].id,
|
||||
source_type: result[:asset].image.metadata[:asset_type]
|
||||
}
|
||||
}, content_type: 'text/html'
|
||||
elsif result[:asset]
|
||||
render json: result[:asset]
|
||||
else
|
||||
render json: new_asset.errors, status: :unprocessable_entity
|
||||
render json: result[:asset].errors, status: :unprocessable_entity
|
||||
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
|
||||
|
|
|
@ -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,7 +66,7 @@ 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.attributes['src'].value = new_asset.preview
|
||||
tm_asset['class'] = 'img-responsive'
|
||||
end
|
||||
description.css('body').inner_html.to_s
|
||||
|
@ -100,14 +91,14 @@ class TinyMceAsset < ApplicationRecord
|
|||
end
|
||||
|
||||
def preview
|
||||
image.variant(resize: Constants::LARGE_PIC_FORMAT)
|
||||
image.variant(resize: Constants::LARGE_PIC_FORMAT).processed.service_url
|
||||
end
|
||||
|
||||
def self.delete_unsaved_image(id)
|
||||
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?
|
||||
|
|
|
@ -12,12 +12,20 @@ class MarvinJsService
|
|||
|
||||
def create_sketch(params, current_user)
|
||||
file = generate_image(params)
|
||||
asset = Asset.new(created_by: current_user, team_id: current_user.current_team.id)
|
||||
asset.team_id = current_user.current_team.id
|
||||
attach_file(asset, file, params)
|
||||
if params[:object_type] == 'TinyMceAsset'
|
||||
asset = TinyMceAsset.new(team_id: current_user.current_team.id)
|
||||
attach_file(asset.image, file, params)
|
||||
else
|
||||
asset = Asset.new(created_by: current_user,
|
||||
last_modified_by: current_user,
|
||||
team_id: current_user.current_team.id)
|
||||
attach_file(asset.file, file, params)
|
||||
end
|
||||
|
||||
asset.save!
|
||||
connect_asset(asset, params)
|
||||
asset
|
||||
return { asset: asset } if params[:object_type] == 'TinyMceAsset'
|
||||
|
||||
connect_asset(asset, params, current_user)
|
||||
end
|
||||
|
||||
def update_sketch(params, current_user)
|
||||
|
@ -32,9 +40,21 @@ class MarvinJsService
|
|||
|
||||
private
|
||||
|
||||
def connect_asset(asset, params)
|
||||
object = params[:object_type].constantize.find(params[:object_id])
|
||||
object.assets << asset
|
||||
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: params[:name],
|
||||
asset: asset,
|
||||
last_modified_by: current_user)
|
||||
end
|
||||
{ asset: asset, object: object }
|
||||
end
|
||||
|
||||
def generate_image(params)
|
||||
|
@ -47,7 +67,7 @@ class MarvinJsService
|
|||
end
|
||||
|
||||
def attach_file(asset, file, params)
|
||||
asset.file.attach(
|
||||
asset.attach(
|
||||
io: file,
|
||||
filename: "#{params[:name]}.jpeg",
|
||||
content_type: 'image/jpeg',
|
||||
|
|
|
@ -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>
|
|
@ -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>
|
||||
|
|
|
@ -2156,8 +2156,5 @@ en:
|
|||
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_button: "New structure"
|
||||
checmical_drawing: "Chemical drawings"
|
Loading…
Reference in a new issue