@@ -524,7 +524,7 @@ function autoLayout() {
display: flex;
padding: 0.25rem;
gap: 0.25rem;
- align-items: end;
+ align-items: start;
flex-direction: column-reverse;
align-self: flex-start;
From 4a33bca47655f0bc6a3dc3d96d35005e411a973c Mon Sep 17 00:00:00 2001
From: Laila Los <44241786+ElectronicBlueberry@users.noreply.github.com>
Date: Thu, 21 Nov 2024 00:23:21 +0100
Subject: [PATCH 117/139] remove collapse buttons from basics test
---
lib/galaxy_test/selenium/test_workflow_editor.py | 11 ++---------
1 file changed, 2 insertions(+), 9 deletions(-)
diff --git a/lib/galaxy_test/selenium/test_workflow_editor.py b/lib/galaxy_test/selenium/test_workflow_editor.py
index a518ec297b5f..53ab237e751b 100644
--- a/lib/galaxy_test/selenium/test_workflow_editor.py
+++ b/lib/galaxy_test/selenium/test_workflow_editor.py
@@ -50,18 +50,11 @@ def test_basics(self):
self.screenshot("workflow_editor_blank")
self.hover_over(self.components._.left_panel_drag.wait_for_visible())
- self.components._.left_panel_collapse.wait_for_and_click()
-
- self.sleep_for(self.wait_types.UX_RENDER)
-
- self.screenshot("workflow_editor_left_collapsed")
-
self.hover_over(self.components._.right_panel_drag.wait_for_visible())
- self.components._.right_panel_collapse.wait_for_and_click()
- self.sleep_for(self.wait_types.UX_RENDER)
+ self.workflow_editor_maximize_center_pane()
- self.screenshot("workflow_editor_left_and_right_collapsed")
+ self.screenshot("workflow_editor_center_pane_maximized")
@selenium_test
def test_edit_annotation(self):
From 21ceb30ebce78cf03e44f9d401b4f9434fe9b5bf Mon Sep 17 00:00:00 2001
From: Laila Los <44241786+ElectronicBlueberry@users.noreply.github.com>
Date: Thu, 21 Nov 2024 15:22:58 +0100
Subject: [PATCH 118/139] wait for save to complete
---
lib/galaxy_test/selenium/framework.py | 1 +
1 file changed, 1 insertion(+)
diff --git a/lib/galaxy_test/selenium/framework.py b/lib/galaxy_test/selenium/framework.py
index 9c300dc7b0de..d9cdb995a386 100644
--- a/lib/galaxy_test/selenium/framework.py
+++ b/lib/galaxy_test/selenium/framework.py
@@ -455,6 +455,7 @@ def assert_workflow_has_changes_and_save(self):
save_button.wait_for_visible()
assert not save_button.has_class("disabled")
save_button.wait_for_and_click()
+ save_button.wait_for_absent()
self.sleep_for(self.wait_types.UX_RENDER)
@retry_assertion_during_transitions
From b84ad7035e081289a17e54991e79a2751f808401 Mon Sep 17 00:00:00 2001
From: Laila Los <44241786+ElectronicBlueberry@users.noreply.github.com>
Date: Thu, 21 Nov 2024 15:34:08 +0100
Subject: [PATCH 119/139] remove test for removed feature
---
.../selenium/test_workflow_editor.py | 24 -------------------
1 file changed, 24 deletions(-)
diff --git a/lib/galaxy_test/selenium/test_workflow_editor.py b/lib/galaxy_test/selenium/test_workflow_editor.py
index 53ab237e751b..d146be21344d 100644
--- a/lib/galaxy_test/selenium/test_workflow_editor.py
+++ b/lib/galaxy_test/selenium/test_workflow_editor.py
@@ -23,7 +23,6 @@
)
from .framework import (
retry_assertion_during_transitions,
- retry_during_transitions,
RunsWorkflows,
selenium_test,
SeleniumTestCase,
@@ -954,29 +953,6 @@ def test_missing_tools(self):
self.assert_modal_has_text("Tool is not installed")
self.screenshot("workflow_editor_missing_tool")
- @selenium_test
- def test_workflow_bookmarking(self):
- @retry_during_transitions
- def assert_workflow_bookmarked_status(target_status):
- name_matches = [c.text == new_workflow_name for c in self.components.tool_panel.workflow_names.all()]
- status = any(name_matches)
- assert status == target_status
-
- new_workflow_name = self.workflow_create_new(clear_placeholder=True)
- self.components.workflow_editor.canvas_body.wait_for_visible()
- self.wait_for_selector_absent_or_hidden(self.modal_body_selector())
-
- # Assert workflow not initially bookmarked.
- self.navigate_to_tools()
- assert_workflow_bookmarked_status(False)
-
- self.click_activity_workflow()
- self.components.workflows.bookmark_link(action="add").wait_for_and_click()
-
- # search for bookmark in tools menu
- self.navigate_to_tools()
- assert_workflow_bookmarked_status(True)
-
def tab_to(self, accessible_name, direction="forward"):
for _ in range(100):
ac = self.action_chains()
From a16574a3083f8c76ba35ccae45a2ee332622321d Mon Sep 17 00:00:00 2001
From: Laila Los <44241786+ElectronicBlueberry@users.noreply.github.com>
Date: Thu, 21 Nov 2024 15:35:13 +0100
Subject: [PATCH 120/139] remove invalid check in insert steps
---
lib/galaxy/selenium/navigates_galaxy.py | 2 --
1 file changed, 2 deletions(-)
diff --git a/lib/galaxy/selenium/navigates_galaxy.py b/lib/galaxy/selenium/navigates_galaxy.py
index 5cdb750ba4e6..1ebfed40d45c 100644
--- a/lib/galaxy/selenium/navigates_galaxy.py
+++ b/lib/galaxy/selenium/navigates_galaxy.py
@@ -1271,8 +1271,6 @@ def workflow_editor_add_steps(self, name: str):
insert_button = self.components.workflows.workflow_card_button(name=name, title="Copy steps into workflow")
insert_button.wait_for_and_click()
- self.components.workflow_editor.node._(label=name).wait_for_present()
-
self.sleep_for(self.wait_types.UX_RENDER)
def workflow_editor_add_subworkflow(self, name: str):
From 852fc4c327d5bb5a79bb584bd116e7f22dfa0940 Mon Sep 17 00:00:00 2001
From: Laila Los <44241786+ElectronicBlueberry@users.noreply.github.com>
Date: Thu, 21 Nov 2024 15:35:51 +0100
Subject: [PATCH 121/139] remove test for removed component
---
lib/galaxy_test/selenium/test_workflow_editor.py | 1 -
1 file changed, 1 deletion(-)
diff --git a/lib/galaxy_test/selenium/test_workflow_editor.py b/lib/galaxy_test/selenium/test_workflow_editor.py
index d146be21344d..515f25f168c9 100644
--- a/lib/galaxy_test/selenium/test_workflow_editor.py
+++ b/lib/galaxy_test/selenium/test_workflow_editor.py
@@ -49,7 +49,6 @@ def test_basics(self):
self.screenshot("workflow_editor_blank")
self.hover_over(self.components._.left_panel_drag.wait_for_visible())
- self.hover_over(self.components._.right_panel_drag.wait_for_visible())
self.workflow_editor_maximize_center_pane()
From b565fea1507ce00999bf12a9942777537b0f52c0 Mon Sep 17 00:00:00 2001
From: Laila Los <44241786+ElectronicBlueberry@users.noreply.github.com>
Date: Mon, 25 Nov 2024 11:33:05 +0100
Subject: [PATCH 122/139] make search selector more specific
---
client/src/utils/navigation/navigation.yml | 5 +----
1 file changed, 1 insertion(+), 4 deletions(-)
diff --git a/client/src/utils/navigation/navigation.yml b/client/src/utils/navigation/navigation.yml
index 6982e4a77b64..f4e925242c53 100644
--- a/client/src/utils/navigation/navigation.yml
+++ b/client/src/utils/navigation/navigation.yml
@@ -811,10 +811,7 @@ workflow_editor:
type: xpath
selector: >
//div[@data-label='Change datatype']//div[contains(@class, 'multiselect')]
- select_datatype_text_search:
- type: xpath
- selector: >
- //input[@class="multiselect__input"]
+ select_datatype_text_search: "div[data-label='Change datatype'] .multiselect__input"
select_datatype:
type: xpath
selector: >
From d899b92e46c81de9bece350fcb4ee3da140c75fd Mon Sep 17 00:00:00 2001
From: Laila Los <44241786+ElectronicBlueberry@users.noreply.github.com>
Date: Mon, 25 Nov 2024 11:48:32 +0100
Subject: [PATCH 123/139] fix selection test
---
lib/galaxy_test/selenium/test_workflow_editor.py | 1 +
1 file changed, 1 insertion(+)
diff --git a/lib/galaxy_test/selenium/test_workflow_editor.py b/lib/galaxy_test/selenium/test_workflow_editor.py
index 515f25f168c9..4f792a3cb1d8 100644
--- a/lib/galaxy_test/selenium/test_workflow_editor.py
+++ b/lib/galaxy_test/selenium/test_workflow_editor.py
@@ -1304,6 +1304,7 @@ def test_editor_selection(self):
self.mouse_drag(from_element=tool_node, to_element=canvas, to_offset=(0, -100))
# select the node
+ editor.node_inspector_close.wait_for_and_click()
self.action_chains().move_to_element(tool_node).key_down(Keys.SHIFT).click().key_up(Keys.SHIFT).perform()
self.sleep_for(self.wait_types.UX_RENDER)
From 5c8b958b9ea661c767a24f404eb5b406faa5f127 Mon Sep 17 00:00:00 2001
From: Laila Los <44241786+ElectronicBlueberry@users.noreply.github.com>
Date: Mon, 25 Nov 2024 12:03:35 +0100
Subject: [PATCH 124/139] clear search before searching for other tool
---
client/src/utils/navigation/navigation.yml | 1 +
lib/galaxy/selenium/navigates_galaxy.py | 3 +++
2 files changed, 4 insertions(+)
diff --git a/client/src/utils/navigation/navigation.yml b/client/src/utils/navigation/navigation.yml
index f4e925242c53..f0099355de25 100644
--- a/client/src/utils/navigation/navigation.yml
+++ b/client/src/utils/navigation/navigation.yml
@@ -904,6 +904,7 @@ tools:
execute: '#execute'
help: 'div.form-help'
search: '#toolbox-panel .search-query'
+ clear_search: '#toolbox-panel .search-clear'
title: '.toolSectionTitle'
admin:
diff --git a/lib/galaxy/selenium/navigates_galaxy.py b/lib/galaxy/selenium/navigates_galaxy.py
index 1ebfed40d45c..511264ff3262 100644
--- a/lib/galaxy/selenium/navigates_galaxy.py
+++ b/lib/galaxy/selenium/navigates_galaxy.py
@@ -1700,6 +1700,9 @@ def open_toolbox(self):
def tool_open(self, tool_id, outer=False):
self.open_toolbox()
+ self.components.tools.clear_search.wait_for_and_click()
+ self.sleep_for(self.wait_types.UX_RENDER)
+
self.components.tools.search.wait_for_and_send_keys(f"id:{tool_id}")
if outer:
From 1dca0367170093e29a926e25403e3fa0b17ca1e7 Mon Sep 17 00:00:00 2001
From: Laila Los <44241786+ElectronicBlueberry@users.noreply.github.com>
Date: Mon, 25 Nov 2024 17:44:42 +0100
Subject: [PATCH 125/139] use confirm dialog composable
---
client/src/components/Workflow/Editor/Index.vue | 7 +++++--
1 file changed, 5 insertions(+), 2 deletions(-)
diff --git a/client/src/components/Workflow/Editor/Index.vue b/client/src/components/Workflow/Editor/Index.vue
index 4913071fa98f..45225d211533 100644
--- a/client/src/components/Workflow/Editor/Index.vue
+++ b/client/src/components/Workflow/Editor/Index.vue
@@ -191,7 +191,7 @@ import { storeToRefs } from "pinia";
import Vue, { computed, nextTick, onUnmounted, ref, unref, watch } from "vue";
import { getUntypedWorkflowParameters } from "@/components/Workflow/Editor/modules/parameters";
-import { ConfirmDialog } from "@/composables/confirmDialog";
+import { ConfirmDialog, useConfirmDialog } from "@/composables/confirmDialog";
import { useDatatypesMapper } from "@/composables/datatypesMapper";
import { useUid } from "@/composables/utils/uid";
import { provideScopedWorkflowStores } from "@/composables/workflowStores";
@@ -464,6 +464,8 @@ export default {
}))
);
+ const { confirm } = useConfirmDialog();
+
return {
id,
name,
@@ -506,6 +508,7 @@ export default {
specialWorkflowActivities,
isNewTempWorkflow,
saveWorkflowTitle,
+ confirm,
};
},
data() {
@@ -724,7 +727,7 @@ export default {
},
async saveOrCreate() {
if (this.hasInvalidConnections) {
- const confirmed = await confirm(
+ const confirmed = await this.confirm(
`Workflow has invalid connections. You can save the workflow, but it may not run correctly.`,
{
id: "save-workflow-confirmation",
From 43ddb6d2fd0674d7d097d62e335b153d2467a657 Mon Sep 17 00:00:00 2001
From: Laila Los <44241786+ElectronicBlueberry@users.noreply.github.com>
Date: Mon, 25 Nov 2024 18:30:49 +0100
Subject: [PATCH 126/139] exclude node buttons from node selection targets
---
.../src/components/Workflow/Editor/Node.vue | 10 +++++-
client/src/utils/dom.ts | 33 +++++++++++++++++++
2 files changed, 42 insertions(+), 1 deletion(-)
create mode 100644 client/src/utils/dom.ts
diff --git a/client/src/components/Workflow/Editor/Node.vue b/client/src/components/Workflow/Editor/Node.vue
index ea9aa2ae19e3..1f4085242a70 100644
--- a/client/src/components/Workflow/Editor/Node.vue
+++ b/client/src/components/Workflow/Editor/Node.vue
@@ -165,6 +165,7 @@ import { useWorkflowStores } from "@/composables/workflowStores";
import type { TerminalPosition, XYPosition } from "@/stores/workflowEditorStateStore";
import { useWorkflowNodeInspectorStore } from "@/stores/workflowNodeInspectorStore";
import type { Step } from "@/stores/workflowStepStore";
+import { composedPartialPath, isClickable } from "@/utils/dom";
import { ToggleStepSelectedAction } from "./Actions/stepActions";
import type { OutputTerminals } from "./modules/terminals";
@@ -324,7 +325,14 @@ function onPointerDown() {
mouseDownTime = Date.now();
}
-function onPointerUp() {
+function onPointerUp(e: PointerEvent) {
+ const path = composedPartialPath(e);
+ const unclickable = path.every((target) => !isClickable(target as Element));
+
+ if (!unclickable) {
+ return;
+ }
+
const mouseUpTime = Date.now();
const clickTime = mouseUpTime - mouseDownTime;
diff --git a/client/src/utils/dom.ts b/client/src/utils/dom.ts
new file mode 100644
index 000000000000..7fd2ec12dd68
--- /dev/null
+++ b/client/src/utils/dom.ts
@@ -0,0 +1,33 @@
+/**
+ * composed array of all Event Targets between the original and current target
+ *
+ * @param e Event to return partial composed path of
+ */
+export function composedPartialPath(e: Event): EventTarget[] {
+ const current = e.currentTarget;
+ const composed = e.composedPath();
+
+ const currentIndex = composed.findIndex((target) => target === current);
+
+ if (currentIndex === -1) {
+ throw new Error("current target is not part of composed path");
+ }
+
+ const partial = composed.slice(0, currentIndex);
+
+ return partial;
+}
+
+/**
+ * checks if an element has a valid mouse interaction
+ */
+export function isClickable(element: Element): boolean {
+ const clickable =
+ element instanceof HTMLButtonElement ||
+ element instanceof HTMLInputElement ||
+ element instanceof HTMLAnchorElement ||
+ element instanceof HTMLSelectElement ||
+ element instanceof HTMLLabelElement;
+
+ return clickable;
+}
From 123843e669fb6fe27552c0198f9eb5dc66383f0e Mon Sep 17 00:00:00 2001
From: Laila Los <44241786+ElectronicBlueberry@users.noreply.github.com>
Date: Mon, 25 Nov 2024 18:51:42 +0100
Subject: [PATCH 127/139] use latest id on insert
---
client/src/components/Workflow/List/WorkflowCardList.vue | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/client/src/components/Workflow/List/WorkflowCardList.vue b/client/src/components/Workflow/List/WorkflowCardList.vue
index dd368b76cb7a..ed6d8bb453af 100644
--- a/client/src/components/Workflow/List/WorkflowCardList.vue
+++ b/client/src/components/Workflow/List/WorkflowCardList.vue
@@ -60,7 +60,7 @@ function onPreview(id: string) {
// TODO: clean-up types, as soon as better Workflow type is available
function onInsert(workflow: Workflow) {
- emit("insertWorkflow", workflow.id as any, workflow.name as any);
+ emit("insertWorkflow", workflow.latest_id as any, workflow.name as any);
}
function onInsertSteps(workflow: Workflow) {
From ea06e7767672b1529474a0119cc96964907cb8a7 Mon Sep 17 00:00:00 2001
From: Laila Los <44241786+ElectronicBlueberry@users.noreply.github.com>
Date: Mon, 25 Nov 2024 19:09:59 +0100
Subject: [PATCH 128/139] save latest id to dict
---
client/src/components/Workflow/List/WorkflowCardList.vue | 2 +-
lib/galaxy/model/__init__.py | 2 ++
lib/galaxy/webapps/galaxy/services/workflows.py | 4 +++-
3 files changed, 6 insertions(+), 2 deletions(-)
diff --git a/client/src/components/Workflow/List/WorkflowCardList.vue b/client/src/components/Workflow/List/WorkflowCardList.vue
index ed6d8bb453af..a4ed88d3a193 100644
--- a/client/src/components/Workflow/List/WorkflowCardList.vue
+++ b/client/src/components/Workflow/List/WorkflowCardList.vue
@@ -60,7 +60,7 @@ function onPreview(id: string) {
// TODO: clean-up types, as soon as better Workflow type is available
function onInsert(workflow: Workflow) {
- emit("insertWorkflow", workflow.latest_id as any, workflow.name as any);
+ emit("insertWorkflow", workflow.latest_workflow_id as any, workflow.name as any);
}
function onInsertSteps(workflow: Workflow) {
diff --git a/lib/galaxy/model/__init__.py b/lib/galaxy/model/__init__.py
index 4a5be7c35257..7ebb770a274f 100644
--- a/lib/galaxy/model/__init__.py
+++ b/lib/galaxy/model/__init__.py
@@ -7770,6 +7770,7 @@ class StoredWorkflow(Base, HasTags, Dictifiable, RepresentById, UsesCreateAndUpd
dict_collection_visible_keys = [
"id",
+ "latest_workflow_id",
"name",
"create_time",
"update_time",
@@ -7780,6 +7781,7 @@ class StoredWorkflow(Base, HasTags, Dictifiable, RepresentById, UsesCreateAndUpd
]
dict_element_visible_keys = [
"id",
+ "latest_workflow_id",
"name",
"create_time",
"update_time",
diff --git a/lib/galaxy/webapps/galaxy/services/workflows.py b/lib/galaxy/webapps/galaxy/services/workflows.py
index 0f7f13b3aa05..f34ce0db46b2 100644
--- a/lib/galaxy/webapps/galaxy/services/workflows.py
+++ b/lib/galaxy/webapps/galaxy/services/workflows.py
@@ -70,7 +70,9 @@ def index(
query, total_matches = self._workflows_manager.index_query(trans, payload, include_total_count)
rval = []
for wf in query.all():
- item = wf.to_dict(value_mapper={"id": trans.security.encode_id})
+ item = wf.to_dict(
+ value_mapper={"id": trans.security.encode_id, "latest_workflow_id": trans.security.encode_id}
+ )
encoded_id = trans.security.encode_id(wf.id)
item["annotations"] = [x.annotation for x in wf.annotations]
item["url"] = web.url_for("workflow", id=encoded_id)
From 63a67ec18c9b05016d94cc2048e1a433fe386b42 Mon Sep 17 00:00:00 2001
From: Laila Los <44241786+ElectronicBlueberry@users.noreply.github.com>
Date: Mon, 25 Nov 2024 23:37:58 +0100
Subject: [PATCH 129/139] fix test_non_data_connections test
---
lib/galaxy_test/selenium/test_workflow_editor.py | 1 +
1 file changed, 1 insertion(+)
diff --git a/lib/galaxy_test/selenium/test_workflow_editor.py b/lib/galaxy_test/selenium/test_workflow_editor.py
index 4f792a3cb1d8..a5dd338557d4 100644
--- a/lib/galaxy_test/selenium/test_workflow_editor.py
+++ b/lib/galaxy_test/selenium/test_workflow_editor.py
@@ -333,6 +333,7 @@ def test_non_data_connections(self):
editor = self.components.workflow_editor
tool_node = editor.node._(label="tool_exec")
+ tool_node.wait_for_and_click()
tool_input = tool_node.input_terminal(name="inttest")
self.hover_over(tool_input.wait_for_visible())
tool_node.connector_destroy_callout(name="inttest").wait_for_and_click()
From 6e7585c2052e2524aa368032451a84bed2ec164c Mon Sep 17 00:00:00 2001
From: Laila Los <44241786+ElectronicBlueberry@users.noreply.github.com>
Date: Mon, 25 Nov 2024 23:51:37 +0100
Subject: [PATCH 130/139] fix test_editor_duplicate_node test
---
client/src/utils/navigation/navigation.yml | 1 +
lib/galaxy_test/selenium/test_workflow_editor.py | 2 ++
2 files changed, 3 insertions(+)
diff --git a/client/src/utils/navigation/navigation.yml b/client/src/utils/navigation/navigation.yml
index f0099355de25..0612bdf75aff 100644
--- a/client/src/utils/navigation/navigation.yml
+++ b/client/src/utils/navigation/navigation.yml
@@ -705,6 +705,7 @@ workflow_editor:
node:
selectors:
_: "[node-label='${label}']"
+ by_id: "#wf-node-step-${id}"
title: '${_} .node-title'
destroy: '${_} .node-destroy'
clone: '${_} .node-clone'
diff --git a/lib/galaxy_test/selenium/test_workflow_editor.py b/lib/galaxy_test/selenium/test_workflow_editor.py
index a5dd338557d4..229b76634b36 100644
--- a/lib/galaxy_test/selenium/test_workflow_editor.py
+++ b/lib/galaxy_test/selenium/test_workflow_editor.py
@@ -770,6 +770,8 @@ def test_editor_duplicate_node(self):
editor.remove_tags_input.wait_for_and_send_keys("#oldboringtag" + Keys.ENTER + Keys.ESCAPE)
self.sleep_for(self.wait_types.UX_RENDER)
cat_node.clone.wait_for_and_click()
+ cloned_node = editor.node.by_id(id=2)
+ cloned_node.wait_for_and_click()
editor.label_input.wait_for_and_send_keys(Keys.BACKSPACE * 20)
editor.label_input.wait_for_and_send_keys("cloned label")
output_label = editor.label_output(output="out_file1")
From 85bde642ca71bc6e1fa945d8f1bd6e96a4bebcb0 Mon Sep 17 00:00:00 2001
From: davelopez <46503462+davelopez@users.noreply.github.com>
Date: Tue, 26 Nov 2024 13:49:50 +0100
Subject: [PATCH 131/139] fix event name for markdown update in
PageEditorMarkdown component
After refactoring `move MarkdownEditor to activity bar`
---
client/src/components/PageEditor/PageEditorMarkdown.vue | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/client/src/components/PageEditor/PageEditorMarkdown.vue b/client/src/components/PageEditor/PageEditorMarkdown.vue
index 6e1cb5bcc76a..3d4834f4cd1e 100644
--- a/client/src/components/PageEditor/PageEditorMarkdown.vue
+++ b/client/src/components/PageEditor/PageEditorMarkdown.vue
@@ -4,7 +4,7 @@
:markdown-text="markdownText"
:markdown-config="contentData"
mode="page"
- @onUpdate="onUpdate">
+ @update="onUpdate">
Date: Tue, 3 Dec 2024 13:27:52 -0500
Subject: [PATCH 132/139] Avoid unhelpful accepted format drop downs.
---
.../src/components/Form/Elements/FormData/FormData.vue | 10 +++++++++-
1 file changed, 9 insertions(+), 1 deletion(-)
diff --git a/client/src/components/Form/Elements/FormData/FormData.vue b/client/src/components/Form/Elements/FormData/FormData.vue
index d2a0e0b87ce9..de820ccef641 100644
--- a/client/src/components/Form/Elements/FormData/FormData.vue
+++ b/client/src/components/Form/Elements/FormData/FormData.vue
@@ -90,6 +90,14 @@ const dragTarget: Ref = ref(null);
const collectionModalShow = ref(false);
const collectionModalType = ref<"list" | "list:paired" | "paired">("list");
const { currentHistoryId } = storeToRefs(useHistoryStore());
+const restrictsExtensions = computed(() => {
+ const extensions = props.extensions;
+ if (!extensions || extensions.length == 0 || extensions.indexOf("data") >= 0) {
+ return false;
+ } else {
+ return true;
+ }
+});
/** Store options which need to be preserved **/
const keepOptions: Record = {};
@@ -649,7 +657,7 @@ const noOptionsWarningMessage = computed(() => {
-
+
accepted formats
From 247d679b6db8ed5c3919f59c8f16143860eda5dd Mon Sep 17 00:00:00 2001
From: John Chilton
Date: Tue, 3 Dec 2024 13:28:22 -0500
Subject: [PATCH 133/139] Upload on empty?
---
.../src/components/Collections/CollectionCreatorModal.vue | 6 ++++++
1 file changed, 6 insertions(+)
diff --git a/client/src/components/Collections/CollectionCreatorModal.vue b/client/src/components/Collections/CollectionCreatorModal.vue
index 278e25f3d706..6788503a60a6 100644
--- a/client/src/components/Collections/CollectionCreatorModal.vue
+++ b/client/src/components/Collections/CollectionCreatorModal.vue
@@ -6,6 +6,7 @@ import { computed, ref, watch } from "vue";
import type { HDASummary, HistoryItemSummary, HistorySummary } from "@/api";
import { createDatasetCollection } from "@/components/History/model/queries";
+import { useGlobalUploadModal } from "@/composables/globalUploadModal.js";
import { useCollectionBuilderItemsStore } from "@/stores/collectionBuilderItemsStore";
import { useHistoryStore } from "@/stores/historyStore";
import localize from "@/utils/localization";
@@ -20,6 +21,8 @@ import Heading from "@/components/Common/Heading.vue";
import GenericItem from "@/components/History/Content/GenericItem.vue";
import LoadingSpan from "@/components/LoadingSpan.vue";
+const { openGlobalUploadModal } = useGlobalUploadModal();
+
interface Props {
historyId: string;
showModal: boolean;
@@ -262,6 +265,9 @@ function resetModal() {
{{ localize("No items available to create a collection.") }}
+
From 5dbf3b0c8d5e63acd66d0b58c902e9314f2f77a9 Mon Sep 17 00:00:00 2001
From: Ahmed Awan
Date: Tue, 3 Dec 2024 14:22:11 -0600
Subject: [PATCH 134/139] add a message and link to upload tab if no initial
elements
This meant also adjusting the creator(s) content to prioritize the alert message with the link.
---
.../Collections/CollectionCreatorModal.vue | 15 +-
.../Collections/ListCollectionCreator.vue | 499 +++++++++---------
.../Collections/PairCollectionCreator.vue | 245 ++++-----
.../PairedListCollectionCreator.vue | 449 ++++++++--------
.../Collections/common/CollectionCreator.vue | 178 ++++---
5 files changed, 693 insertions(+), 693 deletions(-)
diff --git a/client/src/components/Collections/CollectionCreatorModal.vue b/client/src/components/Collections/CollectionCreatorModal.vue
index 6788503a60a6..334f6586e0da 100644
--- a/client/src/components/Collections/CollectionCreatorModal.vue
+++ b/client/src/components/Collections/CollectionCreatorModal.vue
@@ -6,7 +6,6 @@ import { computed, ref, watch } from "vue";
import type { HDASummary, HistoryItemSummary, HistorySummary } from "@/api";
import { createDatasetCollection } from "@/components/History/model/queries";
-import { useGlobalUploadModal } from "@/composables/globalUploadModal.js";
import { useCollectionBuilderItemsStore } from "@/stores/collectionBuilderItemsStore";
import { useHistoryStore } from "@/stores/historyStore";
import localize from "@/utils/localization";
@@ -21,8 +20,6 @@ import Heading from "@/components/Common/Heading.vue";
import GenericItem from "@/components/History/Content/GenericItem.vue";
import LoadingSpan from "@/components/LoadingSpan.vue";
-const { openGlobalUploadModal } = useGlobalUploadModal();
-
interface Props {
historyId: string;
showModal: boolean;
@@ -263,12 +260,6 @@ function resetModal() {
{{ historyItemsError }}
-
- {{ localize("No items available to create a collection.") }}
-
-
@@ -295,7 +286,7 @@ function resetModal() {
-
+
- {{ localize("No datasets were selected") }}
- {{ localize("At least one element is needed for the collection. You may need to") }}
-
- {{ localize("cancel") }}
-
- {{ localize("and reselect new elements.") }}
-
-
-
-
-
-
-
-
- {{
- localize(
- "No elements in your history are valid for this list. You may need to switch to a different history."
- )
- }}
-
- {{ localize("The following extensions are required for this list: ") }}
-
-
- {{ extension }}
-
-
-
-
-
{{ localize("The following selections could not be included due to problems:") }}
{{ problem }}
- {{ localize("At least one element is needed for the collection. You may need to") }}
-
- {{ localize("cancel") }}
-
- {{ localize("and reselect new elements.") }}
+
-
-
-
+
+
+ {{
+ localize("Collections cannot have duplicated names. The following list names are duplicated: ")
+ }}
+
+
{{ name }}
+
+ {{ localize("Please fix these duplicates and try again.") }}
+
-
-
-
- {{ localize("The following selections could not be included due to problems:") }}
-
-
- {{ problem }}
-
-
-
-
-
-
-
+
+
+
+
+
{{
localize(
- "Collections cannot have duplicated names. The following list names are duplicated: "
+ [
+ "Collections of datasets are permanent, ordered lists of datasets that can be passed to tools ",
+ "and workflows in order to have analyses done on each member of the entire group. This interface allows ",
+ "you to create a collection and re-order the final collection.",
+ ].join("")
)
}}
-
-
{{ name }}
-
- {{ localize("Please fix these duplicates and try again.") }}
-
-
-
-
-
-
-
+
+
+
+
+ {{ localize("Rename elements in the list by clicking on") }}
+
+ {{ localize("the existing name") }}
+
+ {{ localize(".") }}
+
+
+
+ {{ localize("Discard elements from the final created list by clicking on the ") }}
+
+ {{ localize("Discard") }}
+
+ {{ localize("button.") }}
+
+
+
{{
localize(
- [
- "Collections of datasets are permanent, ordered lists of datasets that can be passed to tools ",
- "and workflows in order to have analyses done on each member of the entire group. This interface allows ",
- "you to create a collection and re-order the final collection.",
- ].join("")
+ "Reorder the list by clicking and dragging elements. Select multiple elements by clicking on"
)
}}
-
-
-
-
- {{ localize("Rename elements in the list by clicking on") }}
-
- {{ localize("the existing name") }}
-
- {{ localize(".") }}
-
-
-
- {{ localize("Discard elements from the final created list by clicking on the ") }}
-
- {{ localize("Discard") }}
-
- {{ localize("button.") }}
-
-
-
- {{
- localize(
- "Reorder the list by clicking and dragging elements. Select multiple elements by clicking on"
- )
- }}
-
- {{ localize("them") }}
-
- {{
- localize(
- "and you can then move those selected by dragging the entire group. Deselect them by clicking them again or by clicking the"
- )
- }}
-
- {{ localize("Clear selected") }}
-
- {{ localize("link.") }}
-
-
-
- {{ localize("Click ") }}
-
-
-
- {{ localize("to begin again as if you had just opened the interface.") }}
-
- {{ localize("Click the") }}
-
- {{ localize("Cancel") }}
-
- {{ localize("button to exit the interface.") }}
-
-
-
-
-
-
- {{ localize("Once your collection is complete, enter a ") }}
-
- {{ localize("name") }}
+
+ {{ localize("them") }}
- {{ localize("and click") }}
-
- {{ localize("Create list") }}
+ {{
+ localize(
+ "and you can then move those selected by dragging the entire group. Deselect them by clicking them again or by clicking the"
+ )
+ }}
+
+ {{ localize("Clear selected") }}
- {{ localize(".") }}
-
-
+ {{ localize("link.") }}
+
-
-
-
-
+
+ {{ localize("Click ") }}
+
+
+
+ {{ localize("to begin again as if you had just opened the interface.") }}
+
+ {{ localize("Click the") }}
+
+ {{ localize("Cancel") }}
+
+ {{ localize("button to exit the interface.") }}
+
+
+
+
+
+
+ {{ localize("Once your collection is complete, enter a ") }}
+
+ {{ localize("name") }}
+
+ {{ localize("and click") }}
+
+ {{ localize("Create list") }}
+
+ {{ localize(".") }}
+
+
+
+
+
+
+ {{ localize("No datasets were selected") }}
+ {{ localize("At least one element is needed for the collection. You may need to") }}
+
+ {{ localize("cancel") }}
+
+ {{ localize("and reselect new elements.") }}
+
+
+
+
+
+
+
+
+ {{
+ localize(
+ "No elements in your history are valid for this list. You may need to switch to a different history."
+ )
+ }}
+
+ {{ localize("The following extensions are required for this list: ") }}
+
+
+ {{ extension }}
+
+
+
+
+
+ {{ localize("The following selections could not be included due to problems:") }}
+
+
+ {{ problem }}
+
+
+ {{ localize("At least one element is needed for the collection. You may need to") }}
+
+ {{ localize("cancel") }}
+
+ {{ localize("and reselect new elements.") }}
+
+
+
+
+
+
+
+
+
+
+
+ {{ localize("Reset") }}
+
+
+
+
+
+
+
+ {{ workingElements.length }} {{ localize("elements in list") }}
+
- {{ localize("No datasets were selected.") }}
- {{ localize("Exactly two elements needed for the collection. You may need to") }}
-
- {{ localize("cancel") }}
-
- {{ localize("and reselect new elements.") }}
-
-
-
-
-
-
-
-
- {{
- localize(
- "No elements in your history are valid for this pair. You may need to switch to a different history."
- )
- }}
-
- {{ localize("The following extensions are required for this pair: ") }}
-
-
- {{ extension }}
-
-
-
-
-
{{ localize("The following selections could not be included due to problems:") }}
{{ problem }}
- {{ localize("Exactly two elements needed for the collection. You may need to") }}
-
- {{ localize("cancel") }}
-
- {{ localize("and reselect new elements.") }}
+
+
+
+
+ {{ localize("Exactly two elements are needed for the pair.") }}
+
+
+ {{ localize("Cancel") }}
+
+ {{ localize("and reselect new elements.") }}
+
-
+
-
-
-
- {{ localize("The following selections could not be included due to problems:") }}
-
-
- {{ problem }}
-
-
-
-
-
-
- {{ localize("Exactly two elements are needed for the pair.") }}
-
-
+
+
+
+
+
+
{{
localize(
- [
- "Pair collections are permanent collections containing two datasets: one forward and one reverse. ",
- "Often these are forward and reverse reads. The pair collections can be passed to tools and workflows in ",
- "order to have analyses done on both datasets. This interface allows you to create a pair, name it, and ",
- "swap which is forward and which reverse.",
- ].join("")
+ "No elements in your history are valid for this pair. You may need to switch to a different history."
)
}}
-
-
-
-
- {{ localize("Click the ") }}
-
- {{ localize("Swap") }}
-
- {{
- localize(
- "link to make your forward dataset the reverse and the reverse dataset forward"
- )
- }}
-
-
-
- {{ localize("Click the ") }}
-
- {{ localize("Cancel") }}
-
- {{ localize("button to exit the interface.") }}
-
-
-
-
-
-
- {{ localize("Once your collection is complete, enter a ") }}
- {{ localize("name") }}
- {{ localize("and click ") }}
-
- {{ localize("Create list") }}
-
- {{ localize(".") }}
-
-
+
+ {{ localize("The following extensions are required for this pair: ") }}
+
+
+ {{ extension }}
+
+
+
+
+
+ {{ localize("The following selections could not be included due to problems:") }}
+
+
+ {{ problem }}
+
+
+ {{ localize("Exactly two elements needed for the collection. You may need to") }}
+
+ {{ localize("cancel") }}
+
+ {{ localize("and reselect new elements.") }}
+
-
+
+
{{
localize(
- "No elements in your history are valid for this collection. You may need to switch to a different history."
+ "Could not automatically create any pairs from the given dataset names. You may want to choose or enter different filters and try auto-pairing again."
)
}}
-
- {{ localize("The following extensions are required for this collection: ") }}
-
{{
localize(
- "Could not automatically create any pairs from the given dataset names. You may want to choose or enter different filters and try auto-pairing again."
+ [
+ "Collections of paired datasets are ordered lists of dataset pairs (often forward and reverse reads). ",
+ "These collections can be passed to tools and workflows in order to have analyses done on each member of ",
+ "the entire group. This interface allows you to create a collection, choose which datasets are paired, ",
+ "and re-order the final collection.",
+ ].join("")
)
}}
-
-
- {{ CANCEL_TEXT }}
-
- {{ allInvalidElementsPartTwo }}
-
-
{{
- localize(
- "Collections cannot have duplicated names. The following list names are duplicated: "
- )
+ localize("To pair datasets, you can:")
}}
-
-
{{ name }}
-
- {{ localize("Please fix these duplicates and try again.") }}
-
-
-
-
-
-
+
+ {{ localize("Click a dataset in the") }}
+
+ {{ localize("forward column") }}
+
+ {{ localize("to select it then click a dataset in the") }}
+
+ {{ localize("reverse column") }}
+
+
+
{{
localize(
- [
- "Collections of paired datasets are ordered lists of dataset pairs (often forward and reverse reads). ",
- "These collections can be passed to tools and workflows in order to have analyses done on each member of ",
- "the entire group. This interface allows you to create a collection, choose which datasets are paired, ",
- "and re-order the final collection.",
- ].join("")
+ "Click one of the Pair these datasets buttons in the middle column to pair the datasets in a particular row."
)
}}
-
-
- {{ localize("Unpaired datasets are shown in the") }}
-
- {{ localize("unpaired section") }}
+
+
+ {{ localize("Click") }}
+
+ {{ localize("Auto-pair") }}
- {{ "." }}
- {{ localize("Paired datasets are shown in the") }}
-
- {{ localize("paired section") }}
+ {{ localize("to have your datasets automatically paired based on name.") }}
+
+
+
+ {{
+ localize("You can filter what is shown in the unpaired sections by:")
+ }}
+
- {{ localize("Click a dataset in the") }}
-
- {{ localize("forward column") }}
-
- {{ localize("to select it then click a dataset in the") }}
-
- {{ localize("reverse column") }}
-
-
-
- {{
- localize(
- "Click one of the Pair these datasets buttons in the middle column to pair the datasets in a particular row."
- )
- }}
-
-
- {{ localize("Click") }}
-
- {{ localize("Auto-pair") }}
-
- {{ localize("to have your datasets automatically paired based on name.") }}
-
-
-
+
+
{{
- localize("You can filter what is shown in the unpaired sections by:")
+ localize(
+ "Choosing from a list of preset filters by clicking the arrow beside the filter input."
+ )
}}
-
+ {{
+ localize(
+ 'You can include or remove the file extensions (e.g. ".fastq") from your pair names by toggling the'
+ )
+ }}
+
+ {{ localize("Remove file extensions from pair names?") }}
+
+ {{ localize("control.") }}
+
+
+ {{ localize("Once your collection is complete, enter a") }}
+
+ {{ localize("name") }}
+
+ {{ localize("and click ") }}
+
+ {{ localize("Create list") }}
+
+ {{ localize(". (Note: you do not have to pair all unpaired datasets to finish.)") }}
+
+
{{
localize(
- 'You can include or remove the file extensions (e.g. ".fastq") from your pair names by toggling the'
+ "No elements in your history are valid for this collection. You may need to switch to a different history."
)
}}
-
- {{ localize("Remove file extensions from pair names?") }}
-
- {{ localize("control.") }}
-
-
- {{ localize("Once your collection is complete, enter a") }}
-
- {{ localize("name") }}
-
- {{ localize("and click ") }}
-
- {{ localize("Create list") }}
-
- {{ localize(". (Note: you do not have to pair all unpaired datasets to finish.)") }}
-
-
-
+
+ {{ localize("The following extensions are required for this collection: ") }}
+