From 9f628f3a37cf3d6e264c67df6430e4cfcb0770b0 Mon Sep 17 00:00:00 2001 From: Assunta DeSanto Date: Thu, 21 Mar 2024 11:42:02 -0400 Subject: [PATCH 1/6] creating new branch based off dev for help mode --- client/src/components/Form/FormDisplay.vue | 8 ++ .../components/Masthead/HelpModeSwitch.vue | 49 +++++++++++ client/src/components/Masthead/Masthead.vue | 4 + client/src/components/Panels/HelpModeText.vue | 87 +++++++++++++++++++ .../src/entry/analysis/modules/Analysis.vue | 4 + .../stores/helpmode/helpModeStatusStore.js | 20 +++++ .../src/stores/helpmode/helpModeTextStore.js | 25 ++++++ client/src/stores/helpmode/helpTextConfig.yml | 2 + client/webpack.config.js | 6 ++ database/info.txt | 1 - 10 files changed, 205 insertions(+), 1 deletion(-) create mode 100644 client/src/components/Masthead/HelpModeSwitch.vue create mode 100644 client/src/components/Panels/HelpModeText.vue create mode 100644 client/src/stores/helpmode/helpModeStatusStore.js create mode 100644 client/src/stores/helpmode/helpModeTextStore.js create mode 100644 client/src/stores/helpmode/helpTextConfig.yml delete mode 100644 database/info.txt diff --git a/client/src/components/Form/FormDisplay.vue b/client/src/components/Form/FormDisplay.vue index e51dfe7e39b1..5bf7c3544376 100644 --- a/client/src/components/Form/FormDisplay.vue +++ b/client/src/components/Form/FormDisplay.vue @@ -16,8 +16,11 @@ + + + + diff --git a/client/src/components/Masthead/Masthead.vue b/client/src/components/Masthead/Masthead.vue index 0390029c3951..a122410528be 100644 --- a/client/src/components/Masthead/Masthead.vue +++ b/client/src/components/Masthead/Masthead.vue @@ -10,6 +10,7 @@ import { useConfig } from "@/composables/config"; import { useUserStore } from "@/stores/userStore"; import { loadWebhookMenuItems } from "./_webhooks"; +import HelpModeSwitch from "./HelpModeSwitch"; import MastheadItem from "./MastheadItem"; import QuotaMeter from "./QuotaMeter"; import { getActiveTab } from "./utilities"; @@ -138,6 +139,9 @@ onMounted(() => { :active-tab="activeTab" @open-url="emit('open-url', $event)" /> + + + diff --git a/client/src/components/Panels/HelpModeText.vue b/client/src/components/Panels/HelpModeText.vue new file mode 100644 index 000000000000..85cc1f52445d --- /dev/null +++ b/client/src/components/Panels/HelpModeText.vue @@ -0,0 +1,87 @@ + + + diff --git a/client/src/entry/analysis/modules/Analysis.vue b/client/src/entry/analysis/modules/Analysis.vue index df91d66c4655..4e4bde89c9d3 100644 --- a/client/src/entry/analysis/modules/Analysis.vue +++ b/client/src/entry/analysis/modules/Analysis.vue @@ -3,16 +3,19 @@ import { onMounted, onUnmounted, ref } from "vue"; import { useRouter } from "vue-router/composables"; import { usePanels } from "@/composables/usePanels"; +import { useHelpModeStatusStore } from "@/stores/helpmode/helpModeStatusStore"; import CenterFrame from "./CenterFrame.vue"; import ActivityBar from "@/components/ActivityBar/ActivityBar.vue"; import HistoryIndex from "@/components/History/Index.vue"; import FlexPanel from "@/components/Panels/FlexPanel.vue"; +import HelpModeText from "@/components/Panels/HelpModeText.vue"; import DragAndDropModal from "@/components/Upload/DragAndDropModal.vue"; const router = useRouter(); const showCenter = ref(false); const { showPanels } = usePanels(); +const status = useHelpModeStatusStore(); // methods function hideCenter() { @@ -46,5 +49,6 @@ onUnmounted(() => { + diff --git a/client/src/stores/helpmode/helpModeStatusStore.js b/client/src/stores/helpmode/helpModeStatusStore.js new file mode 100644 index 000000000000..282168b17ade --- /dev/null +++ b/client/src/stores/helpmode/helpModeStatusStore.js @@ -0,0 +1,20 @@ +import { defineStore } from "pinia"; + +import { useHelpModeTextStore } from "./helpModeTextStore"; + +export const useHelpModeStatusStore = defineStore("helpModeStatusStore", { + state: () => { + return { + helpmodestatus: false, + }; + }, + + actions: { + setHelpModeStatus(status) { + this.helpmodestatus = status; + if (status == false) { + useHelpModeTextStore().clearHelpModeText(); + } + }, + }, +}); diff --git a/client/src/stores/helpmode/helpModeTextStore.js b/client/src/stores/helpmode/helpModeTextStore.js new file mode 100644 index 000000000000..330c0e3dc422 --- /dev/null +++ b/client/src/stores/helpmode/helpModeTextStore.js @@ -0,0 +1,25 @@ +import { defineStore } from "pinia"; + +import config from "./helpTextConfig.yml"; + +export const useHelpModeTextStore = defineStore("helpModeText", { + state: () => { + return { + helpmodetext: "Welcome to Galaxy Help Mode!", + }; + }, + + actions: { + addHelpModeText(text) { + const file_path = config[text]; + fetch("https://raw.githubusercontent.com/assuntad23/galaxy-help-markdown/main/" + file_path) + .then((response) => response.text()) + .then((text) => { + this.helpmodetext = text; + }); + }, + clearHelpModeText() { + this.helpmodetext = "Welcome to Galaxy Help Mode!"; + }, + }, +}); diff --git a/client/src/stores/helpmode/helpTextConfig.yml b/client/src/stores/helpmode/helpTextConfig.yml new file mode 100644 index 000000000000..6ba27d638556 --- /dev/null +++ b/client/src/stores/helpmode/helpTextConfig.yml @@ -0,0 +1,2 @@ +tool_form_base: tools/tool_form_base.md +collection_builder: collections/collection_builder.md diff --git a/client/webpack.config.js b/client/webpack.config.js index 6ca6b748151d..c9b1aca21f0b 100644 --- a/client/webpack.config.js +++ b/client/webpack.config.js @@ -13,6 +13,7 @@ const scriptsBase = path.join(__dirname, "src"); const testsBase = path.join(__dirname, "tests"); const libsBase = path.join(scriptsBase, "libs"); const styleBase = path.join(scriptsBase, "style"); +const helpTextConfigPath = path.join(scriptsBase, "stores", "helpMode"); const modulesExcludedFromLibs = [ "jspdf", @@ -104,6 +105,11 @@ module.exports = (env = {}, argv = {}) => { test: /\.vue$/, loader: "vue-loader", }, + { + test: /\.ya?ml$/, + include: helpTextConfigPath, + loader: "yaml-loader", + }, { test: /\.tsx?$/, exclude: /node_modules/, diff --git a/database/info.txt b/database/info.txt deleted file mode 100644 index 5b316a096c27..000000000000 --- a/database/info.txt +++ /dev/null @@ -1 +0,0 @@ -This folder contains the data \ No newline at end of file From dcfd079676ecd92af99eac20b55b57bdb1230c50 Mon Sep 17 00:00:00 2001 From: Ahmed Awan Date: Fri, 22 Mar 2024 17:30:29 -0500 Subject: [PATCH 2/6] refactor stores, track help mode position, only drag from header --- client/src/components/Form/FormDisplay.vue | 10 ++- .../components/Masthead/HelpModeSwitch.vue | 18 ++-- client/src/components/Panels/HelpModeText.vue | 86 ++++++++++++------- .../src/entry/analysis/modules/Analysis.vue | 5 +- .../stores/helpmode/helpModeStatusStore.js | 20 ----- .../stores/helpmode/helpModeStatusStore.ts | 32 +++++++ .../src/stores/helpmode/helpModeTextStore.js | 25 ------ .../src/stores/helpmode/helpModeTextStore.ts | 45 ++++++++++ 8 files changed, 146 insertions(+), 95 deletions(-) delete mode 100644 client/src/stores/helpmode/helpModeStatusStore.js create mode 100644 client/src/stores/helpmode/helpModeStatusStore.ts delete mode 100644 client/src/stores/helpmode/helpModeTextStore.js create mode 100644 client/src/stores/helpmode/helpModeTextStore.ts diff --git a/client/src/components/Form/FormDisplay.vue b/client/src/components/Form/FormDisplay.vue index 5bf7c3544376..293857ea4e33 100644 --- a/client/src/components/Form/FormDisplay.vue +++ b/client/src/components/Form/FormDisplay.vue @@ -16,7 +16,7 @@ @@ -22,12 +14,12 @@ function toggleEnabledStatus() {
diff --git a/client/src/components/Panels/HelpModeText.vue b/client/src/components/Panels/HelpModeText.vue index 85cc1f52445d..e5837f4606e8 100644 --- a/client/src/components/Panels/HelpModeText.vue +++ b/client/src/components/Panels/HelpModeText.vue @@ -1,38 +1,58 @@ + - diff --git a/client/src/components/Panels/HelpModeText.vue b/client/src/components/Panels/HelpModeText.vue index e5837f4606e8..1a8067a2e002 100644 --- a/client/src/components/Panels/HelpModeText.vue +++ b/client/src/components/Panels/HelpModeText.vue @@ -1,86 +1,122 @@ diff --git a/client/src/stores/helpmode/helpModeStore.ts b/client/src/stores/helpmode/helpModeStore.ts index 95e704586a2f..e098d4215b8c 100644 --- a/client/src/stores/helpmode/helpModeStore.ts +++ b/client/src/stores/helpmode/helpModeStore.ts @@ -4,7 +4,7 @@ import type { IconDefinition } from "@fortawesome/fontawesome-svg-core"; import { defineStore } from "pinia"; -import { ref } from "vue"; +import { ref, watch } from "vue"; import { rethrowSimple } from "@/utils/simple-error"; @@ -40,8 +40,26 @@ export const useHelpModeStore = defineStore("helpModeStore", () => { const currentTabs = ref([]); /** Component ids for which fetching the help text was unsuccessful */ const invalidIds = ref([]); + /** The ids of the components for which help text was requested while help mode was disabled */ + const idsToStore = ref([]); + + // when help mode is enabled, store help for the ids requested while help mode was disabled + watch(status, async (newStatus) => { + if (newStatus) { + for (const id of idsToStore.value) { + await storeHelpModeText(id); + } + idsToStore.value = []; + } + }); async function storeHelpModeText(id: string, icon?: IconDefinition) { + // if help mode is disabled, store the id in the temp array and return + if (!status.value) { + idsToStore.value.push(id); + return; + } + loading.value = true; try { // Error handling @@ -78,6 +96,14 @@ export const useHelpModeStore = defineStore("helpModeStore", () => { } function clearHelpModeText(id: string) { + // if help mode is disabled, remove the id from the temp array + if (!status.value) { + const idx = idsToStore.value.indexOf(id); + if (idx !== -1) { + idsToStore.value.splice(idx, 1); + } + } + // remove id from currentTabs const idx = currentTabs.value.indexOf(id); if (idx !== -1) { @@ -105,7 +131,7 @@ export const useHelpModeStore = defineStore("helpModeStore", () => { status, /** Removes the tab from the stack for the given component `id` */ clearHelpModeText, - /** Adds help mode text for the given Galaxy component `id` */ + /** Adds help mode text for the given Galaxy component `id` if help mode is enabled */ storeHelpModeText, }; }); diff --git a/doc/source/admin/galaxy_options.rst b/doc/source/admin/galaxy_options.rst index b5511036af2f..098e5ca6571a 100644 --- a/doc/source/admin/galaxy_options.rst +++ b/doc/source/admin/galaxy_options.rst @@ -2360,6 +2360,16 @@ :Type: str +~~~~~~~~~~~~~ +``enable_help_mode`` +~~~~~~~~~~~~~ + +:Description: + Enables the Galaxy Help Mode for this Galaxy Instance. +:Default: ``false`` +:Type: bool + + ~~~~~~~~~~~~~~~~~~ ``static_enabled`` ~~~~~~~~~~~~~~~~~~ diff --git a/lib/galaxy/config/sample/galaxy.yml.sample b/lib/galaxy/config/sample/galaxy.yml.sample index 8032d879039b..28346711745a 100644 --- a/lib/galaxy/config/sample/galaxy.yml.sample +++ b/lib/galaxy/config/sample/galaxy.yml.sample @@ -1438,6 +1438,9 @@ galaxy: # activation emails. #terms_url: null + # Enables the Galaxy Help Mode for this Galaxy Instance. + #enable_help_mode: false + # Serve static content, which must be enabled if you're not serving it # via a proxy server. These options should be self explanatory and so # are not documented individually. You can use these paths (or ones diff --git a/lib/galaxy/config/schemas/config_schema.yml b/lib/galaxy/config/schemas/config_schema.yml index 99dbe9657746..2dbec46f05cb 100644 --- a/lib/galaxy/config/schemas/config_schema.yml +++ b/lib/galaxy/config/schemas/config_schema.yml @@ -1708,6 +1708,13 @@ mapping: The URL linked by the "Terms and Conditions" link in the "Help" menu, as well as on the user registration and login forms and in the activation emails. + enable_help_mode: + type: bool + default: false + required: false + desc: | + Enables the Galaxy Help Mode for this Galaxy Instance. + static_enabled: type: bool default: true diff --git a/lib/galaxy/managers/configuration.py b/lib/galaxy/managers/configuration.py index 14348c06742b..823e09ca54a4 100644 --- a/lib/galaxy/managers/configuration.py +++ b/lib/galaxy/managers/configuration.py @@ -206,6 +206,7 @@ def _config_is_truthy(item, key, **context): "upload_from_form_button": _use_config, "release_doc_base_url": _use_config, "expose_user_email": _use_config, + "enable_help_mode": _use_config, "enable_tool_source_display": _use_config, "enable_celery_tasks": _use_config, "quota_source_labels": lambda item, key, **context: list( From 6cc94ef343a4ccb66c1e5dc2a0dbe334182089db Mon Sep 17 00:00:00 2001 From: Ahmed Awan Date: Mon, 15 Apr 2024 12:46:14 -0500 Subject: [PATCH 5/6] move help mode into side panel (primarily) Still toggleable into a draggable mode if needed --- .../components/ActivityBar/ActivityBar.vue | 14 ++++ .../HelpModeDraggable.vue} | 50 +++++---------- client/src/components/Help/HelpModeText.vue | 49 ++++++++++++++ .../components/Masthead/HelpModeSwitch.vue | 9 ++- client/src/components/Masthead/Masthead.vue | 4 +- .../src/components/Panels/HelpModePanel.vue | 64 +++++++++++++++++++ .../src/entry/analysis/modules/Analysis.vue | 6 +- client/src/stores/helpmode/helpModeStore.ts | 20 +++++- client/src/stores/helpmode/helpTextConfig.yml | 3 + 9 files changed, 173 insertions(+), 46 deletions(-) rename client/src/components/{Panels/HelpModeText.vue => Help/HelpModeDraggable.vue} (67%) create mode 100644 client/src/components/Help/HelpModeText.vue create mode 100644 client/src/components/Panels/HelpModePanel.vue diff --git a/client/src/components/ActivityBar/ActivityBar.vue b/client/src/components/ActivityBar/ActivityBar.vue index 0e2c54e7b181..3b9c1e2e0d14 100644 --- a/client/src/components/ActivityBar/ActivityBar.vue +++ b/client/src/components/ActivityBar/ActivityBar.vue @@ -9,6 +9,7 @@ import { useHashedUserId } from "@/composables/hashedUserId"; import { convertDropData } from "@/stores/activitySetup"; import { type Activity, useActivityStore } from "@/stores/activityStore"; import { useEventStore } from "@/stores/eventStore"; +import { useHelpModeStore } from "@/stores/helpmode/helpModeStore"; import { useUserStore } from "@/stores/userStore"; import VisualizationPanel from "../Panels/VisualizationPanel.vue"; @@ -18,6 +19,7 @@ import NotificationItem from "./Items/NotificationItem.vue"; import UploadItem from "./Items/UploadItem.vue"; import AdminPanel from "@/components/admin/AdminPanel.vue"; import FlexPanel from "@/components/Panels/FlexPanel.vue"; +import HelpModePanel from "@/components/Panels/HelpModePanel.vue"; import MultiviewPanel from "@/components/Panels/MultiviewPanel.vue"; import NotificationsPanel from "@/components/Panels/NotificationsPanel.vue"; import SettingsPanel from "@/components/Panels/SettingsPanel.vue"; @@ -39,6 +41,9 @@ const emit = defineEmits(["dragstart"]); // activities from store const { activities } = storeToRefs(activityStore); +// Galaxy help mode draggable status +const { draggableActive } = storeToRefs(useHelpModeStore()); + // drag references const dragTarget: Ref = ref(null); const dragItem: Ref = ref(null); @@ -198,6 +203,14 @@ watch( + + diff --git a/client/src/components/Panels/HelpModeText.vue b/client/src/components/Help/HelpModeDraggable.vue similarity index 67% rename from client/src/components/Panels/HelpModeText.vue rename to client/src/components/Help/HelpModeDraggable.vue index 1a8067a2e002..c0fd7ece3f37 100644 --- a/client/src/components/Panels/HelpModeText.vue +++ b/client/src/components/Help/HelpModeDraggable.vue @@ -3,35 +3,27 @@ import { library } from "@fortawesome/fontawesome-svg-core"; import { faTimes, faUndo } from "@fortawesome/free-solid-svg-icons"; import { FontAwesomeIcon } from "@fortawesome/vue-fontawesome"; import { useDraggable } from "@vueuse/core"; -import { BButton, BTab, BTabs } from "bootstrap-vue"; +import { BButton } from "bootstrap-vue"; import { storeToRefs } from "pinia"; import { reactive, ref, watch } from "vue"; -import { useMarkdown } from "@/composables/markdown"; import { useAnimationFrameSize } from "@/composables/sensors/animationFrameSize"; -import { DEFAULT_HELP_TEXT, useHelpModeStore } from "@/stores/helpmode/helpModeStore"; -import localize from "@/utils/localization"; +import { useHelpModeStore } from "@/stores/helpmode/helpModeStore"; +import { useUserStore } from "@/stores/userStore"; +import HelpModeText from "./HelpModeText.vue"; import Heading from "@/components/Common/Heading.vue"; -import LoadingSpan from "@/components/LoadingSpan.vue"; library.add(faTimes, faUndo); -const { renderMarkdown } = useMarkdown({ - openLinksInNewPage: true, - html: true, - appendHrRuleToDetails: true, - replaceCodeWithIcon: true, -}); +const userStore = useUserStore(); // local refs -const { status, position, helpModeStyle, activeTab, contents, loading, currentTabs } = storeToRefs(useHelpModeStore()); +const { draggableActive, position, helpModeStyle } = storeToRefs(useHelpModeStore()); const el = ref(null); const helpModeHeader = ref(null); const helpModeSize = reactive(useAnimationFrameSize(el)); -const noHelpTextMsg = localize("No help text available for this component"); - // draggable properties const { style } = useDraggable(helpModeHeader, { initialValue: position.value }); @@ -75,6 +67,15 @@ watch( } ); +/** Close the draggable help mode and toggle the sidebar */ +function closeDraggable() { + const panelActive = userStore.toggledSideBar !== ""; + draggableActive.value = false; + if (!panelActive) { + userStore.toggleSideBar("help"); + } +} + /** Reset the position of the help mode to default */ function resetPosition() { helpModeStyle.value = { @@ -93,22 +94,11 @@ function resetPosition() { - + - {{ DEFAULT_HELP_TEXT }} - - - - -
- - - +
@@ -137,10 +127,4 @@ function resetPosition() { border-bottom: 2px solid #868686; cursor: move; } -.help-mode-container { - margin-top: 0; - padding: 10px; - overflow-y: auto; - height: 100%; -} diff --git a/client/src/components/Help/HelpModeText.vue b/client/src/components/Help/HelpModeText.vue new file mode 100644 index 000000000000..2cdb8a85fc99 --- /dev/null +++ b/client/src/components/Help/HelpModeText.vue @@ -0,0 +1,49 @@ + + + + + diff --git a/client/src/components/Masthead/HelpModeSwitch.vue b/client/src/components/Masthead/HelpModeSwitch.vue index a1a7b7bbf0b4..aed71d8f3211 100644 --- a/client/src/components/Masthead/HelpModeSwitch.vue +++ b/client/src/components/Masthead/HelpModeSwitch.vue @@ -11,9 +11,9 @@ import localize from "@/utils/localization"; library.add(faQuestionCircle); const tooltip = localize("Enable/Disable Help Mode"); -const { status } = storeToRefs(useHelpModeStore()); +const { draggableActive } = storeToRefs(useHelpModeStore()); function toggleEnabledStatus() { - status.value = !status.value; + draggableActive.value = !draggableActive.value; } @@ -22,14 +22,13 @@ function toggleEnabledStatus() { - - + diff --git a/client/src/components/Masthead/Masthead.vue b/client/src/components/Masthead/Masthead.vue index a122410528be..04882a5ec394 100644 --- a/client/src/components/Masthead/Masthead.vue +++ b/client/src/components/Masthead/Masthead.vue @@ -139,9 +139,9 @@ onMounted(() => { :active-tab="activeTab" @open-url="emit('open-url', $event)" /> - + diff --git a/client/src/components/Panels/HelpModePanel.vue b/client/src/components/Panels/HelpModePanel.vue new file mode 100644 index 000000000000..5941e1471657 --- /dev/null +++ b/client/src/components/Panels/HelpModePanel.vue @@ -0,0 +1,64 @@ + + + + + diff --git a/client/src/entry/analysis/modules/Analysis.vue b/client/src/entry/analysis/modules/Analysis.vue index 39b789bdebeb..28a5ad2284c6 100644 --- a/client/src/entry/analysis/modules/Analysis.vue +++ b/client/src/entry/analysis/modules/Analysis.vue @@ -8,15 +8,15 @@ import { useHelpModeStore } from "@/stores/helpmode/helpModeStore"; import CenterFrame from "./CenterFrame.vue"; import ActivityBar from "@/components/ActivityBar/ActivityBar.vue"; +import HelpModeDraggable from "@/components/Help/HelpModeDraggable.vue"; import HistoryIndex from "@/components/History/Index.vue"; import FlexPanel from "@/components/Panels/FlexPanel.vue"; -import HelpModeText from "@/components/Panels/HelpModeText.vue"; import DragAndDropModal from "@/components/Upload/DragAndDropModal.vue"; const router = useRouter(); const showCenter = ref(false); const { showPanels } = usePanels(); -const { status: helpModeStatus } = storeToRefs(useHelpModeStore()); +const { draggableActive } = storeToRefs(useHelpModeStore()); // methods function hideCenter() { @@ -50,6 +50,6 @@ onUnmounted(() => { - + diff --git a/client/src/stores/helpmode/helpModeStore.ts b/client/src/stores/helpmode/helpModeStore.ts index e098d4215b8c..fab82558299f 100644 --- a/client/src/stores/helpmode/helpModeStore.ts +++ b/client/src/stores/helpmode/helpModeStore.ts @@ -3,11 +3,12 @@ */ import type { IconDefinition } from "@fortawesome/fontawesome-svg-core"; -import { defineStore } from "pinia"; -import { ref, watch } from "vue"; +import { defineStore, storeToRefs } from "pinia"; +import { computed, ref, watch } from "vue"; import { rethrowSimple } from "@/utils/simple-error"; +import { useUserStore } from "../userStore"; import config from "./helpTextConfig.yml"; interface HelpContent { @@ -28,7 +29,9 @@ export const useHelpModeStore = defineStore("helpModeStore", () => { // TODO: Maybe `status` should be tracked in local storage? // const status: Ref = useUserLocalStorage("help-mode-status", false); - const status = ref(false); + const { toggledSideBar } = storeToRefs(useUserStore()); + + const draggableActive = ref(false); const position = ref({ x: 0, y: 0 }); const helpModeStyle = ref({ width: "25%", @@ -43,6 +46,15 @@ export const useHelpModeStore = defineStore("helpModeStore", () => { /** The ids of the components for which help text was requested while help mode was disabled */ const idsToStore = ref([]); + const status = computed(() => toggledSideBar.value === "help" || draggableActive.value); + + // if side bar is toggled to help mode, if draggable is active, set it to false + watch(toggledSideBar, (newVal) => { + if (newVal === "help" && draggableActive.value) { + draggableActive.value = false; + } + }); + // when help mode is enabled, store help for the ids requested while help mode was disabled watch(status, async (newStatus) => { if (newStatus) { @@ -129,6 +141,8 @@ export const useHelpModeStore = defineStore("helpModeStore", () => { position, /** Whether help mode is active or not */ status, + /** Whether the draggble help mode is active or not */ + draggableActive, /** Removes the tab from the stack for the given component `id` */ clearHelpModeText, /** Adds help mode text for the given Galaxy component `id` if help mode is enabled */ diff --git a/client/src/stores/helpmode/helpTextConfig.yml b/client/src/stores/helpmode/helpTextConfig.yml index 32997b44f978..8b44bb141b4b 100644 --- a/client/src/stores/helpmode/helpTextConfig.yml +++ b/client/src/stores/helpmode/helpTextConfig.yml @@ -7,3 +7,6 @@ collection_builder: selector_modal_switch: title: History Selector file_path: histories/selector_modal_switch.md +selector_modal_multiview: + title: History Selector + file_path: histories/selector_modal_multiview.md From de7d43c602ea86d7ff29350427ad705c965924f9 Mon Sep 17 00:00:00 2001 From: Ahmed Awan Date: Tue, 20 Aug 2024 09:58:37 -0500 Subject: [PATCH 6/6] help mode updated --- client/src/components/Form/FormDisplay.vue | 2 +- .../src/components/Help/HelpModeDraggable.vue | 2 +- client/src/components/Help/HelpModeText.vue | 112 +++++++++++++++--- .../History/Modals/SelectorModal.vue | 5 +- .../src/components/Panels/HelpModePanel.vue | 9 +- client/src/composables/markdown.ts | 53 +++++++++ client/src/stores/helpmode/helpModeStore.ts | 53 +++++++-- client/src/stores/helpmode/helpTextConfig.yml | 20 +++- 8 files changed, 217 insertions(+), 39 deletions(-) diff --git a/client/src/components/Form/FormDisplay.vue b/client/src/components/Form/FormDisplay.vue index 289972140231..306ab5a5d5a6 100644 --- a/client/src/components/Form/FormDisplay.vue +++ b/client/src/components/Form/FormDisplay.vue @@ -159,7 +159,7 @@ export default { methods: { ...mapActions(useHelpModeStore, ["storeHelpModeText", "clearHelpModeText"]), callHelpMode() { - this.storeHelpModeText("tool_form_base"); + this.storeHelpModeText("tool_form_base", true); }, buildFormData() { const params = {}; diff --git a/client/src/components/Help/HelpModeDraggable.vue b/client/src/components/Help/HelpModeDraggable.vue index c0fd7ece3f37..3935cc751d24 100644 --- a/client/src/components/Help/HelpModeDraggable.vue +++ b/client/src/components/Help/HelpModeDraggable.vue @@ -98,7 +98,7 @@ function resetPosition() {
- + diff --git a/client/src/components/Help/HelpModeText.vue b/client/src/components/Help/HelpModeText.vue index 2cdb8a85fc99..6ec40d10735c 100644 --- a/client/src/components/Help/HelpModeText.vue +++ b/client/src/components/Help/HelpModeText.vue @@ -1,49 +1,133 @@ + + diff --git a/client/src/components/History/Modals/SelectorModal.vue b/client/src/components/History/Modals/SelectorModal.vue index a9472750a9f9..46a65243cf63 100644 --- a/client/src/components/History/Modals/SelectorModal.vue +++ b/client/src/components/History/Modals/SelectorModal.vue @@ -67,19 +67,16 @@ watch( () => propShowModal.value, (show: boolean) => { let helpModeId; - let helpModeIcon; if (props.multiple) { if (show) { selectedHistories.value = [...pinnedHistories.value]; } helpModeId = "selector_modal_multiview"; - helpModeIcon = faCheckSquare; } else { helpModeId = "selector_modal_switch"; - helpModeIcon = faExchangeAlt; } if (show) { - helpModeStore.storeHelpModeText(helpModeId, helpModeIcon); + helpModeStore.storeHelpModeText(helpModeId); } else { helpModeStore.clearHelpModeText(helpModeId); } diff --git a/client/src/components/Panels/HelpModePanel.vue b/client/src/components/Panels/HelpModePanel.vue index 5941e1471657..ddd989e1fa88 100644 --- a/client/src/components/Panels/HelpModePanel.vue +++ b/client/src/components/Panels/HelpModePanel.vue @@ -2,7 +2,7 @@ import { library } from "@fortawesome/fontawesome-svg-core"; import { faExternalLinkAlt } from "@fortawesome/free-solid-svg-icons"; import { FontAwesomeIcon } from "@fortawesome/vue-fontawesome"; -import { BButton, BButtonGroup, BCard } from "bootstrap-vue"; +import { BButton, BButtonGroup } from "bootstrap-vue"; import { storeToRefs } from "pinia"; import { useHelpModeStore } from "@/stores/helpmode/helpModeStore"; @@ -44,13 +44,11 @@ function toggleOut() { - - - + @@ -58,7 +56,6 @@ function toggleOut() { .help-text { display: flex; flex-direction: column; - background-color: aliceblue; overflow: auto; } diff --git a/client/src/composables/markdown.ts b/client/src/composables/markdown.ts index 244f3b4eede8..c9a6ae83a43d 100644 --- a/client/src/composables/markdown.ts +++ b/client/src/composables/markdown.ts @@ -30,6 +30,49 @@ function addRuleOpenLinksInNewPage(engine: MarkdownIt) { }; } +function addRulePrependInternalRouteToInternalLinks(engine: MarkdownIt, internalRoute: string) { + const defaultRender = + engine.renderer.rules.link_open || + function (tokens, idx, options, _env, self) { + return self.renderToken(tokens, idx, options); + }; + + engine.renderer.rules.link_open = function (tokens, idx, options, env, self) { + const token = tokens[idx]; + + if (token) { + const hrefIndex = token.attrIndex("href"); + + if (hrefIndex >= 0) { + const href = token.attrs![hrefIndex]![1]; + if (href.startsWith("/")) { + token.attrs![hrefIndex]![1] = `${internalRoute}${href}`; + } + } + } + + return defaultRender(tokens, idx, options, env, self); + }; +} + +function addRuleRemoveBeforeFirstH1(engine: MarkdownIt) { + const defaultRender = engine.renderer.render; + + engine.renderer.render = function (tokens, options, env) { + let firstH1Index = tokens.findIndex((token) => token.type === "heading_open" && token.tag === "h1"); + + if (firstH1Index !== -1) { + // If there's a closing tag for the h1, we need to keep it + if (tokens[firstH1Index + 1]?.type === "heading_close") { + firstH1Index++; + } + tokens = tokens.slice(firstH1Index); + } + + return defaultRender.call(this, tokens, options, env); + }; +} + function addRuleHeadingIncreaseLevel(engine: MarkdownIt, increaseBy: number) { const defaultOpen = engine.renderer.rules.heading_open || @@ -119,9 +162,11 @@ function adjustMdForOptions(markdown: string, options: UseMarkdownOptions) { interface UseMarkdownOptions { openLinksInNewPage?: boolean; increaseHeadingLevelBy?: number; + removeContentBeforeFirstH1?: boolean; html?: boolean; appendHrRuleToDetails?: boolean; replaceCodeWithIcon?: boolean; + internalRoute?: string; } type RawMarkdown = string; @@ -135,6 +180,14 @@ export function useMarkdown(options: UseMarkdownOptions = {}) { addRuleOpenLinksInNewPage(mdEngine); } + if (options.removeContentBeforeFirstH1) { + addRuleRemoveBeforeFirstH1(mdEngine); + } + + if (options.internalRoute) { + addRulePrependInternalRouteToInternalLinks(mdEngine, options.internalRoute); + } + if (options.increaseHeadingLevelBy) { addRuleHeadingIncreaseLevel(mdEngine, options.increaseHeadingLevelBy); } diff --git a/client/src/stores/helpmode/helpModeStore.ts b/client/src/stores/helpmode/helpModeStore.ts index fab82558299f..7e1bf2fbe9a2 100644 --- a/client/src/stores/helpmode/helpModeStore.ts +++ b/client/src/stores/helpmode/helpModeStore.ts @@ -2,7 +2,6 @@ * A pinia store for the Galaxy Help Mode. */ -import type { IconDefinition } from "@fortawesome/fontawesome-svg-core"; import { defineStore, storeToRefs } from "pinia"; import { computed, ref, watch } from "vue"; @@ -14,7 +13,7 @@ import config from "./helpTextConfig.yml"; interface HelpContent { title: string; content: string; - icon?: IconDefinition; + icon?: string; } interface HelpModeStyle { width: string; @@ -23,6 +22,10 @@ interface HelpModeStyle { left?: string; } +export const routeTextIds: Record = { + "/": ["galaxy_intro", "history_system"], +}; + export const DEFAULT_HELP_TEXT = "Welcome to Galaxy Help Mode!"; export const useHelpModeStore = defineStore("helpModeStore", () => { @@ -45,6 +48,8 @@ export const useHelpModeStore = defineStore("helpModeStore", () => { const invalidIds = ref([]); /** The ids of the components for which help text was requested while help mode was disabled */ const idsToStore = ref([]); + /** The route for which help text is loaded */ + const currentHelpRoute = ref(null); const status = computed(() => toggledSideBar.value === "help" || draggableActive.value); @@ -65,7 +70,7 @@ export const useHelpModeStore = defineStore("helpModeStore", () => { } }); - async function storeHelpModeText(id: string, icon?: IconDefinition) { + async function storeHelpModeText(id: string, top = false) { // if help mode is disabled, store the id in the temp array and return if (!status.value) { idsToStore.value.push(id); @@ -83,21 +88,25 @@ export const useHelpModeStore = defineStore("helpModeStore", () => { throw new Error(`No help mode config found for ${id}`); } - const { title, file_path } = config[id]; + const { title, file_path, icon } = config[id]; // if the text is already stored, don't fetch it again if (!contents.value[id]) { - const response = await fetch( - "https://raw.githubusercontent.com/assuntad23/galaxy-help-markdown/main/" + file_path - ); + const response = await fetch(file_path); const text = await response.text(); contents.value[id] = { title, content: text, icon }; } // set the active tab to the id activeTab.value = id; - // move this id to the top of the stack - currentTabs.value.push(id); + + if (top) { + // move this id to the top of the stack + currentTabs.value = [id, ...currentTabs.value]; + } else { + // move this id to the end of the stack + currentTabs.value.push(id); + } } catch (error) { console.error(`Failed to fetch help mode text for ${id}`, error); invalidIds.value.push(id); @@ -107,6 +116,29 @@ export const useHelpModeStore = defineStore("helpModeStore", () => { } } + async function storeHelpModeTextForRoute(route: string) { + if (currentHelpRoute.value === route) { + return; + } else if (currentHelpRoute.value) { + // clear the previous route's help text(s) + const lastIds = routeTextIds[currentHelpRoute.value]; + if (lastIds) { + for (const id of lastIds) { + clearHelpModeText(id); + } + } + } + // now, set the current route + currentHelpRoute.value = route; + // load the help text(s) for the new route + const ids = routeTextIds[route]; + if (ids) { + for (const id of ids) { + await storeHelpModeText(id); + } + } + } + function clearHelpModeText(id: string) { // if help mode is disabled, remove the id from the temp array if (!status.value) { @@ -147,5 +179,8 @@ export const useHelpModeStore = defineStore("helpModeStore", () => { clearHelpModeText, /** Adds help mode text for the given Galaxy component `id` if help mode is enabled */ storeHelpModeText, + /** Adds help mode text(s) for the given Galaxy route if help mode is enabled */ + storeHelpModeTextForRoute, + currentHelpRoute, }; }); diff --git a/client/src/stores/helpmode/helpTextConfig.yml b/client/src/stores/helpmode/helpTextConfig.yml index 8b44bb141b4b..841cc94d5132 100644 --- a/client/src/stores/helpmode/helpTextConfig.yml +++ b/client/src/stores/helpmode/helpTextConfig.yml @@ -1,12 +1,24 @@ tool_form_base: title: Tool Form - file_path: tools/tool_form_base.md + file_path: https://raw.githubusercontent.com/assuntad23/galaxy-help-markdown/main/tools/tool_form_base.md + icon: fa-wrench collection_builder: title: Collection Builder - file_path: collections/collection_builder.md + file_path: https://raw.githubusercontent.com/assuntad23/galaxy-help-markdown/main/collections/collection_builder.md selector_modal_switch: title: History Selector - file_path: histories/selector_modal_switch.md + file_path: https://raw.githubusercontent.com/assuntad23/galaxy-help-markdown/main/histories/selector_modal_switch.md + icon: fa-exchange-alt selector_modal_multiview: title: History Selector - file_path: histories/selector_modal_multiview.md + file_path: https://raw.githubusercontent.com/assuntad23/galaxy-help-markdown/main/histories/selector_modal_multiview.md + icon: fa-columns +galaxy_intro: + title: A short introduction to Galaxy + file_path: https://raw.githubusercontent.com/galaxyproject/training-material/main/topics/introduction/tutorials/galaxy-intro-short/tutorial.md + origin: training-material +history_system: + title: Understanding Histories + file_path: https://raw.githubusercontent.com/galaxyproject/training-material/main/topics/galaxy-interface/tutorials/history/tutorial.md + origin: training-material + icon: fa-hdd