<script setup lang="ts"> import { computed, onMounted, reactive } from "vue"; import type { ComputedRef } from "vue"; import { useWorkflowStore } from "@/stores/workflows"; import type { WorkflowOut } from "@/client/workflow"; import WorkflowCard from "@/components/workflows/WorkflowCard.vue"; import CardTransitionGroup from "@/components/transitions/CardTransitionGroup.vue"; import dayjs from "dayjs"; import FontAwesomeIcon from "@/components/FontAwesomeIcon.vue"; const workflowRepository = useWorkflowStore(); const workflowsState = reactive({ loading: true, filterString: "", sortByAttribute: "name", sortDesc: true, } as { loading: boolean; filterString: string; sortByAttribute: string; sortDesc: boolean; }); const bla: Record<string, (a: WorkflowOut, b: WorkflowOut) => boolean> = { name: (a: WorkflowOut, b: WorkflowOut) => workflowsState.sortDesc ? a.name > b.name : a.name < b.name, release: (a: WorkflowOut, b: WorkflowOut) => { const a_date = dayjs(a.versions[a.versions.length - 1].created_at); const b_date = dayjs(b.versions[b.versions.length - 1].created_at); return workflowsState.sortDesc ? a_date.isBefore(b_date) : a_date.isAfter(b_date); }, }; function filterWorkflowByString(workflow: WorkflowOut): boolean { return workflowsState.filterString.length > 0 ? workflow.name.includes(workflowsState.filterString) : true; } function filterWorkflowWithoutVersion(workflow: WorkflowOut): boolean { return workflow.versions.length > 0; } const processedWorkflows: ComputedRef<WorkflowOut[]> = computed(() => { return [ ...workflowRepository.workflows.filter( (workflow) => filterWorkflowByString(workflow) && filterWorkflowWithoutVersion(workflow) ), ].sort((a, b) => (bla[workflowsState.sortByAttribute](a, b) ? 1 : -1)); }); onMounted(() => { workflowRepository.fetchWorkflows( null, null, () => (workflowsState.loading = false) ); }); </script> <template> <div class="row m-2 border-bottom border-light mb-4"> <div class="col-12"></div> <h1 class="mb-2 text-light">Workflows</h1> </div> <div class="d-flex m-2 mb-3 align-items-center justify-content-between"> <div class="col-5 me-auto"> <div class="input-group"> <span class="input-group-text" id="workflows-search-wrapping" ><font-awesome-icon icon="fa-solid fa-magnifying-glass" /></span> <input type="text" class="form-control" placeholder="Filter Workflows" aria-label="Filter Workflows" aria-describedby="workflows-search-wrapping" :disabled="workflowsState.loading" v-model.trim="workflowsState.filterString" maxlength="20" /> </div> </div> <span class="fs-5 me-3">Sort By</span> <div class="btn-group btn-group-sm w-fit" role="group" aria-label="Basic radio toggle button group" > <input type="radio" class="btn-check" name="btnradio" id="sortName" autocomplete="off" checked v-model="workflowsState.sortByAttribute" value="name" /> <label class="btn btn-outline-secondary" for="sortName" >Alphabetical</label > <input type="radio" class="btn-check" name="btnradio" id="sortLatestRelease" autocomplete="off" v-model="workflowsState.sortByAttribute" value="release" /> <label class="btn btn-outline-secondary" for="sortLatestRelease" >Latest Release</label > </div> <font-awesome-icon :icon=" workflowsState.sortDesc ? 'fa-solid fa-arrow-down-wide-short' : 'fa-solid fa-arrow-up-wide-short' " @click="workflowsState.sortDesc = !workflowsState.sortDesc" class="fs-4 ms-3 cursor-pointer" /> </div> <div v-if="!workflowsState.loading"> <div v-if="workflowRepository.workflows.length === 0" class="text-center fs-2 mt-5" > <font-awesome-icon icon="fa-solid fa-x" class="my-5" width="75" height="75" style="color: var(--bs-secondary)" /> <p>There are no workflows in the system. Please come again later.</p> </div> <div v-else-if="processedWorkflows.length === 0" class="text-center fs-2 mt-5" > <font-awesome-icon icon="fa-solid fa-magnifying-glass" class="my-5" width="75" height="75" style="color: var(--bs-secondary)" /> <p> Could not find any Workflows containing<br />'{{ workflowsState.filterString }}' </p> </div> <CardTransitionGroup v-else class="d-flex flex-wrap align-items-center justify-content-between" > <workflow-card v-for="workflow in processedWorkflows" :key="workflow.workflow_id" :workflow="workflow" :loading="false" /> </CardTransitionGroup> </div> <div v-else class="d-flex flex-wrap align-items-center justify-content-between" > <workflow-card v-for="workflow in 4" :key="workflow" :workflow="{ name: '', short_description: '', repository_url: '', workflow_id: '', versions: [], }" loading /> </div> </template> <style scoped></style>