-
Daniel Göbel authored
#58
Daniel Göbel authored#58
ArbitraryWorkflowModal.vue 6.21 KiB
<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>