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

feat(lit-wes): add dropdown for workflow type/version #256

Closed
Closed
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
33 changes: 32 additions & 1 deletion packages/ecc-client-lit-ga4gh-wes/src/API/Workflow/wesGet.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -121,4 +146,10 @@ const postWorkflow = async (baseURL: string, data: any) => {
}
};

export { fetchWorkflows, fetchWorkflow, cancelWorkflow, postWorkflow };
export {
fetchWorkflows,
fetchWorkflow,
fetchWorkflowType,
cancelWorkflow,
postWorkflow,
};
Original file line number Diff line number Diff line change
@@ -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
Expand All @@ -21,14 +21,16 @@ export interface Field {
| "array"
| "switch"
| "file"
| "group";
| "group"
| "select";
fieldOptions?: {
required?: boolean;
default?: string | boolean;
multiple?: boolean;
accept?: string;
returnIfEmpty?: string;
tooltip?: string;
options?: Array<{ label: string; value: string }>;
};
arrayOptions?: {
defaultInstances?: number;
Expand Down Expand Up @@ -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: [],
},
},
{
Expand Down Expand Up @@ -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]);
Expand Down
4 changes: 4 additions & 0 deletions packages/ecc-utils-design/src/components/form/form.styles.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
51 changes: 50 additions & 1 deletion packages/ecc-utils-design/src/components/form/form.ts
Original file line number Diff line number Diff line change
@@ -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";
Expand Down Expand Up @@ -29,14 +32,16 @@ export interface Field {
| "array"
| "switch"
| "file"
| "group";
| "group"
| "select";
fieldOptions?: {
required?: boolean;
default?: string | boolean;
multiple?: boolean;
accept?: string;
returnIfEmpty?: string;
tooltip?: string;
options?: Array<{ label: string; value: string }>;
};
arrayOptions?: {
defaultInstances?: number;
Expand Down Expand Up @@ -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`
<sl-dropdown>
<sl-button slot="trigger" caret>${field.label}</sl-button>
<sl-menu>
${field.fieldOptions?.options.map(
(option) => html`
<sl-menu-item
value="${option.value}"
?selected="${option.value === _.get(this.form, path)}"
?required="${field.fieldOptions?.required ? "*" : ""}"
@click="${(e: Event) => {
const { value } = e.target as HTMLSelectElement;
if (!value) {
_.unset(this.form, path);
} else {
_.set(this.form, path, value);
}
this.requestUpdate();
}}"
>
${option.label}
</sl-menu-item>
`
)}
</sl-menu>
</sl-dropdown>
`;
}

if (!_.get(this.form, path)) {
if (field.fieldOptions?.default && !this.hasUpdated) {
_.set(this.form, path, field.fieldOptions.default);
Expand Down Expand Up @@ -486,6 +531,10 @@ export default class EccUtilsDesignForm extends LitElement {
`;
}

public getFormData(): object {
return this.form;
}

public loading() {
this.formState = "loading";
}
Expand Down
Loading