diff --git a/package.json b/package.json index 1da2935046bf1b03c7c5249aa18ff9a2507f6fde..9480d9a3f0588cdfd80db0867fe8ffc9214fd4e7 100644 --- a/package.json +++ b/package.json @@ -10,7 +10,7 @@ "lint": "eslint . --ext .vue,.js,.jsx,.cjs,.mjs,.ts,.tsx,.cts,.mts --fix --ignore-path .gitignore", "generate-s3-client": "openapi --input https://clowm-staging.bi.denbi.de/api/s3proxy-service/openapi.json --output src/client/s3proxy --client axios", "generate-auth-client": "openapi --input https://clowm-staging.bi.denbi.de/api/auth-service/openapi.json --output src/client/auth --client axios", - "generate-workflow-client": "openapi --input http://localhost:9999/api/workflow-service/openapi.json --output src/client/workflow --client axios" + "generate-workflow-client": "openapi --input https://clowm-staging.bi.denbi.de/api/workflow-service/openapi.json --output src/client/workflow --client axios" }, "dependencies": { "@aws-sdk/client-s3": "^3.290.0", diff --git a/src/views/workflows/ListWorkflowExecutionsView.vue b/src/views/workflows/ListWorkflowExecutionsView.vue index 60aff38396b3a4eb08d2a97e9ef36b538237f0aa..2ad5c43b8807c70c3e81721582da093f4b42303d 100644 --- a/src/views/workflows/ListWorkflowExecutionsView.vue +++ b/src/views/workflows/ListWorkflowExecutionsView.vue @@ -10,6 +10,7 @@ import { WorkflowVersionService, } from "@/client/workflow"; import dayjs from "dayjs"; +import DeleteModal from "@/components/modals/DeleteModal.vue"; const userStore = useAuthStore(); @@ -19,12 +20,14 @@ const executionsState = reactive<{ workflowExecutions: WorkflowExecutionOut[]; loading: boolean; mappingLoading: boolean; + executionToDelete?: WorkflowExecutionOut; }>({ workflowMapping: {}, versionMapping: {}, workflowExecutions: [], loading: true, mappingLoading: true, + executionToDelete: undefined, }); const statusToColorMapping = { @@ -49,13 +52,36 @@ const sortedExecutions = computed<WorkflowExecutionOut[]>(() => { const tempList = [...executionsState.workflowExecutions]; tempList.sort((a, b) => { // sort by start time descending - const a_date = dayjs(a.start_time); - const b_date = dayjs(b.start_time); - return a_date.isBefore(b_date) ? 1 : -1; + return dayjs(a.start_time).isBefore(dayjs(b.start_time)) ? 1 : -1; }); return tempList; }); +const deleteModalString = computed<string>(() => { + if (executionsState.executionToDelete === undefined) { + return ""; + } else if ( + !executionsState.executionToDelete.workflow_version_id || + !executionsState.executionToDelete.workflow_id + ) { + return `Workflow Execution from ${dayjs( + executionsState.executionToDelete.start_time + ).format("DD.MM.YYYY HH:mm")}`; + } else { + return `Workflow Execution ${ + executionsState.workflowMapping[ + executionsState.executionToDelete.workflow_id + ] + }@${ + executionsState.versionMapping[ + executionsState.executionToDelete.workflow_version_id + ] + } from ${dayjs(executionsState.executionToDelete.start_time).format( + "DD.MM.YYYY HH:mm" + )}`; + } +}); + // Functions // ----------------------------------------------------------------------------- function updateExecutions() { @@ -153,15 +179,17 @@ function workflowExecutionCancable(status: WorkflowExecutionStatus): boolean { ].includes(status); } -function deleteWorkflowExecution(executionId: string) { - WorkflowExecutionService.workflowExecutionDeleteWorkflowExecution( - executionId - ).then(() => { - executionsState.workflowExecutions = - executionsState.workflowExecutions.filter( - (execution) => execution.execution_id !== executionId - ); - }); +function deleteWorkflowExecution(executionId?: string) { + if (executionId) { + WorkflowExecutionService.workflowExecutionDeleteWorkflowExecution( + executionId + ).then(() => { + executionsState.workflowExecutions = + executionsState.workflowExecutions.filter( + (execution) => execution.execution_id !== executionId + ); + }); + } } function cancelWorkflowExecution(executionId: string) { @@ -186,8 +214,20 @@ onMounted(() => { </script> <template> - <div class="row m-2 border-bottom border-light mb-4"> - <h1 class="mb-2 text-light">My Workflow Executions</h1> + <delete-modal + modal-i-d="deleteWorkflowExecutionModal" + :object-name-delete="deleteModalString" + @confirm-delete=" + deleteWorkflowExecution(executionsState.executionToDelete?.execution_id) + " + /> + <div + class="row m-2 border-bottom border-light mb-4 justify-content-between align-items-center" + > + <h1 class="mb-2 text-light w-fit">My Workflow Executions</h1> + <router-link :to="{ name: 'workflows' }" class="btn btn-primary w-fit" + >Start Workflow Execution</router-link + > </div> <table class="table table-dark table-striped table-hover caption-top align-middle" @@ -241,7 +281,7 @@ onMounted(() => { </td> </tr> </template> - <template v-else> + <template v-else-if="executionsState.workflowExecutions.length > 0"> <tr v-for="execution in sortedExecutions" :key="execution.execution_id"> <td v-if="executionsState.mappingLoading" @@ -304,7 +344,9 @@ onMounted(() => { <button class="dropdown-item text-danger align-middle" type="button" - @click="deleteWorkflowExecution(execution.execution_id)" + data-bs-toggle="modal" + data-bs-target="#deleteWorkflowExecutionModal" + @click="executionsState.executionToDelete = execution" > <font-awesome-icon icon="fa-solid fa-trash" /> <span class="ms-1">Delete</span> @@ -312,10 +354,12 @@ onMounted(() => { </li> </ul> </div> - <!-- Show delete button when row is a folder --> </td> </tr> </template> + <tr v-else> + <td colspan="5" class="text-center"><i>No workflow executions</i></td> + </tr> </tbody> </table> </template>