diff --git a/packages/ecc-client-lit-ga4gh-wes/src/API/Workflow/wesGet.ts b/packages/ecc-client-lit-ga4gh-wes/src/API/Workflow/wesGet.ts index ba6b8c16..dd77d371 100644 --- a/packages/ecc-client-lit-ga4gh-wes/src/API/Workflow/wesGet.ts +++ b/packages/ecc-client-lit-ga4gh-wes/src/API/Workflow/wesGet.ts @@ -68,6 +68,31 @@ const fetchWorkflow = async (baseURL: string, id: string) => { } }; +/** + * Create a workflow run + * @param {string} baseURL - Base URL for fetching workflows + */ +const fetchWorkflowType = async (baseURL: string) => { + const url = `${baseURL}/service-info`; + try { + const response = await fetch(url); + if (!response) { + return { + isError: true, + breakpoint: "fetchWorkflowtype", + error: "No response from server", + }; + } + return await response.json(); + } catch (error) { + return { + isError: true, + breakpoint: "fetchworkflowtype", + error, + }; + } +}; + /** *This mathod cancel a specific workflow * @param id ID of the workflow to be deleted @@ -121,4 +146,10 @@ const postWorkflow = async (baseURL: string, data: any) => { } }; -export { fetchWorkflows, fetchWorkflow, cancelWorkflow, postWorkflow }; +export { + fetchWorkflows, + fetchWorkflow, + fetchWorkflowType, + cancelWorkflow, + postWorkflow, +}; diff --git a/packages/ecc-client-lit-ga4gh-wes/src/components/wes-create-run/wes-create-run.ts b/packages/ecc-client-lit-ga4gh-wes/src/components/wes-create-run/wes-create-run.ts index bead46b6..41b33832 100644 --- a/packages/ecc-client-lit-ga4gh-wes/src/components/wes-create-run/wes-create-run.ts +++ b/packages/ecc-client-lit-ga4gh-wes/src/components/wes-create-run/wes-create-run.ts @@ -1,6 +1,6 @@ import { html, LitElement } from "lit"; import { property, state } from "lit/decorators.js"; -import { postWorkflow } from "../../API/Workflow/wesGet.js"; +import { postWorkflow, fetchWorkflowType } from "../../API/Workflow/wesGet.js"; import "@elixir-cloud/design"; // TODO: import the interface from the design package @@ -21,7 +21,8 @@ export interface Field { | "array" | "switch" | "file" - | "group"; + | "group" + | "select"; fieldOptions?: { required?: boolean; default?: string | boolean; @@ -29,6 +30,7 @@ export interface Field { accept?: string; returnIfEmpty?: string; tooltip?: string; + options?: Array<{ label: string; value: string }>; }; arrayOptions?: { defaultInstances?: number; @@ -69,21 +71,23 @@ export default class ECCClientGa4ghWesCreateRuns extends LitElement { { key: "workflow_type", label: "Type", - type: "text", + type: "select", fieldOptions: { required: true, tooltip: "The type of workflow language and must be CWL or WDL currently.", + options: [], }, }, { key: "workflow_type_version", label: "Type version", - type: "text", + type: "select", fieldOptions: { required: true, tooltip: "The version of the workflow language submitted and must be one supported by this WES instance.", + options: [], }, }, { @@ -136,6 +140,71 @@ export default class ECCClientGa4ghWesCreateRuns extends LitElement { }, ]; + connectedCallback() { + super.connectedCallback?.(); + this._updateWorkflowType(); + } + + private async _updateWorkflowType() { + const data = await fetchWorkflowType(this.baseURL); + const workflowTypes = data.workflow_type_versions; + + const eccUtilsDesignForm = this.shadowRoot?.querySelector( + "ecc-utils-design-form" + ) as any; + + if (eccUtilsDesignForm) { + const workflowTypeKey = "workflow_type"; + const workflowTypeVersionKey = "workflow_type_version"; + + // Find the dropdown field for workflow_type in this.fields + const workflowTypeDropdown = this.fields.find( + (field) => field.key === workflowTypeKey + ); + + // Find the dropdown field for workflow_type_version in this.fields + const workflowTypeVersionDropdown = this.fields.find( + (field) => field.key === workflowTypeVersionKey + ); + + // Check if the dropdown fields exist and have fieldOptions + if ( + workflowTypeDropdown && + workflowTypeDropdown.fieldOptions && + workflowTypeVersionDropdown && + workflowTypeVersionDropdown.fieldOptions + ) { + // Update the options of the workflow_type dropdown + workflowTypeDropdown.fieldOptions.options = Object.keys( + workflowTypes + ).map((type: string) => ({ + label: type, + value: type, + })); + + // Manually trigger a re-render or update of the form + eccUtilsDesignForm.requestUpdate(); + // Add an event listener to workflow_type dropdown change + const formData = eccUtilsDesignForm.getFormData(); + const selectedWorkflowType = formData[workflowTypeKey]; + + // Check if fieldOptions is defined + if (workflowTypeVersionDropdown.fieldOptions) { + // Update the options of the workflow_type_version dropdown based on the selected workflow_type + workflowTypeVersionDropdown.fieldOptions.options = + workflowTypes[selectedWorkflowType] || []; + + eccUtilsDesignForm.requestUpdate(); + } + } + } else { + console.error({ + message: "ecc-utils-design-form not found", + breakPoint: "WESCreateRun.updateDropdown", + }); + } + } + async submitForm(form: any) { Object.keys(form).forEach((key) => { this.form.append(key, form[key]); diff --git a/packages/ecc-utils-design/src/components/form/form.styles.ts b/packages/ecc-utils-design/src/components/form/form.styles.ts index e1d7d32b..16e47c0d 100644 --- a/packages/ecc-utils-design/src/components/form/form.styles.ts +++ b/packages/ecc-utils-design/src/components/form/form.styles.ts @@ -12,6 +12,10 @@ const styles = css` margin-top: 0.5rem; margin-bottom: 0.5rem; } + form sl-dropdown { + margin-top: 0.5rem; + margin-bottom: 0.5rem; + } form sl-switch { margin-top: 0.5rem; margin-bottom: 0.5rem; diff --git a/packages/ecc-utils-design/src/components/form/form.ts b/packages/ecc-utils-design/src/components/form/form.ts index 15edd67b..53b24b3b 100644 --- a/packages/ecc-utils-design/src/components/form/form.ts +++ b/packages/ecc-utils-design/src/components/form/form.ts @@ -1,5 +1,8 @@ import { html, LitElement, TemplateResult } from "lit"; import { property, state } from "lit/decorators.js"; +import "@shoelace-style/shoelace/dist/components/dropdown/dropdown.js"; +import "@shoelace-style/shoelace/dist/components/menu/menu.js"; +import "@shoelace-style/shoelace/dist/components/menu-item/menu-item.js"; import "@shoelace-style/shoelace/dist/components/input/input.js"; import "@shoelace-style/shoelace/dist/components/button/button.js"; import "@shoelace-style/shoelace/dist/components/switch/switch.js"; @@ -29,7 +32,8 @@ export interface Field { | "array" | "switch" | "file" - | "group"; + | "group" + | "select"; fieldOptions?: { required?: boolean; default?: string | boolean; @@ -37,6 +41,7 @@ export interface Field { accept?: string; returnIfEmpty?: string; tooltip?: string; + options?: Array<{ label: string; value: string }>; }; arrayOptions?: { defaultInstances?: number; @@ -201,6 +206,46 @@ export default class EccUtilsDesignForm extends LitElement { `; } + if (field.type === "select" && field.fieldOptions?.options) { + if (!_.get(this.form, path) && !this.hasUpdated) { + _.set( + this.form, + path, + field.fieldOptions?.default || + field.fieldOptions?.options[0]?.value || + "" + ); + } + + return html` + + ${field.label} + + ${field.fieldOptions?.options.map( + (option) => html` + + ${option.label} + + ` + )} + + + `; + } + if (!_.get(this.form, path)) { if (field.fieldOptions?.default && !this.hasUpdated) { _.set(this.form, path, field.fieldOptions.default); @@ -486,6 +531,10 @@ export default class EccUtilsDesignForm extends LitElement { `; } + public getFormData(): object { + return this.form; + } + public loading() { this.formState = "loading"; }