mirror of
https://github.com/scinote-eln/scinote-web.git
synced 2024-11-10 17:36:33 +08:00
Replace flyouts menu in protocol in results [SCI-9265]
This commit is contained in:
parent
1cb4f71db8
commit
b0dc63ebb5
11 changed files with 456 additions and 363 deletions
|
@ -140,6 +140,7 @@
|
||||||
.repositories-dropdown-menu {
|
.repositories-dropdown-menu {
|
||||||
max-height: 250px;
|
max-height: 250px;
|
||||||
overflow: auto;
|
overflow: auto;
|
||||||
|
z-index: 251;
|
||||||
|
|
||||||
.repository {
|
.repository {
|
||||||
@include font-button;
|
@include font-button;
|
||||||
|
|
|
@ -213,7 +213,7 @@
|
||||||
required: true
|
required: true
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
components: { Step, InlineEdit, ProtocolOptions, Tinymce, ReorderableItemsModal, ProtocolMetadata, PublishProtocol },
|
components: { Step, InlineEdit, ProtocolOptions, Tinymce, ReorderableItemsModal, ProtocolMetadata, PublishProtocol},
|
||||||
mixins: [UtilsMixin],
|
mixins: [UtilsMixin],
|
||||||
computed: {
|
computed: {
|
||||||
inRepository() {
|
inRepository() {
|
||||||
|
|
|
@ -14,86 +14,79 @@
|
||||||
<span class="sn-icon sn-icon-down"></span>
|
<span class="sn-icon sn-icon-down"></span>
|
||||||
</button>
|
</button>
|
||||||
<ul
|
<ul
|
||||||
class="dropdown-menu dropdown-menu-right"
|
class="dropdown-menu dropdown-menu-right rounded !p-2.5 sn-shadow-menu-sm"
|
||||||
aria-labelledby="dropdownProtocolOptions"
|
aria-labelledby="dropdownProtocolOptions"
|
||||||
>
|
>
|
||||||
<li v-if="protocol.attributes.urls.load_from_repo_url">
|
<li v-if="protocol.attributes.urls.load_from_repo_url">
|
||||||
<a
|
<a class="!px-3 !py-2.5 hover:!bg-sn-super-light-blue !text-sn-blue"
|
||||||
ref="loadProtocol"
|
ref="loadProtocol"
|
||||||
data-action="load-from-repository"
|
data-action="load-from-repository"
|
||||||
@click="loadProtocol"
|
@click="loadProtocol"
|
||||||
>
|
>
|
||||||
<span class="sn-icon sn-icon-protocols-templates"></span>
|
|
||||||
<span>{{ i18n.t("my_modules.protocol.options_dropdown.load_from_repo") }}</span>
|
<span>{{ i18n.t("my_modules.protocol.options_dropdown.load_from_repo") }}</span>
|
||||||
</a>
|
</a>
|
||||||
</li>
|
</li>
|
||||||
<li>
|
<li>
|
||||||
<a
|
<a class="!px-3 !py-2.5 hover:!bg-sn-super-light-blue !text-sn-blue"
|
||||||
data-toggle="modal"
|
data-toggle="modal"
|
||||||
data-target="#newProtocolModal"
|
data-target="#newProtocolModal"
|
||||||
v-bind:data-protocol-name="protocol.attributes.name"
|
v-bind:data-protocol-name="protocol.attributes.name"
|
||||||
:class="{ disabled: !protocol.attributes.urls.save_to_repo_url }"
|
:class="{ disabled: !protocol.attributes.urls.save_to_repo_url }"
|
||||||
>
|
>
|
||||||
<span class="fas fa-save"></span>
|
|
||||||
<span>{{
|
<span>{{
|
||||||
i18n.t("my_modules.protocol.options_dropdown.save_to_repo")
|
i18n.t("my_modules.protocol.options_dropdown.save_to_repo")
|
||||||
}}</span>
|
}}</span>
|
||||||
</a>
|
</a>
|
||||||
</li>
|
</li>
|
||||||
<li>
|
<li>
|
||||||
<a
|
<a class="!px-3 !py-2.5 hover:!bg-sn-super-light-blue !text-sn-blue"
|
||||||
data-turbolinks="false"
|
data-turbolinks="false"
|
||||||
:href="protocol.attributes.urls.export_url"
|
:href="protocol.attributes.urls.export_url"
|
||||||
:class="{ disabled: !protocol.attributes.urls.export_url }"
|
:class="{ disabled: !protocol.attributes.urls.export_url }"
|
||||||
>
|
>
|
||||||
<span class="sn-icon sn-icon-import"></span>
|
|
||||||
<span>{{
|
<span>{{
|
||||||
i18n.t("my_modules.protocol.options_dropdown.export")
|
i18n.t("my_modules.protocol.options_dropdown.export")
|
||||||
}}</span>
|
}}</span>
|
||||||
</a>
|
</a>
|
||||||
</li>
|
</li>
|
||||||
<li v-if="protocol.attributes.urls.update_protocol_url">
|
<li v-if="protocol.attributes.urls.update_protocol_url">
|
||||||
<a
|
<a class="!px-3 !py-2.5 hover:!bg-sn-super-light-blue !text-sn-blue"
|
||||||
ref="updateProtocol"
|
ref="updateProtocol"
|
||||||
data-action="update-self"
|
data-action="update-self"
|
||||||
@click="updateProtocol"
|
@click="updateProtocol"
|
||||||
>
|
>
|
||||||
<span class="fas fa-sync-alt"></span>
|
|
||||||
<span>{{
|
<span>{{
|
||||||
i18n.t("my_modules.protocol.options_dropdown.update_protocol")
|
i18n.t("my_modules.protocol.options_dropdown.update_protocol")
|
||||||
}}</span>
|
}}</span>
|
||||||
</a>
|
</a>
|
||||||
</li>
|
</li>
|
||||||
<li v-if="protocol.attributes.urls.unlink_url">
|
<li v-if="protocol.attributes.urls.unlink_url">
|
||||||
<a
|
<a class="!px-3 !py-2.5 hover:!bg-sn-super-light-blue !text-sn-blue"
|
||||||
ref="unlinkProtocol"
|
ref="unlinkProtocol"
|
||||||
data-action="unlink"
|
data-action="unlink"
|
||||||
@click="unlinkProtocol"
|
@click="unlinkProtocol"
|
||||||
>
|
>
|
||||||
<span class="fas fa-unlink"></span>
|
|
||||||
<span>{{
|
<span>{{
|
||||||
i18n.t("my_modules.protocol.options_dropdown.unlink")
|
i18n.t("my_modules.protocol.options_dropdown.unlink")
|
||||||
}}</span>
|
}}</span>
|
||||||
</a>
|
</a>
|
||||||
</li>
|
</li>
|
||||||
<li v-if="protocol.attributes.urls.revert_protocol_url">
|
<li v-if="protocol.attributes.urls.revert_protocol_url">
|
||||||
<a
|
<a class="!px-3 !py-2.5 hover:!bg-sn-super-light-blue !text-sn-blue"
|
||||||
ref="revertProtocol"
|
ref="revertProtocol"
|
||||||
data-action="revert"
|
data-action="revert"
|
||||||
@click="revertProtocol"
|
@click="revertProtocol"
|
||||||
>
|
>
|
||||||
<span class="sn-icon sn-icon-restore"></span>
|
|
||||||
<span>{{
|
<span>{{
|
||||||
i18n.t("my_modules.protocol.options_dropdown.revert_protocol")
|
i18n.t("my_modules.protocol.options_dropdown.revert_protocol")
|
||||||
}}</span>
|
}}</span>
|
||||||
</a>
|
</a>
|
||||||
</li>
|
</li>
|
||||||
<li v-if="canDeleteSteps">
|
<li v-if="canDeleteSteps">
|
||||||
<a
|
<a class="!px-3 !py-2.5 hover:!bg-sn-super-light-blue !text-sn-blue"
|
||||||
data-turbolinks="false"
|
data-turbolinks="false"
|
||||||
@click.prevent="openStepsDeletingModal()"
|
@click.prevent="openStepsDeletingModal()"
|
||||||
>
|
>
|
||||||
<span class="sn-icon sn-icon-delete"></span>
|
|
||||||
<span>{{
|
<span>{{
|
||||||
i18n.t("my_modules.protocol.options_dropdown.delete_steps")
|
i18n.t("my_modules.protocol.options_dropdown.delete_steps")
|
||||||
}}</span>
|
}}</span>
|
||||||
|
|
|
@ -53,68 +53,29 @@
|
||||||
</div>
|
</div>
|
||||||
<div class="elements-actions-container">
|
<div class="elements-actions-container">
|
||||||
<input type="file" class="hidden" ref="fileSelector" @change="loadFromComputer" multiple />
|
<input type="file" class="hidden" ref="fileSelector" @change="loadFromComputer" multiple />
|
||||||
<div ref="elementsDropdownButton" v-if="urls.update_url" class="dropdown">
|
|
||||||
<button class="btn btn-light dropdown-toggle insert-button" type="button" :id="'stepInserMenu_' + step.id" data-toggle="dropdown" aria-haspopup="true" aria-expanded="true">
|
|
||||||
{{ i18n.t('protocols.steps.insert.button') }}
|
|
||||||
<span class="sn-icon sn-icon-down"></span>
|
|
||||||
</button>
|
|
||||||
<ul ref="elementsDropdown" class="dropdown-menu insert-element-dropdown dropdown-menu-right" :aria-labelledby="'stepInserMenu_' + step.id">
|
|
||||||
<li class="title">
|
|
||||||
{{ i18n.t('protocols.steps.insert.title') }}
|
|
||||||
</li>
|
|
||||||
<li class="action" @click="createElement('table')">
|
|
||||||
<i class="sn-icon sn-icon-tables"></i>
|
|
||||||
{{ i18n.t('protocols.steps.insert.table') }}
|
|
||||||
</li>
|
|
||||||
<li class="action dropdown-submenu-item">
|
|
||||||
<i class="sn-icon sn-icon-tables"></i>
|
|
||||||
{{ i18n.t('protocols.steps.insert.well_plate') }}
|
|
||||||
<span class="caret"></span>
|
|
||||||
|
|
||||||
<ul class="dropdown-submenu">
|
<MenuDropdown
|
||||||
<li v-for="option in wellPlateOptions" :key="option.dimensions.toString()" class="action" @click="createElement('table', option.dimensions, true)">
|
:listItems="this.insertMenu"
|
||||||
{{ i18n.t(option.label) }}
|
:btnText="i18n.t('protocols.steps.insert.button')"
|
||||||
</li>
|
:position="'right'"
|
||||||
</ul>
|
:caret="true"
|
||||||
</li>
|
@create:table="(...args) => this.createElement('table', ...args)"
|
||||||
<li class="action" @click="createElement('checklist')">
|
@create:checklist="createElement('checklist')"
|
||||||
<i class="sn-icon sn-icon-activities"></i>
|
@create:text="createElement('text')"
|
||||||
{{ i18n.t('protocols.steps.insert.checklist') }}
|
@create:file="openLoadFromComputer"
|
||||||
</li>
|
@create:wopi_file="openWopiFileModal"
|
||||||
<li class="action" @click="createElement('text')">
|
@create:ove_file="openOVEditor"
|
||||||
<i class="sn-icon sn-icon-result-text"></i>
|
@create:marvinjs_file="openMarvinJsModal($refs.marvinJsButton)"
|
||||||
{{ i18n.t('protocols.steps.insert.text') }}
|
></MenuDropdown>
|
||||||
</li>
|
<span
|
||||||
<li class="action dropdown-submenu-item">
|
class="new-marvinjs-upload-button hidden"
|
||||||
<i class="sn-icon sn-icon-files"></i>
|
:data-object-id="step.id"
|
||||||
{{ i18n.t('protocols.steps.insert.attachment') }}
|
ref="marvinJsButton"
|
||||||
<span class="caret"></span>
|
:data-marvin-url="step.attributes.marvinjs_context.marvin_js_asset_url"
|
||||||
<ul class="dropdown-submenu">
|
:data-object-type="step.attributes.type"
|
||||||
<li class="action" @click="openLoadFromComputer">
|
tabindex="0"
|
||||||
{{ i18n.t('protocols.steps.insert.add_file') }}
|
></span> <!-- Hidden element to support legacy code -->
|
||||||
</li>
|
|
||||||
<li class="action" v-if="step.attributes.wopi_enabled" @click="openWopiFileModal">
|
|
||||||
{{ i18n.t('assets.create_wopi_file.button_text') }}
|
|
||||||
</li>
|
|
||||||
<li v-if="step.attributes.open_vector_editor_context.new_sequence_asset_url" @click="openOVEditor" @keyup.enter="openOVEditor">
|
|
||||||
{{ i18n.t('open_vector_editor.new_sequence_file') }}
|
|
||||||
</li>
|
|
||||||
<li class="action" v-if="step.attributes.marvinjs_enabled" @click="openMarvinJsModal($refs.marvinJsButton)">
|
|
||||||
<span
|
|
||||||
class="new-marvinjs-upload-button text-sn-black text-decoration-none"
|
|
||||||
:data-object-id="step.id"
|
|
||||||
ref="marvinJsButton"
|
|
||||||
:data-marvin-url="step.attributes.marvinjs_context.marvin_js_asset_url"
|
|
||||||
:data-object-type="step.attributes.type"
|
|
||||||
tabindex="0"
|
|
||||||
>
|
|
||||||
{{ i18n.t('marvinjs.new_button') }}
|
|
||||||
</span>
|
|
||||||
</li>
|
|
||||||
</ul>
|
|
||||||
</li>
|
|
||||||
</ul>
|
|
||||||
</div>
|
|
||||||
<a href="#"
|
<a href="#"
|
||||||
v-if="!inRepository"
|
v-if="!inRepository"
|
||||||
ref="comments"
|
ref="comments"
|
||||||
|
@ -131,27 +92,15 @@
|
||||||
{{ step.attributes.comments_count }}
|
{{ step.attributes.comments_count }}
|
||||||
</span>
|
</span>
|
||||||
</a>
|
</a>
|
||||||
<div v-if="urls.update_url" class="step-actions-container">
|
<MenuDropdown
|
||||||
<div ref="actionsDropdownButton" class="dropdown">
|
:listItems="this.actionsMenu"
|
||||||
<button class="btn btn-light icon-btn dropdown-toggle insert-button" type="button" :id="'stepOptionsMenu_' + step.id" data-toggle="dropdown" data-display="static" aria-haspopup="true" aria-expanded="true">
|
:btnClasses="'btn btn-light icon-btn'"
|
||||||
<i class="sn-icon sn-icon-more-hori"></i>
|
:position="'right'"
|
||||||
</button>
|
:btnIcon="'sn-icon sn-icon-more-hori'"
|
||||||
<ul ref="actionsDropdown" class="dropdown-menu dropdown-menu-right insert-element-dropdown" :aria-labelledby="'stepOptionsMenu_' + step.id">
|
@reorder="openReorderModal"
|
||||||
<li class="title">
|
@duplicate="duplicateStep"
|
||||||
{{ i18n.t('protocols.steps.options_dropdown.title') }}
|
@delete="showDeleteModal"
|
||||||
</li>
|
></MenuDropdown>
|
||||||
<li v-if="urls.reorder_elements_url" class="action" @click="openReorderModal" :class="{ 'disabled': elements.length < 2 }">
|
|
||||||
{{ i18n.t('protocols.steps.options_dropdown.rearrange') }}
|
|
||||||
</li>
|
|
||||||
<li v-if="urls.duplicate_step_url" class="action" @click="duplicateStep">
|
|
||||||
{{ i18n.t('protocols.steps.options_dropdown.duplicate') }}
|
|
||||||
</li>
|
|
||||||
<li v-if="urls.delete_url" class="action" @click="showDeleteModal">
|
|
||||||
{{ i18n.t('protocols.steps.options_dropdown.delete') }}
|
|
||||||
</li>
|
|
||||||
</ul>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="collapse in" :id="'stepBody' + step.id">
|
<div class="collapse in" :id="'stepBody' + step.id">
|
||||||
|
@ -215,6 +164,7 @@
|
||||||
import Attachments from '../shared/content/attachments.vue'
|
import Attachments from '../shared/content/attachments.vue'
|
||||||
import clipboardPasteModal from '../shared/content/attachments/clipboard_paste_modal.vue'
|
import clipboardPasteModal from '../shared/content/attachments/clipboard_paste_modal.vue'
|
||||||
import ReorderableItemsModal from '../shared/reorderable_items_modal.vue'
|
import ReorderableItemsModal from '../shared/reorderable_items_modal.vue'
|
||||||
|
import MenuDropdown from '../shared/menu_dropdown.vue'
|
||||||
|
|
||||||
import UtilsMixin from '../mixins/utils.js'
|
import UtilsMixin from '../mixins/utils.js'
|
||||||
import AttachmentsMixin from '../shared/content/mixins/attachments.js'
|
import AttachmentsMixin from '../shared/content/mixins/attachments.js'
|
||||||
|
@ -260,12 +210,12 @@
|
||||||
editingName: false,
|
editingName: false,
|
||||||
inlineEditError: null,
|
inlineEditError: null,
|
||||||
wellPlateOptions: [
|
wellPlateOptions: [
|
||||||
{ label: 'protocols.steps.insert.well_plate_options.32_x_48', dimensions: [32, 48] },
|
{ text: I18n.t('protocols.steps.insert.well_plate_options.32_x_48'), emit: 'create:table', params: [32, 48] },
|
||||||
{ label: 'protocols.steps.insert.well_plate_options.16_x_24', dimensions: [16, 24] },
|
{ text: I18n.t('protocols.steps.insert.well_plate_options.16_x_24'), emit: 'create:table', params: [16, 24] },
|
||||||
{ label: 'protocols.steps.insert.well_plate_options.8_x_12', dimensions: [8, 12] },
|
{ text: I18n.t('protocols.steps.insert.well_plate_options.8_x_12'), emit: 'create:table', params: [8, 12] },
|
||||||
{ label: 'protocols.steps.insert.well_plate_options.6_x_8', dimensions: [6, 8] },
|
{ text: I18n.t('protocols.steps.insert.well_plate_options.6_x_8'), emit: 'create:table', params: [6, 8] },
|
||||||
{ label: 'protocols.steps.insert.well_plate_options.6_x_4', dimensions: [6, 4] },
|
{ text: I18n.t('protocols.steps.insert.well_plate_options.6_x_4'), emit: 'create:table', params: [6, 4] },
|
||||||
{ label: 'protocols.steps.insert.well_plate_options.2_x_3', dimensions: [2, 3] }
|
{ text: I18n.t('protocols.steps.insert.well_plate_options.2_x_3'), emit: 'create:table', params: [2, 3] }
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
@ -279,7 +229,8 @@
|
||||||
clipboardPasteModal,
|
clipboardPasteModal,
|
||||||
Attachments,
|
Attachments,
|
||||||
StorageUsage,
|
StorageUsage,
|
||||||
ReorderableItemsModal
|
ReorderableItemsModal,
|
||||||
|
MenuDropdown
|
||||||
},
|
},
|
||||||
created() {
|
created() {
|
||||||
this.loadAttachments();
|
this.loadAttachments();
|
||||||
|
@ -312,6 +263,81 @@
|
||||||
},
|
},
|
||||||
urls() {
|
urls() {
|
||||||
return this.step.attributes.urls || {}
|
return this.step.attributes.urls || {}
|
||||||
|
},
|
||||||
|
filesMenu() {
|
||||||
|
let menu = [];
|
||||||
|
if (this.urls.upload_attachment_url) {
|
||||||
|
menu = menu.concat([{
|
||||||
|
text: this.i18n.t('protocols.steps.insert.add_file'),
|
||||||
|
emit: 'create:file'
|
||||||
|
}]);
|
||||||
|
}
|
||||||
|
if (this.step.attributes.wopi_enabled) {
|
||||||
|
menu = menu.concat([{
|
||||||
|
text: this.i18n.t('assets.create_wopi_file.button_text'),
|
||||||
|
emit: 'create:wopi_file'
|
||||||
|
}]);
|
||||||
|
}
|
||||||
|
if (this.step.attributes.open_vector_editor_context.new_sequence_asset_url) {
|
||||||
|
menu = menu.concat([{
|
||||||
|
text: this.i18n.t('open_vector_editor.new_sequence_file'),
|
||||||
|
emit: 'create:ove_file'
|
||||||
|
}]);
|
||||||
|
}
|
||||||
|
if (this.step.attributes.marvinjs_enabled) {
|
||||||
|
menu = menu.concat([{
|
||||||
|
text: this.i18n.t('marvinjs.new_button'),
|
||||||
|
emit: 'create:marvinjs_file'
|
||||||
|
}]);
|
||||||
|
}
|
||||||
|
return menu;
|
||||||
|
},
|
||||||
|
insertMenu() {
|
||||||
|
let menu = [];
|
||||||
|
if (this.urls.update_url) {
|
||||||
|
menu = menu.concat([{
|
||||||
|
text: this.i18n.t('protocols.steps.insert.text'),
|
||||||
|
emit: 'create:text'
|
||||||
|
},{
|
||||||
|
text: this.i18n.t('protocols.steps.insert.attachment'),
|
||||||
|
submenu: this.filesMenu,
|
||||||
|
position: 'left'
|
||||||
|
},{
|
||||||
|
text: this.i18n.t('protocols.steps.insert.table'),
|
||||||
|
emit: 'create:table'
|
||||||
|
},{
|
||||||
|
text: this.i18n.t('protocols.steps.insert.well_plate'),
|
||||||
|
submenu: this.wellPlateOptions,
|
||||||
|
position: 'left'
|
||||||
|
},{
|
||||||
|
text: this.i18n.t('protocols.steps.insert.checklist'),
|
||||||
|
emit: 'create:checklist'
|
||||||
|
}]);
|
||||||
|
}
|
||||||
|
|
||||||
|
return menu;
|
||||||
|
},
|
||||||
|
actionsMenu() {
|
||||||
|
let menu = [];
|
||||||
|
if (this.urls.reorder_elements_url) {
|
||||||
|
menu = menu.concat([{
|
||||||
|
text: this.i18n.t('protocols.steps.options_dropdown.rearrange'),
|
||||||
|
emit: 'reorder'
|
||||||
|
}]);
|
||||||
|
}
|
||||||
|
if (this.urls.duplicate_step_url) {
|
||||||
|
menu = menu.concat([{
|
||||||
|
text: this.i18n.t('protocols.steps.options_dropdown.duplicate'),
|
||||||
|
emit: 'duplicate'
|
||||||
|
}]);
|
||||||
|
}
|
||||||
|
if (this.urls.delete_url) {
|
||||||
|
menu = menu.concat([{
|
||||||
|
text: this.i18n.t('protocols.steps.options_dropdown.delete'),
|
||||||
|
emit: 'delete'
|
||||||
|
}]);
|
||||||
|
}
|
||||||
|
return menu;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
|
@ -465,7 +491,9 @@
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
createElement(elementType, tableDimensions = [5,5], plateTemplate = false) {
|
createElement(elementType, tableDimensions = null) {
|
||||||
|
let plateTemplate = tableDimensions != null;
|
||||||
|
tableDimensions ||= [5, 5];
|
||||||
$.post(this.urls[`create_${elementType}_url`], { tableDimensions: tableDimensions, plateTemplate: plateTemplate }, (result) => {
|
$.post(this.urls[`create_${elementType}_url`], { tableDimensions: tableDimensions, plateTemplate: plateTemplate }, (result) => {
|
||||||
result.data.isNew = true;
|
result.data.isNew = true;
|
||||||
this.elements.push(result.data)
|
this.elements.push(result.data)
|
||||||
|
|
|
@ -25,64 +25,19 @@
|
||||||
</div>
|
</div>
|
||||||
<div class="result-head-right flex elements-actions-container">
|
<div class="result-head-right flex elements-actions-container">
|
||||||
<input type="file" class="hidden" ref="fileSelector" @change="loadFromComputer" multiple />
|
<input type="file" class="hidden" ref="fileSelector" @change="loadFromComputer" multiple />
|
||||||
<div ref="elementsDropdownButton" v-if="urls.update_url" class="dropdown">
|
<MenuDropdown
|
||||||
<button class="btn btn-light dropdown-toggle insert-button" type="button" :id="'resultInsertMenu_' + result.id" data-toggle="dropdown" aria-haspopup="true" aria-expanded="true">
|
:listItems="this.insertMenu"
|
||||||
{{ i18n.t('my_modules.results.insert.button') }}
|
:btnText="i18n.t('my_modules.results.insert.button')"
|
||||||
<span class="sn-icon sn-icon-down"></span>
|
:position="'right'"
|
||||||
</button>
|
:caret="true"
|
||||||
<ul ref="elementsDropdown" class="dropdown-menu insert-element-dropdown dropdown-menu-right" :aria-labelledby="'resultInsertMenu_' + result.id">
|
@create:table="(...args) => this.createElement('table', ...args)"
|
||||||
<li class="title">
|
@create:checklist="createElement('checklist')"
|
||||||
{{ i18n.t('my_modules.results.insert.title') }}
|
@create:text="createElement('text')"
|
||||||
</li>
|
@create:file="openLoadFromComputer"
|
||||||
<li class="action" @click="createElement('table')">
|
@create:wopi_file="openWopiFileModal"
|
||||||
<i class="sn-icon sn-icon-tables"></i>
|
@create:ove_file="openOVEditor"
|
||||||
{{ i18n.t('my_modules.results.insert.table') }}
|
@create:marvinjs_file="openMarvinJsModal($refs.marvinJsButton)"
|
||||||
</li>
|
></MenuDropdown>
|
||||||
<li class="action dropdown-submenu-item">
|
|
||||||
<i class="sn-icon sn-icon-tables"></i>
|
|
||||||
{{ i18n.t('my_modules.results.insert.well_plate') }}
|
|
||||||
<span class="caret"></span>
|
|
||||||
|
|
||||||
<ul class="dropdown-submenu">
|
|
||||||
<li v-for="option in wellPlateOptions" :key="option.dimensions.toString()" class="action" @click="createElement('table', option.dimensions, true)">
|
|
||||||
{{ i18n.t(option.label) }}
|
|
||||||
</li>
|
|
||||||
</ul>
|
|
||||||
</li>
|
|
||||||
<li class="action" @click="createElement('text')">
|
|
||||||
<i class="sn-icon sn-icon-result-text"></i>
|
|
||||||
{{ i18n.t('my_modules.results.insert.text') }}
|
|
||||||
</li>
|
|
||||||
<li class="action dropdown-submenu-item">
|
|
||||||
<i class="sn-icon sn-icon-files"></i>
|
|
||||||
{{ i18n.t('my_modules.results.insert.attachment') }}
|
|
||||||
<span class="caret"></span>
|
|
||||||
<ul class="dropdown-submenu">
|
|
||||||
<li class="action" @click="openLoadFromComputer">
|
|
||||||
{{ i18n.t('my_modules.results.insert.add_file') }}
|
|
||||||
</li>
|
|
||||||
<li class="action" v-if="result.attributes.wopi_enabled" @click="openWopiFileModal">
|
|
||||||
{{ i18n.t('assets.create_wopi_file.button_text') }}
|
|
||||||
</li>
|
|
||||||
<li v-if="result.attributes.open_vector_editor_context.new_sequence_asset_url" @click="openOVEditor" @keyup.enter="openOVEditor">
|
|
||||||
{{ i18n.t('open_vector_editor.new_sequence_file') }}
|
|
||||||
</li>
|
|
||||||
<li class="action" v-if="result.attributes.marvinjs_enabled" @click="openMarvinJsModal($refs.marvinJsButton)">
|
|
||||||
<span
|
|
||||||
class="new-marvinjs-upload-button text-sn-black text-decoration-none"
|
|
||||||
:data-object-id="result.id"
|
|
||||||
ref="marvinJsButton"
|
|
||||||
:data-marvin-url="result.attributes.marvinjs_context.marvin_js_asset_url"
|
|
||||||
:data-object-type="result.attributes.type"
|
|
||||||
tabindex="0"
|
|
||||||
>
|
|
||||||
{{ i18n.t('marvinjs.new_button') }}
|
|
||||||
</span>
|
|
||||||
</li>
|
|
||||||
</ul>
|
|
||||||
</li>
|
|
||||||
</ul>
|
|
||||||
</div>
|
|
||||||
<a href="#"
|
<a href="#"
|
||||||
ref="comments"
|
ref="comments"
|
||||||
class="open-comments-sidebar btn icon-btn btn-light"
|
class="open-comments-sidebar btn icon-btn btn-light"
|
||||||
|
@ -91,28 +46,18 @@
|
||||||
:data-object-id="result.id">
|
:data-object-id="result.id">
|
||||||
<i class="sn-icon sn-icon-comments"></i>
|
<i class="sn-icon sn-icon-comments"></i>
|
||||||
</a>
|
</a>
|
||||||
<div v-if="!locked" ref="actionsDropdownButton" class="dropdown">
|
<MenuDropdown
|
||||||
<button class="btn btn-light icon-btn dropdown-toggle insert-button" type="button" :id="'resultOptionsMenu_' + result.id" data-toggle="dropdown" data-display="static" aria-haspopup="true" aria-expanded="true">
|
v-if="!locked"
|
||||||
<i class="sn-icon sn-icon-more-hori"></i>
|
:listItems="this.actionsMenu"
|
||||||
</button>
|
:btnClasses="'btn btn-light icon-btn'"
|
||||||
<ul ref="actionsDropdown" class="dropdown-menu dropdown-menu-right insert-element-dropdown" :aria-labelledby="'resultOptionsMenu_' + result.id">
|
:position="'right'"
|
||||||
<li class="action" @click="openReorderModal" v-if="urls.reorder_elements_url">
|
:btnIcon="'sn-icon sn-icon-more-hori'"
|
||||||
{{ i18n.t('my_modules.results.actions.rearrange') }}
|
@reorder="openReorderModal"
|
||||||
</li>
|
@duplicate="duplicateResult"
|
||||||
<li class="action" @click="duplicateResult" v-if="urls.duplicate_url && !result.attributes.archived">
|
@archive="archiveResult"
|
||||||
{{ i18n.t('my_modules.results.actions.duplicate') }}
|
@restore="restoreResult"
|
||||||
</li>
|
@delete="deleteResult"
|
||||||
<li class="action" @click="archiveResult" v-if="urls.archive_url">
|
></MenuDropdown>
|
||||||
{{ i18n.t('my_modules.results.actions.archive') }}
|
|
||||||
</li>
|
|
||||||
<li class="action" @click="restoreResult" v-if="urls.restore_url">
|
|
||||||
{{ i18n.t('my_modules.results.actions.restore') }}
|
|
||||||
</li>
|
|
||||||
<li class="action" @click="deleteResult" v-if="urls.delete_url">
|
|
||||||
{{ i18n.t('my_modules.results.actions.delete') }}
|
|
||||||
</li>
|
|
||||||
</ul>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
@ -165,6 +110,7 @@
|
||||||
import ResultText from '../shared/content/text.vue';
|
import ResultText from '../shared/content/text.vue';
|
||||||
import Attachments from '../shared/content/attachments.vue';
|
import Attachments from '../shared/content/attachments.vue';
|
||||||
import InlineEdit from '../shared/inline_edit.vue'
|
import InlineEdit from '../shared/inline_edit.vue'
|
||||||
|
import MenuDropdown from '../shared/menu_dropdown.vue'
|
||||||
|
|
||||||
import AttachmentsMixin from '../shared/content/mixins/attachments.js'
|
import AttachmentsMixin from '../shared/content/mixins/attachments.js'
|
||||||
import WopiFileModal from '../shared/content/attachments/mixins/wopi_file_modal.js'
|
import WopiFileModal from '../shared/content/attachments/mixins/wopi_file_modal.js'
|
||||||
|
@ -185,12 +131,12 @@
|
||||||
attachmentsReady: false,
|
attachmentsReady: false,
|
||||||
showFileModal: false,
|
showFileModal: false,
|
||||||
wellPlateOptions: [
|
wellPlateOptions: [
|
||||||
{ label: 'my_modules.results.insert.well_plate_options.32_x_48', dimensions: [32, 48] },
|
{ text: I18n.t('protocols.steps.insert.well_plate_options.32_x_48'), emit: 'create:table', params: [32, 48] },
|
||||||
{ label: 'my_modules.results.insert.well_plate_options.16_x_24', dimensions: [16, 24] },
|
{ text: I18n.t('protocols.steps.insert.well_plate_options.16_x_24'), emit: 'create:table', params: [16, 24] },
|
||||||
{ label: 'my_modules.results.insert.well_plate_options.8_x_12', dimensions: [8, 12] },
|
{ text: I18n.t('protocols.steps.insert.well_plate_options.8_x_12'), emit: 'create:table', params: [8, 12] },
|
||||||
{ label: 'my_modules.results.insert.well_plate_options.6_x_8', dimensions: [6, 8] },
|
{ text: I18n.t('protocols.steps.insert.well_plate_options.6_x_8'), emit: 'create:table', params: [6, 8] },
|
||||||
{ label: 'my_modules.results.insert.well_plate_options.6_x_4', dimensions: [6, 4] },
|
{ text: I18n.t('protocols.steps.insert.well_plate_options.6_x_4'), emit: 'create:table', params: [6, 4] },
|
||||||
{ label: 'my_modules.results.insert.well_plate_options.2_x_3', dimensions: [2, 3] }
|
{ text: I18n.t('protocols.steps.insert.well_plate_options.2_x_3'), emit: 'create:table', params: [2, 3] }
|
||||||
],
|
],
|
||||||
editingName: false
|
editingName: false
|
||||||
}
|
}
|
||||||
|
@ -201,7 +147,8 @@
|
||||||
ResultTable,
|
ResultTable,
|
||||||
ResultText,
|
ResultText,
|
||||||
Attachments,
|
Attachments,
|
||||||
InlineEdit
|
InlineEdit,
|
||||||
|
MenuDropdown
|
||||||
},
|
},
|
||||||
watch: {
|
watch: {
|
||||||
resultToReload() {
|
resultToReload() {
|
||||||
|
@ -223,6 +170,90 @@
|
||||||
},
|
},
|
||||||
locked() {
|
locked() {
|
||||||
return !(this.urls.restore_url || this.urls.archive_url || this.urls.delete_url || this.urls.update_url)
|
return !(this.urls.restore_url || this.urls.archive_url || this.urls.delete_url || this.urls.update_url)
|
||||||
|
},
|
||||||
|
filesMenu() {
|
||||||
|
let menu = [];
|
||||||
|
if (this.urls.upload_attachment_url) {
|
||||||
|
menu = menu.concat([{
|
||||||
|
text: this.i18n.t('my_modules.results.insert.add_file'),
|
||||||
|
emit: 'create:file'
|
||||||
|
}]);
|
||||||
|
}
|
||||||
|
if (this.result.attributes.wopi_enabled) {
|
||||||
|
menu = menu.concat([{
|
||||||
|
text: this.i18n.t('assets.create_wopi_file.button_text'),
|
||||||
|
emit: 'create:wopi_file'
|
||||||
|
}]);
|
||||||
|
}
|
||||||
|
if (this.result.attributes.open_vector_editor_context.new_sequence_asset_url) {
|
||||||
|
menu = menu.concat([{
|
||||||
|
text: this.i18n.t('open_vector_editor.new_sequence_file'),
|
||||||
|
emit: 'create:ove_file'
|
||||||
|
}]);
|
||||||
|
}
|
||||||
|
if (this.result.attributes.marvinjs_enabled) {
|
||||||
|
menu = menu.concat([{
|
||||||
|
text: this.i18n.t('marvinjs.new_button'),
|
||||||
|
emit: 'create:marvinjs_file'
|
||||||
|
}]);
|
||||||
|
}
|
||||||
|
return menu;
|
||||||
|
},
|
||||||
|
insertMenu() {
|
||||||
|
let menu = [];
|
||||||
|
if (this.urls.update_url) {
|
||||||
|
menu = menu.concat([{
|
||||||
|
text: this.i18n.t('my_modules.results.insert.text'),
|
||||||
|
emit: 'create:text'
|
||||||
|
},{
|
||||||
|
text: this.i18n.t('my_modules.results.insert.attachment'),
|
||||||
|
submenu: this.filesMenu,
|
||||||
|
position: 'left'
|
||||||
|
},{
|
||||||
|
text: this.i18n.t('my_modules.results.insert.table'),
|
||||||
|
emit: 'create:table'
|
||||||
|
},{
|
||||||
|
text: this.i18n.t('my_modules.results.insert.well_plate'),
|
||||||
|
submenu: this.wellPlateOptions,
|
||||||
|
position: 'left'
|
||||||
|
}]);
|
||||||
|
}
|
||||||
|
|
||||||
|
return menu;
|
||||||
|
},
|
||||||
|
actionsMenu() {
|
||||||
|
let menu = [];
|
||||||
|
if (this.urls.reorder_elements_url) {
|
||||||
|
menu = menu.concat([{
|
||||||
|
text: this.i18n.t('my_modules.results.actions.rearrange'),
|
||||||
|
emit: 'reorder'
|
||||||
|
}]);
|
||||||
|
}
|
||||||
|
if (this.urls.duplicate_url && !this.result.attributes.archived) {
|
||||||
|
menu = menu.concat([{
|
||||||
|
text: this.i18n.t('my_modules.results.actions.duplicate'),
|
||||||
|
emit: 'duplicate'
|
||||||
|
}]);
|
||||||
|
}
|
||||||
|
if (this.urls.archive_url) {
|
||||||
|
menu = menu.concat([{
|
||||||
|
text: this.i18n.t('my_modules.results.actions.archive'),
|
||||||
|
emit: 'archive'
|
||||||
|
}]);
|
||||||
|
}
|
||||||
|
if (this.urls.restore_url) {
|
||||||
|
menu = menu.concat([{
|
||||||
|
text: this.i18n.t('my_modules.results.actions.restore'),
|
||||||
|
emit: 'restore'
|
||||||
|
}]);
|
||||||
|
}
|
||||||
|
if (this.urls.delete_url) {
|
||||||
|
menu = menu.concat([{
|
||||||
|
text: this.i18n.t('my_modules.results.actions.delete'),
|
||||||
|
emit: 'delete'
|
||||||
|
}]);
|
||||||
|
}
|
||||||
|
return menu;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
created() {
|
created() {
|
||||||
|
|
|
@ -34,19 +34,13 @@
|
||||||
</button>
|
</button>
|
||||||
|
|
||||||
<FilterDropdown :filters="filters" @applyFilters="setFilters" />
|
<FilterDropdown :filters="filters" @applyFilters="setFilters" />
|
||||||
|
<MenuDropdown
|
||||||
<div class="dropdown">
|
:listItems="this.sortMenu"
|
||||||
<button class="dropdown-toggle btn btn-light icon-btn mr-3" id="sortDropdown" data-toggle="dropdown" aria-haspopup="true" aria-expanded="true">
|
:btnClasses="'btn btn-light icon-btn'"
|
||||||
<i class="sn-icon sn-icon-sort"></i>
|
:position="'right'"
|
||||||
</button>
|
:btnIcon="'sn-icon sn-icon-sort'"
|
||||||
<ul class="dropdown-menu dropdown-menu-right" aria-labelledby="sortDropdown">
|
@sort="setSort"
|
||||||
<li v-for="sort in sorts" :key="sort">
|
></MenuDropdown>
|
||||||
<a class="cursor-pointer" @click="setSort(sort)">
|
|
||||||
{{ i18n.t(`my_modules.results.sorts.${sort}`)}}
|
|
||||||
</a>
|
|
||||||
</li>
|
|
||||||
</ul>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
@ -62,6 +56,7 @@
|
||||||
];
|
];
|
||||||
|
|
||||||
import FilterDropdown from '../shared/filters/filter_dropdown.vue';
|
import FilterDropdown from '../shared/filters/filter_dropdown.vue';
|
||||||
|
import MenuDropdown from '../shared/menu_dropdown.vue'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'ResultsToolbar',
|
name: 'ResultsToolbar',
|
||||||
|
@ -77,7 +72,7 @@
|
||||||
filters: null
|
filters: null
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
components: { FilterDropdown },
|
components: { FilterDropdown, MenuDropdown },
|
||||||
created() {
|
created() {
|
||||||
this.filters = [
|
this.filters = [
|
||||||
{
|
{
|
||||||
|
@ -100,6 +95,17 @@
|
||||||
|
|
||||||
this.sorts = SORTS;
|
this.sorts = SORTS;
|
||||||
},
|
},
|
||||||
|
computed: {
|
||||||
|
sortMenu() {
|
||||||
|
return this.sorts.map(sort => {
|
||||||
|
return {
|
||||||
|
text: this.i18n.t(`my_modules.results.sorts.${sort}`),
|
||||||
|
emit: 'sort',
|
||||||
|
params: sort
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
},
|
||||||
methods: {
|
methods: {
|
||||||
setSort(sort) {
|
setSort(sort) {
|
||||||
this.$emit('setSort', sort);
|
this.$emit('setSort', sort);
|
||||||
|
|
|
@ -6,45 +6,20 @@
|
||||||
{{ i18n.t('protocols.steps.files', {count: attachments.length}) }}
|
{{ i18n.t('protocols.steps.files', {count: attachments.length}) }}
|
||||||
</div>
|
</div>
|
||||||
<div class="flex items-center gap-2" v-if="parent.attributes.attachments_manageble && attachmentsReady">
|
<div class="flex items-center gap-2" v-if="parent.attributes.attachments_manageble && attachmentsReady">
|
||||||
<div ref="actionsDropdownButton" class="dropdown sci-dropdown">
|
<MenuDropdown
|
||||||
<button class="btn btn-light dropdown-toggle" type="button" id="dropdownAttachmentsOptions" data-toggle="dropdown" aria-haspopup="true" aria-expanded="true">
|
:listItems="this.viewModeMenu"
|
||||||
<span>{{ i18n.t("attachments.preview_menu") }}</span>
|
:btnText="i18n.t('attachments.preview_menu')"
|
||||||
<span class="sn-icon sn-icon-down"></span>
|
:position="'right'"
|
||||||
</button>
|
:caret="true"
|
||||||
<ul ref="actionsDropdown" class="dropdown-menu dropdown-menu-right dropdown-attachment-options"
|
@attachment:viewMode = "changeAttachmentsViewMode"
|
||||||
aria-labelledby="dropdownAttachmentsOptions"
|
></MenuDropdown>
|
||||||
:data-parent-id="parent.id"
|
<MenuDropdown
|
||||||
>
|
:listItems="this.sortMenu"
|
||||||
<template v-if="parent.attributes.urls.update_asset_view_mode_url">
|
:btnIcon="'sn-icon sn-icon-sort-down'"
|
||||||
<li v-for="(viewMode, index) in viewModeOptions" :key="`viewMode_${index}`">
|
:btnClasses="'btn btn-light icon-btn'"
|
||||||
<a
|
:position="'right'"
|
||||||
class="attachments-view-mode action-link"
|
@attachment:order = "changeAttachmentsOrder"
|
||||||
:class="viewMode == parent.attributes.assets_view_mode ? 'selected' : ''"
|
></MenuDropdown>
|
||||||
@click="changeAttachmentsViewMode(viewMode)"
|
|
||||||
v-html="i18n.t(`attachments.view_mode.${viewMode}_html`)"
|
|
||||||
></a>
|
|
||||||
</li>
|
|
||||||
</template>
|
|
||||||
</ul>
|
|
||||||
</div>
|
|
||||||
<div ref="sortDropdownButton" class="dropdown sci-dropdown">
|
|
||||||
<button class="btn btn-light icon-btn dropdown-toggle" type="button" id="dropdownSortAttachmentsOptions" data-toggle="dropdown" aria-haspopup="true" aria-expanded="true">
|
|
||||||
<i class="sn-icon sn-icon-sort-up"></i>
|
|
||||||
</button>
|
|
||||||
<ul ref="sortDropdown" class="dropdown-menu dropdown-menu-right dropdown-attachment-options"
|
|
||||||
aria-labelledby="dropdownSortAttachmentsOptions"
|
|
||||||
:data-parent-id="parent.id"
|
|
||||||
>
|
|
||||||
<li v-for="(orderOption, index) in orderOptions" :key="`orderOption_${index}`" :class="{'divider' : (orderOption == 'divider')}">
|
|
||||||
<a v-if="orderOption != 'divider'" class="action-link change-order"
|
|
||||||
@click="changeAttachmentsOrder(orderOption)"
|
|
||||||
:class="parent.attributes.assets_order == orderOption ? 'selected' : ''"
|
|
||||||
>
|
|
||||||
{{ i18n.t(`general.sort_new.${orderOption}`) }}
|
|
||||||
</a>
|
|
||||||
</li>
|
|
||||||
</ul>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="attachments" :data-parent-id="parent.id">
|
<div class="attachments" :data-parent-id="parent.id">
|
||||||
|
@ -68,6 +43,7 @@
|
||||||
import thumbnailAttachment from './attachments/thumbnail.vue'
|
import thumbnailAttachment from './attachments/thumbnail.vue'
|
||||||
import uploadingAttachment from './attachments/uploading.vue'
|
import uploadingAttachment from './attachments/uploading.vue'
|
||||||
import emptyAttachment from './attachments/empty.vue'
|
import emptyAttachment from './attachments/empty.vue'
|
||||||
|
import MenuDropdown from '../menu_dropdown.vue'
|
||||||
|
|
||||||
import WopiFileModal from './attachments/mixins/wopi_file_modal.js'
|
import WopiFileModal from './attachments/mixins/wopi_file_modal.js'
|
||||||
|
|
||||||
|
@ -90,7 +66,7 @@
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
viewModeOptions: ['inline', 'thumbnail', 'list'],
|
viewModeOptions: ['inline', 'thumbnail', 'list'],
|
||||||
orderOptions: ['new', 'old', 'divider', 'atoz', 'ztoa']
|
orderOptions: ['new', 'old', 'atoz', 'ztoa']
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
mixins: [WopiFileModal, AttachmentMovedMixin],
|
mixins: [WopiFileModal, AttachmentMovedMixin],
|
||||||
|
@ -99,7 +75,8 @@
|
||||||
inlineAttachment,
|
inlineAttachment,
|
||||||
listAttachment,
|
listAttachment,
|
||||||
uploadingAttachment,
|
uploadingAttachment,
|
||||||
emptyAttachment
|
emptyAttachment,
|
||||||
|
MenuDropdown
|
||||||
},
|
},
|
||||||
watch: {
|
watch: {
|
||||||
attachmentsReady() {
|
attachmentsReady() {
|
||||||
|
@ -128,6 +105,29 @@
|
||||||
|
|
||||||
return a.attributes.asset_order > b.attributes.asset_order ? 1 : -1;
|
return a.attributes.asset_order > b.attributes.asset_order ? 1 : -1;
|
||||||
})
|
})
|
||||||
|
},
|
||||||
|
viewModeMenu() {
|
||||||
|
let menu = [];
|
||||||
|
this.viewModeOptions.forEach((viewMode) => {
|
||||||
|
menu.push({
|
||||||
|
text: this.i18n.t(`attachments.view_mode.${viewMode}_html`),
|
||||||
|
emit: 'attachment:viewMode',
|
||||||
|
params: viewMode
|
||||||
|
})
|
||||||
|
})
|
||||||
|
return menu;
|
||||||
|
},
|
||||||
|
sortMenu() {
|
||||||
|
let menu = [];
|
||||||
|
this.orderOptions.forEach((orderOption, i) => {
|
||||||
|
menu.push({
|
||||||
|
text: this.i18n.t(`general.sort_new.${orderOption}`),
|
||||||
|
emit: 'attachment:order',
|
||||||
|
params: orderOption,
|
||||||
|
dividerBefore: i === 2
|
||||||
|
})
|
||||||
|
})
|
||||||
|
return menu;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
mounted() {
|
mounted() {
|
||||||
|
|
|
@ -1,88 +1,39 @@
|
||||||
<template>
|
<template>
|
||||||
<div class="dropdown asset-context-menu" ref="menu">
|
<div class="asset-context-menu" ref="menu">
|
||||||
<button class="btn btn-light btn-xs dropdown-toggle icon-btn" type="button" id="dropdownAssetContextMenu" data-toggle="dropdown" aria-haspopup="true" aria-expanded="true">
|
<a class="marvinjs-edit-button hidden"
|
||||||
<i class="sn-icon sn-icon-more-hori"></i>
|
v-if="attachment.attributes.asset_type == 'marvinjs' && attachment.attributes.urls.marvin_js_start_edit"
|
||||||
</button>
|
ref="marvinjsEditButton"
|
||||||
|
:data-sketch-id="attachment.id"
|
||||||
<ul class="dropdown-menu dropdown-menu-right"
|
:data-update-url="attachment.attributes.urls.marvin_js"
|
||||||
aria-labelledby="dropdownAssetContextMenu"
|
:data-sketch-start-edit-url="attachment.attributes.urls.marvin_js_start_edit"
|
||||||
:data-asset-id="attachment.id"
|
:data-sketch-name="attachment.attributes.metadata.name"
|
||||||
>
|
:data-sketch-description="attachment.attributes.metadata.description"
|
||||||
<li v-if="attachment.attributes.wopi && attachment.attributes.urls.edit_asset" >
|
></a>
|
||||||
<a :href="attachment.attributes.urls.edit_asset"
|
<a class="image-edit-button hidden"
|
||||||
id="wopi_file_edit_button"
|
v-if="attachment.attributes.asset_type != 'marvinjs'
|
||||||
class="btn btn-light"
|
&& attachment.attributes.image_editable
|
||||||
:class="attachment.attributes.wopi_context.edit_supported ? '' : 'disabled'"
|
&& attachment.attributes.urls.start_edit_image"
|
||||||
:title="attachment.attributes.wopi_context.title"
|
ref="imageEditButton"
|
||||||
target="_blank"
|
:data-image-id="attachment.id"
|
||||||
>
|
:data-image-name="attachment.attributes.file_name"
|
||||||
{{ attachment.attributes.wopi_context.button_text }}
|
:data-image-url="attachment.attributes.urls.asset_file"
|
||||||
</a>
|
:data-image-quality="attachment.attributes.image_context.quality"
|
||||||
</li>
|
:data-image-mime-type="attachment.attributes.image_context.type"
|
||||||
<li v-if="attachment.attributes.asset_type == 'gene_sequence' && attachment.attributes.urls.open_vector_editor_edit">
|
:data-image-start-edit-url="attachment.attributes.urls.start_edit_image"
|
||||||
<a class="ove-edit-button" @click="openOVEditor(attachment.attributes.urls.open_vector_editor_edit)">
|
></a>
|
||||||
{{ i18n.t('open_vector_editor.edit_sequence') }}
|
<MenuDropdown
|
||||||
</a>
|
class="ml-auto"
|
||||||
</li>
|
:listItems="this.menu"
|
||||||
<li v-if="attachment.attributes.asset_type == 'marvinjs' && attachment.attributes.urls.marvin_js_start_edit">
|
:btnClasses="'btn btn-light icon-btn !bg-sn-white'"
|
||||||
<a class="marvinjs-edit-button"
|
:position="'right'"
|
||||||
:data-sketch-id="attachment.id"
|
:btnIcon="'sn-icon sn-icon-more-hori'"
|
||||||
:data-update-url="attachment.attributes.urls.marvin_js"
|
@open_ove_editor="openOVEditor(attachment.attributes.urls.open_vector_editor_edit)"
|
||||||
:data-sketch-start-edit-url="attachment.attributes.urls.marvin_js_start_edit"
|
@open_marvinjs_editor="openMarvinJsEditor"
|
||||||
:data-sketch-name="attachment.attributes.metadata.name"
|
@open_scinote_editor="openScinoteEditor"
|
||||||
:data-sketch-description="attachment.attributes.metadata.description"
|
@delete="deleteModal = true"
|
||||||
>
|
@viewMode="changeViewMode"
|
||||||
{{ i18n.t('assets.file_preview.edit_in_marvinjs') }}
|
@move="showMoveModal"
|
||||||
</a>
|
></MenuDropdown>
|
||||||
</li>
|
|
||||||
<li v-if="attachment.attributes.asset_type != 'marvinjs'
|
|
||||||
&& attachment.attributes.image_editable
|
|
||||||
&& attachment.attributes.urls.start_edit_image">
|
|
||||||
<a class="image-edit-button"
|
|
||||||
:data-image-id="attachment.id"
|
|
||||||
:data-image-name="attachment.attributes.file_name"
|
|
||||||
:data-image-url="attachment.attributes.urls.asset_file"
|
|
||||||
:data-image-quality="attachment.attributes.image_context.quality"
|
|
||||||
:data-image-mime-type="attachment.attributes.image_context.type"
|
|
||||||
:data-image-start-edit-url="attachment.attributes.urls.start_edit_image"
|
|
||||||
>
|
|
||||||
{{ i18n.t('assets.file_preview.edit_in_scinote') }}
|
|
||||||
</a>
|
|
||||||
</li>
|
|
||||||
<li>
|
|
||||||
<a :href="attachment.attributes.urls.download" data-turbolinks="false">
|
|
||||||
{{ i18n.t('Download') }}
|
|
||||||
</a>
|
|
||||||
</li>
|
|
||||||
<template v-if="attachment.attributes.urls.move_targets">
|
|
||||||
<li>
|
|
||||||
<a @click.prevent.stop="showMoveModal">
|
|
||||||
{{ i18n.t("assets.context_menu.move") }}
|
|
||||||
</a>
|
|
||||||
</li>
|
|
||||||
</template>
|
|
||||||
<template v-if="attachment.attributes.urls.delete">
|
|
||||||
<li>
|
|
||||||
<a @click.prevent.stop="deleteModal = true">
|
|
||||||
{{ i18n.t("assets.context_menu.delete") }}
|
|
||||||
</a>
|
|
||||||
</li>
|
|
||||||
</template>
|
|
||||||
<template v-if="attachment.attributes.urls.toggle_view_mode">
|
|
||||||
<li role="separator" class="divider"></li>
|
|
||||||
<li class="divider-label">
|
|
||||||
{{ i18n.t("assets.context_menu.set_view_size") }}
|
|
||||||
</li>
|
|
||||||
<li v-for="(viewMode, index) in viewModeOptions" :key="`viewMode_${index}`">
|
|
||||||
<a
|
|
||||||
class="change-preview-type"
|
|
||||||
:class="viewMode == attachment.attributes.view_mode ? 'selected' : ''"
|
|
||||||
@click.prevent.stop="changeViewMode(viewMode)"
|
|
||||||
v-html="i18n.t(`assets.context_menu.${viewMode}_html`)"
|
|
||||||
></a>
|
|
||||||
</li>
|
|
||||||
</template>
|
|
||||||
</ul>
|
|
||||||
<deleteAttachmentModal
|
<deleteAttachmentModal
|
||||||
v-if="deleteModal"
|
v-if="deleteModal"
|
||||||
:fileName="attachment.attributes.file_name"
|
:fileName="attachment.attributes.file_name"
|
||||||
|
@ -100,10 +51,11 @@
|
||||||
import deleteAttachmentModal from './delete_modal.vue'
|
import deleteAttachmentModal from './delete_modal.vue'
|
||||||
import moveAssetModal from '../modal/move.vue'
|
import moveAssetModal from '../modal/move.vue'
|
||||||
import MoveMixin from './mixins/move.js'
|
import MoveMixin from './mixins/move.js'
|
||||||
|
import MenuDropdown from '../../menu_dropdown.vue'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'contextMenu',
|
name: 'contextMenu',
|
||||||
components: { deleteAttachmentModal, moveAssetModal },
|
components: { deleteAttachmentModal, moveAssetModal, MenuDropdown },
|
||||||
mixins: [MoveMixin],
|
mixins: [MoveMixin],
|
||||||
props: {
|
props: {
|
||||||
attachment: {
|
attachment: {
|
||||||
|
@ -117,17 +69,65 @@
|
||||||
deleteModal: false
|
deleteModal: false
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
mounted() {
|
computed: {
|
||||||
$(this.$refs.menu).on('show.bs.dropdown', function() {
|
menu() {
|
||||||
let screenHeight = screen.height;
|
let menu = [];
|
||||||
let dropdownPosition = this.getBoundingClientRect().y;
|
if (this.attachment.attributes.wopi && this.attachment.attributes.urls.edit_asset) {
|
||||||
let dropdownMenu = $(this).find('.dropdown-menu');
|
menu.push({
|
||||||
if ((screenHeight / 2) < dropdownPosition) {
|
text: this.attachment.attributes.wopi_context.button_text,
|
||||||
dropdownMenu.css({ top: 'unset', bottom: '100%' });
|
url: this.attachment.attributes.urls.edit_asset,
|
||||||
} else {
|
url_target: '_blank'
|
||||||
dropdownMenu.css({ bottom: 'unset', top: '100%' });
|
})
|
||||||
}
|
}
|
||||||
})
|
if (this.attachment.attributes.asset_type == 'gene_sequence' && this.attachment.attributes.urls.open_vector_editor_edit) {
|
||||||
|
menu.push({
|
||||||
|
text: this.i18n.t('open_vector_editor.edit_sequence'),
|
||||||
|
emit: 'open_ove_editor',
|
||||||
|
})
|
||||||
|
}
|
||||||
|
if (this.attachment.attributes.asset_type == 'marvinjs' && this.attachment.attributes.urls.marvin_js_start_edit) {
|
||||||
|
menu.push({
|
||||||
|
text: this.i18n.t('assets.file_preview.edit_in_marvinjs'),
|
||||||
|
emit: 'open_marvinjs_editor',
|
||||||
|
})
|
||||||
|
}
|
||||||
|
if (this.attachment.attributes.asset_type != 'marvinjs'
|
||||||
|
&& this.attachment.attributes.image_editable
|
||||||
|
&& this.attachment.attributes.urls.start_edit_image) {
|
||||||
|
menu.push({
|
||||||
|
text: this.i18n.t('assets.file_preview.edit_in_scinote'),
|
||||||
|
emit: 'open_scinote_editor',
|
||||||
|
})
|
||||||
|
}
|
||||||
|
menu.push({
|
||||||
|
text: this.i18n.t('Download'),
|
||||||
|
url: this.attachment.attributes.urls.download,
|
||||||
|
url_target: '_blank'
|
||||||
|
})
|
||||||
|
if (this.attachment.attributes.urls.move_targets) {
|
||||||
|
menu.push({
|
||||||
|
text: this.i18n.t('assets.context_menu.move'),
|
||||||
|
emit: 'move'
|
||||||
|
})
|
||||||
|
}
|
||||||
|
if (this.attachment.attributes.urls.delete) {
|
||||||
|
menu.push({
|
||||||
|
text: this.i18n.t('assets.context_menu.delete'),
|
||||||
|
emit: 'delete'
|
||||||
|
})
|
||||||
|
}
|
||||||
|
if (this.attachment.attributes.urls.toggle_view_mode) {
|
||||||
|
this.viewModeOptions.forEach((viewMode, i) => {
|
||||||
|
menu.push({
|
||||||
|
text: this.i18n.t(`assets.context_menu.${viewMode}_html`),
|
||||||
|
emit: 'viewMode',
|
||||||
|
params: viewMode,
|
||||||
|
dividerBefore: i === 0
|
||||||
|
})
|
||||||
|
})
|
||||||
|
}
|
||||||
|
return menu;
|
||||||
|
}
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
changeViewMode(viewMode) {
|
changeViewMode(viewMode) {
|
||||||
|
@ -145,7 +145,14 @@
|
||||||
},
|
},
|
||||||
openOVEditor(url) {
|
openOVEditor(url) {
|
||||||
window.showIFrameModal(url);
|
window.showIFrameModal(url);
|
||||||
}
|
},
|
||||||
|
openMarvinJsEditor() {
|
||||||
|
console.log(this.$refs)
|
||||||
|
$(this.$refs.marvinjsEditButton).trigger('click');
|
||||||
|
},
|
||||||
|
openScinoteEditor() {
|
||||||
|
$(this.$refs.imageEditButton).trigger('click');
|
||||||
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
|
@ -7,8 +7,7 @@ export default {
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
showMoveModal(event) {
|
showMoveModal() {
|
||||||
event.stopPropagation();
|
|
||||||
this.movingAttachment = true;
|
this.movingAttachment = true;
|
||||||
},
|
},
|
||||||
closeMoveModal() {
|
closeMoveModal() {
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
<template>
|
<template>
|
||||||
<div class="w-full relative">
|
<div class="w-full relative flex">
|
||||||
<template v-if="editing">
|
<template v-if="editing">
|
||||||
<input type="text"
|
<input type="text"
|
||||||
v-if="singleLine"
|
v-if="singleLine"
|
||||||
|
@ -18,7 +18,7 @@
|
||||||
@focus="setCaretAtEnd"/>
|
@focus="setCaretAtEnd"/>
|
||||||
<textarea v-else
|
<textarea v-else
|
||||||
ref="input"
|
ref="input"
|
||||||
class="overflow-hidden leading-5 inline-block outline-none px-0 py-1 border-0 border-solid border-b w-full border-t-transparent"
|
class="overflow-hidden leading-5 inline-block outline-none px-0 py-1 border-0 border-solid border-y w-full border-t-transparent mb-[1px]"
|
||||||
:class="{
|
:class="{
|
||||||
'inline-edit-placeholder text-sn-grey caret-black': isBlank,
|
'inline-edit-placeholder text-sn-grey caret-black': isBlank,
|
||||||
'border-sn-delete-red': error,
|
'border-sn-delete-red': error,
|
||||||
|
@ -269,7 +269,7 @@
|
||||||
if (this.editing && !this.singleLine) {
|
if (this.editing && !this.singleLine) {
|
||||||
this.$nextTick(() => {
|
this.$nextTick(() => {
|
||||||
this.$refs.input.style.height = '0px';
|
this.$refs.input.style.height = '0px';
|
||||||
this.$refs.input.style.height = this.$refs.input.scrollHeight - 3 + 'px';
|
this.$refs.input.style.height = this.$refs.input.scrollHeight + 'px';
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,22 +3,48 @@
|
||||||
<button ref="openBtn" :class="btnClasses" @click="showMenu = !showMenu">
|
<button ref="openBtn" :class="btnClasses" @click="showMenu = !showMenu">
|
||||||
<i v-if="btnIcon" :class="btnIcon"></i>
|
<i v-if="btnIcon" :class="btnIcon"></i>
|
||||||
{{ btnText }}
|
{{ btnText }}
|
||||||
<i v-if="caret && showMenu" class="fas fa-caret-up"></i>
|
<i v-if="caret && showMenu" class="sn-icon sn-icon-up"></i>
|
||||||
<i v-else-if="caret" class="fas fa-caret-down"></i>
|
<i v-else-if="caret" class="sn-icon sn-icon-down"></i>
|
||||||
</button>
|
</button>
|
||||||
<div ref="flyout"
|
<div ref="flyout"
|
||||||
class="absolute z-50 bg-sn-white rounded p-2.5 sn-shadow-menu-sm"
|
class="absolute z-[150] bg-sn-white rounded p-2.5 sn-shadow-menu-sm min-w-full"
|
||||||
:class="{'right-0': position === 'right', 'left-0': position === 'left'}"
|
:class="{'right-0': position === 'right', 'left-0': position === 'left'}"
|
||||||
v-if="showMenu"
|
v-if="showMenu"
|
||||||
v-click-outside="{handler: 'closeMenu', exclude: ['openBtn', 'flyout']}">
|
v-click-outside="{handler: 'closeMenu', exclude: ['openBtn', 'flyout']}">
|
||||||
<a v-for="(item, i) in listItems"
|
<span v-for="(item, i) in listItems" :key="i">
|
||||||
:key="i"
|
<a :href="item.url" v-if="!item.submenu"
|
||||||
:href="item.url"
|
:class="{'border-0 border-t border-solid border-sn-light-grey': item.dividerBefore}"
|
||||||
class="block whitespace-nowrap px-3 py-2.5 hover:no-underline cursor-pointer hover:bg-sn-super-light-blue"
|
:traget="item.url_target || '_self'"
|
||||||
@click="handleClick($event, item)"
|
class="block whitespace-nowrap px-3 py-2.5 hover:no-underline cursor-pointer hover:bg-sn-super-light-blue"
|
||||||
>
|
@click="handleClick($event, item)"
|
||||||
{{ item.text }}
|
>
|
||||||
</a>
|
{{ item.text }}
|
||||||
|
</a>
|
||||||
|
<span v-else
|
||||||
|
@click="showSubmenu = i"
|
||||||
|
:class="{'!bg-sn-super-light-grey': showSubmenu == i}"
|
||||||
|
class="flex group items-center relative text-sn-blue whitespace-nowrap px-3 py-2.5 hover:no-underline cursor-pointer hover:bg-sn-super-light-blue"
|
||||||
|
>
|
||||||
|
{{ item.text }}
|
||||||
|
<i class="sn-icon sn-icon-right ml-auto"></i>
|
||||||
|
<div v-if="showSubmenu == i"
|
||||||
|
class="absolute top-0 bg-sn-white rounded p-2.5 sn-shadow-menu-sm"
|
||||||
|
:class="{
|
||||||
|
'left-0 ml-[calc(100%_+_0.625rem)]': item.position === 'right',
|
||||||
|
'right-0 mr-[calc(100%_+_0.625rem)]': item.position === 'left'
|
||||||
|
}"
|
||||||
|
>
|
||||||
|
<a v-for="(sub_item, si) in item.submenu" :key="si"
|
||||||
|
:href="sub_item.url"
|
||||||
|
:traget="sub_item.url_target || '_self'"
|
||||||
|
class="block whitespace-nowrap px-3 py-2.5 hover:no-underline cursor-pointer hover:bg-sn-super-light-blue"
|
||||||
|
@click="handleClick($event, sub_item)"
|
||||||
|
>
|
||||||
|
{{ sub_item.text }}
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
</span>
|
||||||
|
</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
@ -28,7 +54,7 @@
|
||||||
export default {
|
export default {
|
||||||
name: 'DropdownMenu',
|
name: 'DropdownMenu',
|
||||||
props: {
|
props: {
|
||||||
listItems: { type: Array, required: true },
|
listItems: { type: Array, default: () => [] },
|
||||||
position: { type: String, default: 'left' },
|
position: { type: String, default: 'left' },
|
||||||
btnClasses: { type: String, default: 'btn btn-light' },
|
btnClasses: { type: String, default: 'btn btn-light' },
|
||||||
btnText: { type: String, required: false },
|
btnText: { type: String, required: false },
|
||||||
|
@ -38,11 +64,13 @@ export default {
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
showMenu: false,
|
showMenu: false,
|
||||||
|
showSubmenu: null,
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
closeMenu() {
|
closeMenu() {
|
||||||
this.showMenu = false;
|
this.showMenu = false;
|
||||||
|
this.showSubmenu = null;
|
||||||
},
|
},
|
||||||
handleClick(event, item) {
|
handleClick(event, item) {
|
||||||
if (!item.url) {
|
if (!item.url) {
|
||||||
|
@ -50,10 +78,10 @@ export default {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (item.emit) {
|
if (item.emit) {
|
||||||
this.$emit(item.emit)
|
this.$emit(item.emit, item.params)
|
||||||
}
|
}
|
||||||
|
|
||||||
this.showMenu = false;
|
this.closeMenu();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue