mirror of
https://github.com/scinote-eln/scinote-web.git
synced 2025-09-10 23:25:31 +08:00
Add drag n drop to results [SCI-9576]
This commit is contained in:
parent
d6f03c6bcc
commit
3dd36e1dda
4 changed files with 54 additions and 6 deletions
|
@ -1,6 +1,17 @@
|
||||||
<template>
|
<template>
|
||||||
<div class="result-wrapper bg-white p-4 mb-4 rounded">
|
<div class="result-wrapper p-4 mb-4 rounded relative"
|
||||||
<div class="result-header flex justify-between ">
|
@drop.prevent="dropFile"
|
||||||
|
@dragenter.prevent="dragEnter($event)"
|
||||||
|
@dragover.prevent
|
||||||
|
:class="{ 'bg-sn-super-light-blue': dragingFile, 'bg-white': !dragingFile }"
|
||||||
|
>
|
||||||
|
<div class="text-xl items-center flex text-sn-blue h-full justify-center left-0 absolute top-0 w-full"
|
||||||
|
v-if="dragingFile"
|
||||||
|
@dragleave.prevent="dragingFile = false">
|
||||||
|
{{ i18n.t('my_modules.results.drop_message', { name: result.attributes.name }) }}
|
||||||
|
<StorageUsage v-if="showStorageUsage()" :parent="result"/>
|
||||||
|
</div>
|
||||||
|
<div class="result-header flex justify-between" :class="{ 'opacity-0 pointer-events-none': dragingFile }">
|
||||||
<div class="result-head-left flex items-start flex-grow gap-4">
|
<div class="result-head-left flex items-start flex-grow gap-4">
|
||||||
<a class="result-collapse-link hover:no-underline focus:no-underline py-0.5 border-0 border-y border-transparent border-solid text-sn-black"
|
<a class="result-collapse-link hover:no-underline focus:no-underline py-0.5 border-0 border-y border-transparent border-solid text-sn-black"
|
||||||
:href="'#resultBody' + result.id"
|
:href="'#resultBody' + result.id"
|
||||||
|
@ -85,7 +96,7 @@
|
||||||
@reorder="updateElementOrder"
|
@reorder="updateElementOrder"
|
||||||
@close="closeReorderModal"
|
@close="closeReorderModal"
|
||||||
/>
|
/>
|
||||||
<div class="collapse in pl-10" :id="'resultBody' + result.id">
|
<div class="collapse in pl-10" :class="{ 'opacity-0 pointer-events-none': dragingFile }" :id="'resultBody' + result.id">
|
||||||
<div v-for="(element, index) in orderedElements" :key="element.id">
|
<div v-for="(element, index) in orderedElements" :key="element.id">
|
||||||
<component
|
<component
|
||||||
:is="elements[index].attributes.orderable_type"
|
:is="elements[index].attributes.orderable_type"
|
||||||
|
@ -130,12 +141,17 @@
|
||||||
import WopiFileModal from '../shared/content/attachments/mixins/wopi_file_modal.js'
|
import WopiFileModal from '../shared/content/attachments/mixins/wopi_file_modal.js'
|
||||||
import OveMixin from '../shared/content/attachments/mixins/ove.js'
|
import OveMixin from '../shared/content/attachments/mixins/ove.js'
|
||||||
import UtilsMixin from '../mixins/utils.js'
|
import UtilsMixin from '../mixins/utils.js'
|
||||||
|
import StorageUsage from '../shared/content/attachments/storage_usage.vue'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'Results',
|
name: 'Results',
|
||||||
props: {
|
props: {
|
||||||
result: { type: Object, required: true },
|
result: { type: Object, required: true },
|
||||||
resultToReload: { type: Number, required: false }
|
resultToReload: { type: Number, required: false },
|
||||||
|
activeDragResult: {
|
||||||
|
type: Number,
|
||||||
|
required: false
|
||||||
|
}
|
||||||
},
|
},
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
|
@ -144,6 +160,7 @@
|
||||||
attachments: [],
|
attachments: [],
|
||||||
attachmentsReady: false,
|
attachmentsReady: false,
|
||||||
showFileModal: false,
|
showFileModal: false,
|
||||||
|
dragingFile: false,
|
||||||
wellPlateOptions: [
|
wellPlateOptions: [
|
||||||
{ text: I18n.t('protocols.steps.insert.well_plate_options.32_x_48'), emit: 'create:table', params: [[32, 48], true] },
|
{ text: I18n.t('protocols.steps.insert.well_plate_options.32_x_48'), emit: 'create:table', params: [[32, 48], true] },
|
||||||
{ text: I18n.t('protocols.steps.insert.well_plate_options.16_x_24'), emit: 'create:table', params: [[16, 24], true] },
|
{ text: I18n.t('protocols.steps.insert.well_plate_options.16_x_24'), emit: 'create:table', params: [[16, 24], true] },
|
||||||
|
@ -164,7 +181,8 @@
|
||||||
Attachments,
|
Attachments,
|
||||||
InlineEdit,
|
InlineEdit,
|
||||||
MenuDropdown,
|
MenuDropdown,
|
||||||
deleteResultModal
|
deleteResultModal,
|
||||||
|
StorageUsage
|
||||||
},
|
},
|
||||||
watch: {
|
watch: {
|
||||||
resultToReload() {
|
resultToReload() {
|
||||||
|
@ -172,6 +190,11 @@
|
||||||
this.loadElements();
|
this.loadElements();
|
||||||
this.loadAttachments();
|
this.loadAttachments();
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
activeDragResult() {
|
||||||
|
if (this.activeDragResult != this.result.id && this.dragingFile) {
|
||||||
|
this.dragingFile = false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
|
@ -277,6 +300,20 @@
|
||||||
this.loadElements();
|
this.loadElements();
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
|
dragEnter(e) {
|
||||||
|
if (!this.urls.upload_attachment_url) return;
|
||||||
|
|
||||||
|
// Detect if dragged element is a file
|
||||||
|
// https://stackoverflow.com/a/8494918
|
||||||
|
let dt = e.dataTransfer;
|
||||||
|
if (dt.types && (dt.types.indexOf ? dt.types.indexOf('Files') != -1 : dt.types.contains('Files'))) {
|
||||||
|
this.dragingFile = true;
|
||||||
|
this.$emit('result:drag_enter', this.result.id);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
showStorageUsage() {
|
||||||
|
return (this.elements.length || this.attachments.length) && !this.isCollapsed && this.result.attributes.storage_limit;
|
||||||
|
},
|
||||||
openReorderModal() {
|
openReorderModal() {
|
||||||
this.reordering = true;
|
this.reordering = true;
|
||||||
},
|
},
|
||||||
|
|
|
@ -20,6 +20,7 @@
|
||||||
<Result v-for="result in results" :key="result.id"
|
<Result v-for="result in results" :key="result.id"
|
||||||
:result="result"
|
:result="result"
|
||||||
:resultToReload="resultToReload"
|
:resultToReload="resultToReload"
|
||||||
|
:activeDragResult="activeDragResult"
|
||||||
@result:elements:loaded="resultToReload = null"
|
@result:elements:loaded="resultToReload = null"
|
||||||
@result:move_element="reloadResult"
|
@result:move_element="reloadResult"
|
||||||
@result:attachments:loaded="resultToReload = null"
|
@result:attachments:loaded="resultToReload = null"
|
||||||
|
@ -28,6 +29,7 @@
|
||||||
@result:archived="removeResult"
|
@result:archived="removeResult"
|
||||||
@result:deleted="removeResult"
|
@result:deleted="removeResult"
|
||||||
@result:restored="removeResult"
|
@result:restored="removeResult"
|
||||||
|
@result:drag_enter="dragEnter"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -60,6 +62,7 @@
|
||||||
resultToReload: null,
|
resultToReload: null,
|
||||||
nextPageUrl: null,
|
nextPageUrl: null,
|
||||||
loadingPage: false,
|
loadingPage: false,
|
||||||
|
activeDragResult: null
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
mounted() {
|
mounted() {
|
||||||
|
@ -130,6 +133,9 @@
|
||||||
},
|
},
|
||||||
removeResult(result_id) {
|
removeResult(result_id) {
|
||||||
this.results = this.results.filter((r) => r.id != result_id);
|
this.results = this.results.filter((r) => r.id != result_id);
|
||||||
|
},
|
||||||
|
dragEnter(id) {
|
||||||
|
this.activeDragResult = id;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,7 +10,7 @@ class ResultSerializer < ActiveModel::Serializer
|
||||||
attributes :name, :id, :urls, :updated_at, :created_at_formatted, :updated_at_formatted, :user,
|
attributes :name, :id, :urls, :updated_at, :created_at_formatted, :updated_at_formatted, :user,
|
||||||
:my_module_id, :attachments_manageble, :marvinjs_enabled, :marvinjs_context, :type,
|
:my_module_id, :attachments_manageble, :marvinjs_enabled, :marvinjs_context, :type,
|
||||||
:wopi_enabled, :wopi_context, :created_at, :created_by, :archived, :assets_order,
|
:wopi_enabled, :wopi_context, :created_at, :created_by, :archived, :assets_order,
|
||||||
:open_vector_editor_context, :comments_count, :assets_view_mode
|
:open_vector_editor_context, :comments_count, :assets_view_mode, :storage_limit
|
||||||
|
|
||||||
def marvinjs_enabled
|
def marvinjs_enabled
|
||||||
MarvinJsService.enabled?
|
MarvinJsService.enabled?
|
||||||
|
@ -36,6 +36,10 @@ class ResultSerializer < ActiveModel::Serializer
|
||||||
scope
|
scope
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def storage_limit
|
||||||
|
nil
|
||||||
|
end
|
||||||
|
|
||||||
def marvinjs_context
|
def marvinjs_context
|
||||||
if marvinjs_enabled
|
if marvinjs_enabled
|
||||||
{
|
{
|
||||||
|
|
|
@ -1274,6 +1274,7 @@ en:
|
||||||
published_table: "entered a table on %{timestamp}."
|
published_table: "entered a table on %{timestamp}."
|
||||||
published_text: "entered a text on %{timestamp}."
|
published_text: "entered a text on %{timestamp}."
|
||||||
published_asset: "uploaded a file on %{timestamp}."
|
published_asset: "uploaded a file on %{timestamp}."
|
||||||
|
drop_message: "Drop file to add to result %{name}"
|
||||||
expand_label: "Expand All"
|
expand_label: "Expand All"
|
||||||
collapse_label: "Collapse All"
|
collapse_label: "Collapse All"
|
||||||
empty_name: "Add title"
|
empty_name: "Add title"
|
||||||
|
|
Loading…
Add table
Reference in a new issue