mirror of
https://github.com/scinote-eln/scinote-web.git
synced 2024-11-18 23:21:30 +08:00
Merge branch 'develop'
This commit is contained in:
commit
b7e2e227b5
77 changed files with 3077 additions and 199 deletions
2
VERSION
2
VERSION
|
@ -1 +1 @@
|
|||
1.28.1.3
|
||||
1.28.2
|
||||
|
|
10
app/assets/images/icon_small/sequence-editor.svg
Normal file
10
app/assets/images/icon_small/sequence-editor.svg
Normal file
|
@ -0,0 +1,10 @@
|
|||
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M11.4923 3.51517C10.0704 3.60025 8.69275 4.04129 7.48581 4.79777C6.27887 5.55426 5.28139 6.60192 4.58502 7.84452C3.88865 9.08711 3.51572 10.4848 3.50049 11.9091C3.48526 13.3335 3.82822 14.7388 4.49786 15.996" stroke="#1D2939" stroke-linecap="round"/>
|
||||
<path d="M11.5501 6.51843C10.6743 6.59031 9.8284 6.87102 9.08335 7.33704C8.3383 7.80307 7.71577 8.44084 7.26789 9.19694C6.82001 9.95304 6.55984 10.8055 6.50916 11.6828C6.45847 12.5601 6.61875 13.4368 6.97658 14.2395" stroke="#1D2939" stroke-linecap="round"/>
|
||||
<path d="M10.7142 14.144C11.0835 14.3654 11.5036 14.4878 11.934 14.4991C12.3644 14.5105 12.7904 14.4105 13.1708 14.2089" stroke="#1D2939" stroke-linecap="round"/>
|
||||
<path d="M11.5231 9.54591C11.0365 9.64048 10.5889 9.87759 10.2374 10.2271C9.88584 10.5766 9.64613 11.0227 9.54873 11.5088" stroke="#1D2939" stroke-linecap="round"/>
|
||||
<path d="M16.4528 15.2284C17.2432 14.1382 17.6062 12.7958 17.473 11.4558" stroke="#1D2939" stroke-linecap="round"/>
|
||||
<path d="M8.8669 16.5204C9.66189 17.0714 10.5881 17.403 11.5522 17.4817C12.5163 17.5605 13.4841 17.3836 14.358 16.9689" stroke="#1D2939" stroke-linecap="round"/>
|
||||
<path d="M19.4459 7.90013C18.6397 6.43599 17.4197 5.24203 15.9386 4.46756" stroke="#1D2939" stroke-linecap="round"/>
|
||||
<path d="M6.52764 18.5041C7.79803 19.573 9.35364 20.2464 11.0024 20.4413C12.6512 20.6361 14.3209 20.3439 15.8054 19.6006C17.29 18.8573 18.5244 17.6955 19.3562 16.2587C20.188 14.8219 20.5808 13.1729 20.4862 11.5154" stroke="#1D2939" stroke-linecap="round"/>
|
||||
</svg>
|
After Width: | Height: | Size: 1.6 KiB |
2
app/assets/javascripts/i18n_bundle.js
Normal file
2
app/assets/javascripts/i18n_bundle.js
Normal file
|
@ -0,0 +1,2 @@
|
|||
//= require i18n.js
|
||||
//= require i18n/translations
|
|
@ -58,12 +58,41 @@ function importProtocolFromFile(
|
|||
}
|
||||
|
||||
function getAssetBytes(folder, stepGuid, fileRef) {
|
||||
var stepPath = stepGuid ? stepGuid + '/' : '';
|
||||
var filePath = folder + stepPath + fileRef;
|
||||
var assetBytes = zipFiles.files[cleanFilePath(filePath)].asBinary();
|
||||
const stepPath = stepGuid ? stepGuid + '/' : '';
|
||||
const filePath = folder + stepPath + fileRef;
|
||||
const assetBytes = zipFiles.files[cleanFilePath(filePath)].asBinary();
|
||||
return window.btoa(assetBytes);
|
||||
}
|
||||
|
||||
function getAssetPreview(folder, stepGuid, fileRef, fileName, fileType) {
|
||||
if ($.inArray(fileType, ['image/png', 'image/jpeg', 'image/gif', 'image/bmp']) > 0) {
|
||||
return {
|
||||
fileName: fileName,
|
||||
fileType: fileType,
|
||||
bytes: getAssetBytes(folder, stepGuid, fileRef)
|
||||
};
|
||||
} else {
|
||||
const stepPath = stepGuid ? folder + stepGuid + '/' : folder;
|
||||
let baseName;
|
||||
baseName = fileRef.split('.');
|
||||
baseName.pop();
|
||||
baseName.join('.');
|
||||
let previewFileRef = zipFiles.file(new RegExp(stepPath + 'previews/' + baseName));
|
||||
if (previewFileRef.length > 0) {
|
||||
const previewFileExt = previewFileRef[0].name.split('.').at(-1);
|
||||
let previewFileName = fileName.split('.');
|
||||
previewFileName.splice(-1, 1, previewFileExt);
|
||||
previewFileName.join('.');
|
||||
return {
|
||||
fileName: previewFileName,
|
||||
fileType: `image/${previewFileExt}`,
|
||||
bytes: window.btoa(previewFileRef[0].asBinary())
|
||||
};
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/* Template functions */
|
||||
|
||||
function newPreviewElement(name, values) {
|
||||
|
@ -82,14 +111,14 @@ function importProtocolFromFile(
|
|||
}
|
||||
|
||||
function newAssetElement(folder, stepGuid, fileRef, fileName, fileType) {
|
||||
var html = '<li class="col-xs-12">';
|
||||
var assetBytes;
|
||||
if ($.inArray(fileType, ['image/png', 'image/jpeg', 'image/gif', 'image/bmp']) > 0) {
|
||||
assetBytes = getAssetBytes(folder, stepGuid, fileRef);
|
||||
let html = '<li class="col-xs-12">';
|
||||
let assetPreview = getAssetPreview(folder, stepGuid, fileRef, fileName, fileType);
|
||||
|
||||
html += '<img style="max-width:300px; max-height:300px;" src="data:' + fileType + ';base64,' + assetBytes + '" />';
|
||||
if (assetPreview) {
|
||||
html += '<img style="max-width:300px; max-height:300px;" src="data:' + assetPreview.fileType + ';base64,' + assetPreview.bytes + '" />';
|
||||
html += '<br>';
|
||||
}
|
||||
|
||||
html += '<span>' + fileName + '</span>';
|
||||
html += '</li>';
|
||||
return $.parseHTML(html);
|
||||
|
@ -708,6 +737,7 @@ function importProtocolFromFile(
|
|||
var assetId = $(this).attr('id');
|
||||
var fileRef = $(this).attr('fileRef');
|
||||
var fileName = $(this).children('fileName').text();
|
||||
|
||||
stepAssetJson.id = assetId;
|
||||
stepAssetJson.fileName = fileName;
|
||||
stepAssetJson.fileType = $(this).children('fileType').text();
|
||||
|
@ -723,6 +753,14 @@ function importProtocolFromFile(
|
|||
fileRef
|
||||
);
|
||||
|
||||
stepAssetJson.preview_image = getAssetPreview(
|
||||
protocolFolders[index],
|
||||
stepGuid,
|
||||
fileRef,
|
||||
fileName,
|
||||
null
|
||||
);
|
||||
|
||||
stepAssetsJson.push(stepAssetJson);
|
||||
});
|
||||
stepJson.assets = stepAssetsJson;
|
||||
|
|
|
@ -17,6 +17,8 @@ var ActiveStoragePreviews = (function() {
|
|||
|
||||
if (img.retryCount >= RETRY_COUNT) return;
|
||||
|
||||
$(img).css('opacity', 0);
|
||||
|
||||
if (!$(img).parent().hasClass('processing')) $(img).parent().addClass('processing');
|
||||
|
||||
setTimeout(() => {
|
||||
|
|
35
app/assets/javascripts/sitewide/iframe_modal.js
Normal file
35
app/assets/javascripts/sitewide/iframe_modal.js
Normal file
|
@ -0,0 +1,35 @@
|
|||
/* global iFrameModal */
|
||||
// General-purpose iframe modal. For closing the modal, you need will to take care of triggering
|
||||
// the 'hide' event on the modal itself, example from inside the iframe:
|
||||
// parent.document.getElementById('iFrameModal').dispatchEvent(new Event('hide'));
|
||||
|
||||
$(document).on('turbolinks:load', function() {
|
||||
window.iFrameModal = document.getElementById('iFrameModal');
|
||||
let iFrameModalFrame = document.getElementById('iFrameModalFrame');
|
||||
|
||||
// Block from running when accessing page without defined iframe modal
|
||||
// (sign in, reset password, accept invitation, 2fa)
|
||||
if (!iFrameModalFrame || !iFrameModal) return;
|
||||
|
||||
window.showIFrameModal = (url) => {
|
||||
iFrameModalFrame.setAttribute('src', url);
|
||||
iFrameModal.classList.remove('hidden');
|
||||
iFrameModal.dispatchEvent(new Event('shown'));
|
||||
};
|
||||
|
||||
iFrameModal.addEventListener('hide', () => {
|
||||
iFrameModal.classList.add('hidden');
|
||||
iFrameModalFrame.removeAttribute('src');
|
||||
iFrameModal.dispatchEvent(new Event('hidden'));
|
||||
});
|
||||
|
||||
iFrameModal.addEventListener('shown', () => {
|
||||
document.body.classList.add('overflow-hidden');
|
||||
document.body.classList.remove('overflow-auto');
|
||||
});
|
||||
|
||||
iFrameModal.addEventListener('hidden', () => {
|
||||
document.body.classList.remove('overflow-hidden');
|
||||
document.body.classList.add('overflow-auto');
|
||||
});
|
||||
});
|
|
@ -303,6 +303,12 @@ $(document).on('click', '.marvinjs-edit-button', function() {
|
|||
});
|
||||
});
|
||||
|
||||
$(document).on('click', '.gene-sequence-edit-button', function() {
|
||||
var editButton = $(this);
|
||||
$('#filePreviewModal').modal('hide');
|
||||
window.showIFrameModal(editButton.data('sequence-edit-url'));
|
||||
});
|
||||
|
||||
$(document).on('turbolinks:load', function() {
|
||||
MarvinJsEditor = MarvinJsEditorApi();
|
||||
if (MarvinJsEditor.enabled()) {
|
||||
|
|
|
@ -67,6 +67,8 @@ label {
|
|||
* Global fix for handsontable
|
||||
*/
|
||||
.hot-table-container {
|
||||
display: flex;
|
||||
overflow: auto;
|
||||
.ht_master .wtHolder {
|
||||
height: auto !important;
|
||||
width: auto !important;
|
||||
|
|
|
@ -29,6 +29,8 @@ div.print-report {
|
|||
}
|
||||
|
||||
.hot-table-container {
|
||||
display: flex;
|
||||
overflow: auto;
|
||||
.ht_master .wtHolder {
|
||||
overflow: hidden !important;
|
||||
|
||||
|
|
|
@ -445,3 +445,15 @@
|
|||
padding: 4px 8px;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.sn-file-ove {
|
||||
height: 1.5rem;
|
||||
width: 1.5rem;
|
||||
|
||||
&::before {
|
||||
content: url("icon_small/sequence-editor.svg");
|
||||
display: inline-block;
|
||||
margin: auto;
|
||||
width: 100%;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -26,11 +26,22 @@
|
|||
|
||||
.file-preview-container {
|
||||
align-items: center;
|
||||
background-color: var(--sn-color-white);
|
||||
display: flex;
|
||||
height: 100%;
|
||||
height: calc(100% - 4rem);
|
||||
justify-content: center;
|
||||
margin: 2rem;
|
||||
text-align: center;
|
||||
width: 100%;
|
||||
width: calc(100% - 4rem);
|
||||
|
||||
.asset-image {
|
||||
background-color: var(--sn-white);
|
||||
}
|
||||
|
||||
.gene-sequence-asset {
|
||||
height: 500px;
|
||||
width: 500px;
|
||||
}
|
||||
|
||||
&.processing {
|
||||
background-image: url("/images/medium/loading_white.svg");
|
||||
|
|
|
@ -15,7 +15,7 @@
|
|||
.sci-input-field {
|
||||
@include font-button;
|
||||
animation-timing-function: $timing-function-sharp;
|
||||
border: $border-secondary;
|
||||
border: 1px solid var(--sn-light-grey);
|
||||
border-radius: $border-radius-default !important;
|
||||
box-shadow: none;
|
||||
height: 36px;
|
||||
|
@ -24,12 +24,18 @@
|
|||
transition: .3s;
|
||||
width: 100%;
|
||||
|
||||
&:hover {
|
||||
border: 1px solid var(--sn-science-blue-hover);
|
||||
}
|
||||
|
||||
&:focus {
|
||||
border: $border-focus;
|
||||
}
|
||||
|
||||
&:disabled {
|
||||
background: transparent;
|
||||
background-color: var(--sn-super-light-grey);
|
||||
color: var(--sn-light-grey);
|
||||
border: 1px solid var(--sn-light-grey);
|
||||
}
|
||||
|
||||
&::placeholder {
|
||||
|
|
4
app/assets/stylesheets/sn_icon_font.css
Normal file
4
app/assets/stylesheets/sn_icon_font.css
Normal file
|
@ -0,0 +1,4 @@
|
|||
/*
|
||||
*= require sn-icon-font
|
||||
*= require sn-inter-font
|
||||
*/
|
|
@ -29,6 +29,16 @@
|
|||
box-shadow: none;
|
||||
}
|
||||
|
||||
.sci-input-container-v2 input:hover {
|
||||
border-color: var(--sn-science-blue-hover);
|
||||
}
|
||||
|
||||
.sci-input-container-v2 input:disabled {
|
||||
background-color: var(--sn-super-light-grey);
|
||||
color: var(--sn-light-grey);
|
||||
border: 1px solid var(--sn-light-grey);
|
||||
}
|
||||
|
||||
.sci-input-container-v2 .sn-icon {
|
||||
@apply m-2;
|
||||
color: var(--sn-black)
|
||||
|
|
174
app/controllers/gene_sequence_assets_controller.rb
Normal file
174
app/controllers/gene_sequence_assets_controller.rb
Normal file
|
@ -0,0 +1,174 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
class GeneSequenceAssetsController < ApplicationController
|
||||
include ActiveStorage::SetCurrent
|
||||
|
||||
skip_before_action :verify_authenticity_token
|
||||
|
||||
before_action :check_open_vector_service_enabled, except: %i(new edit)
|
||||
before_action :load_vars, except: %i(new create)
|
||||
before_action :load_create_vars, only: %i(new create)
|
||||
|
||||
before_action :check_read_permission
|
||||
before_action :check_manage_permission, only: %i(new update create)
|
||||
|
||||
def new
|
||||
render :edit, layout: false
|
||||
end
|
||||
|
||||
def edit
|
||||
@file_url = rails_representation_url(@asset.file)
|
||||
@file_name = @asset.render_file_name
|
||||
log_activity('sequence_asset_edit_started')
|
||||
render :edit, layout: false
|
||||
end
|
||||
|
||||
def create
|
||||
save_asset!
|
||||
log_activity('sequence_asset_added')
|
||||
head :ok
|
||||
end
|
||||
|
||||
def update
|
||||
save_asset!
|
||||
log_activity('sequence_asset_edit_finished')
|
||||
head :ok
|
||||
end
|
||||
|
||||
def destroy
|
||||
log_activity('sequence_asset_deleted')
|
||||
head :ok
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def save_asset!
|
||||
ActiveRecord::Base.transaction do
|
||||
ensure_asset!
|
||||
|
||||
@asset.file.purge
|
||||
@asset.preview_image.purge
|
||||
|
||||
@asset.file.attach(
|
||||
io: StringIO.new(params[:sequence_data].to_json),
|
||||
filename: "#{params[:sequence_name]}.json"
|
||||
)
|
||||
|
||||
@asset.preview_image.attach(
|
||||
io: StringIO.new(Base64.decode64(params[:base64_image].split(',').last)),
|
||||
filename: "#{params[:sequence_name]}.png"
|
||||
)
|
||||
|
||||
file = @asset.file
|
||||
|
||||
file.blob.metadata['asset_type'] = 'gene_sequence'
|
||||
file.blob.metadata['name'] = params[:sequence_name]
|
||||
file.save!
|
||||
@asset.view_mode ||= @parent.assets_view_mode
|
||||
@asset.save!
|
||||
end
|
||||
end
|
||||
|
||||
def ensure_asset!
|
||||
return if @asset
|
||||
return unless @parent
|
||||
|
||||
@asset = @parent.assets.create!(last_modified_by: current_user, team: current_team)
|
||||
end
|
||||
|
||||
def load_vars
|
||||
@ove_enabled = OpenVectorEditorService.enabled?
|
||||
@asset = current_team.assets.find_by(id: params[:id])
|
||||
return render_404 unless @asset
|
||||
|
||||
@parent ||= @asset.step
|
||||
@parent ||= @asset.result
|
||||
|
||||
case @parent
|
||||
when Step
|
||||
@protocol = @parent.protocol
|
||||
when Result
|
||||
@my_module = @parent.my_module
|
||||
end
|
||||
end
|
||||
|
||||
def load_create_vars
|
||||
@ove_enabled = OpenVectorEditorService.enabled?
|
||||
@parent = case params[:parent_type]
|
||||
when 'Step'
|
||||
Step.find_by(id: params[:parent_id])
|
||||
when 'Result'
|
||||
Result.find_by(id: params[:parent_id])
|
||||
end
|
||||
|
||||
case @parent
|
||||
when Step
|
||||
@protocol = @parent.protocol
|
||||
when Result
|
||||
@result = @parent
|
||||
end
|
||||
end
|
||||
|
||||
def check_read_permission
|
||||
case @parent
|
||||
when Step
|
||||
return render_403 unless can_read_protocol_in_module?(@protocol) ||
|
||||
can_read_protocol_in_repository?(@protocol)
|
||||
when Result
|
||||
return render_403 unless can_read_my_module?(@my_module)
|
||||
else
|
||||
render_403
|
||||
end
|
||||
end
|
||||
|
||||
def check_manage_permission
|
||||
render_403 unless asset_managable?
|
||||
end
|
||||
|
||||
def check_open_vector_service_enabled
|
||||
render_403 unless OpenVectorEditorService.enabled?
|
||||
end
|
||||
|
||||
helper_method :asset_managable?
|
||||
def asset_managable?
|
||||
case @parent
|
||||
when Step
|
||||
can_manage_step?(@parent)
|
||||
when Result
|
||||
can_manage_my_module?(@parent)
|
||||
else
|
||||
false
|
||||
end
|
||||
end
|
||||
|
||||
def log_activity(type_of, project = nil, message_items = {})
|
||||
return unless @parent.is_a?(Step)
|
||||
|
||||
my_module = @parent.my_module
|
||||
default_items = {
|
||||
protocol: @parent.protocol.id,
|
||||
step: @parent.id,
|
||||
asset_name: { id: @asset.id, value_for: 'file_name' },
|
||||
step_position: { id: @parent.id, value_for: 'position_plus_one' }
|
||||
}
|
||||
|
||||
if my_module
|
||||
project = my_module.project
|
||||
default_items[:my_module] = my_module.id
|
||||
type_of = "task_#{type_of}".to_sym
|
||||
else
|
||||
type_of = "protocol_#{type_of}".to_sym
|
||||
end
|
||||
|
||||
message_items = default_items.merge(message_items)
|
||||
|
||||
Activities::CreateActivityService.call(
|
||||
activity_type: type_of,
|
||||
owner: current_user,
|
||||
team: @parent.protocol.team,
|
||||
subject: @parent.protocol,
|
||||
message_items: message_items,
|
||||
project: project
|
||||
)
|
||||
end
|
||||
end
|
|
@ -65,13 +65,17 @@ class GlobalActivitiesController < ApplicationController
|
|||
end
|
||||
|
||||
def team_filter
|
||||
render json: current_user.teams.ordered.global_activity_filter(activity_filters, params[:query])
|
||||
teams = current_user.teams.ordered.global_activity_filter(activity_filters, params[:query])
|
||||
render json: teams.select(:id, :name)
|
||||
.map { |i| { value: i[:id], label: escape_input(i[:name]) } }
|
||||
end
|
||||
|
||||
def user_filter
|
||||
filter = activity_filters
|
||||
filter = { subjects: { MyModule: [params[:my_module_id].to_i] } } if params[:my_module_id]
|
||||
render json: current_user.global_activity_filter(filter, params[:query])
|
||||
users = current_user.global_activity_filter(filter, params[:query])
|
||||
render json: users.select(:full_name, :id)
|
||||
.map { |i| { label: escape_input(i[:full_name]), value: i[:id] } }
|
||||
end
|
||||
|
||||
def project_filter
|
||||
|
|
|
@ -697,6 +697,12 @@ class ProtocolsController < ApplicationController
|
|||
asset_file_name = asset_guid.to_s + File.extname(asset.file_name).to_s
|
||||
ostream.put_next_entry("#{step_dir}/#{asset_file_name}")
|
||||
ostream.print(asset.file.download)
|
||||
|
||||
next unless asset.preview_image.attached?
|
||||
|
||||
asset_preview_image_name = asset_guid.to_s + File.extname(asset.preview_image_file_name).to_s
|
||||
ostream.put_next_entry("#{step_dir}/previews/#{asset_preview_image_name}")
|
||||
ostream.print(asset.preview_image.download)
|
||||
end
|
||||
end
|
||||
ostream = step.tiny_mce_assets.save_to_eln(ostream, step_dir)
|
||||
|
|
|
@ -40,6 +40,8 @@ module FileIconsHelper
|
|||
image_link = 'icon_small/pptx_file.svg'
|
||||
elsif asset.file.attached? && asset.file.metadata['asset_type'] == 'marvinjs'
|
||||
image_link = 'icon_small/marvinjs_file.svg'
|
||||
elsif asset.file.attached? && asset.file.metadata['asset_type'] == 'gene_sequence'
|
||||
image_link = 'icon_small/sequence-editor.svg'
|
||||
end
|
||||
|
||||
# Now check for custom mappings or possible overrides
|
||||
|
|
2
app/javascript/packs/open_vector_editor.js
Normal file
2
app/javascript/packs/open_vector_editor.js
Normal file
|
@ -0,0 +1,2 @@
|
|||
import '@teselagen/ove';
|
||||
import '@teselagen/ove/style.css';
|
11
app/javascript/packs/vue/open_vector_editor.js
Normal file
11
app/javascript/packs/vue/open_vector_editor.js
Normal file
|
@ -0,0 +1,11 @@
|
|||
import TurbolinksAdapter from 'vue-turbolinks';
|
||||
import Vue from 'vue/dist/vue.esm';
|
||||
import OpenVectorEditor from '../../vue/ove/OpenVectorEditor.vue';
|
||||
|
||||
Vue.use(TurbolinksAdapter);
|
||||
Vue.prototype.i18n = window.I18n;
|
||||
|
||||
new Vue({
|
||||
el: '#open-vector-editor',
|
||||
components: { OpenVectorEditor }
|
||||
});
|
154
app/javascript/vue/ove/OpenVectorEditor.vue
Normal file
154
app/javascript/vue/ove/OpenVectorEditor.vue
Normal file
|
@ -0,0 +1,154 @@
|
|||
<template>
|
||||
<div class="ove-wrapper flex flex-col h-screen">
|
||||
<div class="ove-header flex justify-between h-14 px-4 py-2">
|
||||
<span class="file-name flex items-center ml-3 w-56">
|
||||
<div class="sci-input-container-v2 w-full">
|
||||
<input v-model="sequenceName"
|
||||
class="sci-input-field"
|
||||
type="text"
|
||||
:disabled="readOnly"
|
||||
:placeholder="i18n.t('open_vector_editor.sequence_name_placeholder')"/>
|
||||
</div>
|
||||
</span>
|
||||
<div v-if="oveWarning" class="flex items-center">
|
||||
<i class="mr-1 text-brand-warning sn-icon sn-icon-alert-warning"></i>
|
||||
<p v-html="oveWarning" class="mb-0"></p>
|
||||
</div>
|
||||
<div class="ove-buttons text-sn-blue">
|
||||
<button :style="{ pointerEvents: 'all' }" @click="saveAndClose" class="btn btn-light font-sans" :disabled="this.readOnly">
|
||||
<i class="sn-icon sn-icon-save"></i>
|
||||
{{ i18n.t('SaveClose') }}
|
||||
</button>
|
||||
<button @click="closeModal" class="preview-close btn btn-light icon-btn">
|
||||
<i class="sn-icon sn-icon-close"></i>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<div ref="container" class="ove-container w-full h-full">
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import axios from 'axios';
|
||||
import { blobToBase64 } from '../shared/blobToBase64.js'
|
||||
|
||||
export default {
|
||||
name: 'OpenVectorEditor',
|
||||
props: {
|
||||
fileUrl: { type: String },
|
||||
fileName: { type: String },
|
||||
updateUrl: { type: String },
|
||||
canEditFile: { type: String },
|
||||
oveWarning: { type: String }
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
editor: null,
|
||||
sequenceName: null,
|
||||
closeAfterSave: false,
|
||||
readOnly: this.canEditFile !== 'true'
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
let editorConfig = {
|
||||
onSave: this.saveFile,
|
||||
generatePng: true,
|
||||
showMenuBar: true,
|
||||
alwaysAllowSave: true,
|
||||
menuFilter: this.menuFilter,
|
||||
beforeReadOnlyChange: this.readOnlyHandler,
|
||||
ToolBarProps: {
|
||||
toolList: [
|
||||
'saveTool',
|
||||
'downloadTool',
|
||||
{ name: 'importTool', tooltip: I18n.t('open_vector_editor.editor.tooltips.importTool'), disabled: this.readOnly },
|
||||
'undoTool',
|
||||
'redoTool',
|
||||
'cutsiteTool',
|
||||
'featureTool',
|
||||
'partTool',
|
||||
'oligoTool',
|
||||
'orfTool',
|
||||
// Hide allignment tool
|
||||
// 'alignmentTool',
|
||||
'editTool',
|
||||
'findTool',
|
||||
'visibilityTool'
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
if (this.readOnly) {
|
||||
editorConfig = {
|
||||
...editorConfig,
|
||||
showReadOnly: false,
|
||||
ToolBarProps: {
|
||||
toolList: []
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
this.editor = window.createVectorEditor(this.$refs.container, editorConfig);
|
||||
this.sequenceName = this.fileName;
|
||||
|
||||
if (this.fileUrl) {
|
||||
this.loadFile();
|
||||
} else {
|
||||
this.editor.updateEditor(
|
||||
{
|
||||
sequenceData: { circular: true, name: this.sequenceName },
|
||||
readOnly: this.readOnly
|
||||
}
|
||||
);
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
loadFile() {
|
||||
fetch(this.fileUrl).then((response) => response.json()).then(
|
||||
(json) => this.editor.updateEditor(
|
||||
{ sequenceData: json, readOnly: this.readOnly }
|
||||
)
|
||||
);
|
||||
},
|
||||
saveAndClose() {
|
||||
this.closeAfterSave = true;
|
||||
document.querySelector('[data-test=saveTool]').click()
|
||||
},
|
||||
saveFile(opts, sequenceDataToSave, editorState, onSuccessCallback) {
|
||||
if (this.readOnly) return;
|
||||
blobToBase64(opts.pngFile).then((base64image) => {
|
||||
(this.fileUrl ? axios.patch : axios.post)(
|
||||
this.updateUrl,
|
||||
{
|
||||
sequence_data: sequenceDataToSave,
|
||||
sequence_name: this.sequenceName || this.i18n.t('open_vector_editor.default_sequence_name'),
|
||||
base64_image: base64image
|
||||
}
|
||||
).then(() => {
|
||||
parent.document.getElementById('iFrameModal').dispatchEvent(new Event('sequenceSaved'));
|
||||
if (this.closeAfterSave) this.closeModal();
|
||||
});
|
||||
});
|
||||
},
|
||||
closeModal() {
|
||||
if (parent !== window) {
|
||||
parent.document.getElementById('iFrameModal').dispatchEvent(new Event('hide'));
|
||||
}
|
||||
},
|
||||
menuFilter(menus) {
|
||||
return menus.map(menu => {
|
||||
if(menu.text !== 'Help') return menu;
|
||||
const menuOverride = {
|
||||
...menu,
|
||||
submenu: menu.submenu.filter(item => item.cmd !== 'versionNumber')
|
||||
}
|
||||
|
||||
return menuOverride;
|
||||
});
|
||||
},
|
||||
|
||||
readOnlyHandler(val) { this.readOnly = val; return true }
|
||||
}
|
||||
}
|
||||
</script>
|
|
@ -1,5 +1,5 @@
|
|||
<template>
|
||||
<div class="step-attachments">
|
||||
<div class="step-attachments" v-if="attachments && attachments.length">
|
||||
<div class="attachments-actions">
|
||||
<div class="title">
|
||||
<h3>{{ i18n.t('protocols.steps.files', {count: attachments.length}) }}</h3>
|
||||
|
@ -27,6 +27,12 @@
|
|||
{{ i18n.t('protocols.steps.attachments.menu.office_file') }}
|
||||
</a>
|
||||
</li>
|
||||
<li v-if="step.attributes.open_vector_editor_context.new_sequence_asset_url">
|
||||
<a @click="openOVEditor" class="open-vector-editor-button" tabindex="0" @keyup.enter="openOVEditor">
|
||||
<img :src="step.attributes.open_vector_editor_context.icon"/>
|
||||
{{ i18n.t('open_vector_editor.new_sequence_file') }}
|
||||
</a>
|
||||
</li>
|
||||
<li v-if="step.attributes.marvinjs_enabled">
|
||||
<a
|
||||
class="new-marvinjs-upload-button"
|
||||
|
@ -36,7 +42,7 @@
|
|||
:data-sketch-container="`.attachments[data-step-id=${step.id}]`"
|
||||
>
|
||||
<span class="new-marvinjs-upload-icon">
|
||||
<img :src="step.attributes.marvinjs_context.icon">
|
||||
<i class="sn-icon sn-icon-marvinjs"></i>
|
||||
</span>
|
||||
{{ i18n.t('protocols.steps.attachments.menu.chemical_drawing') }}
|
||||
</a>
|
||||
|
@ -68,8 +74,9 @@
|
|||
</div>
|
||||
</div>
|
||||
<div class="attachments">
|
||||
<template v-for="(attachment, index) in attachmentsOrdered">
|
||||
<template >
|
||||
<component
|
||||
v-for="(attachment, index) in attachmentsOrdered"
|
||||
:is="attachment_view_mode(attachmentsOrdered[index])"
|
||||
:key="attachment.id"
|
||||
:attachment="attachment"
|
||||
|
@ -150,6 +157,7 @@
|
|||
}
|
||||
},
|
||||
mounted() {
|
||||
this.initOVE(this);
|
||||
this.initMarvinJS();
|
||||
$(this.$refs.actionsDropdownButton).on('shown.bs.dropdown hidden.bs.dropdown', this.handleDropdownPosition);
|
||||
},
|
||||
|
@ -174,6 +182,11 @@
|
|||
deleteAttachment(id) {
|
||||
this.$emit('attachment:deleted', id)
|
||||
},
|
||||
initOVE(component) {
|
||||
$(window.iFrameModal).on('sequenceSaved', function() {
|
||||
component.$emit('attachment:uploaded');
|
||||
});
|
||||
},
|
||||
initMarvinJS() {
|
||||
// legacy logic from app/assets/javascripts/sitewide/marvinjs_editor.js
|
||||
MarvinJsEditor.initNewButton(
|
||||
|
@ -190,6 +203,9 @@
|
|||
}
|
||||
});
|
||||
},
|
||||
openOVEditor() {
|
||||
window.showIFrameModal(this.step.attributes.open_vector_editor_context.new_sequence_asset_url);
|
||||
},
|
||||
handleDropdownPosition() {
|
||||
this.$refs.actionsDropdownButton.classList.toggle("dropup", !this.isInViewport(this.$refs.actionsDropdown));
|
||||
},
|
||||
|
|
|
@ -140,8 +140,8 @@
|
|||
<div class="collapse in" :id="'stepBody' + step.id">
|
||||
<div class="step-elements">
|
||||
<div class="step-timestamp">{{ i18n.t('protocols.steps.timestamp', {date: step.attributes.created_at, user: step.attributes.created_by}) }}</div>
|
||||
<template v-for="(element, index) in orderedElements">
|
||||
<component
|
||||
v-for="(element, index) in orderedElements"
|
||||
:is="elements[index].attributes.orderable_type"
|
||||
:key="index"
|
||||
:element.sync="elements[index]"
|
||||
|
@ -154,17 +154,16 @@
|
|||
@reorder="openReorderModal"
|
||||
@component:insert="insertElement"
|
||||
/>
|
||||
</template>
|
||||
<Attachments v-if="attachments.length"
|
||||
:step="step"
|
||||
:attachments="attachments"
|
||||
:attachmentsReady="attachmentsReady"
|
||||
@attachments:openFileModal="showFileModal = true"
|
||||
@attachment:deleted="attachmentDeleted"
|
||||
@attachment:uploaded="loadAttachments"
|
||||
@attachments:order="changeAttachmentsOrder"
|
||||
@attachments:viewMode="changeAttachmentsViewMode"
|
||||
@attachment:viewMode="updateAttachmentViewMode"/>
|
||||
<Attachments
|
||||
:step="step"
|
||||
:attachments="attachments"
|
||||
:attachmentsReady="attachmentsReady"
|
||||
@attachments:openFileModal="showFileModal = true"
|
||||
@attachment:deleted="attachmentDeleted"
|
||||
@attachment:uploaded="loadAttachments"
|
||||
@attachments:order="changeAttachmentsOrder"
|
||||
@attachments:viewMode="changeAttachmentsViewMode"
|
||||
@attachment:viewMode="updateAttachmentViewMode"/>
|
||||
</div>
|
||||
</div>
|
||||
<deleteStepModal v-if="confirmingDelete" @confirm="deleteStep" @cancel="closeDeleteModal"/>
|
||||
|
@ -308,7 +307,6 @@
|
|||
|
||||
$.get(this.urls.attachments_url, (result) => {
|
||||
this.attachments = result.data
|
||||
|
||||
if (this.attachments.findIndex((e) => e.attributes.attached === false) >= 0) {
|
||||
setTimeout(() => {
|
||||
this.loadAttachments()
|
||||
|
|
|
@ -20,6 +20,12 @@
|
|||
{{ attachment.attributes.wopi_context.button_text }}
|
||||
</a>
|
||||
</li>
|
||||
<li v-if="attachment.attributes.asset_type == 'gene_sequence' && attachment.attributes.urls.open_vector_editor_edit">
|
||||
<a class="ove-edit-button" @click="openOVEditor(attachment.attributes.urls.open_vector_editor_edit)">
|
||||
<span class="sn-icon sn-icon-sequence-editor"></span>
|
||||
{{ i18n.t('open_vector_editor.edit_sequence') }}
|
||||
</a>
|
||||
</li>
|
||||
<li v-if="attachment.attributes.asset_type == 'marvinjs' && attachment.attributes.urls.marvin_js_start_edit">
|
||||
<a class="marvinjs-edit-button"
|
||||
:data-sketch-id="attachment.id"
|
||||
|
@ -28,7 +34,7 @@
|
|||
:data-sketch-name="attachment.attributes.metadata.name"
|
||||
:data-sketch-description="attachment.attributes.metadata.description"
|
||||
>
|
||||
<img :src="attachment.attributes.urls.marvin_js_icon"/>
|
||||
<span class="sn-icon sn-icon-marvinjs"></span>
|
||||
{{ i18n.t('assets.file_preview.edit_in_marvinjs') }}
|
||||
</a>
|
||||
</li>
|
||||
|
@ -129,6 +135,9 @@
|
|||
deleteAttachment() {
|
||||
this.deleteModal = false
|
||||
this.$emit('attachment:delete')
|
||||
},
|
||||
openOVEditor(url) {
|
||||
window.showIFrameModal(url);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -34,7 +34,7 @@
|
|||
{{ i18n.t("protocols.steps.attachments.file_modal.drag_zone_notification", {position: step.attributes.position + 1}) }}
|
||||
</div>
|
||||
</div>
|
||||
<div class="divider" v-if="step.attributes.marvinjs_enabled || step.attributes.wopi_enabled">
|
||||
<div class="divider" v-if="step.attributes.marvinjs_enabled || step.attributes.wopi_enabled || step.attributes.open_vector_editor_context.new_sequence_asset_url">
|
||||
{{ i18n.t("protocols.steps.attachments.file_modal.or") }}
|
||||
</div>
|
||||
<div class="integrations-container">
|
||||
|
@ -44,6 +44,12 @@
|
|||
{{ i18n.t('assets.create_wopi_file.button_text') }}
|
||||
</a>
|
||||
</div>
|
||||
<div class="integration-block" v-if="step.attributes.open_vector_editor_context.new_sequence_asset_url">
|
||||
<a @click="openOVEditor" class="open-vector-editor-button btn btn-light">
|
||||
<img :src="step.attributes.open_vector_editor_context.icon"/>
|
||||
{{ i18n.t('open_vector_editor.new_sequence') }}
|
||||
</a>
|
||||
</div>
|
||||
<div class="integration-block marvinjs" v-if="step.attributes.marvinjs_enabled">
|
||||
<a
|
||||
class="new-marvinjs-upload-button btn btn-light"
|
||||
|
@ -57,7 +63,7 @@
|
|||
<span class="new-marvinjs-upload-icon">
|
||||
<img :src="step.attributes.marvinjs_context.icon"/>
|
||||
</span>
|
||||
{{ i18n.t('marvinjs.new_button') }}
|
||||
{{ i18n.t('marvinjs.new_li_button') }}
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -148,6 +154,10 @@
|
|||
HelperModule.flashAlertMsg(this.i18n.t('errors.general'), 'danger');
|
||||
}
|
||||
});
|
||||
},
|
||||
openOVEditor() {
|
||||
$(this.$refs.modal).modal('hide');
|
||||
window.showIFrameModal(this.step.attributes.open_vector_editor_context.new_sequence_asset_url);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
<div class="list-attachment-container asset"
|
||||
:data-asset-id="attachment.id"
|
||||
>
|
||||
<div v-html="attachment.attributes.icon"></div>
|
||||
<i class="fas asset-icon" :class="attachment.attributes.icon"></i>
|
||||
<a :href="attachment.attributes.urls.blob"
|
||||
class="file-preview-link file-name"
|
||||
|
|
|
@ -10,13 +10,15 @@
|
|||
:data-gallery-view-id="stepId"
|
||||
:data-preview-url="attachment.attributes.urls.preview"
|
||||
>
|
||||
<div class="attachment-preview" :class= "attachment.attributes.asset_type">
|
||||
<img v-if="attachment.attributes.medium_preview !== null"
|
||||
<div v-if="attachment.attributes.medium_preview" class="attachment-preview" :class= "attachment.attributes.asset_type">
|
||||
<img
|
||||
:src="attachment.attributes.medium_preview"
|
||||
@error="ActiveStoragePreviews.reCheckPreview"
|
||||
@load="ActiveStoragePreviews.showPreview"
|
||||
style='opacity: 0' />
|
||||
<i v-else class="fas" :class="attachment.attributes.icon"></i>
|
||||
</div>
|
||||
<div v-else class="attachment-preview flex">
|
||||
<span class="fa fa-paperclip m-auto text-4xl"></span>
|
||||
</div>
|
||||
<div class="attachment-label"
|
||||
data-toggle="tooltip"
|
||||
|
|
|
@ -237,6 +237,7 @@
|
|||
setTimeout(this.updateTable, 100) // delay makes cancel button work
|
||||
}
|
||||
});
|
||||
this.$nextTick(this.tableObject.render);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -9,10 +9,6 @@
|
|||
<div class="modal-body text-xs" v-html="i18n.t(`protocols.import_modal.${state}.body_html`, { url: protocolUrl })">
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<button type="button"
|
||||
class="btn btn-default"
|
||||
data-dismiss="modal">{{ i18n.t('protocols.import_modal.cancel') }}</button>
|
||||
|
||||
<button v-if="state === 'confirm'" type="button"
|
||||
class="btn btn-primary"
|
||||
@click.stop.prevent="confirm">{{ i18n.t('protocols.import_modal.import') }}</button>
|
||||
|
|
9
app/javascript/vue/shared/blobToBase64.js
Normal file
9
app/javascript/vue/shared/blobToBase64.js
Normal file
|
@ -0,0 +1,9 @@
|
|||
export function blobToBase64(blob) {
|
||||
const reader = new FileReader();
|
||||
reader.readAsDataURL(blob);
|
||||
return new Promise(resolve => {
|
||||
reader.onloadend = () => {
|
||||
resolve(reader.result);
|
||||
};
|
||||
});
|
||||
}
|
|
@ -17,6 +17,7 @@ class Asset < ApplicationRecord
|
|||
# ActiveStorage configuration
|
||||
has_one_attached :file
|
||||
has_one_attached :file_pdf_preview
|
||||
has_one_attached :preview_image
|
||||
|
||||
# Asset validation
|
||||
# This could cause some problems if you create empty asset and want to
|
||||
|
@ -165,17 +166,21 @@ class Asset < ApplicationRecord
|
|||
end
|
||||
|
||||
def previewable?
|
||||
return false unless file.attached?
|
||||
return false unless preview_image.attached? || file.attached?
|
||||
|
||||
previewable_document?(blob) || previewable_image?
|
||||
end
|
||||
|
||||
def preview_attachment
|
||||
preview_image.attached? ? preview_image : file
|
||||
end
|
||||
|
||||
def medium_preview
|
||||
file.representation(resize_to_limit: Constants::MEDIUM_PIC_FORMAT)
|
||||
preview_attachment.representation(resize_to_limit: Constants::MEDIUM_PIC_FORMAT)
|
||||
end
|
||||
|
||||
def large_preview
|
||||
file.representation(resize_to_limit: Constants::LARGE_PIC_FORMAT)
|
||||
preview_attachment.representation(resize_to_limit: Constants::LARGE_PIC_FORMAT)
|
||||
end
|
||||
|
||||
def file_name
|
||||
|
@ -184,6 +189,12 @@ class Asset < ApplicationRecord
|
|||
file.blob&.filename&.sanitized
|
||||
end
|
||||
|
||||
def preview_image_file_name
|
||||
return '' unless preview_image.attached?
|
||||
|
||||
preview_image.blob&.filename&.sanitized
|
||||
end
|
||||
|
||||
def render_file_name
|
||||
if file.attached? && file.metadata['asset_type']
|
||||
file.metadata['name']
|
||||
|
@ -221,6 +232,18 @@ class Asset < ApplicationRecord
|
|||
to_blob = ActiveStorage::Blob.create_and_upload!(io: tmp_file, filename: blob.filename, metadata: blob.metadata)
|
||||
to_asset.file.attach(to_blob)
|
||||
end
|
||||
|
||||
if preview_image.attached?
|
||||
preview_image.blob.open do |tmp_preview_image|
|
||||
to_blob = ActiveStorage::Blob.create_and_upload!(
|
||||
io: tmp_preview_image,
|
||||
filename: blob.filename,
|
||||
metadata: blob.metadata
|
||||
)
|
||||
to_asset.preview_image.attach(to_blob)
|
||||
end
|
||||
end
|
||||
|
||||
to_asset.post_process_file(to_asset.team)
|
||||
end
|
||||
|
||||
|
@ -449,7 +472,8 @@ class Asset < ApplicationRecord
|
|||
end
|
||||
|
||||
def previewable_image?
|
||||
file.blob&.content_type =~ %r{^image/#{Regexp.union(Constants::WHITELISTED_IMAGE_TYPES)}}
|
||||
preview_image.attached? ||
|
||||
file.blob&.content_type =~ %r{^image/#{Regexp.union(Constants::WHITELISTED_IMAGE_TYPES)}}
|
||||
end
|
||||
|
||||
def step_or_result_or_repository_asset_value
|
||||
|
|
|
@ -1,47 +0,0 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
module TeamBySubjectModel
|
||||
extend ActiveSupport::Concern
|
||||
|
||||
class_methods do
|
||||
def team_by_subject(subjects)
|
||||
teams = []
|
||||
valid_subjects = Extends::ACTIVITY_SUBJECT_CHILDREN
|
||||
# Check all activity subject
|
||||
valid_subjects.each do |subject, _children|
|
||||
subject = subject.to_s.camelize.to_sym
|
||||
next unless subjects[subject]
|
||||
|
||||
parent_array = [subject.to_s.underscore]
|
||||
find_parent = true
|
||||
# Trying to build parent array
|
||||
while find_parent
|
||||
possible_parent = valid_subjects.find { |_sub, ch| ((ch || []).include? parent_array[-1].pluralize.to_sym) }
|
||||
possible_parent = { Project: nil } if parent_array[-1] == 'experiment'
|
||||
if possible_parent
|
||||
parent_array.push(possible_parent.flatten[0].to_s.underscore)
|
||||
else
|
||||
find_parent = false
|
||||
end
|
||||
end
|
||||
# Remove initial object from parent array
|
||||
parent_array.shift
|
||||
subjects[subject].each do |child|
|
||||
child_subject = subject.to_s.constantize.find_by_id(child)
|
||||
next unless child_subject
|
||||
|
||||
# Call all parent subjects
|
||||
parent_array.each do |parent|
|
||||
temp_child_subject = child_subject.public_send(parent)
|
||||
# Some fix for protocols in repository
|
||||
break unless temp_child_subject
|
||||
|
||||
child_subject = temp_child_subject
|
||||
end
|
||||
teams.push(child_subject.team_id)
|
||||
end
|
||||
end
|
||||
teams.uniq
|
||||
end
|
||||
end
|
||||
end
|
|
@ -11,6 +11,7 @@ class RepositoryRow < ApplicationRecord
|
|||
include PrefixedIdModel
|
||||
|
||||
belongs_to :repository, class_name: 'RepositoryBase'
|
||||
delegate :team, to: :repository
|
||||
belongs_to :parent, class_name: 'RepositoryRow', optional: true
|
||||
belongs_to :created_by, foreign_key: :created_by_id, class_name: 'User'
|
||||
belongs_to :last_modified_by, foreign_key: :last_modified_by_id, class_name: 'User'
|
||||
|
|
|
@ -14,6 +14,7 @@ class Result < ApplicationRecord
|
|||
belongs_to :archived_by, foreign_key: 'archived_by_id', class_name: 'User', optional: true
|
||||
belongs_to :restored_by, foreign_key: 'restored_by_id', class_name: 'User', optional: true
|
||||
belongs_to :my_module, inverse_of: :results
|
||||
delegate :team, to: :my_module
|
||||
has_one :result_asset, inverse_of: :result, dependent: :destroy
|
||||
has_one :asset, through: :result_asset
|
||||
has_one :result_table, inverse_of: :result, dependent: :destroy
|
||||
|
|
|
@ -1,14 +1,18 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
class Settings < ApplicationRecord
|
||||
attr_accessor :merged_values
|
||||
|
||||
before_validation -> { self.values = merged_values || values }
|
||||
|
||||
def self.instance
|
||||
first || new
|
||||
end
|
||||
|
||||
def values
|
||||
merged_values = super
|
||||
self.merged_values ||= super
|
||||
self.class.instance_methods(false).grep(/^load_values_from_[A-Z0-9_]*/).each do |method|
|
||||
merged_values = merged_values.merge(public_send(method))
|
||||
self.merged_values = self.merged_values.merge(public_send(method))
|
||||
end
|
||||
merged_values
|
||||
end
|
||||
|
|
|
@ -32,6 +32,7 @@ class Step < ApplicationRecord
|
|||
belongs_to :user, inverse_of: :steps
|
||||
belongs_to :last_modified_by, foreign_key: 'last_modified_by_id', class_name: 'User', optional: true
|
||||
belongs_to :protocol, inverse_of: :steps
|
||||
delegate :team, to: :protocol
|
||||
has_many :step_orderable_elements, inverse_of: :step, dependent: :destroy
|
||||
has_many :checklists, inverse_of: :step, dependent: :destroy
|
||||
has_many :step_comments, foreign_key: :associated_id, dependent: :destroy
|
||||
|
|
|
@ -5,7 +5,6 @@ class Team < ApplicationRecord
|
|||
include ViewableModel
|
||||
include Assignable
|
||||
include PermissionCheckableModel
|
||||
include TeamBySubjectModel
|
||||
include TinyMceImages
|
||||
|
||||
# Not really MVC-compliant, but we just use it for logger
|
||||
|
@ -169,14 +168,26 @@ class Team < ApplicationRecord
|
|||
ProtocolKeyword.where(team: self).pluck(:name)
|
||||
end
|
||||
|
||||
def self.by_activity_subjects(subjects)
|
||||
team_ids = []
|
||||
valid_subjects = subjects.select { |k| Extends::SEARCHABLE_ACTIVITY_SUBJECT_TYPES.include?(k.to_s) }
|
||||
valid_subjects.each do |subject_name, subject_id|
|
||||
subject = subject_name.to_s.constantize.find_by(id: subject_id)
|
||||
next if subject.blank?
|
||||
|
||||
team_ids << subject.team.id
|
||||
end
|
||||
where(id: team_ids.uniq)
|
||||
end
|
||||
|
||||
def self.global_activity_filter(filters, search_query)
|
||||
query = where('name ILIKE ?', "%#{search_query}%")
|
||||
query = where_attributes_like(:name, search_query)
|
||||
if filters[:users]
|
||||
user_teams = User.where(id: filters[:users]).joins(:teams).group(:team_id).select(:team_id)
|
||||
query = query.where(id: user_teams)
|
||||
end
|
||||
query = query.where(id: team_by_subject(filters[:subjects])) if filters[:subjects]
|
||||
query.select(:id, :name).map { |i| { value: i[:id], label: ApplicationController.helpers.escape_input(i[:name]) } }
|
||||
query = query.by_activity_subjects(filters[:subjects]) if filters[:subjects].present?
|
||||
query
|
||||
end
|
||||
|
||||
def self.search_by_object(obj)
|
||||
|
|
|
@ -4,7 +4,6 @@ class User < ApplicationRecord
|
|||
include SearchableModel
|
||||
include SettingsModel
|
||||
include VariablesModel
|
||||
include TeamBySubjectModel
|
||||
include InputSanitizeHelper
|
||||
include ActiveStorageConcerns
|
||||
|
||||
|
@ -581,13 +580,11 @@ class User < ApplicationRecord
|
|||
end
|
||||
|
||||
def global_activity_filter(filters, search_query)
|
||||
query_teams = teams.pluck(:id)
|
||||
query_teams &= filters[:teams].map(&:to_i) if filters[:teams]
|
||||
query_teams &= User.team_by_subject(filters[:subjects]) if filters[:subjects]
|
||||
query_teams = teams
|
||||
query_teams = query_teams.where(id: filters[:teams].map(&:to_i)) if filters[:teams].present?
|
||||
query_teams = query_teams.by_activity_subjects(filters[:subjects]) if filters[:subjects].present?
|
||||
User.where(id: UserAssignment.where(assignable_id: query_teams, assignable_type: 'Team').select(:user_id))
|
||||
.search(false, search_query)
|
||||
.select(:full_name, :id)
|
||||
.map { |i| { label: escape_input(i[:full_name]), value: i[:id] } }
|
||||
end
|
||||
|
||||
def file_name
|
||||
|
|
|
@ -14,11 +14,11 @@ class AssetSerializer < ActiveModel::Serializer
|
|||
:updated_at, :metadata, :image_editable, :image_context, :pdf, :attached
|
||||
|
||||
def icon
|
||||
file_fa_icon_class(object)
|
||||
file_extension_icon_html(object)
|
||||
end
|
||||
|
||||
def file_name
|
||||
escape_input(object.render_file_name)
|
||||
object.render_file_name
|
||||
end
|
||||
|
||||
def updated_at
|
||||
|
@ -127,6 +127,7 @@ class AssetSerializer < ActiveModel::Serializer
|
|||
delete: asset_destroy_path(object)
|
||||
)
|
||||
end
|
||||
urls[:open_vector_editor_edit] = edit_gene_sequence_asset_path(object.id) if can_manage_asset?(user, object)
|
||||
urls[:wopi_action] = object.get_action_url(user, 'embedview') if wopi && can_manage_asset?(user, object)
|
||||
urls[:blob] = rails_blob_path(object.file, disposition: 'attachment') if object.file.attached?
|
||||
|
||||
|
|
|
@ -9,7 +9,8 @@ class StepSerializer < ActiveModel::Serializer
|
|||
|
||||
attributes :name, :position, :completed, :attachments_manageble, :urls, :assets_view_mode,
|
||||
:marvinjs_enabled, :marvinjs_context, :created_by, :created_at, :assets_order,
|
||||
:wopi_enabled, :wopi_context, :comments_count, :unseen_comments, :storage_limit
|
||||
:wopi_enabled, :wopi_context, :comments_count, :unseen_comments, :storage_limit,
|
||||
:open_vector_editor_context
|
||||
|
||||
def marvinjs_enabled
|
||||
MarvinJsService.enabled?
|
||||
|
@ -24,6 +25,15 @@ class StepSerializer < ActiveModel::Serializer
|
|||
end
|
||||
end
|
||||
|
||||
def open_vector_editor_context
|
||||
if can_manage_step?(object)
|
||||
{
|
||||
new_sequence_asset_url: new_gene_sequence_asset_url(parent_type: 'Step', parent_id: object.id),
|
||||
icon: image_path('icon_small/sequence-editor.svg')
|
||||
}
|
||||
end
|
||||
end
|
||||
|
||||
def comments_count
|
||||
object.comments.count
|
||||
end
|
||||
|
|
9
app/services/open_vector_editor_service.rb
Normal file
9
app/services/open_vector_editor_service.rb
Normal file
|
@ -0,0 +1,9 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
class OpenVectorEditorService
|
||||
class << self
|
||||
def enabled?
|
||||
ENV.fetch('SCINOTE_OVE_ENABLED') == 'true'
|
||||
end
|
||||
end
|
||||
end
|
|
@ -9,8 +9,8 @@ module Reports::Docx::DrawResultTable
|
|||
table_data = JSON.parse(table.contents_utf_8)['data']
|
||||
table_data = obj.add_headers_to_table(table_data, false)
|
||||
|
||||
if table.metadata.present?
|
||||
table.metadata['cells']&.each do |cell|
|
||||
if table.metadata.present? && table.metadata['cells'].is_a?(Array)
|
||||
table.metadata['cells'].each do |cell|
|
||||
next unless cell['row'].present? && cell['col'].present?
|
||||
|
||||
row_index = cell['row'].to_i + 1
|
||||
|
@ -27,8 +27,8 @@ module Reports::Docx::DrawResultTable
|
|||
cell_style rows[0], bold: true, background: color[:concrete]
|
||||
cell_style cols[0], bold: true, background: color[:concrete]
|
||||
|
||||
if table.metadata.present?
|
||||
table.metadata['cells']&.each do |cell|
|
||||
if table.metadata.present? && table.metadata['cells'].is_a?(Array)
|
||||
table.metadata['cells'].each do |cell|
|
||||
next unless cell.present? && cell['row'].present? && cell['col'].present? && cell['className'].present?
|
||||
|
||||
cell_style rows.dig(cell['row'].to_i + 1, cell['col'].to_i + 1),
|
||||
|
|
|
@ -8,8 +8,8 @@ module Reports::Docx::DrawStepTable
|
|||
table_data = JSON.parse(table.contents_utf_8)['data']
|
||||
table_data = obj.add_headers_to_table(table_data, table_type == 'step_well_plates_table')
|
||||
|
||||
if table.metadata.present?
|
||||
table.metadata['cells']&.each do |cell|
|
||||
if table.metadata.present? && table.metadata['cells'].is_a?(Array)
|
||||
table.metadata['cells'].each do |cell|
|
||||
next unless cell['row'].present? && cell['col'].present?
|
||||
|
||||
row_index = cell['row'].to_i + 1
|
||||
|
@ -26,8 +26,8 @@ module Reports::Docx::DrawStepTable
|
|||
cell_style rows[0], bold: true, background: color[:concrete]
|
||||
cell_style cols[0], bold: true, background: color[:concrete]
|
||||
|
||||
if table.metadata.present?
|
||||
table.metadata['cells']&.each do |cell|
|
||||
if table.metadata.present? && table.metadata['cells'].is_a?(Array)
|
||||
table.metadata['cells'].each do |cell|
|
||||
data = cell[1]
|
||||
next unless data.present? && data['row'].present? && data['col'].present? && data['className'].present?
|
||||
|
||||
|
|
|
@ -115,6 +115,11 @@ class ProtocolsImporterV2
|
|||
filename: asset_json['fileName'],
|
||||
content_type: asset_json['fileType'],
|
||||
metadata: JSON.parse(asset_json['fileMetadata'] || '{}'))
|
||||
if asset_json['preview_image'].present?
|
||||
asset.preview_image.attach(io: StringIO.new(Base64.decode64(asset_json.dig('preview_image', 'bytes'))),
|
||||
filename: asset_json.dig('preview_image', 'fileName'))
|
||||
end
|
||||
|
||||
asset.save!
|
||||
asset_ids << asset.id
|
||||
|
||||
|
|
30
app/views/gene_sequence_assets/edit.html.erb
Normal file
30
app/views/gene_sequence_assets/edit.html.erb
Normal file
|
@ -0,0 +1,30 @@
|
|||
<html>
|
||||
<head>
|
||||
<%= csp_meta_tag %>
|
||||
<%= javascript_include_tag 'i18n_bundle' %>
|
||||
<%= stylesheet_link_tag 'sn_icon_font' %>
|
||||
<%= stylesheet_link_tag 'application' %>
|
||||
<%= stylesheet_link_tag 'tailwind' %>
|
||||
<%= stylesheet_link_tag 'open_vector_editor' %>
|
||||
<style>
|
||||
body {
|
||||
margin: 0;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<% if @ove_enabled %>
|
||||
<div id="open-vector-editor" data-behaviour="vue">
|
||||
<open-vector-editor
|
||||
file-url="<%= @file_url %>"
|
||||
file-name="<%= @file_name %>"
|
||||
update-url="<%= @asset ? gene_sequence_asset_url(@asset) : gene_sequence_assets_url(parent_type: params[:parent_type], parent_id: params[:parent_id]) %>"
|
||||
can-edit-file="<%= asset_managable? %>"
|
||||
ove-warning="<%= defined?(@warnings) ? @warnings : '' %>"
|
||||
/>
|
||||
</div>
|
||||
<%= javascript_include_tag 'open_vector_editor' %>
|
||||
<%= javascript_include_tag 'vue_components_open_vector_editor' %>
|
||||
<% end %>
|
||||
</body>
|
||||
</html>
|
|
@ -109,6 +109,7 @@
|
|||
<%= render "shared/file_preview/modal" %>
|
||||
<%= render "shared/file_edit_modal" %>
|
||||
<%= render "shared/marvinjs_modal" %>
|
||||
<%= render "shared/iframe_modal" %>
|
||||
<%= render "users/sessions/session_expire_modal" %>
|
||||
<%= render "users/sessions/session_end_modal" %>
|
||||
<%= render "label_printers/label_printer_modal" %>
|
||||
|
|
|
@ -68,9 +68,7 @@
|
|||
:name,
|
||||
{},
|
||||
{ class: 'selectpicker' }) %>
|
||||
<%= f.button class: 'btn btn-primary' do %>
|
||||
<span><%= t("experiments.canvas.modal_manage_tags.create") %></span>
|
||||
<% end %>
|
||||
<%= f.submit t("experiments.canvas.modal_manage_tags.create"), class: 'btn btn-primary' %>
|
||||
</div>
|
||||
</div>
|
||||
<% end %>
|
||||
|
|
|
@ -80,7 +80,7 @@
|
|||
<button type="button" class="btn btn-secondary" data-dismiss="modal">
|
||||
<%= t('general.cancel') %>
|
||||
</button>
|
||||
<%= f.button t('experiments.canvas.new_my_module_modal.create'), class: "btn btn-primary" %>
|
||||
<%= f.submit t('experiments.canvas.new_my_module_modal.create'), class: "btn btn-primary" %>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -40,7 +40,7 @@
|
|||
</div>
|
||||
<div class="modal-footer">
|
||||
<button type="button" class="btn btn-secondary" data-dismiss="modal"><%= t('general.cancel') %></button>
|
||||
<%= f.button t('projects.index.modal_new_project.create'), class: "btn btn-primary" %>
|
||||
<%= f.submit t('projects.index.modal_new_project.create'), class: "btn btn-primary" %>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -41,7 +41,7 @@
|
|||
</div>
|
||||
<div class="modal-footer">
|
||||
<button type="button" class="btn btn-secondary" data-dismiss="modal"><%= t('general.cancel') %></button>
|
||||
<%= f.button t("protocols.new_protocol_modal.create_#{type}") , class: "btn btn-primary create-protocol-button" %>
|
||||
<%= f.submit t("protocols.new_protocol_modal.create_#{type}") , class: "btn btn-primary create-protocol-button" %>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -17,8 +17,7 @@
|
|||
<button type="button" class="btn btn-secondary cancel-edit">
|
||||
<%= t("general.cancel")%>
|
||||
</button>
|
||||
<%= f.button t("general.save"),
|
||||
class: 'btn btn-primary save-result' %>
|
||||
<%= f.submit t("general.save"), class: 'btn btn-primary save-result' %>
|
||||
</div>
|
||||
<% end %>
|
||||
</div>
|
||||
|
|
|
@ -18,8 +18,7 @@
|
|||
<button type="button" class="btn btn-secondary cancel-edit">
|
||||
<%= t("general.cancel")%>
|
||||
</button>
|
||||
<%= f.button t("general.save"),
|
||||
class: 'btn btn-primary save-result' %>
|
||||
<%= f.submit t("general.save"), class: 'btn btn-primary save-result' %>
|
||||
</div>
|
||||
<% end %>
|
||||
</div>
|
||||
|
|
|
@ -17,8 +17,7 @@
|
|||
<button type="button" class="btn btn-secondary cancel-new">
|
||||
<%= t("general.cancel")%>
|
||||
</button>
|
||||
<%= f.button t("result_tables.new.create"),
|
||||
class: 'btn btn-primary save-result' %>
|
||||
<%= f.submit t("result_tables.new.create"), class: 'btn btn-primary save-result' %>
|
||||
</div>
|
||||
<% end %>
|
||||
</div>
|
||||
|
|
|
@ -19,8 +19,7 @@
|
|||
<button type="button" class="btn btn-secondary cancel-edit">
|
||||
<%= t("general.cancel")%>
|
||||
</button>
|
||||
<%= f.button t("general.save"),
|
||||
class: 'btn btn-primary save-result' %>
|
||||
<%= f.submit t("general.save"), class: 'btn btn-primary save-result' %>
|
||||
</div>
|
||||
<% end %>
|
||||
</div>
|
||||
|
|
|
@ -18,8 +18,7 @@
|
|||
<button type="button" class="btn btn-secondary cancel-new">
|
||||
<%= t("general.cancel")%>
|
||||
</button>
|
||||
<%= f.button t("result_texts.new.create"),
|
||||
class: 'btn btn-primary save-result' %>
|
||||
<%= f.submit t("result_texts.new.create"), class: 'btn btn-primary save-result' %>
|
||||
</div>
|
||||
<% end %>
|
||||
</div>
|
||||
|
|
|
@ -1,7 +1,9 @@
|
|||
<% @asset_results.each do |asset| %>
|
||||
<h5>
|
||||
<h5 class="flex flex-row flex-nowrap items-center gap-1">
|
||||
<% if asset.blob.metadata["asset_type"] == 'marvinjs' %>
|
||||
<span class="mce-i-marvinjs"></span>
|
||||
<% elsif asset.blob.metadata["asset_type"] == 'gene_sequence' %>
|
||||
<span class="sn-file-ove"></span>
|
||||
<% else %>
|
||||
<% if wopi_file?(asset) %>
|
||||
<%= file_extension_icon(asset) %>
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
</span>
|
||||
</div>
|
||||
|
||||
<div class="my-5 flex-1 bg-sn-white">
|
||||
<div class="my-5 max-w-4xl flex-1 bg-sn-white">
|
||||
<div class="content-pane flexible">
|
||||
<%= render partial: 'shareable_links/my_modules/header_actions' %>
|
||||
<div class="px-4">
|
||||
|
|
|
@ -2,13 +2,13 @@
|
|||
<div class="comment-container">
|
||||
<div class="avatar-placehodler">
|
||||
<span class='global-avatar-container'>
|
||||
<%= image_tag avatar_path(comment.user, :icon_small), class: 'avatar' %>
|
||||
<%= image_tag user_avatar_absolute_url(comment.user, :icon_small, true), class: 'user-avatar' %>
|
||||
</span>
|
||||
</div>
|
||||
<div class="content-placeholder">
|
||||
<div class="comment-name"><%= comment.user.full_name %></div>
|
||||
<div class="comment-right !w-fit">
|
||||
<div class="comment-datetime !w-fit"><%= comment.created_at.iso8601 %></div>
|
||||
<div class="comment-datetime !w-fit"><%= l(comment.created_at, format: :full) %></div>
|
||||
</div>
|
||||
<div class="comment-message">
|
||||
<div class="view-mode"><%= smart_annotation_text(comment.message) %></div>
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
<% if element.name.present? %>
|
||||
<div class="step-element-name">
|
||||
<%= render partial: "shareable_links/my_modules/inline_view", locals: { text: element.name, smart_annotation_enabled: false } %>
|
||||
</div>
|
||||
</div>
|
||||
<% end %>
|
||||
</div>
|
||||
<div class="step-table view locked" tabindex="0">
|
||||
|
|
3
app/views/shared/_iframe_modal.html.erb
Normal file
3
app/views/shared/_iframe_modal.html.erb
Normal file
|
@ -0,0 +1,3 @@
|
|||
<div id="iFrameModal" class="fixed top-0 left-0 right-0 z-[2000] w-full h-full bg-sn-white hidden">
|
||||
<iframe id="iFrameModalFrame" class="w-full h-full border-0"></iframe>
|
||||
</div>
|
|
@ -22,6 +22,14 @@
|
|||
<%= t('assets.file_preview.edit_in_marvinjs') %>
|
||||
</button>
|
||||
|
||||
<% elsif asset.blob.metadata["asset_type"] == 'gene_sequence' %>
|
||||
<button class="btn btn-light gene-sequence-edit-button"
|
||||
data-sequence-edit-url="<%= edit_gene_sequence_asset_path(asset) %>"
|
||||
>
|
||||
<span class="sn-icon sn-icon-sequence-editor"></span>
|
||||
<%= t('open_vector_editor.edit_sequence') %>
|
||||
</button>
|
||||
|
||||
<% elsif asset.editable_image? %>
|
||||
<button class="btn btn-light image-edit-button"
|
||||
data-image-id="<%= asset.id %>"
|
||||
|
@ -54,8 +62,8 @@
|
|||
<%= render partial: 'shared/pdf_viewer', locals: { asset: asset, report_document: false } %>
|
||||
<% else %>
|
||||
<%= image_tag asset.large_preview,
|
||||
class: 'asset-image',
|
||||
style: 'opacity: 0' %>
|
||||
class: class_names('asset-image', 'gene-sequence-asset': asset.blob&.metadata["asset_type"] == 'gene_sequence'),
|
||||
style: 'opacity: 0' %>
|
||||
<% end %>
|
||||
<% else %>
|
||||
<%= render partial: 'shared/file_preview/file_icon', locals: { asset: asset } %>
|
||||
|
|
|
@ -131,5 +131,11 @@ Rails.application.config.assets.precompile += %w(big.min.js)
|
|||
# JQuery related includes
|
||||
Rails.application.config.assets.precompile += %w(jquery_bundle.js)
|
||||
|
||||
# Separate icon font file
|
||||
Rails.application.config.assets.precompile += %w(sn_icon_font.css)
|
||||
|
||||
# Separate translations file
|
||||
Rails.application.config.assets.precompile += %w(i18n_bundle.js)
|
||||
|
||||
# Add stuff installed by yarn
|
||||
Rails.application.config.assets.paths << Rails.root.join('node_modules')
|
||||
|
|
|
@ -449,7 +449,15 @@ class Extends
|
|||
team_sharing_tasks_disabled: 245,
|
||||
task_link_sharing_enabled: 246,
|
||||
task_link_sharing_disabled: 247,
|
||||
shared_task_message_edited: 248
|
||||
shared_task_message_edited: 248,
|
||||
task_sequence_asset_added: 249,
|
||||
task_sequence_asset_edit_started: 250,
|
||||
task_sequence_asset_edit_finished: 251,
|
||||
task_sequence_asset_deleted: 252,
|
||||
protocol_sequence_asset_added: 253,
|
||||
protocol_sequence_asset_edit_started: 254,
|
||||
protocol_sequence_asset_edit_finished: 255,
|
||||
protocol_sequence_asset_deleted: 256
|
||||
}
|
||||
|
||||
ACTIVITY_GROUPS = {
|
||||
|
@ -458,7 +466,7 @@ class Extends
|
|||
task: [8, 58, 9, 59, *10..14, 35, 36, 37, 53, 54, *60..63, 138, 139, 140, 64, 66, 106, 126, 120, 132,
|
||||
*146..148, 166, 246, 247, 248],
|
||||
task_protocol: [15, 22, 16, 18, 19, 20, 21, 17, 38, 39, 100, 111, 45, 46, 47, 121, 124, 115, 118, 127, 130, 137,
|
||||
217, 168, 171, 177, 184, 185, 188, 189, *192..203, 222, 224, 225, 226, 236],
|
||||
217, 168, 171, 177, 184, 185, 188, 189, *192..203, 222, 224, 225, 226, 236, *249..252],
|
||||
task_inventory: [55, 56, 146, 147, 183],
|
||||
experiment: [*27..31, 57, 141, 165],
|
||||
reports: [48, 50, 49, 163, 164],
|
||||
|
@ -466,7 +474,7 @@ class Extends
|
|||
78, 96, 107, 113, 114, *133..136, 180, 181, 182],
|
||||
protocol_repository: [80, 103, 89, 87, 79, 90, 91, 88, 85, 86, 84, 81, 82,
|
||||
83, 101, 112, 123, 125, 117, 119, 129, 131, 170, 173, 179, 187, 186,
|
||||
190, 191, *204..215, 220, 221, 223, 227, 228, 229, *230..235, *237..240],
|
||||
190, 191, *204..215, 220, 221, 223, 227, 228, 229, *230..235, *237..240, *253..256],
|
||||
team: [92, 94, 93, 97, 104, 244, 245],
|
||||
label_templates: [*216..219]
|
||||
}
|
||||
|
|
|
@ -2696,9 +2696,9 @@ en:
|
|||
body_html: "The process of importing has started. Please wait..."
|
||||
not_yet_done:
|
||||
title: "Importing in progress"
|
||||
body_html: "The import is taking longer than expected. You'll get a notice in <i class=\"sn-icon sn-icon-notifications\"></i> Notifications when your protocol template is ready. You can close the window and continue with your work."
|
||||
body_html: "The import is taking longer than expected. You'll get a notice in Notifications when your protocol template is ready. You can close the window and continue with your work."
|
||||
done:
|
||||
title: "Importing completed"
|
||||
title: "Importing finished"
|
||||
body_html: 'The protocol has been successfully imported. You can access the draft of protocol template <a href="%{url}">here.</a>'
|
||||
failed:
|
||||
title: "Import failed"
|
||||
|
@ -3097,7 +3097,7 @@ en:
|
|||
drag_zone_title: "Upload a file from your PC"
|
||||
drag_zone_description: "You can also drag & drop files to here or into steps to upload"
|
||||
drag_zone_notification: "Drop files to add to step %{position}"
|
||||
or: "OR"
|
||||
or: "or create new"
|
||||
new:
|
||||
description: 'New'
|
||||
uploading: 'Uploading'
|
||||
|
@ -3277,7 +3277,7 @@ en:
|
|||
wopi_supported_table_formats_title: 'Only .xlsx, .xlsm, .xlsb, .ods file formats are supported for editing in Excel Online.'
|
||||
wopi_supported_presentation_formats_title: 'Only .pptx, ppsx, .odp file formats are supported for editing in PowerPoint Online.'
|
||||
create_wopi_file:
|
||||
button_text: 'Create an MS Office file'
|
||||
button_text: 'MS Office file'
|
||||
li_text: "Office file"
|
||||
modal_title: 'Create new Microsoft Office Online document'
|
||||
text_field_label: 'Document name'
|
||||
|
@ -3701,9 +3701,18 @@ en:
|
|||
new_li_button: "Chemical drawing"
|
||||
structure_placeholder: "Click here to enter Chemical Drawing name"
|
||||
modal_name_title: "Chemical Drawing name:"
|
||||
checmical_drawing: "Chemical drawings"
|
||||
chemical_drawing: "Chemical drawings"
|
||||
no_sketches_found: "No Sketches Found"
|
||||
|
||||
open_vector_editor:
|
||||
new_sequence: "Sequence"
|
||||
new_sequence_file: "New sequence"
|
||||
default_sequence_name: "New sequence"
|
||||
edit_sequence: "Edit in Sequence editor"
|
||||
sequence_name_placeholder: "Click here to enter sequence name"
|
||||
editor:
|
||||
tooltips:
|
||||
importTool: "Click or drag to import and view files (.fasta .gb .dna .json)"
|
||||
pdf_preview:
|
||||
fit_to_screen: 'Fit to screen'
|
||||
pages:
|
||||
|
|
|
@ -273,6 +273,14 @@ en:
|
|||
task_link_sharing_enabled_html: "%{user} enabled link sharing for task %{my_module}."
|
||||
task_link_sharing_disabled_html: "%{user} disabled link sharing for task %{my_module}."
|
||||
shared_task_message_edited_html: "%{user} edited message for shared task %{my_module}."
|
||||
task_sequence_asset_added_html: "%{user} created sequence <strong>%{asset_name}</strong> on protocol’s step <strong>%{step_position}</strong> <strong>%{step}</strong> on task <strong>%{my_module}</strong>."
|
||||
task_sequence_asset_edit_started_html: "%{user} edited sequence <strong>%{asset_name}</strong> on protocol’s step <strong>%{step_position}</strong> <strong>%{step}</strong> on task <strong>%{my_module}</strong>: editing started."
|
||||
task_sequence_asset_edit_finished_html: "%{user} edited sequence <strong>%{asset_name}</strong> on protocol’s step <strong>%{step_position}</strong> <strong>%{step}</strong> on task <strong>%{my_module}</strong>: editing finished."
|
||||
task_sequence_asset_deleted_html: "%{user} deleted sequence <strong>%{asset_name}</strong> on protocol’s step <strong>%{step_position}</strong> <strong>%{step}</strong> on task <strong>%{my_module}</strong>."
|
||||
protocol_sequence_asset_added_html: "%{user} created sequence <strong>%{asset_name}</strong> on protocol’s step <strong>%{step_position}</strong> <strong>%{step}</strong> in Protocol repository."
|
||||
protocol_sequence_asset_edit_started_html: "%{user} edited sequence <strong>%{asset_name}</strong> on protocol’s step <strong>%{step_position}</strong> <strong>%{step}</strong> in Protocol repository: editing started."
|
||||
protocol_sequence_asset_edit_finished_html: "%{user} edited sequence <strong>%{asset_name}</strong> on protocol’s step <strong>%{step_position}</strong> <strong>%{step}</strong> in Protocol repository: editing finished."
|
||||
protocol_sequence_asset_deleted_html: "%{user} deleted sequence <strong>%{asset_name}</strong> on protocol’s step <strong>%{step_position}</strong> <strong>%{step}</strong> in Protocol repository."
|
||||
activity_name:
|
||||
create_project: "Project created"
|
||||
rename_project: "Project renamed"
|
||||
|
@ -500,6 +508,14 @@ en:
|
|||
task_link_sharing_enabled: "Task link sharing enabled"
|
||||
task_link_sharing_disabled: "Task link sharing disabled"
|
||||
shared_task_message_edited: "Shared task message edited"
|
||||
task_sequence_asset_added: "Task sequence asset added"
|
||||
task_sequence_asset_edit_started: "Task sequence asset editing started"
|
||||
task_sequence_asset_edit_finished: "Task sequence asset editing finished"
|
||||
task_sequence_asset_deleted: "Task sequence asset deleted"
|
||||
protocol_sequence_asset_added: "Protocol sequence asset added"
|
||||
protocol_sequence_asset_edit_started: "Protocol sequence asset editing started"
|
||||
protocol_sequence_asset_edit_finished: "Protocol sequence asset editing finished"
|
||||
protocol_sequence_asset_deleted: "Protocol sequence asset deleted"
|
||||
activity_group:
|
||||
projects: "Projects"
|
||||
task_results: "Task results"
|
||||
|
|
|
@ -991,4 +991,6 @@ Rails.application.routes.draw do
|
|||
get 'wopi/files/:id', to: 'wopi#file_get_endpoint', as: 'wopi_rest_endpoint'
|
||||
post 'wopi/files/:id', to: 'wopi#post_file_endpoint'
|
||||
end
|
||||
|
||||
resources :gene_sequence_assets, only: %i(new create edit update)
|
||||
end
|
||||
|
|
|
@ -19,7 +19,10 @@ module.exports = {
|
|||
},
|
||||
colors: {
|
||||
transparent: 'transparent',
|
||||
current: 'currentColor'
|
||||
current: 'currentColor',
|
||||
'brand-warning': '#f0ad4e',
|
||||
'sn-blue': '#104DA9',
|
||||
'sn-grey': '#98a2b3'
|
||||
}
|
||||
}
|
||||
},
|
||||
|
|
|
@ -16,6 +16,7 @@ const entryList = {
|
|||
emoji_button: './app/javascript/packs/emoji_button.js',
|
||||
fontawesome: './app/javascript/packs/fontawesome.scss',
|
||||
prism: './app/javascript/packs/prism.js',
|
||||
open_vector_editor: './app/javascript/packs/open_vector_editor.js',
|
||||
tiny_mce: './app/javascript/packs/tiny_mce.js',
|
||||
tiny_mce_styles: './app/javascript/packs/tiny_mce_styles.scss',
|
||||
tui_image_editor: './app/javascript/packs/tui_image_editor.js',
|
||||
|
@ -36,8 +37,9 @@ const entryList = {
|
|||
vue_share_task_container: './app/javascript/packs/vue/share_task_container.js',
|
||||
vue_navigation_top_menu: './app/javascript/packs/vue/navigation/top_menu.js',
|
||||
vue_navigation_navigator: './app/javascript/packs/vue/navigation/navigator.js',
|
||||
vue_navigation_breadcrumbs: './app/javascript/packs/vue/navigation/breadcrumbs.js',
|
||||
vue_components_action_toolbar: './app/javascript/packs/vue/action_toolbar.js',
|
||||
vue_components_open_vector_editor: './app/javascript/packs/vue/open_vector_editor.js',
|
||||
vue_navigation_breadcrumbs: './app/javascript/packs/vue/navigation/breadcrumbs.js',
|
||||
vue_protocol_file_import_modal: './app/javascript/packs/vue/protocol_file_import_modal.js'
|
||||
}
|
||||
|
||||
|
|
|
@ -49,8 +49,10 @@
|
|||
"@babel/preset-env": "^7.20.2",
|
||||
"@fortawesome/fontawesome-free": "^5.2.0",
|
||||
"@joeattardi/emoji-button": "^4.6.2",
|
||||
"@teselagen/ove": "^0.3.15",
|
||||
"ajv": "6.12.6",
|
||||
"autoprefixer": "10.4.14",
|
||||
"axios": "^1.4.0",
|
||||
"babel-loader": "^8.2.5",
|
||||
"babel-plugin-macros": "^3.1.0",
|
||||
"bootstrap": "^3.4.1",
|
||||
|
|
10
public/images/icon_small/sequence-editor.svg
Normal file
10
public/images/icon_small/sequence-editor.svg
Normal file
|
@ -0,0 +1,10 @@
|
|||
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M11.4923 3.51517C10.0704 3.60025 8.69275 4.04129 7.48581 4.79777C6.27887 5.55426 5.28139 6.60192 4.58502 7.84452C3.88865 9.08711 3.51572 10.4848 3.50049 11.9091C3.48526 13.3335 3.82822 14.7388 4.49786 15.996" stroke="#1D2939" stroke-linecap="round"/>
|
||||
<path d="M11.5501 6.51843C10.6743 6.59031 9.8284 6.87102 9.08335 7.33704C8.3383 7.80307 7.71577 8.44084 7.26789 9.19694C6.82001 9.95304 6.55984 10.8055 6.50916 11.6828C6.45847 12.5601 6.61875 13.4368 6.97658 14.2395" stroke="#1D2939" stroke-linecap="round"/>
|
||||
<path d="M10.7142 14.144C11.0835 14.3654 11.5036 14.4878 11.934 14.4991C12.3644 14.5105 12.7904 14.4105 13.1708 14.2089" stroke="#1D2939" stroke-linecap="round"/>
|
||||
<path d="M11.5231 9.54591C11.0365 9.64048 10.5889 9.87759 10.2374 10.2271C9.88584 10.5766 9.64613 11.0227 9.54873 11.5088" stroke="#1D2939" stroke-linecap="round"/>
|
||||
<path d="M16.4528 15.2284C17.2432 14.1382 17.6062 12.7958 17.473 11.4558" stroke="#1D2939" stroke-linecap="round"/>
|
||||
<path d="M8.8669 16.5204C9.66189 17.0714 10.5881 17.403 11.5522 17.4817C12.5163 17.5605 13.4841 17.3836 14.358 16.9689" stroke="#1D2939" stroke-linecap="round"/>
|
||||
<path d="M19.4459 7.90013C18.6397 6.43599 17.4197 5.24203 15.9386 4.46756" stroke="#1D2939" stroke-linecap="round"/>
|
||||
<path d="M6.52764 18.5041C7.79803 19.573 9.35364 20.2464 11.0024 20.4413C12.6512 20.6361 14.3209 20.3439 15.8054 19.6006C17.29 18.8573 18.5244 17.6955 19.3562 16.2587C20.188 14.8219 20.5808 13.1729 20.4862 11.5154" stroke="#1D2939" stroke-linecap="round"/>
|
||||
</svg>
|
After Width: | Height: | Size: 1.6 KiB |
BIN
vendor/assets/stylesheets/fonts/SN-icon-font.eot
vendored
BIN
vendor/assets/stylesheets/fonts/SN-icon-font.eot
vendored
Binary file not shown.
26
vendor/assets/stylesheets/fonts/SN-icon-font.svg
vendored
26
vendor/assets/stylesheets/fonts/SN-icon-font.svg
vendored
|
@ -10,9 +10,9 @@
|
|||
"description": "SN icon font\nFont generated by IcoMoon.",
|
||||
"copyright": "SciNote LLC",
|
||||
"majorVersion": 1,
|
||||
"minorVersion": 12,
|
||||
"minorVersion": 14,
|
||||
"fontURL": "https://www.scinote.net",
|
||||
"version": "Version 1.12",
|
||||
"version": "Version 1.14",
|
||||
"fontId": "SN-icon-font",
|
||||
"psName": "SN-icon-font",
|
||||
"subFamily": "Regular",
|
||||
|
@ -64,19 +64,19 @@
|
|||
<glyph unicode="" glyph-name="resize" data-tags="resize" d="M725.76 618.24l-29.867-29.867 140.373-140.373h-648.533l140.8 140.8-29.867 29.867-192-192 192-192 29.867 29.867-140.8 140.8h648.533l-140.8-140.8 29.867-29.867 192 192-191.573 191.573z" />
|
||||
<glyph unicode="" glyph-name="reset-password" data-tags="reset-password" d="M512 768c-128.853 0-240.64-71.68-298.667-176.64v91.307h-42.667v-170.667h170.667v42.667h-98.987c48.213 100.693 150.613 170.667 269.653 170.667 164.693 0 298.667-133.973 298.667-298.667s-133.973-298.667-298.667-298.667c-134.827 0-249.173 90.027-286.293 213.333h-43.947c37.973-147.2 171.093-256 330.24-256 188.587 0 341.333 152.747 341.333 341.333s-152.747 341.333-341.333 341.333zM597.333 469.334v42.667c0 46.933-38.4 85.333-85.333 85.333s-85.333-38.4-85.333-85.333v-42.667c-23.467 0-42.667-19.2-42.667-42.667v-128c0-23.467 19.2-42.667 42.667-42.667h170.667c23.467 0 42.667 19.2 42.667 42.667v128c0 23.467-19.2 42.667-42.667 42.667zM512 554.667c23.467 0 42.667-19.2 42.667-42.667v-42.667h-85.333v42.667c0 23.467 19.2 42.667 42.667 42.667z" />
|
||||
<glyph unicode="" glyph-name="reports" data-tags="reports" d="M762.027 725.334c29.013 0 48.213-21.76 48.213-42.667v-512c0-20.907-18.773-42.667-48.213-42.667h-500.48c-29.013 0-48.213 21.76-48.213 42.667v512c0 20.907 18.773 42.667 48.213 42.667h500.907zM261.973 768c-50.347 0-90.88-38.4-90.88-85.333v-512c0-46.933 40.96-85.333 90.88-85.333h500.48c50.347 0 90.88 38.4 90.88 85.333v512c0 46.933-40.96 85.333-90.88 85.333h-500.907zM682.667 618.667c0 11.947 9.387 21.333 21.333 21.333s21.333-9.387 21.333-21.333v-384c0-11.947-9.387-21.333-21.333-21.333s-21.333 9.387-21.333 21.333v384zM554.667 362.667c0 11.947 9.387 21.333 21.333 21.333s21.333-9.387 21.333-21.333v-128c0-11.947-9.387-21.333-21.333-21.333s-21.333 9.387-21.333 21.333v128zM426.667 533.334c0 11.947 9.387 21.333 21.333 21.333s21.333-9.387 21.333-21.333v-298.667c0-11.947-9.387-21.333-21.333-21.333s-21.333 9.387-21.333 21.333v298.667zM298.667 448c0 11.947 9.387 21.333 21.333 21.333s21.333-9.387 21.333-21.333v-213.333c0-11.947-9.387-21.333-21.333-21.333s-21.333 9.387-21.333 21.333v213.333z" />
|
||||
<glyph unicode="" glyph-name="relationships" data-tags="relationships" d="M810.667 490.667v298.667h-298.667v-128h-256v128h-42.667v-597.333h298.667v-128h298.667v298.667h-298.667v-128h-256v384h256v-128h298.667zM554.667 320h213.333v-213.333h-213.333v213.333zM554.667 746.667h213.333v-213.333h-213.333v213.333z" />
|
||||
<glyph unicode="" glyph-name="relationships-solid" data-tags="relationships-solid" d="M810.667 490.667v298.667h-298.667v-128h-256v128h-42.667v-597.333h298.667v-128h298.667v298.667h-298.667v-128h-256v384h256v-128h298.667z" />
|
||||
<glyph unicode="" glyph-name="navigator-light" data-tags="relationships" d="M810.667 490.667v298.667h-298.667v-128h-256v128h-42.667v-597.333h298.667v-128h298.667v298.667h-298.667v-128h-256v384h256v-128h298.667zM554.667 320h213.333v-213.333h-213.333v213.333zM554.667 746.667h213.333v-213.333h-213.333v213.333z" />
|
||||
<glyph unicode="" glyph-name="navigator" data-tags="relationships-solid" d="M810.667 490.667v298.667h-298.667v-128h-256v128h-42.667v-597.333h298.667v-128h298.667v298.667h-298.667v-128h-256v384h256v-128h298.667z" />
|
||||
<glyph unicode="" glyph-name="read-more" data-tags="read-more" d="M432.213 570.454c-4.267-4.267-6.4-9.813-5.547-16.213s3.84-12.373 9.387-17.92l88.32-88.32h-353.707v-42.667h353.707l-87.893-87.893c-5.547-5.547-8.533-11.52-9.387-17.92s0.853-11.947 5.547-16.213c4.267-4.267 9.813-6.4 16.213-5.547s12.373 3.84 17.92 9.387l125.44 125.44s2.987 4.267 3.84 6.4c0.853 2.133 1.28 4.693 1.28 7.68s0 5.12-1.28 7.253c-0.853 2.56-2.133 4.693-3.84 6.4l-125.867 125.867c-5.547 5.547-11.52 8.533-17.92 9.387s-11.947-0.853-16.213-5.547v0zM640 576h213.333v-42.667h-213.333v42.667zM725.333 448h128v-42.667h-128v42.667zM640 320h213.333v-42.667h-213.333v42.667z" />
|
||||
<glyph unicode="" glyph-name="protocols-templates" data-tags="protocols-templates" d="M512 45.227c-86.187 24.747-157.44 76.8-213.76 155.307s-84.907 166.827-84.907 264.96v230.4l298.667 112.213 298.667-112.213v-230.4c0-98.133-28.16-186.453-84.907-264.96-56.32-78.507-128-130.133-213.76-155.307zM512 90.027c73.813 23.467 135.253 70.4 183.467 140.8s72.533 148.48 72.533 234.667v201.813l-256 94.72-256-94.72v-201.813c0-86.187 24.32-164.267 72.533-234.667s109.653-117.333 183.467-140.8zM640 555.094h-256v42.667h256v-42.667zM640 427.094h-256v42.667h256v-42.667zM640 299.094h-256v42.667h256v-42.667z" />
|
||||
<glyph unicode="" glyph-name="projects" data-tags="projects" d="M853.333 42.667h-256c-23.467 0-42.667 19.2-42.667 42.667v256c0 23.467 19.2 42.667 42.667 42.667h256c23.467 0 42.667-19.2 42.667-42.667v-256c0-23.467-19.2-42.667-42.667-42.667zM597.333 341.334v-256h256v256h-256zM299.093 42.667c-94.293 0-170.667 76.373-170.667 170.667s76.373 170.667 170.667 170.667 170.667-76.373 170.667-170.667-76.373-170.667-170.667-170.667zM299.093 341.334c-70.4 0-128-57.6-128-128s57.6-128 128-128 128 57.6 128 128-57.6 128-128 128zM725.76 469.334c-94.293 0-170.667 76.373-170.667 170.667s76.373 170.667 170.667 170.667 170.667-76.373 170.667-170.667-76.373-170.667-170.667-170.667zM725.76 768c-70.4 0-128-57.6-128-128s57.6-128 128-128 128 57.6 128 128-57.6 128-128 128zM427.093 469.334h-256c-23.467 0-42.667 19.2-42.667 42.667v256c0 23.467 19.2 42.667 42.667 42.667h256c23.467 0 42.667-19.2 42.667-42.667v-256c0-23.467-19.2-42.667-42.667-42.667zM171.093 768v-256h256v256h-256z" />
|
||||
<glyph unicode="" glyph-name="project-member-access" data-tags="project-member-access" d="M170.667 85.334v42.667h85.333v570.88c0 20.053 6.4 36.267 19.627 49.493s29.867 19.627 49.493 19.627h373.333c20.053 0 36.267-6.4 49.493-19.627s19.627-29.867 19.627-49.493v-570.88h85.333v-42.667h-682.24zM298.667 128h426.667v570.88c0 7.253-2.56 13.227-8.107 18.773-5.12 5.547-11.52 8.107-18.773 8.107h-373.333c-7.253 0-13.227-2.56-18.773-8.107-5.547-5.12-8.107-11.52-8.107-18.773v-570.88zM456.107 397.227c-8.533-8.533-18.347-13.227-29.44-13.227-11.947 0-22.187 4.267-30.293 13.227-8.107 8.533-12.373 18.347-12.373 29.44s4.267 20.907 12.373 29.44c8.107 8.533 18.347 13.227 30.293 13.227 11.093 0 20.907-4.267 29.44-13.227 8.533-8.533 13.227-18.773 13.227-29.44s-4.267-20.907-13.227-29.44z" />
|
||||
<glyph unicode="" glyph-name="printer" data-tags="printer" d="M874.667 533.334c0 23.467-19.2 42.667-42.667 42.667h-85.333v170.667h-469.333v-170.667h-85.333c-23.467 0-42.667-19.2-42.667-42.667v-256h128v-170.667h469.333v170.667h128v256zM320 149.334v213.333h384v-213.333h-384zM277.333 405.334v-85.333h-85.333v213.333h640v-213.333h-85.333v85.333h-469.333zM320 704h384v-128h-384v128z" />
|
||||
<glyph unicode="" glyph-name="open-show" data-tags="open-show" d="M512 298.667l-213.333 225.28 28.16 30.72 185.173-195.413 185.173 195.413 28.16-30.72-213.333-225.28z" />
|
||||
<glyph unicode="" glyph-name="down" data-tags="open-show" d="M512 298.667l-213.333 225.28 28.16 30.72 185.173-195.413 185.173 195.413 28.16-30.72-213.333-225.28z" />
|
||||
<glyph unicode="" glyph-name="notifications" data-tags="notifications" d="M512 768c-35.413 0-64-28.587-64-64v-21.333h128v21.333c0 35.413-28.587 64-64 64zM746.667 213.334v281.173c0 55.467-17.92 104.107-54.613 145.92-34.133 39.68-77.653 64.427-128.853 75.947-41.387 8.533-78.507 4.693-100.693 0.427-52.48-11.093-96-36.267-130.987-76.373-36.267-41.813-54.613-90.453-54.613-145.92v-281.173h-84.907v-42.667h640v42.667h-85.333zM704 213.334h-384v281.173c0 52.053 18.773 96 55.893 132.267 37.547 36.267 82.773 54.613 136.107 54.613s98.56-18.347 136.107-54.613c37.12-36.267 55.893-80.64 55.893-132.267v-281.173zM467.2 97.28c12.8-8.107 27.733-11.947 44.8-11.947 18.347 0 33.707 3.84 45.653 11.947s18.347 18.347 18.347 30.72h-128c0-12.373 6.4-22.613 19.2-30.72z" />
|
||||
<glyph unicode="" glyph-name="notes" data-tags="notes" d="M282.453 42.667c-20.053 0-36.267 6.4-49.493 19.627s-19.627 29.867-19.627 49.493v629.76c0 20.053 6.4 36.267 19.627 49.493s29.867 19.627 49.493 19.627h336.213l192-192v-506.88c0-20.053-6.4-36.267-19.627-49.493s-29.867-19.627-49.493-19.627h-459.093zM597.333 597.334v170.667h-314.88c-7.253 0-13.227-2.56-18.773-8.107-5.547-5.12-8.107-11.52-8.107-18.773v-629.333c0-7.253 2.56-13.227 8.107-18.773 5.12-5.547 11.52-8.107 18.773-8.107h458.667c7.253 0 13.227 2.56 18.773 8.107 5.547 5.12 8.107 11.52 8.107 18.773v485.547h-170.667zM682.667 256v-42.667h-341.333v42.667h341.333zM682.667 384v-42.667h-341.333v42.667h341.333zM512 554.667v-42.667h-170.667v42.667h170.667z" />
|
||||
<glyph unicode="" glyph-name="new-task" data-tags="new-task" d="M490.667 149.334v554.667h42.667v-554.667h-42.667zM789.333 405.334h-554.667v42.667h554.667v-42.667z" />
|
||||
<glyph unicode="" glyph-name="navigate-next" data-tags="navigate-next" d="M406.187 667.734l-29.867-29.867 211.627-211.627-211.627-211.2 29.867-29.867 241.493 241.067-241.493 241.493z" />
|
||||
<glyph unicode="" glyph-name="navigate-before" data-tags="navigate-before" d="M617.813 667.734l29.867-29.867-211.627-211.627 211.627-211.2-29.867-29.867-241.493 241.067 241.493 241.493z" />
|
||||
<glyph unicode="" glyph-name="right" data-tags="navigate-next" d="M406.187 667.734l-29.867-29.867 211.627-211.627-211.627-211.2 29.867-29.867 241.493 241.067-241.493 241.493z" />
|
||||
<glyph unicode="" glyph-name="left" data-tags="navigate-before" d="M617.813 667.734l29.867-29.867-211.627-211.627 211.627-211.2-29.867-29.867-241.493 241.067 241.493 241.493z" />
|
||||
<glyph unicode="" glyph-name="move" data-tags="move" d="M309.333 106.667l-29.44 29.44 84.053 84.053c-76.8 1.28-142.507 26.453-197.12 75.947-54.187 49.493-81.493 111.787-81.493 187.307s25.6 135.68 76.373 186.88c51.2 50.773 113.493 76.373 186.88 76.373h101.547v-40.533h-101.547c-61.44 0-113.92-21.76-157.44-65.28s-65.28-96-65.28-157.44 22.187-114.773 66.56-155.307c44.373-40.96 101.547-63.147 171.947-67.413l-84.053 84.053 29.44 29.44 132.693-133.547-132.693-133.547zM896 704v-170.667h-256v170.667h256zM640 746.667c-23.467 0-42.667-19.2-42.667-42.667v-170.667c0-23.467 19.2-42.667 42.667-42.667h256c23.467 0 42.667 19.2 42.667 42.667v170.667c0 23.467-19.2 42.667-42.667 42.667h-256zM597.333 362.667c0 23.467 19.2 42.667 42.667 42.667h256c23.467 0 42.667-19.2 42.667-42.667v-170.667c0-23.467-19.2-42.667-42.667-42.667h-256c-23.467 0-42.667 19.2-42.667 42.667v170.667z" />
|
||||
<glyph unicode="" glyph-name="more-vert" data-tags="more-vert" d="M542.293 140.8c8.107 8.533 12.373 18.347 12.373 29.867 0 11.947-4.267 22.187-12.373 30.293s-18.347 12.373-30.293 12.373-22.187-4.267-30.293-12.373c-8.107-8.107-12.373-18.347-12.373-30.293 0-11.52 4.267-21.333 12.373-29.867s18.347-12.8 30.293-12.8 22.187 4.267 30.293 12.8zM542.293 396.8c8.107 8.533 12.373 18.347 12.373 29.867 0 11.947-4.267 22.187-12.373 30.293s-18.347 12.373-30.293 12.373-22.187-4.267-30.293-12.373-12.373-18.347-12.373-30.293c0-11.52 4.267-21.333 12.373-29.867s18.347-12.8 30.293-12.8 22.187 4.267 30.293 12.8zM542.293 652.8c8.107 8.533 12.373 18.347 12.373 29.867 0 11.947-4.267 22.187-12.373 30.293s-18.347 12.373-30.293 12.373-22.187-4.267-30.293-12.373c-8.107-8.107-12.373-18.347-12.373-30.293 0-11.52 4.267-21.333 12.373-29.867s18.347-12.8 30.293-12.8 22.187 4.267 30.293 12.8z" />
|
||||
<glyph unicode="" glyph-name="more-hori" data-tags="more-hori" d="M226.133 396.374c8.533-8.107 18.347-12.373 29.867-12.373 11.947 0 22.187 4.267 30.293 12.373s12.373 18.347 12.373 30.293-4.267 22.187-12.373 30.293c-8.107 8.107-18.347 12.373-30.293 12.373-11.52 0-21.333-4.267-29.867-12.373s-12.8-18.347-12.8-30.293 4.267-22.187 12.8-30.293zM482.133 396.374c8.533-8.107 18.347-12.373 29.867-12.373 11.947 0 22.187 4.267 30.293 12.373s12.373 18.347 12.373 30.293-4.267 22.187-12.373 30.293-18.347 12.373-30.293 12.373c-11.52 0-21.333-4.267-29.867-12.373s-12.8-18.347-12.8-30.293 4.267-22.187 12.8-30.293zM738.133 396.374c8.533-8.107 18.347-12.373 29.867-12.373 11.947 0 22.187 4.267 30.293 12.373s12.373 18.347 12.373 30.293-4.267 22.187-12.373 30.293c-8.107 8.107-18.347 12.373-30.293 12.373-11.52 0-21.333-4.267-29.867-12.373s-12.8-18.347-12.8-30.293 4.267-22.187 12.8-30.293z" />
|
||||
|
@ -93,7 +93,7 @@
|
|||
<glyph unicode="" glyph-name="import" data-tags="import" d="M533.333 21.334v472.747l89.6-89.6 29.867 30.72-140.8 140.8-140.8-140.8 29.867-30.72 89.6 89.6v-472.747h42.667zM789.333 277.334h-128v42.667h117.333c5.973 0 10.667 4.693 10.667 10.667v448c0 5.973-4.693 10.667-10.667 10.667h-533.333c-5.973 0-10.667-4.693-10.667-10.667v-448c0-5.973 4.693-10.667 10.667-10.667h117.333v-42.667h-128c-23.467 0-42.667 19.2-42.667 42.667v469.333c0 23.467 19.2 42.667 42.667 42.667h554.667c23.467 0 42.667-19.2 42.667-42.667v-469.333c0-23.467-19.2-42.667-42.667-42.667z" />
|
||||
<glyph unicode="" glyph-name="help" data-tags="help" d="M512 42.667c-53.333 0-103.253 10.24-149.76 30.293-46.507 20.48-87.040 47.787-121.6 82.347s-61.867 75.093-82.347 121.6c-20.053 46.507-30.293 96.427-30.293 149.76s10.24 103.253 30.293 149.76c20.48 46.507 47.787 87.040 82.347 121.6s75.093 61.867 121.6 82.347c46.507 20.053 96.427 30.293 149.76 30.293s103.253-10.24 149.76-30.293c46.507-20.48 87.040-47.787 121.6-82.347s61.867-75.093 81.92-121.6c20.053-46.507 30.293-96.427 30.293-149.76s-10.24-103.253-30.293-149.76c-20.48-46.507-47.787-87.040-81.92-121.6s-75.093-61.867-121.6-82.347c-46.507-20.053-96.427-30.293-149.76-30.293zM512 85.334c95.147 0 175.787 32.853 241.92 99.413 66.133 66.133 99.413 146.773 99.413 241.92s-32.853 175.787-99.413 242.347c-66.133 66.133-146.773 98.987-241.92 98.987s-175.787-33.28-242.347-98.987c-66.133-66.133-98.987-146.773-98.987-242.347s33.28-175.787 98.987-241.92c66.133-66.133 146.773-99.413 242.347-99.413zM512 341.334h-42.667c3.413 25.173 9.387 32.427 13.653 42.667 7.68 15.787 36.267 45.653 61.013 68.267 12.8 11.947 23.040 23.893 31.147 34.987s11.52 24.32 11.52 39.68c0 18.347-6.4 34.987-19.2 49.92s-33.28 22.613-61.013 22.613c-23.467 0-41.813-5.973-54.187-17.493-12.8-11.947-22.613-25.6-29.867-40.96l-38.4 16.213c9.813 22.187 25.6 41.387 46.933 58.027s47.36 25.173 77.653 25.173 59.733-9.813 83.627-29.867c23.893-20.053 35.84-46.933 35.84-81.067 0-20.053-4.693-37.547-14.080-52.053-9.387-14.933-23.467-32-42.667-51.2-18.347-17.92-30.72-31.573-40.533-41.813-8.107-9.813-18.347-20.48-19.2-42.667zM520.533 225.707c-8.533-8.107-18.773-12.373-30.293-12.373s-21.76 4.267-29.867 12.373-12.373 17.92-12.373 29.867c0 12.8 4.267 23.040 12.373 31.147s17.92 12.373 29.867 12.373 21.76-4.267 30.293-12.373c8.533-8.107 12.8-18.347 12.8-31.147 0-11.947-4.267-21.76-12.8-29.867z" />
|
||||
<glyph unicode="" glyph-name="help-s" data-tags="help-s" d="M514.987 240.64c7.253 0 13.653 2.56 18.773 7.68s7.68 11.52 7.68 18.773-2.56 13.653-7.68 18.773c-5.12 5.12-11.52 7.68-18.773 7.68s-13.653-2.56-18.773-7.68c-5.12-5.12-7.68-11.52-7.68-18.773s2.56-13.653 7.68-18.773c5.12-5.12 11.52-7.68 18.773-7.68zM496.64 357.547h33.28c0.853 17.92 3.413 30.72 7.68 37.973 4.267 7.68 11.093 16.213 20.48 26.027 21.333 20.48 35.413 37.547 42.24 50.347s10.24 26.453 10.24 40.533c0 27.307-8.96 50.773-26.453 69.973s-40.533 29.013-68.693 29.013c-22.187 0-42.667-5.973-61.44-18.347-19.2-11.947-32.853-28.587-41.813-48.64l32-14.507c8.107 18.773 17.92 31.573 29.867 38.4s24.747 9.813 38.827 9.813c20.48 0 37.12-5.973 48.64-17.493 11.947-11.947 17.92-26.88 17.92-44.8 0-14.080-4.267-26.027-13.227-36.267-8.533-9.813-18.773-20.48-29.867-31.573-15.36-14.933-25.6-29.013-31.147-42.667s-8.107-29.44-8.107-48.213zM512.427 120.747c-41.813 0-81.493 8.107-118.613 23.893s-69.547 37.973-97.707 65.707c-27.733 27.733-49.92 60.587-65.707 97.707s-23.893 76.8-23.893 118.613 8.107 82.347 23.893 119.040c15.787 36.693 37.973 69.12 65.707 97.28 27.733 27.733 60.587 49.92 97.707 65.707s76.8 23.893 118.613 23.893 82.347-8.107 119.040-23.893 69.12-37.973 97.28-65.707c27.733-27.733 49.92-60.16 65.707-97.28 15.787-36.693 23.893-76.373 23.893-119.040s-8.107-81.493-23.893-118.613c-15.787-37.12-37.973-69.547-65.707-97.707-27.733-27.733-60.16-49.92-97.28-65.707-36.693-15.787-76.373-23.893-119.040-23.893zM512.427 149.334c77.227 0 142.507 26.88 196.267 81.067 53.76 53.76 81.067 119.467 81.067 196.267s-26.88 142.507-81.067 196.267c-53.76 53.76-119.467 81.067-196.267 81.067s-142.507-26.88-196.267-81.067c-53.76-53.76-81.067-119.467-81.067-196.267s26.88-142.507 81.067-196.267c53.76-53.76 119.467-81.067 196.267-81.067z" />
|
||||
<glyph unicode="" glyph-name="hamburger-menu" data-tags="hamburger-menu" d="M853.333 597.334h-682.667v-42.667h682.667v42.667zM853.333 298.667h-682.667v-42.667h682.667v42.667z" />
|
||||
<glyph unicode="" glyph-name="hamburger" data-tags="hamburger-menu" d="M853.333 597.334h-682.667v-42.667h682.667v42.667zM853.333 298.667h-682.667v-42.667h682.667v42.667z" />
|
||||
<glyph unicode="" glyph-name="hamburger-big" data-tags="hamburger-big" d="M597.333 661.334h-426.667v-42.667h426.667v42.667zM853.333 447.574h-682.667v-42.667h682.667v42.667zM597.333 234.667h-426.667v-42.667h426.667v42.667z" />
|
||||
<glyph unicode="" glyph-name="grid-view" data-tags="grid-view" d="M170.667 469.334v256c0 23.467 19.2 42.667 42.667 42.667h256v-298.667h-298.667zM213.333 85.334c-23.467 0-42.667 19.2-42.667 42.667v256h298.667v-298.667h-256zM554.667 469.334v298.667h256c23.467 0 42.667-19.2 42.667-42.667v-256h-298.667zM554.667 85.334v298.667h298.667v-256c0-23.467-19.2-42.667-42.667-42.667h-256zM213.333 512h213.333v213.333h-213.333v-213.333zM597.333 512h213.333v213.333h-213.333v-213.333zM597.333 128h213.333v213.333h-213.333v-213.333zM213.333 128h213.333v213.333h-213.333v-213.333z" />
|
||||
<glyph unicode="" glyph-name="folder" data-tags="folder" d="M876.8 641.707c-13.227 13.227-29.867 19.627-49.493 19.627h-314.027l-42.667 42.667h-273.067c-19.627 0-36.267-6.4-49.493-19.627s-19.627-29.44-19.627-48.64v-417.28c0-20.053 6.4-36.267 19.627-49.493s29.867-19.627 49.493-19.627h629.333c20.053 0 36.267 6.4 49.493 19.627s19.627 29.867 19.627 49.493v373.76c0 20.053-6.4 36.267-19.627 49.493h0.427zM853.76 218.88c0-7.68-2.56-14.080-7.253-19.2s-11.52-7.253-19.2-7.253h-630.187c-7.68 0-14.080 2.56-19.2 7.253-5.12 5.12-7.253 11.52-7.253 19.2v416.853c0 7.253 2.56 13.227 7.253 17.92s11.52 7.68 19.2 7.68h255.147l42.667-42.667h331.947c7.68 0 14.080-2.56 19.2-7.253s7.253-11.52 7.253-19.2v-373.76z" />
|
||||
|
@ -117,9 +117,9 @@
|
|||
<glyph unicode="" glyph-name="courses" data-tags="courses" d="M506.027 745.387c2.987 1.707 6.827 1.707 9.813 0l368.64-214.613c7.253-3.84 10.667-11.093 10.667-18.773v-170.667c0-11.947-8.96-21.333-20.053-21.333s-20.053 9.387-20.053 21.333v134.4l-80.64-46.933v-172.8c0-8.107-4.267-15.787-11.093-19.2l-242.347-128c-5.547-2.987-12.373-2.987-17.92 0l-242.347 128c-6.827 3.84-11.093 11.093-11.093 19.2v172.8l-110.933 64.427c-14.080 8.107-14.080 29.44 0 37.547l368.64 214.613zM190.72 512l321.707-187.307 321.707 187.307-321.707 187.307-321.707-187.307zM734.72 405.334l-217.6-126.72c-2.987-1.707-6.827-1.707-9.813 0l-217.6 126.72v-136.107l222.293-117.333 222.293 117.333v136.107z" />
|
||||
<glyph unicode="" glyph-name="comments" data-tags="comments" d="M128 62.294v659.2c0 20.053 6.4 36.267 19.627 49.493s29.867 19.627 49.493 19.627h629.333c20.053 0 36.267-6.4 49.493-19.627s19.627-29.867 19.627-49.493v-458.667c0-20.053-6.4-36.267-19.627-49.493s-29.867-19.627-49.493-19.627h-567.467l-130.987-131.413zM170.667 165.974l70.4 70.4h585.387c7.68 0 14.080 2.56 19.2 7.68s7.253 11.52 7.253 19.2v458.24c0 7.68-2.56 14.080-7.253 19.2-5.12 5.12-11.52 7.68-19.2 7.68h-629.333c-7.68 0-14.080-2.56-19.2-7.68s-7.68-11.52-7.68-19.2v-555.52zM170.667 721.494v0zM725.333 535.040h-426.667v42.667h426.667v-42.667zM725.333 407.040h-426.667v42.667h426.667v-42.667z" />
|
||||
<glyph unicode="" glyph-name="collapse" data-tags="collapse" d="M810.667 426.667v42.667h-256v256h-42.667v-298.667h298.667zM823.040 768l-283.733-283.733 30.293-30.293 283.733 283.733-30.293 30.293zM213.333 426.667v-42.667h256v-256h42.667v298.667h-298.667zM453.973 399.36l-283.733-283.733 30.293-30.293 283.733 283.733-30.293 30.293z" />
|
||||
<glyph unicode="" glyph-name="close-remove" data-tags="close-remove" d="M273.067 157.867l-29.867 29.867 238.933 238.933-238.933 238.933 29.867 29.867 238.933-238.933 238.933 238.933 29.867-29.867-238.933-238.933 238.933-238.933-29.867-29.867-238.933 238.933-238.933-238.933z" />
|
||||
<glyph unicode="" glyph-name="close-remove-small" data-tags="close-remove-small" d="M331.093 637.867l-30.293-30.293 392.107-392.107 30.293 30.293-392.107 392.107zM300.8 245.76l30.293-30.293 392.107 392.107-30.293 30.293-392.107-392.107z" />
|
||||
<glyph unicode="" glyph-name="close-hide" data-tags="close-hide" d="M512 554.667l213.333-225.28-28.16-30.72-185.173 195.413-185.173-195.413-28.16 30.72 213.333 225.28z" />
|
||||
<glyph unicode="" glyph-name="close" data-tags="close-remove" d="M273.067 157.867l-29.867 29.867 238.933 238.933-238.933 238.933 29.867 29.867 238.933-238.933 238.933 238.933 29.867-29.867-238.933-238.933 238.933-238.933-29.867-29.867-238.933 238.933-238.933-238.933z" />
|
||||
<glyph unicode="" glyph-name="close-small" data-tags="close-remove-small" d="M331.093 637.867l-30.293-30.293 392.107-392.107 30.293 30.293-392.107 392.107zM300.8 245.76l30.293-30.293 392.107 392.107-30.293 30.293-392.107-392.107z" />
|
||||
<glyph unicode="" glyph-name="up" data-tags="close-hide" d="M512 554.667l213.333-225.28-28.16-30.72-185.173 195.413-185.173-195.413-28.16 30.72 213.333 225.28z" />
|
||||
<glyph unicode="" glyph-name="checkllist" data-tags="checkllist" d="M281.6 541.44l-68.267 68.267 30.293 30.293 37.973-38.4 123.733 123.733 30.293-30.293-154.027-153.6zM810.667 640h-298.667v-42.667h298.667v42.667zM810.667 256h-298.667v-42.667h298.667v42.667zM324.267 298.667c35.413 0 64-28.587 64-64s-28.587-64-64-64-64 28.587-64 64 28.587 64 64 64zM324.267 341.334c-58.88 0-106.667-47.787-106.667-106.667s47.787-106.667 106.667-106.667 106.667 47.787 106.667 106.667-47.787 106.667-106.667 106.667z" />
|
||||
<glyph unicode="" glyph-name="check" data-tags="check" d="M407.467 200.96l-212.053 211.2 30.72 31.147 181.333-181.333 390.4 390.4 30.72-30.72-421.547-420.267z" />
|
||||
<glyph unicode="" glyph-name="card-view" data-tags="card-view" d="M832 704h-640c-23.467 0-42.667-19.2-42.667-42.667v-469.333c0-23.467 19.2-42.667 42.667-42.667h640c23.467 0 42.667 19.2 42.667 42.667v469.333c0 23.467-19.2 42.667-42.667 42.667zM661.333 661.334v-128h-128v128h128zM533.333 490.667h128v-128h-128v128zM490.667 362.667h-128v128h128v-128zM490.667 661.334v-128h-128v128h128zM192 661.334h128v-128h-128v128zM192 490.667h128v-128h-128v128zM192 192v128h128v-128h-128zM362.667 192v128h128v-128h-128zM533.333 192v128h128v-128h-128zM832 192h-128v128h128v-128zM832 362.667h-128v128h128v-128zM832 533.334h-128v128h128v-128z" />
|
||||
|
@ -146,4 +146,8 @@
|
|||
<glyph unicode="" glyph-name="file-pdf" data-tags="file-pdf" d="M234.667 64c-29.867 0-55.111 10.313-75.733 30.933s-30.933 45.867-30.933 75.733v554.667c0 29.867 10.311 55.111 30.933 75.733s45.867 30.933 75.733 30.933h554.667c29.867 0 55.113-10.311 75.733-30.933s30.933-45.867 30.933-75.733v-554.667c0-29.867-10.313-55.113-30.933-75.733s-45.867-30.933-75.733-30.933h-554.667zM234.667 106.667h554.667c17.779 0 32.883 6.229 45.312 18.688 12.459 12.429 18.688 27.533 18.688 45.312v554.667c0 17.778-6.229 32.882-18.688 45.312-12.429 12.459-27.533 18.688-45.312 18.688h-554.667c-17.778 0-32.882-6.229-45.312-18.688-12.459-12.43-18.688-27.534-18.688-45.312v-554.667c0-17.779 6.229-32.883 18.688-45.312 12.43-12.459 27.534-18.688 45.312-18.688zM256 330.308v203.025h76.134c15.597 0 28.683-2.91 39.257-8.725 10.64-5.815 18.67-13.811 24.089-23.987 5.486-10.112 8.228-21.611 8.228-34.5 0-13.018-2.743-24.585-8.228-34.697s-13.581-18.074-24.288-23.889c-10.706-5.751-23.891-8.627-39.554-8.627h-50.459v30.238h45.502c9.12 0 16.588 1.583 22.404 4.757 5.816 3.17 10.112 7.535 12.887 13.086 2.842 5.551 4.263 11.93 4.263 19.132s-1.421 13.547-4.263 19.034c-2.776 5.487-7.104 9.749-12.986 12.787-5.816 3.106-13.317 4.659-22.503 4.659h-33.705v-172.292h-36.779zM504.452 330.308h-68.796v203.025h70.187c20.156 0 37.47-4.066 51.942-12.194 14.541-8.064 25.711-19.661 33.51-34.795 7.795-15.134 11.695-33.242 11.695-54.327 0-21.146-3.93-39.322-11.797-54.524-7.795-15.198-19.063-26.863-33.805-34.991-14.669-8.128-32.316-12.194-52.937-12.194zM472.435 362.129h30.234c14.144 0 25.941 2.577 35.392 7.731 9.451 5.222 16.555 12.988 21.312 23.3 4.757 10.372 7.138 23.326 7.138 38.857s-2.381 28.42-7.138 38.665c-4.757 10.308-11.797 18.010-21.116 23.095-9.25 5.158-20.753 7.735-34.496 7.735h-31.326v-139.383zM637.935 330.308v203.025h130.065v-30.831h-93.286v-55.117h84.365v-30.831h-84.365v-86.246h-36.779z" />
|
||||
<glyph unicode="" glyph-name="save" data-tags="save" d="M707.2 789.125h-467.627c-19.627 0-35.84-6.4-49.067-19.627s-19.627-29.44-19.627-49.067v-544.854c0-19.627 6.4-35.84 19.627-49.067s29.44-19.627 49.067-19.627h544.853c19.627 0 35.84 6.4 49.067 19.627s19.627 29.44 19.627 49.067v467.628l-145.92 145.92zM298.453 746.458h298.667v-106.667c0-11.947-9.387-21.333-21.333-21.333h-256c-11.947 0-21.333 9.387-21.333 21.333v106.667zM810.453 175.578c0-7.68-2.56-14.080-7.253-18.773-5.12-5.12-11.093-7.253-18.773-7.253h-544.853c-7.68 0-14.080 2.56-18.773 7.253-5.12 5.12-7.253 11.093-7.253 18.773v544.428c0 7.68 2.56 14.080 7.253 18.773 5.12 5.12 11.093 7.253 18.773 7.253h16.213v-127.573c0-23.467 19.2-42.667 42.667-42.667h298.667c23.467 0 42.667 19.2 42.667 42.667v128h49.067l121.6-121.6v-449.281zM511.787 447.791c-23.467 0-43.52-8.533-60.16-25.173s-25.173-36.693-25.173-60.16c0-23.467 8.533-43.52 25.173-60.16s36.693-25.173 60.16-25.173c23.467 0 43.52 8.533 60.16 25.173s25.173 36.693 25.173 60.16c0 23.467-8.533 43.52-25.173 60.16s-36.693 25.173-60.16 25.173z" />
|
||||
<glyph unicode="" glyph-name="archived" data-tags="archived" d="M240 106.667c-19.911 0-36.437 6.571-49.579 19.712-13.17 13.171-19.755 29.709-19.755 49.621v457.6c0 7.111 0.882 13.696 2.645 19.755 1.792 6.030 4.466 11.534 8.021 16.512l53.333 62.933c4.978 4.978 10.667 8.533 17.067 10.667s13.155 3.2 20.267 3.2h480c7.113 0 13.867-0.711 20.267-2.133s12.087-5.333 17.067-11.733l51.2-62.933c4.979-4.978 8.363-10.482 10.155-16.512 1.762-6.059 2.645-12.643 2.645-19.755v-457.6c0-19.913-6.571-36.45-19.712-49.621-13.171-13.141-29.709-19.712-49.621-19.712h-544zM230.4 661.333h563.2l-36.267 42.667h-490.667l-36.267-42.667zM213.333 618.667v-442.667c0-7.113 2.674-13.325 8.021-18.645 5.319-5.346 11.534-8.021 18.645-8.021h544c7.113 0 13.325 2.675 18.645 8.021 5.346 5.321 8.021 11.533 8.021 18.645v442.667h-597.333zM298.667 277.333h426.667v-42.667h-426.667v42.667z" />
|
||||
<glyph unicode="" glyph-name="star" data-tags="star" horiz-adv-x="983" d="M391.569 280.412l99.951 76.407 99.951-76.407-37.482 125.968 93.704 66.077h-116.609l-39.563 128.033-39.563-128.033h-116.611l93.706-66.077-37.483-125.968zM312.039 169.058l67.196 220.164-174.435 124.539h217.203l69.517 228.739 69.517-228.739h217.203l-174.436-124.539 67.195-220.164-179.479 135.34-179.481-135.34z" />
|
||||
<glyph unicode="" glyph-name="star-filled" data-tags="star-filled" horiz-adv-x="983" d="M778.24 513.942h-217.088l-69.632 228.558-69.632-228.558h-217.088l174.49-124.518-67.174-220.365 179.405 135.168 179.405-135.168-67.174 220.365 174.49 124.518z" />
|
||||
<glyph unicode="" glyph-name="marvinjs" data-tags="marvinjs" horiz-adv-x="983" d="M491.52 777.123l285.639-160.672v-321.343l-285.639-160.674-285.639 160.674v321.343l285.639 160.672zM819.2 640.1l-327.68 184.32-327.68-184.32v-368.642l327.68-184.32 327.68 184.32v368.642zM484.835 688.801l203.817-124.109-22.282-34.736-203.817 124.11 22.282 34.734zM344.375 578.66v-245.762h-42.041v245.762h42.041zM688.652 346.866l-203.817-124.109-22.282 34.734 203.817 124.109 22.282-34.734z" />
|
||||
<glyph unicode="" glyph-name="sequence-editor" data-tags="sequence-editor" horiz-adv-x="983" d="M317.364 734.104c46.285 29.082 99.94 46.285 154.417 49.562 11.469 0.819 20.070 10.24 19.251 21.709-0.819 11.059-9.421 19.661-21.709 19.251-61.438-3.686-121.649-22.938-173.668-55.706s-95.846-78.643-125.747-132.301c-30.31-53.658-46.285-114.687-47.104-176.127s14.336-122.88 43.418-177.357c3.686-6.963 10.65-10.65 18.022-10.65 3.277 0 6.554 0.819 9.83 2.458 9.83 5.325 13.926 17.613 8.602 27.853-25.805 48.333-38.912 102.81-38.502 157.696s15.155 108.952 41.779 156.876c26.624 47.923 65.536 88.474 111.821 117.555l-0.41-0.819zM285.825 344.166c2.867 0 5.734 0.41 8.192 1.638 10.24 4.506 15.155 16.794 10.24 27.034-13.107 29.901-19.251 62.669-17.613 95.437 2.048 32.768 11.469 64.717 28.262 92.568 16.794 28.262 40.141 52.019 67.584 69.222 27.441 17.203 59.39 27.853 91.748 30.31 11.469 0.819 19.661 10.65 18.842 22.118s-11.878 19.661-22.118 18.842c-38.912-3.277-77.003-15.974-110.18-36.454-33.178-20.89-61.030-49.562-81.101-83.149s-31.539-72.088-33.997-111 4.915-78.643 20.89-114.278c3.277-7.782 11.059-12.288 18.842-12.288h0.41zM449.253 385.946c-9.83 5.734-22.118 2.867-28.262-6.963-5.734-9.83-2.867-22.118 6.963-28.262 18.022-11.059 38.912-16.794 59.802-17.613 1.229 0 2.048 0 3.277 0 20.070 0 39.731 4.915 57.344 14.336 9.83 5.325 13.926 17.613 8.602 27.853s-17.613 13.926-27.853 8.602c-12.288-6.554-26.624-9.83-40.55-9.421-13.926 0-27.853 4.506-39.731 11.469h0.41zM386.996 456.397c0 0 2.867 0 4.096 0 9.421 0 18.022 6.554 20.068 16.384 3.277 15.974 11.059 30.31 22.528 42.189 11.469 11.469 26.214 19.251 42.189 22.528 11.059 2.048 18.432 13.106 16.384 24.165s-13.107 18.022-24.166 16.384c-23.757-4.506-45.875-16.384-63.076-33.586-17.203-17.203-29.082-38.912-33.997-63.078-2.048-11.059 4.915-21.709 15.974-24.166v-0.819zM661.836 307.302c3.686-2.458 7.782-4.096 11.878-4.096 6.144 0 12.698 2.867 16.384 8.602 35.226 48.742 51.61 108.544 45.466 168.755-1.229 11.059-10.24 18.842-22.528 18.432-11.059-1.229-19.251-11.059-18.432-22.528 4.915-49.971-8.602-99.942-38.093-140.493-6.554-9.011-4.506-22.118 4.506-28.672h0.819zM474.649 252.006c-36.045 2.867-70.449 15.565-99.94 36.045-9.421 6.554-22.118 4.096-28.672-5.325s-4.096-22.118 5.325-28.672c35.635-24.576 77.003-39.322 120.011-43.008 6.554-0.41 13.107-0.819 19.661-0.819 36.454 0 72.499 8.192 105.677 23.757 10.24 4.915 14.746 17.203 9.83 27.443s-17.203 14.746-27.443 9.83c-32.358-15.565-68.813-22.118-104.448-19.251zM643.404 746.802c57.344-29.901 104.038-75.776 135.168-132.301 3.686-6.963 10.65-10.65 18.022-10.65 3.277 0 6.963 0.819 9.83 2.458 9.83 5.325 13.517 18.022 8.192 27.853-35.226 63.898-87.654 115.098-151.962 149.094-9.83 5.325-22.118 1.229-27.443-8.602s-1.229-22.528 8.602-27.853h-0.41zM837.964 496.538c-11.469-0.819-20.070-10.24-19.251-21.709 3.686-64.307-11.469-127.386-43.418-183.091s-79.462-100.352-136.806-129.024c-57.344-28.672-121.651-39.731-185.139-32.358-63.486 7.373-123.288 33.587-172.44 74.547-8.602 7.373-21.709 6.144-29.082-2.458s-6.144-21.709 2.458-29.082c55.296-46.694 122.47-75.776 194.148-83.968 14.336-1.638 29.082-2.458 43.418-2.458 56.934 0 113.050 13.107 164.659 38.912 64.717 32.358 117.965 82.33 154.010 144.998s53.248 133.53 49.152 206.029c-0.41 11.469-8.602 19.661-21.709 19.251v0.41z" />
|
||||
</font></defs></svg>
|
Before Width: | Height: | Size: 91 KiB After Width: | Height: | Size: 95 KiB |
BIN
vendor/assets/stylesheets/fonts/SN-icon-font.ttf
vendored
BIN
vendor/assets/stylesheets/fonts/SN-icon-font.ttf
vendored
Binary file not shown.
BIN
vendor/assets/stylesheets/fonts/SN-icon-font.woff
vendored
BIN
vendor/assets/stylesheets/fonts/SN-icon-font.woff
vendored
Binary file not shown.
BIN
vendor/assets/stylesheets/fonts/SN-icon-font.woff2
vendored
Normal file
BIN
vendor/assets/stylesheets/fonts/SN-icon-font.woff2
vendored
Normal file
Binary file not shown.
35
vendor/assets/stylesheets/sn-icon-font.css
vendored
35
vendor/assets/stylesheets/sn-icon-font.css
vendored
|
@ -1,10 +1,11 @@
|
|||
@font-face {
|
||||
font-family: 'SN-icon-font';
|
||||
src: url('fonts/SN-icon-font.eot?n7qhkp');
|
||||
src: url('fonts/SN-icon-font.eot?n7qhkp#iefix') format('embedded-opentype'),
|
||||
url('fonts/SN-icon-font.ttf?n7qhkp') format('truetype'),
|
||||
url('fonts/SN-icon-font.woff?n7qhkp') format('woff'),
|
||||
url('fonts/SN-icon-font.svg?n7qhkp#SN-icon-font') format('svg');
|
||||
src: url('fonts/SN-icon-font.eot?x922k8');
|
||||
src: url('fonts/SN-icon-font.eot?x922k8#iefix') format('embedded-opentype'),
|
||||
url('fonts/SN-icon-font.woff2?x922k8') format('woff2'),
|
||||
url('fonts/SN-icon-font.ttf?x922k8') format('truetype'),
|
||||
url('fonts/SN-icon-font.woff?x922k8') format('woff'),
|
||||
url('fonts/SN-icon-font.svg?x922k8#SN-icon-font') format('svg');
|
||||
font-weight: normal;
|
||||
font-style: normal;
|
||||
font-display: block;
|
||||
|
@ -25,14 +26,6 @@
|
|||
-moz-osx-font-smoothing: grayscale;
|
||||
}
|
||||
|
||||
.sn-icon {
|
||||
font-size: 24px !important;
|
||||
}
|
||||
|
||||
.sn-icon.mini {
|
||||
font-size: 16px !important;
|
||||
}
|
||||
|
||||
.sn-icon-info:before {
|
||||
content: "\e900";
|
||||
}
|
||||
|
@ -279,10 +272,10 @@
|
|||
.sn-icon-drag:before {
|
||||
content: "\e951";
|
||||
}
|
||||
.sn-icon-double-left:before {
|
||||
.sn-icon-double-navigate-before:before {
|
||||
content: "\e952";
|
||||
}
|
||||
.sn-icon-double-right:before {
|
||||
.sn-icon-double-navigate-after:before {
|
||||
content: "\e953";
|
||||
}
|
||||
.sn-icon-dot-small:before {
|
||||
|
@ -393,3 +386,15 @@
|
|||
.sn-icon-archived:before {
|
||||
content: "\e977";
|
||||
}
|
||||
.sn-icon-star:before {
|
||||
content: "\e978";
|
||||
}
|
||||
.sn-icon-star-filled:before {
|
||||
content: "\e979";
|
||||
}
|
||||
.sn-icon-marvinjs:before {
|
||||
content: "\e97a";
|
||||
}
|
||||
.sn-icon-sequence-editor:before {
|
||||
content: "\e97b";
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue