mirror of
https://github.com/galaxyproject/galaxy.git
synced 2026-09-24 16:30:27 +08:00
@@ -367,21 +367,28 @@ export default {
|
||||
},
|
||||
onDrop(evt) {
|
||||
this.showDropZone = false;
|
||||
const data = JSON.parse(evt.dataTransfer.getData("text"))[0];
|
||||
const dataSource = data.history_content_type === "dataset" ? "hda" : "hdca";
|
||||
if (data.history_id != this.historyId) {
|
||||
copyDataset(data.id, this.historyId, data.history_content_type, dataSource)
|
||||
.then(() => {
|
||||
if (data.history_content_type === "dataset") {
|
||||
Toast.info("Dataset copied to history");
|
||||
} else {
|
||||
Toast.info("Collection copied to history");
|
||||
}
|
||||
this.loadHistoryById(this.historyId);
|
||||
})
|
||||
.catch((error) => {
|
||||
this.onError(error);
|
||||
});
|
||||
let data;
|
||||
try {
|
||||
data = JSON.parse(evt.dataTransfer.getData("text"))[0];
|
||||
} catch (error) {
|
||||
// this was not a valid object for this dropzone, ignore
|
||||
}
|
||||
if (data) {
|
||||
const dataSource = data.history_content_type === "dataset" ? "hda" : "hdca";
|
||||
if (data.history_id != this.historyId) {
|
||||
copyDataset(data.id, this.historyId, data.history_content_type, dataSource)
|
||||
.then(() => {
|
||||
if (data.history_content_type === "dataset") {
|
||||
Toast.info("Dataset copied to history");
|
||||
} else {
|
||||
Toast.info("Collection copied to history");
|
||||
}
|
||||
this.loadHistoryById(this.historyId);
|
||||
})
|
||||
.catch((error) => {
|
||||
this.onError(error);
|
||||
});
|
||||
}
|
||||
}
|
||||
},
|
||||
onError(error) {
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
import { ref, unref, type Ref } from "vue";
|
||||
import { computed, ref, unref, type Ref } from "vue";
|
||||
import { useEventListener, type MaybeComputedRef } from "@vueuse/core";
|
||||
import { wait } from "@/utils/wait";
|
||||
|
||||
export type FileDropHandler = (event: DragEvent) => void;
|
||||
|
||||
@@ -9,114 +8,108 @@ export type FileDropHandler = (event: DragEvent) => void;
|
||||
* @param dropZone Element which files should be dropped on
|
||||
* @param onDrop callback function called when drop occurs
|
||||
* @param solo when true, only reacts if no modal is open
|
||||
* @param idleTime how long to wait until state resets
|
||||
*/
|
||||
export function useFileDrop(
|
||||
dropZone: MaybeComputedRef<EventTarget | null | undefined>,
|
||||
onDrop: Ref<FileDropHandler> | FileDropHandler,
|
||||
solo: MaybeComputedRef<boolean>
|
||||
solo: MaybeComputedRef<boolean>,
|
||||
idleTime = 800
|
||||
) {
|
||||
const isFileOverDocument = ref(false);
|
||||
const isFileOverDropZone = ref(false);
|
||||
|
||||
// blocks drag events in this composable, to avoid drag events in unwanted situations
|
||||
let dragBlocked = false;
|
||||
|
||||
// keeps track if the drag has exited, to avoid premature drag canceling
|
||||
let hasExited = true;
|
||||
|
||||
// Don't react to page-internal drag events
|
||||
useEventListener(
|
||||
document.body,
|
||||
"dragstart",
|
||||
() => {
|
||||
dragBlocked = true;
|
||||
},
|
||||
true
|
||||
);
|
||||
|
||||
useEventListener(
|
||||
document.body,
|
||||
"dragover",
|
||||
(event) => {
|
||||
if (!dragBlocked) {
|
||||
// prevent the browser from opening the file
|
||||
event.preventDefault();
|
||||
hasExited = false;
|
||||
}
|
||||
},
|
||||
true
|
||||
);
|
||||
|
||||
useEventListener(
|
||||
document.body,
|
||||
"drop",
|
||||
(event) => {
|
||||
if (!dragBlocked) {
|
||||
// prevent the browser from opening the file
|
||||
event.preventDefault();
|
||||
|
||||
if (isFileOverDropZone.value && isFileOverDocument.value) {
|
||||
const dropHandler = unref(onDrop);
|
||||
dropHandler(event as DragEvent);
|
||||
}
|
||||
}
|
||||
isFileOverDocument.value = false;
|
||||
dragBlocked = false;
|
||||
hasExited = true;
|
||||
},
|
||||
true
|
||||
);
|
||||
|
||||
/** Reset all variables */
|
||||
const reset = () => {
|
||||
isFileOverDocument.value = false;
|
||||
isFileOverDropZone.value = false;
|
||||
dragBlocked = false;
|
||||
hasExited = true;
|
||||
};
|
||||
|
||||
useEventListener(document.body, "dragend", reset, true);
|
||||
|
||||
useEventListener(document.body, "dragleave", async () => {
|
||||
hasExited = true;
|
||||
|
||||
// This event may have been triggered by components
|
||||
// which have not been properly childed to the body yet.
|
||||
// Wait a bit, and check if hasExited is still true.
|
||||
await wait(100);
|
||||
|
||||
if (hasExited) {
|
||||
reset();
|
||||
}
|
||||
});
|
||||
|
||||
useEventListener(
|
||||
document.body,
|
||||
"dragenter",
|
||||
(event) => {
|
||||
// init values if drag is possible
|
||||
if (!dragBlocked && !(unref(solo) && isAnyModalOpen())) {
|
||||
isFileOverDocument.value = true;
|
||||
isFileOverDropZone.value = false;
|
||||
hasExited = false;
|
||||
|
||||
event.preventDefault();
|
||||
}
|
||||
},
|
||||
true
|
||||
);
|
||||
|
||||
/** returns if any bootstrap modal is open */
|
||||
function isAnyModalOpen() {
|
||||
return document.querySelectorAll(".modal.show").length > 0;
|
||||
}
|
||||
|
||||
type State = "idle" | "blocked" | "fileDragging";
|
||||
type StateMachine = {
|
||||
[state in State]: (event: MouseEvent) => State;
|
||||
};
|
||||
|
||||
const currentState: Ref<State> = ref("idle");
|
||||
|
||||
let idleTimer: ReturnType<typeof setTimeout> | null = null;
|
||||
const resetTimer = () => {
|
||||
if (idleTimer) {
|
||||
clearTimeout(idleTimer);
|
||||
}
|
||||
};
|
||||
|
||||
const stateMachine = {
|
||||
idle(event: MouseEvent): State {
|
||||
switch (event.type) {
|
||||
case "dragstart":
|
||||
return "blocked";
|
||||
case "dragenter":
|
||||
if (!(unref(solo) && isAnyModalOpen())) {
|
||||
return "fileDragging";
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
return "idle";
|
||||
},
|
||||
blocked(event: MouseEvent): State {
|
||||
switch (event.type) {
|
||||
case "drop":
|
||||
return "idle";
|
||||
case "dragend":
|
||||
return "idle";
|
||||
}
|
||||
|
||||
return "blocked";
|
||||
},
|
||||
fileDragging(event: MouseEvent): State {
|
||||
resetTimer();
|
||||
|
||||
switch (event.type) {
|
||||
case "dragover":
|
||||
event.preventDefault();
|
||||
idleTimer = setTimeout(() => (currentState.value = "idle"), idleTime);
|
||||
break;
|
||||
case "drop":
|
||||
event.preventDefault();
|
||||
if (isFileOverDropZone.value) {
|
||||
const dropHandler = unref(onDrop);
|
||||
dropHandler(event as DragEvent);
|
||||
}
|
||||
return "idle";
|
||||
case "dragend":
|
||||
return "idle";
|
||||
}
|
||||
|
||||
return "fileDragging";
|
||||
},
|
||||
} as const satisfies StateMachine;
|
||||
|
||||
const eventHandler = (event: MouseEvent) => (currentState.value = stateMachine[currentState.value](event));
|
||||
|
||||
useEventListener(document.body, "dragstart", eventHandler, true);
|
||||
useEventListener(document.body, "dragover", eventHandler, true);
|
||||
useEventListener(document.body, "drop", eventHandler, true);
|
||||
useEventListener(document.body, "dragend", eventHandler, true);
|
||||
useEventListener(document.body, "dragenter", eventHandler, true);
|
||||
|
||||
const isFileOverDocument = computed({
|
||||
get() {
|
||||
return currentState.value === "fileDragging";
|
||||
},
|
||||
set(value) {
|
||||
if (value !== true) {
|
||||
currentState.value = "idle";
|
||||
} else {
|
||||
currentState.value = "fileDragging";
|
||||
}
|
||||
},
|
||||
});
|
||||
|
||||
const isFileOverDropZone = ref(false);
|
||||
|
||||
useEventListener(
|
||||
dropZone,
|
||||
"dragenter",
|
||||
() => {
|
||||
isFileOverDropZone.value = true;
|
||||
hasExited = false;
|
||||
},
|
||||
true
|
||||
);
|
||||
@@ -126,7 +119,6 @@ export function useFileDrop(
|
||||
"dragleave",
|
||||
() => {
|
||||
isFileOverDropZone.value = false;
|
||||
hasExited = false;
|
||||
},
|
||||
true
|
||||
);
|
||||
|
||||
@@ -1,19 +1,27 @@
|
||||
<tool id="CONVERTER_uncompressed_to_gz" name="Convert uncompressed file to compressed" hidden="true" version="@TOOL_VERSION@+galaxy@VERSION_SUFFIX@" profile="20.01">
|
||||
<macros>
|
||||
<token name="@TOOL_VERSION@">1.15.1</token>
|
||||
<token name="@TOOL_VERSION@">1.16</token>
|
||||
<token name="@VERSION_SUFFIX@">0</token>
|
||||
</macros>
|
||||
<requirements>
|
||||
<requirement type="package" version="@TOOL_VERSION@">htslib</requirement>
|
||||
<requirement type="package" version="1.0.8">bzip2</requirement>
|
||||
</requirements>
|
||||
<command><![CDATA[
|
||||
cp '$ext_config' galaxy.json &&
|
||||
bgzip -@ "\${GALAXY_SLOTS:-1}" -c '$input1' > '$output1'
|
||||
#if $input1.ext.endswith(".bz2"):
|
||||
bzcat '$input1' | bgzip -@ "\${GALAXY_SLOTS:-1}" -c > '$output1'
|
||||
#else:
|
||||
bgzip -@ "\${GALAXY_SLOTS:-1}" -c '$input1' > '$output1'
|
||||
#end if
|
||||
]]></command>
|
||||
<configfiles>
|
||||
<configfile name="ext_config">{"output1": {
|
||||
"name": "${input1.name + '.gz' if not $input1.name.endswith('.vcf') else $input1.name + '.bgzip'} compressed",
|
||||
"ext": "${input1.ext + '.gz' if $input1.ext != 'vcf' else 'vcf_bgzip'}"
|
||||
<configfile name="ext_config">
|
||||
#silent ext = $input1.ext[:-4] if $input1.ext.endswith(".bz2") else $input1.ext
|
||||
#silent ext = ext + '.gz' if ext != 'vcf' else 'vcf_bgzip'
|
||||
{"output1": {
|
||||
"name": "${input1.name} compressed",
|
||||
"ext": "${ext}"
|
||||
}}</configfile>
|
||||
</configfiles>
|
||||
<inputs>
|
||||
@@ -32,6 +40,10 @@ bgzip -@ "\${GALAXY_SLOTS:-1}" -c '$input1' > '$output1'
|
||||
<param name="input1" value="1.fasta" ftype="fasta"/>
|
||||
<output name="output1" file="1.fasta.gz" ftype="fasta.gz" decompress="true"/>
|
||||
</test>
|
||||
<test>
|
||||
<param name="input1" value="1.fastqsanger.bz2" ftype="fastqsanger.bz2"/>
|
||||
<output name="output1" file="1.fastqsanger.gz" ftype="fastqsanger.gz" decompress="true"/>
|
||||
</test>
|
||||
</tests>
|
||||
<help>
|
||||
</help>
|
||||
|
||||
Reference in New Issue
Block a user