<script setup lang="ts"> import BootstrapModal from "@/components/modals/BootstrapModal.vue"; import FontAwesomeIcon from "@/components/FontAwesomeIcon.vue"; import { computed, onMounted, reactive, ref } from "vue"; import { useRouter } from "vue-router"; import { GitRepository, requiredRepositoryFiles, determineGitIcon, } from "@/utils/GitRepository"; import { Modal } from "bootstrap"; const props = defineProps<{ modalID: string; }>(); let createWorkflowModal: Modal | null = null; const arbitraryWorkflowForm = ref<HTMLFormElement | undefined>(undefined); const workflowRepositoryElement = ref<HTMLInputElement | undefined>(undefined); const router = useRouter(); const workflow = reactive<{ repository_url: string; git_commit_hash: string; }>({ repository_url: "", git_commit_hash: "", }); const formState = reactive<{ loading: boolean; checkRepoLoading: boolean; validated: boolean; allowUpload: boolean; missingFiles: string[]; unsupportedRepository: boolean; }>({ validated: false, allowUpload: false, loading: false, checkRepoLoading: false, missingFiles: [], unsupportedRepository: false, }); function modalClosed() { formState.validated = false; } function viewWorkflow() { console.log("View", workflow); createWorkflowModal?.hide(); router.push({ name: "arbitrary-workflow", query: { repository: encodeURI(workflow.repository_url), commit_hash: workflow.git_commit_hash, }, }); } function checkRepository() { formState.validated = true; if (arbitraryWorkflowForm.value?.checkValidity() && !formState.allowUpload) { formState.unsupportedRepository = false; formState.missingFiles = []; workflowRepositoryElement.value?.setCustomValidity(""); try { const repo = GitRepository.buildRepository( workflow.repository_url, workflow.git_commit_hash ); repo .checkFilesExist(requiredRepositoryFiles, true) .then(() => { formState.allowUpload = true; }) .catch((e: Error) => { formState.missingFiles = e.message.split(","); // Allow execution of the workflow if main.nf and parameter schema are not missing if ( formState.missingFiles.findIndex( (file) => file === "main.nf" || file === "nextflow_schema.json" ) < 0 ) { formState.allowUpload = true; } }); } catch (e) { formState.unsupportedRepository = true; workflowRepositoryElement.value?.setCustomValidity( "Repository is not supported" ); } } } const gitIcon = computed<string>(() => determineGitIcon(workflow.repository_url) ); onMounted(() => { createWorkflowModal = new Modal("#" + props.modalID); }); </script> <template> <bootstrap-modal :modalID="modalID" :static-backdrop="false" modal-label="Create Workflow Modal" v-on="{ 'hidden.bs.modal': modalClosed }" > <template v-slot:header>Start arbitrary Workflow</template> <template v-slot:body> <form id="arbitraryWorkflowForm" :class="{ 'was-validated': formState.validated }" ref="arbitraryWorkflowForm" > <div class="mb-3"> <label for="workflowRepositoryInput" class="form-label" >Git Repository URL</label > <div class="input-group"> <div class="input-group-text"> <font-awesome-icon :icon="gitIcon" /> </div> <input type="url" class="form-control" id="workflowRepositoryInput" placeholder="https://..." required ref="workflowRepositoryElement" v-model="workflow.repository_url" @change="formState.allowUpload = false" aria-describedby="gitRepoProviderHelp" /> </div> <div id="gitRepoProviderHelp" class="form-text"> We support Github and GitLab Repositories </div> <div class="text-danger"> <div v-if="formState.unsupportedRepository"> Repository is not supported </div> </div> </div> <div class="mb-3"> <label for="workflowGitCommitInput" class="form-label" >Git Commit Hash</label > <div class="input-group"> <div class="input-group-text"> <font-awesome-icon icon="fa-solid fa-code-commit" /> </div> <input type="text" class="form-control text-lowercase" id="workflowGitCommitInput" placeholder="ba8bcd9..." required ref="workflowGitCommitHashElement" maxlength="40" minlength="40" pattern="[0-9a-f]{40}" v-model="workflow.git_commit_hash" @change="formState.allowUpload = false" /> </div> </div> <div v-if="formState.missingFiles.length > 0" class="text-danger"> The following files are missing in the repository <ul> <li v-for="file in formState.missingFiles" :key="file"> {{ file }} </li> </ul> </div> </form> </template> <template v-slot:footer> <button type="button" class="btn btn-info me-auto" @click="checkRepository" :disabled="formState.allowUpload" > <span v-if="formState.checkRepoLoading" class="spinner-border spinner-border-sm" role="status" aria-hidden="true" ></span> Check Repository </button> <button type="button" class="btn btn-secondary" data-bs-dismiss="modal"> Close </button> <button type="submit" form="workflowCreateForm" class="btn btn-primary" :disabled="formState.loading || !formState.allowUpload" @click.prevent="viewWorkflow" > <span v-if="formState.loading" class="spinner-border spinner-border-sm" role="status" aria-hidden="true" ></span> View </button> </template> </bootstrap-modal> </template> <style scoped></style>