diff --git a/src/client/index.ts b/src/client/index.ts index 98752ac488193a71a44ea94354a30ae46310a955..77aaffd1232103efd2fcb8b7033c79f369c4e18c 100644 --- a/src/client/index.ts +++ b/src/client/index.ts @@ -26,6 +26,7 @@ export type { ErrorDetail } from './models/ErrorDetail'; export { FileTree } from './models/FileTree'; export type { HTTPValidationError } from './models/HTTPValidationError'; export type { IconUpdateOut } from './models/IconUpdateOut'; +export { NextflowVersion } from './models/NextflowVersion'; export { OIDCProvider } from './models/OIDCProvider'; export type { ParameterExtension } from './models/ParameterExtension'; export { Permission } from './models/Permission'; diff --git a/src/client/models/DevWorkflowExecutionIn.ts b/src/client/models/DevWorkflowExecutionIn.ts index f65f6ebdab303ad85e1ba0ba7705702b59bc0877..e075238c1ef96b282a13b5d8c1483ec554dd4fb4 100644 --- a/src/client/models/DevWorkflowExecutionIn.ts +++ b/src/client/models/DevWorkflowExecutionIn.ts @@ -2,6 +2,7 @@ /* istanbul ignore file */ /* tslint:disable */ /* eslint-disable */ +import type { NextflowVersion } from './NextflowVersion'; import type { WorkflowModeIn } from './WorkflowModeIn'; export type DevWorkflowExecutionIn = { /** @@ -36,5 +37,9 @@ export type DevWorkflowExecutionIn = { * Mode of the workflow with an alternative entrypoint */ mode?: (WorkflowModeIn | null); + /** + * The version of Nextflow this workflow execution requires + */ + nextflow_version: NextflowVersion; }; diff --git a/src/client/models/NextflowVersion.ts b/src/client/models/NextflowVersion.ts new file mode 100644 index 0000000000000000000000000000000000000000..e16dfe95107760e5551d303748e3a4e7818e0226 --- /dev/null +++ b/src/client/models/NextflowVersion.ts @@ -0,0 +1,18 @@ +/* generated using openapi-typescript-codegen -- do not edit */ +/* istanbul ignore file */ +/* tslint:disable */ +/* eslint-disable */ +export enum NextflowVersion { + _23_04_0 = '23.04.0', + _23_04_1 = '23.04.1', + _23_04_2 = '23.04.2', + _23_04_3 = '23.04.3', + _23_04_4 = '23.04.4', + _23_04_5 = '23.04.5', + _23_10_0 = '23.10.0', + _23_10_1 = '23.10.1', + _23_10_2 = '23.10.2', + _23_10_3 = '23.10.3', + _24_04_1 = '24.04.1', + _24_04_2 = '24.04.2', +} diff --git a/src/client/models/UserOutExtended.ts b/src/client/models/UserOutExtended.ts index a05ecb616dfa92c76dde11b89fa03407d39cd2dd..709361b6a4248f1e99d2aadc193eaa6862d72740 100644 --- a/src/client/models/UserOutExtended.ts +++ b/src/client/models/UserOutExtended.ts @@ -27,6 +27,6 @@ export type UserOutExtended = { /** * URL to the gravatar avatar based on the users email */ - gravatar_url?: (string | null); + gravatar_url: string; }; diff --git a/src/client/models/WorkflowIn.ts b/src/client/models/WorkflowIn.ts index acc74b596d2bde22f15f43cf5cdd563644e24935..f433bf975a0b5f8684942d6c6c14b5ae47e41d44 100644 --- a/src/client/models/WorkflowIn.ts +++ b/src/client/models/WorkflowIn.ts @@ -2,6 +2,7 @@ /* istanbul ignore file */ /* tslint:disable */ /* eslint-disable */ +import type { NextflowVersion } from './NextflowVersion'; import type { WorkflowModeIn } from './WorkflowModeIn'; export type WorkflowIn = { /** @@ -32,5 +33,9 @@ export type WorkflowIn = { * List of modes with alternative entrypoint the new workflow has */ modes?: Array<WorkflowModeIn>; + /** + * The version of Nextflow this workflow version requires + */ + nextflow_version: NextflowVersion; }; diff --git a/src/client/models/WorkflowUpdate.ts b/src/client/models/WorkflowUpdate.ts index 9b3dac395a7cc364ad439019492ac29fd4291582..a67749a44add93e13f56fc724ec2379f5df1c46d 100644 --- a/src/client/models/WorkflowUpdate.ts +++ b/src/client/models/WorkflowUpdate.ts @@ -2,6 +2,7 @@ /* istanbul ignore file */ /* tslint:disable */ /* eslint-disable */ +import type { NextflowVersion } from './NextflowVersion'; import type { WorkflowModeIn } from './WorkflowModeIn'; export type WorkflowUpdate = { /** @@ -20,5 +21,9 @@ export type WorkflowUpdate = { * Delete modes for the new workflow version. */ delete_modes?: Array<string>; + /** + * The version of Nextflow this new workflow version requires. + */ + nextflow_version: NextflowVersion; }; diff --git a/src/client/models/WorkflowVersion.ts b/src/client/models/WorkflowVersion.ts index 1974ff18e1a2a3bc5434fc72b959ec01ade3ecc9..3e3138e5f54dcb89bdb0e91b831191489885659f 100644 --- a/src/client/models/WorkflowVersion.ts +++ b/src/client/models/WorkflowVersion.ts @@ -2,6 +2,7 @@ /* istanbul ignore file */ /* tslint:disable */ /* eslint-disable */ +import type { NextflowVersion } from './NextflowVersion'; import type { ParameterExtension } from './ParameterExtension'; import type { WorkflowVersionStatus } from './WorkflowVersionStatus'; export type WorkflowVersion = { @@ -37,5 +38,9 @@ export type WorkflowVersion = { * Parameter extension specific for this CloWM instance */ parameter_extension?: (ParameterExtension | null); + /** + * The version of Nextflow this workflow version requires + */ + nextflow_version: NextflowVersion; }; diff --git a/src/components/AppHeader.vue b/src/components/AppHeader.vue index 97d73da3b85183aaea7ec4fe325e0e30e92ddc53..331c790cda5193e6e020161ee04d0035325acada 100644 --- a/src/components/AppHeader.vue +++ b/src/components/AppHeader.vue @@ -3,7 +3,6 @@ import { useUserStore } from "@/stores/users"; import { useRoute, useRouter } from "vue-router"; import { watch, ref, computed } from "vue"; import { OpenAPI } from "@/client"; -import FontAwesomeIcon from "@/components/FontAwesomeIcon.vue"; const userRepository = useUserStore(); const route = useRoute(); @@ -266,18 +265,12 @@ watch( > <strong class="me-2">{{ userRepository.user.display_name }}</strong> <img - v-if="userRepository.user.gravatar_url" :src="userRepository.user.gravatar_url + '?d=mp&s=32'" class="rounded-circle" height="32" width="32" alt="profile picture" /> - <font-awesome-icon - v-else - icon="fa-solid fa-circle-user" - class="text-secondary fs-4" - /> </a> <ul class="dropdown-menu text-small shadow" diff --git a/src/components/workflows/WorkflowWithVersionsCard.vue b/src/components/workflows/WorkflowWithVersionsCard.vue index cae0ee587fc8915a7699a8231367f64737031bbc..a5a95f24109f68fb3f4c60b53ae6c9cb65df622d 100644 --- a/src/components/workflows/WorkflowWithVersionsCard.vue +++ b/src/components/workflows/WorkflowWithVersionsCard.vue @@ -215,6 +215,7 @@ onMounted(() => { <th scope="col">Version</th> <th scope="col">Status</th> <th scope="col">Updated at</th> + <th scope="col">Nextflow version</th> <th scope="col" class="text-align-center">Usage</th> <th scope="col" class="text-align-center">Icon</th> <th scope="col"></th> @@ -246,6 +247,9 @@ onMounted(() => { <td> {{ dayjs.unix(version.created_at).format("DD MMM YYYY") }} </td> + <td class="text-align-center"> + {{ version.nextflow_version }} + </td> <td class="text-align-center"> <span class="text-success me-1" @@ -351,7 +355,7 @@ onMounted(() => { </tr> <tr> <th scope="row" class="fw-bold">Overall</th> - <td colspan="2"></td> + <td colspan="3"></td> <td class="text-align-center"> <span class="text-success me-1" diff --git a/src/components/workflows/modals/ArbitraryWorkflowModal.vue b/src/components/workflows/modals/ArbitraryWorkflowModal.vue index 6399ce38a55565905515c12e9ba04d3649125c91..749dcd9dab1dc075d5cc4a38aaf0e504f33e781b 100644 --- a/src/components/workflows/modals/ArbitraryWorkflowModal.vue +++ b/src/components/workflows/modals/ArbitraryWorkflowModal.vue @@ -10,7 +10,7 @@ import { } from "@/utils/GitRepository"; import { Collapse, Modal } from "bootstrap"; import { useWorkflowStore } from "@/stores/workflows"; -import type { WorkflowModeOut } from "@/client"; +import { NextflowVersion, type WorkflowModeOut } from "@/client"; import { environment } from "@/environment"; import { useS3KeyStore } from "@/stores/s3keys"; import { useResourceStore } from "@/stores/resources"; @@ -38,9 +38,12 @@ const resourceStore = useResourceStore(); const workflow = reactive<{ repository_url: string; git_commit_hash: string; + nextflow_version: NextflowVersion; }>({ repository_url: "", git_commit_hash: "", + nextflow_version: + Object.values(NextflowVersion)[Object.values(NextflowVersion).length - 1], }); const repositoryCredentials = reactive<{ @@ -504,7 +507,7 @@ onMounted(() => { /> </div> <div id="gitRepoProviderHelp" class="form-text"> - We support Github and GitLab Repositories + We support Github and (self-hosted) GitLab Repositories </div> <div class="text-danger"> <div v-if="formState.unsupportedRepository"> @@ -555,6 +558,25 @@ onMounted(() => { </li> </ul> </div> + <div class="mb-3"> + <label for="workflowNextflowVersionInput" class="form-label" + >Nextflow version</label + > + <select + class="form-select" + id="workflowNextflowVersionInput" + required + v-model="workflow.nextflow_version" + > + <option + v-for="version in Object.values(NextflowVersion).reverse()" + :key="version" + :value="version" + > + {{ version }} + </option> + </select> + </div> <div class="mb-3"> <div class="form-check fs-5"> <input diff --git a/src/components/workflows/modals/CreateWorkflowModal.vue b/src/components/workflows/modals/CreateWorkflowModal.vue index 61398ea7ecc77c509e912b20a33883260e4c154d..c1ec15a1573a77e820434c8c705cde6856b8b416 100644 --- a/src/components/workflows/modals/CreateWorkflowModal.vue +++ b/src/components/workflows/modals/CreateWorkflowModal.vue @@ -1,7 +1,12 @@ <script setup lang="ts"> import { computed, onMounted, reactive, ref, watch } from "vue"; import { Modal, Toast, Collapse, Tooltip } from "bootstrap"; -import type { WorkflowIn, WorkflowOut, WorkflowModeOut } from "@/client"; +import { + type WorkflowIn, + type WorkflowOut, + type WorkflowModeOut, + NextflowVersion, +} from "@/client"; import BootstrapModal from "@/components/modals/BootstrapModal.vue"; import FontAwesomeIcon from "@/components/FontAwesomeIcon.vue"; import { ApiError } from "@/client"; @@ -61,6 +66,8 @@ const workflow = reactive<WorkflowIn>({ initial_version: undefined, token: undefined, modes: [], + nextflow_version: + Object.values(NextflowVersion)[Object.values(NextflowVersion).length - 1], }); const formState = reactive<{ @@ -410,7 +417,7 @@ onMounted(() => { </div> </div> <div id="gitRepoProviderHelp" class="form-text"> - We support GitHub and GitLab Repositories + We support GitHub and (self-hosted) GitLab Repositories </div> <div class="text-danger"> <div v-if="formState.unsupportedRepository"> @@ -501,6 +508,25 @@ onMounted(() => { </div> </div> </div> + <div class="mb-3"> + <label for="createWorkflowNextflowVersionInput" class="form-label" + >Nextflow version</label + > + <select + class="form-select" + id="createWorkflowNextflowVersionInput" + required + v-model="workflow.nextflow_version" + > + <option + v-for="version in Object.values(NextflowVersion).reverse()" + :key="version" + :value="version" + > + {{ version }} + </option> + </select> + </div> <div class="mb-3"> <div class="form-check fs-5"> <input diff --git a/src/components/workflows/modals/UpdateWorkflowModal.vue b/src/components/workflows/modals/UpdateWorkflowModal.vue index 55d13e79e28fbac6b5ce315f7ed62d82bcb0480b..734785589d47f74c7bf23033e801691b9718a5bc 100644 --- a/src/components/workflows/modals/UpdateWorkflowModal.vue +++ b/src/components/workflows/modals/UpdateWorkflowModal.vue @@ -1,13 +1,14 @@ <script setup lang="ts"> import { computed, onMounted, reactive, ref, watch } from "vue"; import { Collapse, Modal, Toast } from "bootstrap"; -import type { - WorkflowUpdate, - WorkflowOut, - WorkflowModeIn, - WorkflowModeOut, - WorkflowVersion, - ApiError, +import { + type WorkflowUpdate, + type WorkflowOut, + type WorkflowModeIn, + type WorkflowModeOut, + type WorkflowVersion, + type ApiError, + NextflowVersion, } from "@/client"; import BootstrapModal from "@/components/modals/BootstrapModal.vue"; import FontAwesomeIcon from "@/components/FontAwesomeIcon.vue"; @@ -59,6 +60,8 @@ const workflowUpdate = reactive<WorkflowUpdate>({ git_commit_hash: "", delete_modes: [], append_modes: [], + nextflow_version: + Object.values(NextflowVersion)[Object.values(NextflowVersion).length - 1], }); const workflowModes = reactive<{ @@ -96,6 +99,7 @@ watch( () => { resetForm(); formState.modesEnabled = (latestVersion.value.modes ?? []).length > 0; + workflowUpdate.nextflow_version = latestVersion.value.nextflow_version; if (props.workflow.private) { formState.loadCredentials = true; WorkflowCredentialsService.workflowCredentialsGetWorkflowCredentials( @@ -431,6 +435,25 @@ onMounted(() => { </div> </div> </div> + <div class="mb-3"> + <label for="updateWorkflowNextflowVersionInput" class="form-label" + >Nextflow version</label + > + <select + class="form-select" + id="updateWorkflowNextflowVersionInput" + required + v-model="workflowUpdate.nextflow_version" + > + <option + v-for="version in Object.values(NextflowVersion).reverse()" + :key="version" + :value="version" + > + {{ version }} + </option> + </select> + </div> <div class="mb-3"> <div class="form-check fs-5"> <input diff --git a/src/views/admin/AdminUsersView.vue b/src/views/admin/AdminUsersView.vue index 69fa6eaa340db8d8adc92dd1b5ba8762456d5832..498e36f1147b9ed057639ee9a7050264c5e4eb92 100644 --- a/src/views/admin/AdminUsersView.vue +++ b/src/views/admin/AdminUsersView.vue @@ -213,18 +213,12 @@ onMounted(() => { <tr v-for="(user, index) in userState.users" :key="user.uid"> <th scope="row"> <img - v-if="user.gravatar_url" :src="user.gravatar_url + '?d=mp&s=32'" class="rounded-circle" height="32" width="32" alt="profile picture" /> - <font-awesome-icon - v-else - icon="fa-solid fa-circle-user" - class="text-secondary fs-4" - /> <span class="ms-2">{{ user.display_name }}</span> </th> <td>{{ user.uid }}</td> diff --git a/src/views/workflows/ArbitraryWorkflowView.vue b/src/views/workflows/ArbitraryWorkflowView.vue index 45f1b3e40275759697cd8b148da29c7a8459bf0a..3a5899243649a614b7b2cc8f42d84c4d935f6b92 100644 --- a/src/views/workflows/ArbitraryWorkflowView.vue +++ b/src/views/workflows/ArbitraryWorkflowView.vue @@ -121,6 +121,7 @@ function startWorkflow( debug_s3_path: metaParameters.debug_s3_path, provenance_s3_path: metaParameters.provenance_s3_path, repository_url: workflowState.workflow.repository_url, + nextflow_version: workflowState.workflow.nextflow_version, token: workflowState.workflow.token ?? undefined, mode: (workflowState.workflow.modes ?? []).length > 0 @@ -185,8 +186,9 @@ onMounted(() => { workflowState.workflow?.repository_url }}</a> </h5> + <h5>Git Commit Hash: {{ workflowState.workflow?.git_commit_hash }}</h5> <h5 :class="{ 'mb-5': workflowState.workflow.modes!.length < 1 }"> - Git Commit Hash: {{ workflowState.workflow?.git_commit_hash }} + Nextflow version: {{ workflowState.workflow?.nextflow_version }} </h5> <template v-if="workflowState.workflow.modes!.length > 0"> <h5>Entrypoint: {{ workflowState.workflow?.modes?.[0].entrypoint }}</h5> diff --git a/src/views/workflows/MyWorkflowsView.vue b/src/views/workflows/MyWorkflowsView.vue index 9ad162d2b3c0af57da23e5dbff5083c690bfd68f..7ccfeb417a1e568343f92b04d7e4d487da1cee94 100644 --- a/src/views/workflows/MyWorkflowsView.vue +++ b/src/views/workflows/MyWorkflowsView.vue @@ -1,7 +1,11 @@ <script setup lang="ts"> import { computed, onMounted, reactive } from "vue"; -import type { WorkflowOut, WorkflowVersion } from "@/client"; -import { WorkflowVersionStatus } from "@/client"; +import { + NextflowVersion, + type WorkflowOut, + type WorkflowVersion, + WorkflowVersionStatus, +} from "@/client"; import WorkflowWithVersionsCard from "@/components/workflows/WorkflowWithVersionsCard.vue"; import CreateWorkflowModal from "@/components/workflows/modals/CreateWorkflowModal.vue"; import CardTransitionGroup from "@/components/transitions/CardTransitionGroup.vue"; @@ -37,6 +41,7 @@ const workflowsState = reactive<{ workflow_id: "", icon_url: "", modes: [], + nextflow_version: NextflowVersion._24_04_2, }, ], repository_url: "", @@ -52,6 +57,7 @@ const workflowsState = reactive<{ icon_url: null, created_at: 0, status: WorkflowVersionStatus.CREATED, + nextflow_version: NextflowVersion._24_04_2, }, });