From de7d43c602ea86d7ff29350427ad705c965924f9 Mon Sep 17 00:00:00 2001 From: Ahmed Awan Date: Tue, 20 Aug 2024 09:58:37 -0500 Subject: [PATCH] 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