Skip to content
Snippets Groups Projects
Verified Commit 2ba00971 authored by Daniel Göbel's avatar Daniel Göbel
Browse files

Use object repository in parameter schema form

#71
parent fb8ffb05
No related branches found
No related tags found
1 merge request!66Resolve "Fetch Objects directly from S3 Endpoint instead of S3 proxy"
This commit is part of merge request !66. Comments created here will be created in the context of that merge request.
......@@ -6,6 +6,11 @@ import Ajv from "ajv";
import type { ValidateFunction } from "ajv";
import ParameterStringInput from "@/components/parameter-schema/form-mode/ParameterStringInput.vue";
import { Toast } from "bootstrap";
import { useBucketStore } from "@/stores/buckets";
import { useS3KeyStore } from "@/stores/s3keys";
const bucketRepository = useBucketStore();
const s3KeyRepository = useS3KeyStore();
// Props
// =============================================================================
......@@ -165,6 +170,9 @@ function startWorkflow() {
// =============================================================================
onMounted(() => {
if (props.schema) updateSchema(props.schema);
bucketRepository.fetchBuckets();
bucketRepository.fetchOwnPermissions();
s3KeyRepository.fetchS3Keys();
errorToast = new Toast("#workflowExecutionErrorToast");
});
</script>
......@@ -208,6 +216,18 @@ onMounted(() => {
@submit.prevent="startWorkflow"
novalidate
>
<template v-for="(group, groupName) in parameterGroups" :key="groupName">
<parameter-group-form
:modelValue="formState.formInput[groupName]"
@update:model-value="
(newValue) => (formState.formInput[groupName] = newValue)
"
v-if="formState.formInput[groupName]"
:parameter-group-name="groupName"
:parameter-group="group"
:showHidden="formState.showHidden"
/>
</template>
<div class="card mb-3">
<h2 class="card-header" id="pipelineGeneralOptions">
<font-awesome-icon icon="fa-solid fa-gear" class="me-2" />
......@@ -256,18 +276,6 @@ onMounted(() => {
</label>
</div>
</div>
<template v-for="(group, groupName) in parameterGroups" :key="groupName">
<parameter-group-form
:modelValue="formState.formInput[groupName]"
@update:model-value="
(newValue) => (formState.formInput[groupName] = newValue)
"
v-if="formState.formInput[groupName]"
:parameter-group-name="groupName"
:parameter-group="group"
:showHidden="formState.showHidden"
/>
</template>
</form>
<!-- Loading card -->
<div v-else class="col-9">
......@@ -317,12 +325,6 @@ onMounted(() => {
<nav class="h-100">
<nav v-if="props.schema" class="nav">
<ul class="ps-0">
<li class="nav-link">
<a href="#pipelineGeneralOptions">
<font-awesome-icon icon="fa-solid fa-gear" class="me-2" />
General Pipeline Options
</a>
</li>
<li
class="nav-link"
v-for="group in navParameterGroups"
......@@ -337,6 +339,12 @@ onMounted(() => {
{{ group.title }}</a
>
</li>
<li class="nav-link">
<a href="#pipelineGeneralOptions">
<font-awesome-icon icon="fa-solid fa-gear" class="me-2" />
General Pipeline Options
</a>
</li>
</ul>
<div class="mx-auto mb-3">
<input
......
<script setup lang="ts">
import { computed, watch, ref, onMounted, reactive } from "vue";
import { useBucketStore } from "@/stores/buckets";
import { ObjectService } from "@/client/s3proxy";
import { useS3ObjectStore } from "@/stores/s3objects";
const bucketRepository = useBucketStore();
const s3objectRepository = useS3ObjectStore();
const props = defineProps({
parameter: {
......@@ -38,8 +39,6 @@ const s3Path = reactive<{
key: undefined,
});
const keysInBucket = ref<string[]>([]);
watch(defaultValue, (newVal, oldVal) => {
if (newVal != oldVal && newVal != undefined) {
emit("update:modelValue", newVal);
......@@ -72,13 +71,18 @@ const stringInput = ref<HTMLInputElement | undefined>(undefined);
const format = computed<string | undefined>(() => props.parameter["format"]);
const filesInBucket = computed<string[]>(() =>
keysInBucket.value.filter((obj) => !obj.endsWith("/")),
(s3objectRepository.objectMapping[s3Path.bucket ?? ""] ?? [])
.filter((obj) => !obj.Key?.endsWith("/"))
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
.map((obj) => obj.Key!),
);
const foldersInBucket = computed<string[]>(() =>
keysInBucket.value
(s3objectRepository.objectMapping[s3Path.bucket ?? ""] ?? [])
.filter((obj) => obj.Key != undefined)
.map((obj) => {
const parts = obj.split("/");
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
const parts = obj.Key!.split("/");
return parts
.slice(0, parts.length - 1)
.map((part, index) =>
......@@ -126,17 +130,14 @@ const helpTextPresent = computed<boolean>(() => props.parameter["help_text"]);
function updateKeysInBucket(bucketName?: string) {
if (bucketName != null) {
ObjectService.objectGetBucketObjects(bucketName).then((objs) => {
keysInBucket.value = objs.map((obj) => obj.key);
});
} else {
keysInBucket.value = [];
s3objectRepository.fetchS3Objects(
bucketName,
bucketRepository.ownPermissions[bucketName]?.file_prefix ?? undefined,
);
}
}
onMounted(() => {
bucketRepository.fetchBuckets();
bucketRepository.fetchOwnPermissions();
if (format.value) {
s3Path.key = defaultValue.value;
}
......
......@@ -22,11 +22,11 @@ export const useS3KeyStore = defineStore({
},
},
actions: {
fetchS3Keys(uid: string, onFinally?: () => void): Promise<S3Key[]> {
fetchS3Keys(onFinally?: () => void): Promise<S3Key[]> {
if (this.keys.length > 0) {
onFinally?.();
}
return S3KeyService.s3KeyGetUserKeys(uid)
return S3KeyService.s3KeyGetUserKeys(useAuthStore().currentUID)
.then((keys) => {
const s3ObjectRepository = useS3ObjectStore();
s3ObjectRepository.updateS3Client(keys[0]);
......
......@@ -64,7 +64,7 @@ onMounted(() => {
class="img-fluid mb-3"
width="128"
height="128"
alt="..."
alt="CloWM Logo"
/>
<h1>
<span class="blue fw-bold">Clo</span><span class="red fw-bold">W</span
......@@ -98,7 +98,7 @@ onMounted(() => {
<img
src="/src/assets/images/nfdi.svg"
alt="NFDI4Microbiota Logo"
height="70"
height="50"
/>
</a>
</div>
......@@ -108,25 +108,25 @@ onMounted(() => {
<img
src="/src/assets/images/denbi.svg"
alt="de.NBI Logo"
height="70"
height="50"
/>
</a>
</div>
<div class="border rounded p-4 icon text-center">
<h4 class="mb-4">Hosted By</h4>
<a href="https://bibi.uni-bielefeld.de/">
<img src="/src/assets/images/bibi.png" alt="BiBi Logo" height="70" />
<img src="/src/assets/images/bibi.png" alt="BiBi Logo" height="50" />
</a>
</div>
<div class="border rounded p-4 icon text-center">
<h4 class="mb-4">Funded By</h4>
<img src="/src/assets/images/dfg.png" alt="DFG Logo" height="70" />
<img src="/src/assets/images/dfg.png" alt="DFG Logo" height="50" />
</div>
<div class="border rounded p-4 icon text-center">
<img
src="/src/assets/images/unibi.svg"
alt="Bielefeld University Logo"
height="70"
height="50"
/>
</div>
</div>
......
......@@ -267,7 +267,7 @@ onMounted(() => {
}
};
// wait till s3keys and ownPermissions are available before fetching objects
s3KeyRepository.fetchS3Keys(authStore.currentUID, onFinally);
s3KeyRepository.fetchS3Keys(onFinally);
bucketRepository.fetchOwnPermissions(onFinally);
document
......@@ -488,9 +488,9 @@ function getObjectFileName(key: string): string {
</nav>
<!-- Inputs on top -->
<!-- Search bucket text input -->
<div class="row">
<div class="col-5 me-auto">
<div class="input-group mt-2 rounded shadow-sm">
<div class="d-flex justify-content-between align-items-center">
<div class="flex-grow-1 me-2">
<div class="input-group rounded shadow-sm">
<span class="input-group-text" id="objects-search-wrapping"
><font-awesome-icon icon="fa-solid fa-magnifying-glass"
/></span>
......@@ -506,10 +506,10 @@ function getObjectFileName(key: string): string {
</div>
</div>
<!-- Upload object button -->
<div id="BucketViewButtons" class="col-auto">
<div id="BucketViewButtons" class="">
<button
type="button"
class="btn btn-light me-4 tooltip-container border shadow-sm"
class="btn btn-light me-3 tooltip-container border shadow-sm"
:disabled="errorLoadingObjects"
data-bs-toggle="tooltip"
data-bs-title="Refresh Objects"
......@@ -538,7 +538,7 @@ function getObjectFileName(key: string): string {
<!-- Add folder button -->
<button
type="button"
class="btn btn-light me-4 tooltip-container border shadow-sm"
class="btn btn-light me-3 tooltip-container border shadow-sm"
:disabled="errorLoadingObjects || !writableBucket"
data-bs-toggle="modal"
data-bs-title="Create Folder"
......
......@@ -26,7 +26,7 @@ const allowKeyDeletion = computed<boolean>(() => keyRepository.keys.length > 1);
function fetchKeys() {
keyRepository
.fetchS3Keys(authStore.currentUID, () => (keyState.initialLoading = false))
.fetchS3Keys(() => (keyState.initialLoading = false))
.then((keys) => {
if (keyState.activeKey >= keys.length) {
keyState.activeKey = keys.length - 1;
......
<script setup lang="ts">
import FontAwesomeIcon from "@/components/FontAwesomeIcon.vue";
import { onMounted, reactive, computed } from "vue";
import { onMounted, reactive, computed, onUnmounted } from "vue";
import type { WorkflowExecutionOut } from "@/client/workflow";
import { WorkflowExecutionStatus } from "@/client/workflow";
import dayjs from "dayjs";
......@@ -13,6 +13,7 @@ const workflowRepository = useWorkflowStore();
const executionRepository = useWorkflowExecutionStore();
let refreshTimeout: NodeJS.Timeout | undefined = undefined;
let intervalId: NodeJS.Timer | undefined = undefined;
const executionsState = reactive<{
loading: boolean;
......@@ -115,11 +116,26 @@ function cancelWorkflowExecution(executionId: string) {
executionRepository.cancelExecution(executionId);
}
function refreshRunningWorkflowExecution() {
Promise.all(
executionRepository.executions
.filter((execution) => workflowExecutionCancelable(execution.status))
.map((execution) =>
executionRepository.fetchExecution(execution.execution_id),
),
);
}
onMounted(() => {
workflowRepository.fetchWorkflows();
updateExecutions();
intervalId = setInterval(refreshRunningWorkflowExecution, 5000);
new Tooltip("#refreshExecutionsButton");
});
onUnmounted(() => {
clearInterval(intervalId);
});
</script>
<template>
......
......@@ -255,7 +255,7 @@ onMounted(() => {
v-if="activeVersionModeIds.length > 0"
class="row align-items-center mb-3 fs-5"
>
<label class="col-sm-1 col-form-label">Mode:</label>
<label class="col-sm-1 col-form-label"><b>Mode:</b></label>
<div class="col-sm-11">
<select class="form-select w-fit" v-model="workflowState.activeModeId">
<option
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment