From 4659f34e1ec19877a76699e4a48aee17f2b1aebe Mon Sep 17 00:00:00 2001 From: Ahmed Awan Date: Thu, 22 Feb 2024 19:02:02 -0600 Subject: [PATCH] add multi drag/drop for Tool forms as well Also allow dropping multiple histories to create a new history in multiview. --- .../components/ActivityBar/ActivityBar.vue | 2 +- .../Form/Elements/FormData/FormData.vue | 6 +- .../History/CurrentHistory/HistoryPanel.vue | 30 ++++++-- .../History/Multiple/MultipleViewList.vue | 68 ++++++++++++++----- 4 files changed, 83 insertions(+), 23 deletions(-) diff --git a/client/src/components/ActivityBar/ActivityBar.vue b/client/src/components/ActivityBar/ActivityBar.vue index baf94bb99493..9bfea756a65e 100644 --- a/client/src/components/ActivityBar/ActivityBar.vue +++ b/client/src/components/ActivityBar/ActivityBar.vue @@ -72,7 +72,7 @@ function panelActivityIsActive(activity: Activity) { */ function onDragEnter(evt: MouseEvent) { const eventData = eventStore.getDragData(); - if (eventData) { + if (eventData && !eventStore.multipleDragData) { dragTarget.value = evt.target; dragItem.value = convertDropData(eventData); emit("dragstart", dragItem.value); diff --git a/client/src/components/Form/Elements/FormData/FormData.vue b/client/src/components/Form/Elements/FormData/FormData.vue index 68b0ac9530ed..87ecd98f4928 100644 --- a/client/src/components/Form/Elements/FormData/FormData.vue +++ b/client/src/components/Form/Elements/FormData/FormData.vue @@ -394,7 +394,11 @@ function onDragOver() { function onDrop() { if (dragData.value) { - handleIncoming(dragData.value); + if (eventStore.multipleDragData) { + handleIncoming(Object.values(dragData.value) as any, false); + } else { + handleIncoming(dragData.value); + } currentHighlighting.value = "success"; dragData.value = null; clearHighlighting(); diff --git a/client/src/components/History/CurrentHistory/HistoryPanel.vue b/client/src/components/History/CurrentHistory/HistoryPanel.vue index e7a0c82ee656..f5372a39e91e 100644 --- a/client/src/components/History/CurrentHistory/HistoryPanel.vue +++ b/client/src/components/History/CurrentHistory/HistoryPanel.vue @@ -335,6 +335,8 @@ async function onDrop(evt: any) { return; } + let datasetCount = 0; + let collectionCount = 0; try { // iterate over the data array and copy each item to the current history for (const item of data) { @@ -342,12 +344,24 @@ async function onDrop(evt: any) { await copyDataset(item.id, props.history.id, item.history_content_type, dataSource); if (item.history_content_type === "dataset") { - Toast.info("Dataset copied to history"); + datasetCount++; + if (!multiple) { + Toast.info("Dataset copied to history"); + } } else { - Toast.info("Collection copied to history"); + collectionCount++; + if (!multiple) { + Toast.info("Collection copied to history"); + } } } + if (multiple && datasetCount > 0) { + Toast.info(`${datasetCount} datasets copied to history`); + } + if (multiple && collectionCount > 0) { + Toast.info(`${collectionCount} collections copied to history`); + } historyStore.loadHistoryById(props.history.id); } catch (error) { Toast.error(`${error}`); @@ -395,12 +409,12 @@ function arrowNavigate(item: HistoryItem, eventKey: string) { function setItemDragstart( item: HistoryItem, - showSelection: boolean, + itemIsSelected: boolean, selectedItems: Map, selectionSize: number, event: DragEvent ) { - if (showSelection && selectionSize > 1) { + if (itemIsSelected && selectionSize > 1) { const selectedItemsObj: any = {}; for (const [key, value] of selectedItems) { selectedItemsObj[key] = value; @@ -561,7 +575,13 @@ function setItemDragstart( initKeySelection(); " @drag-start=" - setItemDragstart(item, showSelection, selectedItems, selectionSize, $event) + setItemDragstart( + item, + showSelection && isSelected(item), + selectedItems, + selectionSize, + $event + ) " @hide-selection="setShowSelection(false)" @shift-select="(eventKey) => shiftSelect(nextSelections(item, eventKey))" diff --git a/client/src/components/History/Multiple/MultipleViewList.vue b/client/src/components/History/Multiple/MultipleViewList.vue index 99af2b246265..f312e894b21f 100644 --- a/client/src/components/History/Multiple/MultipleViewList.vue +++ b/client/src/components/History/Multiple/MultipleViewList.vue @@ -10,6 +10,8 @@ import { copyDataset } from "@/api/datasets"; import { useAnimationFrameResizeObserver } from "@/composables/sensors/animationFrameResizeObserver"; import { useAnimationFrameScroll } from "@/composables/sensors/animationFrameScroll"; import { Toast } from "@/composables/toast"; +import { useEventStore } from "@/stores/eventStore"; +import type { HistoryItem } from "@/stores/historyItemsStore"; import { useHistoryStore } from "@/stores/historyStore"; import localize from "@/utils/localization"; import { errorMessageAsString } from "@/utils/simple-error"; @@ -66,35 +68,69 @@ async function createAndPin() { const showDropZone = ref(false); const processingDrop = ref(false); async function onDrop(evt: any) { + const eventStore = useEventStore(); if (processingDrop.value) { showDropZone.value = false; return; } processingDrop.value = true; showDropZone.value = false; - let data: any; + let data: HistoryItem[] | undefined; + let originalHistoryId: string | undefined; + const multiple = eventStore.multipleDragData; try { - data = JSON.parse(evt.dataTransfer.getData("text"))[0]; + if (multiple) { + const dragData = eventStore.getDragData() as Record; + // set originalHistoryId to the first history_id in the multiple drag data + const firstItem = Object.values(dragData)[0]; + if (firstItem) { + originalHistoryId = firstItem.history_id; + } + data = Object.values(dragData); + } else { + data = [eventStore.getDragData() as HistoryItem]; + if (data[0]) { + originalHistoryId = data[0].history_id; + } + } } catch (error) { // this was not a valid object for this dropzone, ignore } - if (data) { - const originalHistoryId = data.history_id; + + if (data && originalHistoryId) { await historyStore.createNewHistory(); const currentHistoryId = historyStore.currentHistoryId; - const dataSource = data.history_content_type === "dataset" ? "hda" : "hdca"; + + let datasetCount = 0; + let collectionCount = 0; if (currentHistoryId) { - await copyDataset(data.id, currentHistoryId, data.history_content_type, dataSource) - .then(() => { - if (data.history_content_type === "dataset") { - Toast.info(localize("Dataset copied to new history")); - } else { - Toast.info(localize("Collection copied to new history")); - } - }) - .catch((error) => { - Toast.error(errorMessageAsString(error)); - }); + // iterate over the data array and copy each item to the new history + for (const item of data) { + const dataSource = item.history_content_type === "dataset" ? "hda" : "hdca"; + await copyDataset(item.id, currentHistoryId, item.history_content_type, dataSource) + .then(() => { + if (item.history_content_type === "dataset") { + datasetCount++; + if (!multiple) { + Toast.info(localize("Dataset copied to new history")); + } + } else { + collectionCount++; + if (!multiple) { + Toast.info(localize("Collection copied to new history")); + } + } + }) + .catch((error) => { + Toast.error(errorMessageAsString(error)); + }); + } + if (multiple && datasetCount > 0) { + Toast.info(`${datasetCount} dataset${datasetCount > 1 ? "s" : ""} copied to new history`); + } + if (multiple && collectionCount > 0) { + Toast.info(`${collectionCount} collection${collectionCount > 1 ? "s" : ""} copied to new history`); + } // pin the newly created history via the drop historyStore.pinHistory(currentHistoryId); // also pin the original history where the item came from