Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Show workflow help (and readme?) in run form #19736

Open
wants to merge 2 commits into
base: dev
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions client/src/api/schema/schema.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16448,6 +16448,11 @@ export interface components {
* @description The hash of the email of the creator of this workflow
*/
email_hash: string | null;
/**
* Help
* @description The detailed help text for how to use the workflow and debug problems with it.
*/
help: string | null;
/**
* Hidden
* @description TODO
Expand Down Expand Up @@ -16507,6 +16512,11 @@ export interface components {
* @description Whether this workflow is currently publicly available to all users.
*/
published: boolean;
/**
* Readme
* @description The detailed markdown readme of the workflow.
*/
readme: string | null;
/**
* Show in Tool Panel
* @description Whether to display this workflow in the Tools Panel.
Expand Down
69 changes: 46 additions & 23 deletions client/src/components/Workflow/Run/WorkflowRunFormSimple.vue
Original file line number Diff line number Diff line change
@@ -1,13 +1,14 @@
<script setup lang="ts">
import { faSitemap } from "@fortawesome/free-solid-svg-icons";
import { faInfoCircle, faSitemap } from "@fortawesome/free-solid-svg-icons";
import { FontAwesomeIcon } from "@fortawesome/vue-fontawesome";
import { BAlert, BButton, BDropdown, BDropdownForm, BFormCheckbox } from "bootstrap-vue";
import { BAlert, BButton, BButtonGroup, BCard, BDropdown, BDropdownForm, BFormCheckbox } from "bootstrap-vue";
import { storeToRefs } from "pinia";
import { computed, ref, watch } from "vue";

import { allowCachedJobs } from "@/components/Tool/utilities";
import { isWorkflowInput } from "@/components/Workflow/constants";
import { useConfig } from "@/composables/config";
import { useMarkdown } from "@/composables/markdown";
import { usePanels } from "@/composables/usePanels";
import { provideScopedWorkflowStores } from "@/composables/workflowStores";
import { useUserStore } from "@/stores/userStore";
Expand Down Expand Up @@ -58,10 +59,12 @@ const splitObjectStore = ref(false);
const preferredObjectStoreId = ref<string | null>(null);
const preferredIntermediateObjectStoreId = ref<string | null>(null);
const waitingForRequest = ref(false);
// TODO: Once we add readme/help to the right side of the form, we can default the unified `showRightPanel`
// (panel that toggles between readme/help or graph) to `true` if the readme/help exists, and if no
// readme/help exists, it will be `false`.
const showGraph = ref(!showPanels.value);
const showRightPanel = ref<"help" | "graph" | null>(!showPanels.value && props.model.runData.help ? "help" : null);

const showGraph = computed(() => showRightPanel.value === "graph");
const showHelp = computed(() => showRightPanel.value === "help");

const { renderMarkdown } = useMarkdown({ openLinksInNewPage: true, removeNewlinesAfterList: true });

watch(
() => showGraph.value,
Expand Down Expand Up @@ -201,9 +204,9 @@ async function onExecute() {
</script>

<template>
<div :class="{ 'd-flex flex-column h-100': showGraph }">
<div v-if="!showGraph" class="ui-form-header-underlay sticky-top" />
<div v-if="isConfigLoaded" :class="{ 'sticky-top': !showGraph }">
<div :class="{ 'd-flex flex-column h-100': showRightPanel }">
<div v-if="!showRightPanel" class="ui-form-header-underlay sticky-top" />
<div v-if="isConfigLoaded" :class="{ 'sticky-top': !showRightPanel }">
<BAlert v-if="!canRunOnHistory" variant="warning" show>
<span v-localize>
The workflow cannot run because the current history is immutable. Please select a different history
Expand All @@ -216,15 +219,27 @@ async function onExecute() {
:run-waiting="waitingForRequest"
@on-execute="onExecute">
<template v-slot:workflow-title-actions>
<BButton
v-b-tooltip.hover.noninteractive.html
size="sm"
:title="!showGraph ? 'Show workflow graph' : 'Hide workflow graph'"
variant="link"
:pressed="showGraph"
@click="showGraph = !showGraph">
<FontAwesomeIcon :icon="faSitemap" fixed-width />
</BButton>
<BButtonGroup>
<BButton
v-b-tooltip.hover.noninteractive.html
size="sm"
:title="!showGraph ? 'Show workflow graph' : 'Hide workflow graph'"
variant="link"
:pressed="showGraph"
@click="showRightPanel = showGraph ? null : 'graph'">
<FontAwesomeIcon :icon="faSitemap" fixed-width />
</BButton>
<BButton
v-if="model.runData.help"
v-b-tooltip.hover.noninteractive.html
size="sm"
:title="!showHelp ? 'Show workflow help' : 'Hide workflow help'"
variant="link"
:pressed="showHelp"
@click="showRightPanel = showHelp ? null : 'help'">
<FontAwesomeIcon :icon="faInfoCircle" fixed-width />
</BButton>
</BButtonGroup>
<BDropdown
v-if="showRuntimeSettings(currentUser)"
id="dropdown-form"
Expand Down Expand Up @@ -274,10 +289,10 @@ async function onExecute() {
<div class="overflow-auto h-100">
<div class="d-flex h-100">
<div
:class="showGraph ? 'w-50 flex-grow-1' : 'w-100'"
:class="showRightPanel ? 'w-50 flex-grow-1' : 'w-100'"
:style="{ 'overflow-y': 'auto', 'overflow-x': 'hidden' }">
<div v-if="showGraph" class="ui-form-header-underlay sticky-top" />
<Heading v-if="showGraph" class="sticky-top" h2 separator bold size="sm"> Parameters </Heading>
<div v-if="showRightPanel" class="ui-form-header-underlay sticky-top" />
<Heading v-if="showRightPanel" class="sticky-top" h2 separator bold size="sm"> Parameters </Heading>
<FormDisplay
:inputs="formInputs"
:allow-empty-value-on-required-input="true"
Expand All @@ -288,15 +303,23 @@ async function onExecute() {
@onValidation="onValidation"
@update:active-node-id="($event) => (activeNodeId = $event)" />
</div>
<div v-if="showGraph" class="h-100 w-50 d-flex flex-shrink-0">
<div v-if="showRightPanel" class="h-100 w-50 d-flex flex-shrink-0">
<WorkflowRunGraph
v-if="isConfigLoaded"
v-if="isConfigLoaded && showGraph"
:workflow-id="model.workflowId"
:step-validation="stepValidation || undefined"
:stored-id="model.runData.workflow_id"
:version="model.runData.version"
:inputs="formData"
:form-inputs="formInputs" />
<div v-else-if="showHelp" class="d-flex flex-column">
<Heading class="sticky-top" h2 separator bold size="sm"> Help </Heading>
<BCard class="mx-1 flex-grow-1 overflow-auto">
<!-- eslint-disable-next-line vue/no-v-html -->
<p class="container" v-html="renderMarkdown(model.runData.help)" />
<div class="py-2 text-center">- End of help -</div>
</BCard>
</div>
</div>
</div>
</div>
Expand Down
27 changes: 25 additions & 2 deletions client/src/components/Workflow/WorkflowAnnotation.vue
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,15 @@ import { faExclamation, faHdd } from "@fortawesome/free-solid-svg-icons";
import { FontAwesomeIcon } from "@fortawesome/vue-fontawesome";
import { BBadge } from "bootstrap-vue";
import { storeToRefs } from "pinia";
import { computed } from "vue";
import { computed, ref } from "vue";

import { isRegisteredUser } from "@/api";
import { useMarkdown } from "@/composables/markdown";
import { useWorkflowInstance } from "@/composables/useWorkflowInstance";
import { useHistoryStore } from "@/stores/historyStore";
import { useUserStore } from "@/stores/userStore";

import Heading from "../Common/Heading.vue";
import TextSummary from "../Common/TextSummary.vue";
import SwitchToHistoryLink from "../History/SwitchToHistoryLink.vue";
import StatelessTags from "../TagsMultiselect/StatelessTags.vue";
Expand Down Expand Up @@ -56,6 +58,14 @@ const timeElapsed = computed(() => {
const workflowTags = computed(() => {
return workflow.value?.tags || [];
});

const readmeShown = ref(false);

const { renderMarkdown } = useMarkdown({
openLinksInNewPage: true,
removeNewlinesAfterList: true,
increaseHeadingLevelBy: 1,
});
</script>

<template>
Expand Down Expand Up @@ -94,7 +104,20 @@ const workflowTags = computed(() => {
<div v-if="props.showDetails">
<TextSummary v-if="description" class="my-1" :description="description" one-line-summary component="span" />
<StatelessTags v-if="workflowTags.length" :value="workflowTags" :disabled="true" />
<hr class="mb-0 mt-2" />
<div v-if="workflow.readme" class="mt-2">
<Heading
h2
separator
bold
size="sm"
:collapse="readmeShown ? 'open' : 'closed'"
@click="readmeShown = !readmeShown">
<span v-localize>Readme</span>
</Heading>
<!-- eslint-disable-next-line vue/no-v-html -->
<p v-if="readmeShown" v-html="renderMarkdown(workflow.readme)" />
</div>
<hr v-if="!workflow.readme" class="mb-0 mt-2" />
</div>
</div>
</template>
1 change: 1 addition & 0 deletions lib/galaxy/managers/workflows.py
Original file line number Diff line number Diff line change
Expand Up @@ -1090,6 +1090,7 @@ def _workflow_to_dict_run(self, trans, stored, workflow, history=None):
return {
"id": trans.app.security.encode_id(stored.id),
"workflow_id": trans.app.security.encode_id(workflow.id),
"help": workflow.help,
"history_id": trans.app.security.encode_id(history.id) if history else None,
"name": stored.name,
"owner": stored.user.username,
Expand Down
10 changes: 10 additions & 0 deletions lib/galaxy/schema/workflows.py
Original file line number Diff line number Diff line change
Expand Up @@ -258,6 +258,16 @@ class StoredWorkflowDetailed(StoredWorkflowSummary):
title="Email Hash",
description="The hash of the email of the creator of this workflow",
)
readme: Optional[str] = Field(
...,
title="Readme",
description="The detailed markdown readme of the workflow.",
)
help: Optional[str] = Field(
...,
title="Help",
description="The detailed help text for how to use the workflow and debug problems with it.",
)
slug: Optional[str] = Field(
...,
title="Slug",
Expand Down
Loading