diff --git a/src/client/services/WorkflowExecutionService.ts b/src/client/services/WorkflowExecutionService.ts index 22693fdaefe15666c4775ee28964d7cc58b5f108..c0879d98f3edbbb8092fbb5557075d4cb7193df1 100644 --- a/src/client/services/WorkflowExecutionService.ts +++ b/src/client/services/WorkflowExecutionService.ts @@ -50,6 +50,7 @@ export class WorkflowExecutionService { * @param executorId Filter for workflow executions by a user. If none, Permission `workflow_execution:read_any` required. * @param executionStatus Filter for status of workflow execution * @param workflowVersionId Filter for workflow version + * @param workflowId Filter for workflow * @param startAfter Filter for workflow executions that started after this UNIX timestamp * @param startBefore Filter for workflow executions that started before this UNIX timestamp * @param idAfter Id of the item to start the query from. DO NOT SET MANUALLY. @@ -62,6 +63,7 @@ export class WorkflowExecutionService { executorId?: string, executionStatus?: Array<WorkflowExecutionStatus>, workflowVersionId?: string, + workflowId?: string, startAfter?: number, startBefore?: number, idAfter?: string, @@ -75,6 +77,7 @@ export class WorkflowExecutionService { 'executor_id': executorId, 'execution_status': executionStatus, 'workflow_version_id': workflowVersionId, + 'workflow_id': workflowId, 'start_after': startAfter, 'start_before': startBefore, 'id_after': idAfter, diff --git a/src/components/modals/SearchWorkflowVersionModal.vue b/src/components/modals/SearchWorkflowVersionModal.vue index 402133f7db76f22993d21099e74bcce062f0c528..e16f31d4fbe40a3bbd15d2beb6f31776c43c9e65 100644 --- a/src/components/modals/SearchWorkflowVersionModal.vue +++ b/src/components/modals/SearchWorkflowVersionModal.vue @@ -8,6 +8,7 @@ import FontAwesomeIcon from "@/components/FontAwesomeIcon.vue"; const props = defineProps<{ modalId: string; backModalId?: string; + allowSelectWorkflow?: boolean; }>(); const randomIDSuffix = Math.random().toString(16).substring(2, 8); @@ -19,19 +20,21 @@ const formState = reactive<{ lastSearchTimerId: ReturnType<typeof setTimeout> | null; error: boolean; loading: boolean; + selectedWorkflow?: WorkflowOut; }>({ searchString: "", potentialUsers: [], lastSearchTimerId: null, error: false, loading: false, + selectedWorkflow: undefined, }); const emit = defineEmits<{ ( e: "workflow-found", workflow: WorkflowOut, - workflowVersion: WorkflowVersion, + workflowVersion?: WorkflowVersion, ): void; }>(); @@ -63,7 +66,7 @@ onMounted(() => { modal-label="Search User Modal" v-on="{ 'hidden.bs.modal': modalClosed }" > - <template #header>Search Workflow Version</template> + <template #header>Search Workflow (Version)</template> <template #body> <div class="input-group mt-2 mb-4"> <span class="input-group-text" @@ -90,6 +93,13 @@ onMounted(() => { <button class="accordion-button collapsed" type="button" + @click=" + formState.selectedWorkflow = + formState.selectedWorkflow?.workflow_id === + workflow.workflow_id + ? undefined + : workflow + " data-bs-toggle="collapse" :data-bs-target="`#collapse-workflow-${workflow.workflow_id}-${randomIDSuffix}`" :aria-controls="`collapse-workflow-${workflow.workflow_id}-${randomIDSuffix}`" @@ -174,6 +184,18 @@ onMounted(() => { > Close </button> + <button + type="button" + class="btn btn-success" + v-if="allowSelectWorkflow" + :disabled="formState.selectedWorkflow == undefined" + @click="emit('workflow-found', formState.selectedWorkflow!, undefined)" + :data-bs-target="props.backModalId ? '#' + props.backModalId : null" + :data-bs-toggle="props.backModalId ? 'modal' : null" + :data-bs-dismiss="props.backModalId ? null : 'modal'" + > + Select + </button> </template> </bootstrap-modal> </template> diff --git a/src/stores/workflowExecutions.ts b/src/stores/workflowExecutions.ts index 2389f45e95b9f6c31a81fe38b027b85e390cebf3..c29c6d882d6c0ca5bb92b125b8079887108fdddc 100644 --- a/src/stores/workflowExecutions.ts +++ b/src/stores/workflowExecutions.ts @@ -61,6 +61,7 @@ export const useWorkflowExecutionStore = defineStore({ executorId?: string, executionStatus?: Array<WorkflowExecutionStatus>, workflowVersionId?: string, + workflowId?: string, startAfter?: number, startBefore?: number, perPage: number = 20, @@ -72,6 +73,7 @@ export const useWorkflowExecutionStore = defineStore({ executor_id: executorId, execution_status: executionStatus, workflow_version_id: workflowVersionId, + workflow_id: workflowId, start_after: startAfter, start_before: startBefore, per_page: perPage, @@ -144,6 +146,7 @@ export const useWorkflowExecutionStore = defineStore({ undefined, undefined, undefined, + undefined, 50, )) { onFinally?.(); diff --git a/src/views/admin/AdminWorkflowExecutionView.vue b/src/views/admin/AdminWorkflowExecutionView.vue index 0b0936cf50ae7e30290a93b7d2b3cc99c0a2dfb2..dd187aca15a99ba3cb61f65ccff08855b4209b99 100644 --- a/src/views/admin/AdminWorkflowExecutionView.vue +++ b/src/views/admin/AdminWorkflowExecutionView.vue @@ -37,7 +37,7 @@ const statusToIconMapping = { }; let loadingObserver: IntersectionObserver; -const endOfTableElement = ref<HTMLDivElement | undefined>(undefined); +const endOfTableElement = ref<HTMLTableCaptionElement | undefined>(undefined); const filters = reactive<{ executorId?: string; @@ -72,11 +72,12 @@ const executionIterator = ref< >(undefined); const workflowVersionName = computed<string>(() => { - if ( - filters.workflowId != undefined && - filters.workflowVersionId != undefined - ) { - return `${nameRepository.getName(filters.workflowId)}@${nameRepository.getName(filters.workflowVersionId)}`; + if (filters.workflowId != undefined) { + let name = nameRepository.getName(filters.workflowId) ?? ""; + if (filters.workflowVersionId != undefined) { + name = name + `@${nameRepository.getName(filters.workflowVersionId)}`; + } + return name; } return ""; }); @@ -87,9 +88,9 @@ function updateUser(user: UserOut) { function updateWorkflow( workflow: WorkflowOut, - workflowVersion: WorkflowVersion, + workflowVersion?: WorkflowVersion, ) { - filters.workflowVersionId = workflowVersion.workflow_version_id; + filters.workflowVersionId = workflowVersion?.workflow_version_id; filters.workflowId = workflow.workflow_id; } @@ -101,6 +102,7 @@ function searchExecution() { filters.executorId, filters.executionStatus, filters.workflowVersionId, + filters.workflowVersionId == undefined ? filters.workflowId : undefined, filters.startAfter, filters.startBefore, 30, @@ -157,7 +159,7 @@ function resetForm() { loadingObserver.disconnect(); filters.executorId = undefined; filters.executorId = undefined; - filters.executionStatus = undefined; + filters.executionStatus = []; filters.workflowVersionId = undefined; filters.workflowId = undefined; filters.startAfter = undefined; @@ -177,6 +179,7 @@ onMounted(() => { }, { threshold: 0, + rootMargin: "0px 0px 150px 0px", }, ); }); @@ -190,6 +193,7 @@ onMounted(() => { <search-workflow-modal modal-id="admin-execution-search-workflow-modal" @workflow-found="updateWorkflow" + allow-select-workflow /> <parameter-modal modal-id="workflowExecutionParameterModal" @@ -222,23 +226,23 @@ onMounted(() => { <input class="form-check-input" type="radio" - name="flexRadioDefault" - id="flexRadioDefault1" + name="sort-radio" + id="sort-radio-asc" value="asc" v-model="filters.sort" /> - <label class="form-check-label" for="flexRadioDefault1"> Asc </label> + <label class="form-check-label" for="sort-radio-asc"> Asc </label> </div> <div class="form-check form-check-inline"> <input class="form-check-input" type="radio" - name="flexRadioDefault" - id="flexRadioDefault2" + name="sort-radio" + id="sort-radio-desc" value="desc" v-model="filters.sort" /> - <label class="form-check-label" for="flexRadioDefault2"> Desc </label> + <label class="form-check-label" for="sort-radio-desc"> Desc </label> </div> </div> <div class="flex-fill mx-2"> @@ -309,7 +313,7 @@ onMounted(() => { /> </div> <label for="admin-execution-workflow-search" class="form-label" - >Workflow Version</label + >Workflow (Version)</label > <div class="input-group"> <div class="input-group-text"> @@ -321,7 +325,7 @@ onMounted(() => { class="form-control" readonly :value="workflowVersionName" - placeholder="Search for workflow version" + placeholder="Search for workflow (version)" data-bs-toggle="modal" data-bs-target="#admin-execution-search-workflow-modal" /> @@ -345,7 +349,7 @@ onMounted(() => { </button> </form> <table class="table table-hover align-middle" ref="executionTable"> - <caption> + <caption ref="endOfTableElement"> Displaying {{ formState.executions.length @@ -480,7 +484,6 @@ onMounted(() => { </tr> </tbody> </table> - <div ref="endOfTableElement"></div> </template> <style scoped></style>