From 9ac49b466c98d0a6ebdc446b38d72cf99b4bb569 Mon Sep 17 00:00:00 2001 From: John Chilton Date: Sun, 15 Dec 2024 10:25:12 -0500 Subject: [PATCH] New components for seeding the rule builder. This uses the wizard introduced by David for workflow exports instead of adapting the upload paradigm. The old component was very compact but also very unintuitive and just hacked together as quickly as possible and never really revisited. The wizard provides more space to explain things and is probably the way we want to go but still needs some serious love from someone better at UI than me. I need a component like this... but different for sample sheet seeding so I wanted to do a refresh and get something we're all more comfortable with ahead of that. --- .../Collections/BuildFileSetWizard.vue | 169 ++++++++++++++++++ .../RuleBasedCollectionCreatorModal.js | 19 +- client/src/components/Collections/tables.ts | 61 +++++++ .../Collections/wizard/CreatingWhat.vue | 43 +++++ .../Collections/wizard/JaggedDataAlert.vue | 17 ++ .../Collections/wizard/PasteData.vue | 82 +++++++++ .../Collections/wizard/SelectDataset.vue | 62 +++++++ .../Collections/wizard/SelectFolder.vue | 35 ++++ .../wizard/SourceFromCollection.vue | 29 +++ .../wizard/SourceFromDatasetAsTable.vue | 29 +++ .../wizard/SourceFromPastedData.vue | 29 +++ .../wizard/SourceFromRemoteFiles.vue | 26 +++ .../components/Collections/wizard/types.ts | 8 + .../Collections/wizard/useFileSetSources.ts | 45 +++++ .../Common/Wizard/GenericWizard.vue | 30 +++- client/src/components/Common/Wizard/utils.ts | 5 + client/src/components/Panels/ToolBox.vue | 7 +- .../src/components/Upload/UploadContainer.vue | 14 ++ .../Export/InvocationExportWizard.vue | 5 +- client/src/composables/route.ts | 11 +- 20 files changed, 696 insertions(+), 30 deletions(-) create mode 100644 client/src/components/Collections/BuildFileSetWizard.vue create mode 100644 client/src/components/Collections/tables.ts create mode 100644 client/src/components/Collections/wizard/CreatingWhat.vue create mode 100644 client/src/components/Collections/wizard/JaggedDataAlert.vue create mode 100644 client/src/components/Collections/wizard/PasteData.vue create mode 100644 client/src/components/Collections/wizard/SelectDataset.vue create mode 100644 client/src/components/Collections/wizard/SelectFolder.vue create mode 100644 client/src/components/Collections/wizard/SourceFromCollection.vue create mode 100644 client/src/components/Collections/wizard/SourceFromDatasetAsTable.vue create mode 100644 client/src/components/Collections/wizard/SourceFromPastedData.vue create mode 100644 client/src/components/Collections/wizard/SourceFromRemoteFiles.vue create mode 100644 client/src/components/Collections/wizard/types.ts create mode 100644 client/src/components/Collections/wizard/useFileSetSources.ts create mode 100644 client/src/components/Common/Wizard/utils.ts diff --git a/client/src/components/Collections/BuildFileSetWizard.vue b/client/src/components/Collections/BuildFileSetWizard.vue new file mode 100644 index 000000000000..9d659ce1e528 --- /dev/null +++ b/client/src/components/Collections/BuildFileSetWizard.vue @@ -0,0 +1,169 @@ + + + diff --git a/client/src/components/Collections/RuleBasedCollectionCreatorModal.js b/client/src/components/Collections/RuleBasedCollectionCreatorModal.js index 353f3e312c7c..ab88bbea5dcf 100644 --- a/client/src/components/Collections/RuleBasedCollectionCreatorModal.js +++ b/client/src/components/Collections/RuleBasedCollectionCreatorModal.js @@ -1,6 +1,8 @@ import _l from "utils/localization"; import Vue from "vue"; +import { rawToTable } from "@/components/Collections/tables"; + import { collectionCreatorModalSetup } from "./common/modal"; function ruleBasedCollectionCreatorModal(elements, elementsType, importType, options) { @@ -58,22 +60,7 @@ function createCollectionViaRules(selection, defaultHideSourceItems = true) { importType = selection.dataType || "collections"; elements = selection.elements; } else { - const hasNonWhitespaceChars = RegExp(/[^\s]/); - // Have pasted data, data from a history dataset, or FTP list. - const lines = selection.content - .split(/[\n\r]/) - .filter((line) => line.length > 0 && hasNonWhitespaceChars.exec(line)); - // Really poor tabular parser - we should get a library for this or expose options? I'm not - // sure. - let hasTabs = false; - if (lines.length > 0) { - const firstLine = lines[0]; - if (firstLine.indexOf("\t") >= 0) { - hasTabs = true; - } - } - const regex = hasTabs ? /\t/ : /\s+/; - elements = lines.map((line) => line.split(regex)); + elements = rawToTable(selection.content); elementsType = selection.selectionType; importType = selection.dataType || "collections"; } diff --git a/client/src/components/Collections/tables.ts b/client/src/components/Collections/tables.ts new file mode 100644 index 000000000000..9752f232ba8d --- /dev/null +++ b/client/src/components/Collections/tables.ts @@ -0,0 +1,61 @@ +import { computed, ref } from "vue"; + +export function useTableSummary() { + const rawValue = ref(""); + + const table = computed(() => { + return rawToTable(rawValue.value); + }); + + const columnCount = computed(() => { + const tableVal = table.value; + if (tableVal && tableVal.length) { + return tableVal[0]?.length || 0; + } else { + return 0; + } + }); + + const isJaggedData = computed(() => { + const tableVal = table.value; + const columnCountVal = columnCount.value; + for (const row of tableVal) { + if (row.length != columnCountVal) { + return true; + } + } + return false; + }); + + const jaggedDataWarning = computed(() => { + if (isJaggedData.value) { + return "This data contains a different number of columns per-row, this probably shouldn't be used as is."; + } else { + return undefined; + } + }); + return { + rawValue, + isJaggedData, + jaggedDataWarning, + columnCount, + table, + }; +} + +export function rawToTable(content: string): string[][] { + const hasNonWhitespaceChars = RegExp(/[^\s]/); + // Have pasted data, data from a history dataset, or FTP list. + const lines = content.split(/[\n\r]/).filter((line) => line.length > 0 && hasNonWhitespaceChars.exec(line)); + // Really poor tabular parser - we should get a library for this or expose options? I'm not + // sure. + let hasTabs = false; + if (lines.length > 0) { + const firstLine = lines[0]; + if (firstLine && firstLine.indexOf("\t") >= 0) { + hasTabs = true; + } + } + const regex = hasTabs ? /\t/ : /\s+/; + return lines.map((line) => line.split(regex)); +} diff --git a/client/src/components/Collections/wizard/CreatingWhat.vue b/client/src/components/Collections/wizard/CreatingWhat.vue new file mode 100644 index 000000000000..fb971e024c12 --- /dev/null +++ b/client/src/components/Collections/wizard/CreatingWhat.vue @@ -0,0 +1,43 @@ + + + diff --git a/client/src/components/Collections/wizard/JaggedDataAlert.vue b/client/src/components/Collections/wizard/JaggedDataAlert.vue new file mode 100644 index 000000000000..75fa2ef95adc --- /dev/null +++ b/client/src/components/Collections/wizard/JaggedDataAlert.vue @@ -0,0 +1,17 @@ + + + diff --git a/client/src/components/Collections/wizard/PasteData.vue b/client/src/components/Collections/wizard/PasteData.vue new file mode 100644 index 000000000000..1c9b2849fd65 --- /dev/null +++ b/client/src/components/Collections/wizard/PasteData.vue @@ -0,0 +1,82 @@ + + +