diff --git a/client/src/api/index.ts b/client/src/api/index.ts index d96eaedc56f8..d1dbc8854bbb 100644 --- a/client/src/api/index.ts +++ b/client/src/api/index.ts @@ -211,6 +211,10 @@ export function isHistorySummaryExtended(history: AnyHistory): history is Histor return "contents_active" in history && "user_id" in history; } +export function isHistoryItem(item: object): item is HistoryItemSummary { + return item && "history_content_type" in item; +} + type QuotaUsageResponse = components["schemas"]["UserQuotaUsage"]; /** Represents a registered user.**/ diff --git a/client/src/components/History/CurrentHistory/HistoryPanel.vue b/client/src/components/History/CurrentHistory/HistoryPanel.vue index 0d4cd40d8fd4..f1e94fd4ea68 100644 --- a/client/src/components/History/CurrentHistory/HistoryPanel.vue +++ b/client/src/components/History/CurrentHistory/HistoryPanel.vue @@ -3,7 +3,7 @@ import { BAlert } from "bootstrap-vue"; import { storeToRefs } from "pinia"; import { computed, onMounted, type Ref, ref, set as VueSet, unref, watch } from "vue"; -import { type HistoryItemSummary, type HistorySummaryExtended, userOwnsHistory } from "@/api"; +import { type HistoryItemSummary, type HistorySummaryExtended, isHistoryItem, userOwnsHistory } from "@/api"; import { copyDataset } from "@/api/datasets"; import ExpandedItems from "@/components/History/Content/ExpandedItems"; import SelectedItems from "@/components/History/Content/SelectedItems"; @@ -225,28 +225,11 @@ function dragSameHistory() { function getDragData() { const eventStore = useEventStore(); - const multiple = eventStore.multipleDragData; - let data: HistoryItemSummary[] | undefined; - let historyId: string | undefined; - try { - if (multiple) { - const dragData = eventStore.getDragData() as Record; - // set historyId to the first history_id in the multiple drag data - const firstItem = Object.values(dragData)[0]; - if (firstItem) { - historyId = firstItem.history_id; - } - data = Object.values(dragData); - } else { - data = [eventStore.getDragData() as HistoryItemSummary]; - if (data[0]) { - historyId = data[0].history_id; - } - } - } catch (error) { - // this was not a valid object for this dropzone, ignore - } - return { data, sameHistory: historyId === props.history.id, multiple }; + const dragItems = eventStore.getDragItems(); + // Filter out any non-history items + const historyItems = dragItems?.filter((item: any) => isHistoryItem(item)) as HistoryItemSummary[]; + const historyId = historyItems?.[0]?.history_id; + return { data: historyItems, sameHistory: historyId === props.history.id, multiple: historyItems?.length > 1 }; } function getHighlight(item: HistoryItemSummary) { diff --git a/client/src/components/History/Multiple/MultipleViewList.vue b/client/src/components/History/Multiple/MultipleViewList.vue index ea7d8da600cc..36eaac0e68cb 100644 --- a/client/src/components/History/Multiple/MultipleViewList.vue +++ b/client/src/components/History/Multiple/MultipleViewList.vue @@ -6,7 +6,7 @@ import { computed, type Ref, ref } from "vue"; //@ts-ignore missing typedefs import VirtualList from "vue-virtual-scroll-list"; -import { HistoryItemSummary } from "@/api"; +import { HistoryItemSummary, isHistoryItem } from "@/api"; import { copyDataset } from "@/api/datasets"; import { useAnimationFrameResizeObserver } from "@/composables/sensors/animationFrameResizeObserver"; import { useAnimationFrameScroll } from "@/composables/sensors/animationFrameScroll"; @@ -75,29 +75,13 @@ async function onDrop(evt: any) { } processingDrop.value = true; showDropZone.value = false; - let data: HistoryItemSummary[] | undefined; - let originalHistoryId: string | undefined; - const multiple = eventStore.multipleDragData; - try { - 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 HistoryItemSummary]; - if (data[0]) { - originalHistoryId = data[0].history_id; - } - } - } catch (error) { - // this was not a valid object for this dropzone, ignore - } + const dragItems = eventStore.getDragItems(); + // Filter out any non-history items + const historyItems = dragItems?.filter((item: any) => isHistoryItem(item)) as HistoryItemSummary[]; + const multiple = historyItems.length > 1; + const originalHistoryId = historyItems?.[0]?.history_id; - if (data && originalHistoryId) { + if (historyItems && originalHistoryId) { await historyStore.createNewHistory(); const currentHistoryId = historyStore.currentHistoryId; @@ -105,7 +89,7 @@ async function onDrop(evt: any) { let collectionCount = 0; if (currentHistoryId) { // iterate over the data array and copy each item to the new history - for (const item of data) { + for (const item of historyItems) { const dataSource = item.history_content_type === "dataset" ? "hda" : "hdca"; await copyDataset(item.id, currentHistoryId, item.history_content_type, dataSource) .then(() => { diff --git a/client/src/stores/eventStore.ts b/client/src/stores/eventStore.ts index 16ec29b74b7b..2b9b8e61dd3b 100644 --- a/client/src/stores/eventStore.ts +++ b/client/src/stores/eventStore.ts @@ -22,6 +22,13 @@ export const useEventStore = defineStore("eventStore", () => { return dragData.value; } + function getDragItems(): EventData[] { + if (!dragData.value) { + return []; + } + return multipleDragData.value ? (Object.values(dragData.value) as EventData[]) : [dragData.value]; + } + function setDragData(data: EventData, multiple = false) { dragData.value = data; multipleDragData.value = multiple; @@ -32,6 +39,7 @@ export const useEventStore = defineStore("eventStore", () => { multipleDragData, clearDragData, getDragData, + getDragItems, setDragData, }; }); diff --git a/client/src/utils/setDrag.ts b/client/src/utils/setDrag.ts index fef754a15995..baa079764f36 100644 --- a/client/src/utils/setDrag.ts +++ b/client/src/utils/setDrag.ts @@ -1,9 +1,9 @@ /** * Helper to configure datatransfer for drag & drop operations */ -import { useEventStore } from "@/stores/eventStore"; +import { type EventData, useEventStore } from "@/stores/eventStore"; -export function setDrag(evt: DragEvent, data = null, multiple = false) { +export function setDrag(evt: DragEvent, data?: EventData, multiple = false) { const eventStore = useEventStore(); if (data) { evt.dataTransfer?.setData("text", JSON.stringify([data]));