Skip to content

Commit

Permalink
help mode updated
Browse files Browse the repository at this point in the history
  • Loading branch information
ahmedhamidawan committed Aug 20, 2024
1 parent 6cc94ef commit de7d43c
Show file tree
Hide file tree
Showing 8 changed files with 217 additions and 39 deletions.
2 changes: 1 addition & 1 deletion client/src/components/Form/FormDisplay.vue
Original file line number Diff line number Diff line change
Expand Up @@ -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 = {};
Expand Down
2 changes: 1 addition & 1 deletion client/src/components/Help/HelpModeDraggable.vue
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,7 @@ function resetPosition() {
<FontAwesomeIcon :icon="faTimes" />
</BButton>
</div>
<HelpModeText />
<HelpModeText tabbed />
</div>
</template>

Expand Down
112 changes: 98 additions & 14 deletions client/src/components/Help/HelpModeText.vue
Original file line number Diff line number Diff line change
@@ -1,49 +1,133 @@
<script setup lang="ts">
import { library } from "@fortawesome/fontawesome-svg-core";
import { faCaretDown, faCaretUp } from "@fortawesome/free-solid-svg-icons";
import { FontAwesomeIcon } from "@fortawesome/vue-fontawesome";
import { BAlert, BTab, BTabs } from "bootstrap-vue";
import { BAlert, BCard, BCardBody, BCardHeader, BCollapse, BTab, BTabs } from "bootstrap-vue";
import { storeToRefs } from "pinia";
import { computed, watch } from "vue";
import { useRoute } from "vue-router/composables";
import { useMarkdown } from "@/composables/markdown";
import { DEFAULT_HELP_TEXT, useHelpModeStore } from "@/stores/helpmode/helpModeStore";
import localize from "@/utils/localization";
import Heading from "../Common/Heading.vue";
import LoadingSpan from "@/components/LoadingSpan.vue";
library.add(faCaretDown, faCaretUp);
const props = defineProps<{
tabbed?: boolean;
}>();
const route = useRoute();
const tabNo = computed<number>({
get: () => {
if (activeTab.value) {
return currentTabs.value.indexOf(activeTab.value);
} else {
return currentTabs.value.length - 1;
}
},
set: (value: number) => {
if (value === null) {
activeTab.value = null;
} else {
activeTab.value = currentTabs.value[value] || null;
}
},
});
const { renderMarkdown } = useMarkdown({
openLinksInNewPage: true,
html: true,
appendHrRuleToDetails: true,
replaceCodeWithIcon: true,
removeContentBeforeFirstH1: true,
internalRoute: "https://galaxyproject.org",
});
// local refs
const { activeTab, contents, loading, currentTabs } = storeToRefs(useHelpModeStore());
const helpModeStore = useHelpModeStore();
const { activeTab, contents, loading, currentTabs } = storeToRefs(helpModeStore);
const currentRoute = computed(() => route.path);
watch(
() => currentRoute.value,
async (newVal) => {
await helpModeStore.storeHelpModeTextForRoute(newVal);
},
{ immediate: true }
);
const noHelpTextMsg = localize("No help text available for this component");
function changeTab(helpId: string) {
if (activeTab.value === helpId && !props.tabbed) {
activeTab.value = null;
} else {
activeTab.value = helpId;
}
}
</script>

<template>
<span v-if="!activeTab" v-localize class="help-mode-container">{{ DEFAULT_HELP_TEXT }}</span>
<BTabs v-else class="help-mode-container">
<BTab v-for="helpId of currentTabs" :key="helpId" :active="activeTab === helpId">
<span v-if="currentTabs.length === 0" v-localize class="help-mode-container">{{ DEFAULT_HELP_TEXT }}</span>
<component
:is="props.tabbed ? BTabs : 'div'"
v-else
v-model="tabNo"
class="d-flex flex-column help-mode-container"
pills
fill
title-link-class="w-100 h-100 bg-danger"
content-class="overflow-auto"
nav-class="help-mode-tabs">
<component :is="props.tabbed ? BTab : BCard" v-for="helpId of currentTabs" :key="helpId" no-body>
<BCardHeader
v-if="!props.tabbed"
role="button"
class="unselectable d-flex justify-content-between"
@click="changeTab(helpId)">
<Heading h3 size="sm" inline :icon="contents[helpId]?.icon" class="truncate">{{ contents[helpId]?.title }}</Heading>
<FontAwesomeIcon :icon="activeTab === helpId ? faCaretUp : faCaretDown" />
</BCardHeader>
<template v-slot:title>
<FontAwesomeIcon v-if="contents[helpId]?.icon" :icon="contents[helpId]?.icon" />
{{ contents[helpId]?.title }}
</template>
<!-- eslint-disable-next-line vue/no-v-html -->
<div v-if="!loading" v-html="renderMarkdown(contents[helpId]?.content || noHelpTextMsg)" />
<BAlert v-else variant="info" show>
<LoadingSpan message="Loading help text" />
</BAlert>
</BTab>
</BTabs>

<BCollapse :visible="activeTab && activeTab === helpId">
<BCardBody class="pt-1">
<!-- eslint-disable-next-line vue/no-v-html -->
<div v-if="!loading" v-html="renderMarkdown(contents[helpId]?.content || noHelpTextMsg)" />
<BAlert v-else variant="info" show>
<LoadingSpan message="Loading help text" />
</BAlert>
</BCardBody>
</BCollapse>
</component>
</component>
</template>

<style>
.help-mode-tabs {
overflow-x: auto;
flex-wrap: unset;
text-wrap: nowrap;
}
</style>

<style scoped lang="scss">
.help-mode-container {
margin-top: 0;
padding: 10px;
overflow-y: auto;
height: 100%;
}
.truncate {
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
</style>
5 changes: 1 addition & 4 deletions client/src/components/History/Modals/SelectorModal.vue
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}
Expand Down
9 changes: 3 additions & 6 deletions client/src/components/Panels/HelpModePanel.vue
Original file line number Diff line number Diff line change
Expand Up @@ -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";
Expand Down Expand Up @@ -44,21 +44,18 @@ function toggleOut() {

<template v-slot:header>
<div v-localize class="ml-1">
This is Galaxy's help mode. It shows help text for the current component you are interacting with.
This is Galaxy's help mode. It shows help text for the current view you are interacting with.
</div>
</template>

<BCard class="help-text">
<HelpModeText />
</BCard>
<HelpModeText class="help-text" />
</ActivityPanel>
</template>

<style lang="scss" scoped>
.help-text {
display: flex;
flex-direction: column;
background-color: aliceblue;
overflow: auto;
}
</style>
53 changes: 53 additions & 0 deletions client/src/composables/markdown.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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 ||
Expand Down Expand Up @@ -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;
Expand All @@ -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);
}
Expand Down
Loading

0 comments on commit de7d43c

Please sign in to comment.