From 30e43a8a95ac3fc7b5ea1e304371f7333b8a0822 Mon Sep 17 00:00:00 2001 From: John Chilton Date: Mon, 6 Nov 2023 11:23:40 -0500 Subject: [PATCH] Toward declarative help for Galaxy markdown directives. --- .../components/Markdown/MarkdownToolBox.vue | 246 +++++++----------- client/src/components/Markdown/directives.ts | 64 +++++ client/src/components/Markdown/directives.yml | 111 ++++++++ client/src/components/Panels/Common/Tool.vue | 9 +- client/webpack.config.js | 4 + 5 files changed, 276 insertions(+), 158 deletions(-) create mode 100644 client/src/components/Markdown/directives.ts create mode 100644 client/src/components/Markdown/directives.yml diff --git a/client/src/components/Markdown/MarkdownToolBox.vue b/client/src/components/Markdown/MarkdownToolBox.vue index e7f2d7c6b1ca..2f6e5d027858 100644 --- a/client/src/components/Markdown/MarkdownToolBox.vue +++ b/client/src/components/Markdown/MarkdownToolBox.vue @@ -47,67 +47,48 @@ import ToolSection from "components/Panels/Common/ToolSection"; import { getAppRoot } from "onload/loadConfig"; import Vue from "vue"; +import { directiveEntry } from "./directives.ts"; import MarkdownDialog from "./MarkdownDialog"; Vue.use(BootstrapVue); -const historySharedElements = [ - { - id: "history_dataset_display", - name: "Dataset", - emitter: "onHistoryDatasetId", - }, - { - id: "history_dataset_collection_display", - name: "Collection", - emitter: "onHistoryCollectionId", - }, - { - id: "history_dataset_as_image", - name: "Image", - emitter: "onHistoryDatasetId", - }, - { - id: "history_dataset_index", - name: "Dataset Index", - emitter: "onHistoryDatasetId", - }, - { - id: "history_dataset_embedded", - name: "Embedded Dataset", - emitter: "onHistoryDatasetId", - }, - { - id: "history_dataset_as_table", - name: "Embedded Dataset (as table)", - emitter: "onHistoryDatasetId", - }, - { - id: "history_dataset_type", - name: "Dataset Type", - emitter: "onHistoryDatasetId", - }, - { - id: "history_dataset_link", - name: "Link to Dataset", - emitter: "onHistoryDatasetId", - }, - { - id: "history_dataset_name", - name: "Name of Dataset", - emitter: "onHistoryDatasetId", - }, - { - id: "history_dataset_peek", - name: "Peek into Dataset", - emitter: "onHistoryDatasetId", - }, - { - id: "history_dataset_info", - name: "Dataset Details", - emitter: "onHistoryDatasetId", - }, -]; +function historySharedElements(mode) { + return [ + directiveEntry("history_dataset_display", mode, { + emitter: "onHistoryDatasetId", + }), + directiveEntry("history_dataset_collection_display", mode, { + emitter: "onHistoryCollectionId", + }), + directiveEntry("history_dataset_as_image", mode, { + emitter: "onHistoryDatasetId", + }), + directiveEntry("history_dataset_index", mode, { + emitter: "onHistoryDatasetId", + }), + directiveEntry("history_dataset_embedded", mode, { + emitter: "onHistoryDatasetId", + }), + directiveEntry("history_dataset_as_table", mode, { + emitter: "onHistoryDatasetId", + }), + directiveEntry("history_dataset_type", mode, { + emitter: "onHistoryDatasetId", + }), + directiveEntry("history_dataset_link", mode, { + emitter: "onHistoryDatasetId", + }), + directiveEntry("history_dataset_name", mode, { + emitter: "onHistoryDatasetId", + }), + directiveEntry("history_dataset_peek", mode, { + emitter: "onHistoryDatasetId", + }), + directiveEntry("history_dataset_info", mode, { + emitter: "onHistoryDatasetId", + }), + ]; +} export default { components: { @@ -133,127 +114,45 @@ export default { title: "History", name: "history", elems: [ - ...historySharedElements, - { - id: "history_link", - name: "Link to Import", + ...historySharedElements("page"), + directiveEntry("history_link", "page", { emitter: "onHistoryId", - }, + }), ], }, historyInEditorSection: { title: "History", name: "history", - elems: [ - ...historySharedElements, - { - id: "history_link", - name: "Link to Import", - }, - ], - }, - jobSection: { - title: "Jobs", - name: "jobs", - elems: [ - { - id: "job_metrics", - name: "Job Metrics", - description: "as table", - emitter: "onJobId", - }, - { - id: "job_parameters", - name: "Job Parameters", - description: "as table", - emitter: "onJobId", - }, - { - id: "tool_stdout", - name: "Tool Output", - description: "of job run", - emitter: "onJobId", - }, - { - id: "tool_stderr", - name: "Tool Error", - description: "of job run", - emitter: "onJobId", - }, - ], + elems: [...historySharedElements("report"), directiveEntry("history_link", "report")], }, workflowSection: { title: "Workflow", name: "workflow", elems: [ - { - id: "invocation_time", - name: "Invocation Time", + directiveEntry("invocation_time", "page", { emitter: "onInvocationId", - }, - { - id: "workflow_display", - name: "Workflow Display", + }), + directiveEntry("workflow_display", "page", { emitter: "onWorkflowId", - }, - { - id: "workflow_license", - name: "Workflow License", + }), + directiveEntry("workflow_license", "page", { emitter: "onWorkflowId", - }, - { - id: "workflow_image", - name: "Workflow Image", + }), + directiveEntry("workflow_image", "page", { emitter: "onWorkflowId", - }, + }), ], }, workflowInEditorSection: { title: "Workflow", name: "workflow", elems: [ - { - id: "invocation_inputs", - name: "Invocation Inputs", - }, - { - id: "invocation_outputs", - name: "Invocation Output", - }, - { - id: "invocation_time", - name: "Time a Workflow", - description: "was invoked", - }, - { - id: "workflow_display", - name: "Current Workflow", - description: "containing all steps", - }, - { - id: "workflow_image", - name: "Current Workflow Image", - }, - { - id: "workflow_license", - name: "Current Workflow License", - }, - ], - }, - otherSection: { - title: "Miscellaneous", - name: "others", - elems: [ - { - id: "generate_galaxy_version", - name: "Galaxy Version", - description: "as text", - }, - { - id: "generate_time", - name: "Current Time", - description: "as text", - }, + directiveEntry("invocation_inputs", "report"), + directiveEntry("invocation_outputs", "report"), + directiveEntry("invocation_time", "report"), + directiveEntry("workflow_display", "report"), + directiveEntry("workflow_license", "report"), + directiveEntry("workflow_image", "report"), ], }, linksSection: { @@ -309,9 +208,42 @@ export default { isWorkflow() { return !!this.steps; }, + mode() { + return this.isWorkflow ? "report" : "page"; + }, hasVisualizations() { return this.visualizationSection.elems.length > 0; }, + otherSection() { + return { + title: "Miscellaneous", + name: "others", + elems: [ + directiveEntry("generate_galaxy_version", this.mode), + directiveEntry("generate_time", this.mode), + ], + }; + }, + jobSection() { + return { + title: "Jobs", + name: "jobs", + elems: [ + directiveEntry("job_metrics", this.mode, { + emitter: "onJobId", + }), + directiveEntry("job_parameters", this.mode, { + emitter: "onJobId", + }), + directiveEntry("tool_stdout", this.mode, { + emitter: "onJobId", + }), + directiveEntry("tool_stderr", this.mode, { + emitter: "onJobId", + }), + ], + }; + }, }, created() { this.getVisualizations(); diff --git a/client/src/components/Markdown/directives.ts b/client/src/components/Markdown/directives.ts new file mode 100644 index 000000000000..256537b5d0fe --- /dev/null +++ b/client/src/components/Markdown/directives.ts @@ -0,0 +1,64 @@ +import RAW_DIRECTIVE_DATA from "./directives.yml"; + +type DirectiveMode = "page" | "report"; + +type DirectiveMetadataValueByMode = { + [key: string]: string; +}; + +interface DirectiveMetadata { + side_panel_name: string | DirectiveMetadataValueByMode; + side_panel_description?: string | DirectiveMetadataValueByMode; + help?: string | DirectiveMetadataValueByMode; +} + +type DirectivesMetadata = { + [key: string]: DirectiveMetadata; +}; + +type SidePanelEntry = { + [key: string]: string; +}; + +const DIRECTIVE_METADATA = RAW_DIRECTIVE_DATA as DirectivesMetadata; + +export function directiveEntry( + directiveId: string, + mode: DirectiveMode, + baseEntry: SidePanelEntry = {} +): SidePanelEntry { + const directiveMetadataData: DirectiveMetadata | undefined = DIRECTIVE_METADATA[directiveId]; + if (directiveMetadataData == undefined) { + throw Error(`Client logic error, cannot find directive metadata for ${directiveId}`); + } + let name = directiveMetadataData.side_panel_name; + if (name && !(typeof name == "string")) { + const modeName = name[mode]; + if (modeName == undefined) { + throw Error(`Client logic error, cannot find directive metadata for ${directiveId}`); + } + name = modeName; + } + let description = directiveMetadataData.side_panel_description; + if (description && !(typeof description == "string")) { + description = description[mode]; + } + let help = directiveMetadataData.help; + if (help && !(typeof help == "string")) { + help = help[mode]; + } + if (help) { + help = help.replace(/%MODE%/g, mode); + } + const entry: SidePanelEntry = { id: directiveId, ...baseEntry }; + if (name) { + entry.name = name; + } + if (description) { + entry.description = description; + } + if (help) { + entry.help = help; + } + return entry; +} diff --git a/client/src/components/Markdown/directives.yml b/client/src/components/Markdown/directives.yml new file mode 100644 index 000000000000..51ae5ebeed0c --- /dev/null +++ b/client/src/components/Markdown/directives.yml @@ -0,0 +1,111 @@ +--- +history_dataset_display: + side_panel_name: Dataset + help: | + Display a dataset and relevant options for viewing, importing, downloading, + and visualization in the resulting document. To embed a dataset directly + into the document use the "history_dataset_embedded" / "Embedded Dataset" + directive. + +history_dataset_collection_display: + side_panel_name: Collection + help: | + Display a dataset collection and relevant options for viewing, importing, downloading + in the resulting documenting. + +history_dataset_as_image: + side_panel_name: Image + help: | + Embed a dataset in the resulting document as an image. This only works for simple image + types. This can be used to present graphs and other visual summaries of an analysis into + a Galaxy Markdown document summary. + +history_dataset_index: + side_panel_name: Dataset Index + help: | + For Galaxy composite datasets (datasets that consist on multiple files), this option will + display the contents of the composite dataset as files and folders in the resulting document. +history_dataset_embedded: + side_panel_name: Embedded Dataset +history_dataset_as_table: + side_panel_name: Embedded Dataset as table +history_dataset_type: + side_panel_name: Dataset Type +history_dataset_link: + side_panel_name: Link to Dataset +history_dataset_name: + side_panel_name: Name of Dataset +history_dataset_peek: + side_panel_name: Peek into Dataset +history_dataset_info: + side_panel_name: Dataset Details + +history_link: + side_panel_name: Link to Import + help: + report: | + Add a link to import the history the workflow invocation was executed in. + page: | + Add a link to import the target history referenced by the directive. + +invocation_time: + side_panel_name: + report: Time Workflow + page: Time a Workflow + + side_panel_description: was invoked + +invocation_inputs: + side_panel_name: Invocation Inputs + +invocation_outputs: + side_panel_name: Invocation Output + +workflow_license: + side_panel_name: Workflow License + +workflow_image: + side_panel_name: Workflow (as image) + +workflow_display: + side_panel_name: + report: Current Workflow + page: Display a Workflow + side_panel_description: containing all steps + +generate_galaxy_version: + side_panel_name: Galaxy Version + side_panel_description: as text + + help: | + Report the current Galaxy version at the time %MODE% generation. + + Warning: This is the Galaxy version at the time the %MODE% was generated and + not the time of an analysis. This option makes the most sense for PDF generation + of %MODE%s designed for external archiving or printing. + +generate_time: + side_panel_name: Current Time + side_panel_description: as text + help: | + Report the current time of %MODE% generation. + + Warning: This is the time the %MODE% was generated and not the time of + an analysis. This option makes the most sense for PDF generation of %MODE%s + designed for external archiving or printing. + +job_metrics: + side_panel_name: Job Metrics + side_panel_description: as table + +job_parameters: + side_panel_name: Job Parameters + side_panel_description: as table + +tool_stdout: + side_panel_name: Tool Output + side_panel_description: of job run + +tool_stderr: + side_panel_name: Tool Error + side_panel_description: of job run diff --git a/client/src/components/Panels/Common/Tool.vue b/client/src/components/Panels/Common/Tool.vue index ec4ad493745f..2ed5e20820fd 100644 --- a/client/src/components/Panels/Common/Tool.vue +++ b/client/src/components/Panels/Common/Tool.vue @@ -4,7 +4,14 @@ {{ tool.name }} {{ tool.description }} - + { test: /\.(txt|tmpl)$/, loader: "raw-loader", }, + { + test: /\.ya?ml$/, + use: "yaml-loader", + }, ], }, resolveLoader: {