diff --git a/src/assets/main.css b/src/assets/main.css
index 06d798ea4ea6f5af9cf9dce8a26eaf8bbdc7ba90..7024e78b25fc6d1c60c77ff425523d2a21fca9e4 100644
--- a/src/assets/main.css
+++ b/src/assets/main.css
@@ -6,3 +6,11 @@ body {
 .top-toast {
     top: 4rem;
 }
+
+.w-fit {
+    width: fit-content;
+}
+
+.cursor-pointer {
+    cursor: pointer;
+}
diff --git a/src/components/NavbarTop.vue b/src/components/NavbarTop.vue
index 949d38e3c3e7ea54d9e86467eefe61fa934be7e6..d8fbb2f5c5818102c073affce8c418c42ddbae96 100644
--- a/src/components/NavbarTop.vue
+++ b/src/components/NavbarTop.vue
@@ -142,7 +142,7 @@ watch(
         >
           <li><hr class="dropdown-divider" /></li>
           <li>
-            <a class="dropdown-item pseudo-link" @click="logout">Sign out</a>
+            <a class="dropdown-item cursor-pointer" @click="logout">Sign out</a>
           </li>
         </ul>
       </div>
@@ -150,8 +150,4 @@ watch(
   </header>
 </template>
 
-<style scoped>
-.pseudo-link {
-  cursor: pointer;
-}
-</style>
+<style scoped></style>
diff --git a/src/components/object-storage/modals/PermissionModal.vue b/src/components/object-storage/modals/PermissionModal.vue
index 0c61ba93d20d4531bca60a83cbf6a6a886d66a55..30048c8b331711f61bc284cc358b2dcbe2430b89 100644
--- a/src/components/object-storage/modals/PermissionModal.vue
+++ b/src/components/object-storage/modals/PermissionModal.vue
@@ -336,7 +336,7 @@ onMounted(() => {
       <bootstrap-icon
         v-if="props.deletable"
         icon="trash-fill"
-        class="me-2"
+        class="me-2 cursor-pointer"
         :class="{ 'delete-icon': !formState.loading }"
         data-bs-toggle="modal"
         :data-bs-target="'#delete-permission-modal' + randomIDSuffix"
@@ -344,7 +344,7 @@ onMounted(() => {
       <bootstrap-icon
         v-if="formState.readonly && props.editable"
         icon="pencil-fill"
-        class="pseudo-link"
+        class="pseudo-link cursor-pointer"
         @click="formState.readonly = false"
       />
     </template>
@@ -547,7 +547,6 @@ onMounted(() => {
 
 <style scoped>
 .pseudo-link {
-  cursor: pointer;
   color: var(--bs-secondary);
 }
 .pseudo-link:hover {
@@ -556,7 +555,6 @@ onMounted(() => {
 
 .delete-icon {
   color: var(--bs-secondary);
-  cursor: pointer;
 }
 .delete-icon:hover {
   color: var(--bs-danger);
diff --git a/src/components/workflows/WorkflowCard.vue b/src/components/workflows/WorkflowCard.vue
index 09826b6bad1425767fc2ee1e267b7811c78e4e67..42e31f131eb0547f04c642b08bfac8f229778c5d 100644
--- a/src/components/workflows/WorkflowCard.vue
+++ b/src/components/workflows/WorkflowCard.vue
@@ -30,9 +30,7 @@ onMounted(() => {
 </script>
 
 <template>
-  <div
-    class="card-hover border border-secondary card text-bg-dark m-3 align-self-center"
-  >
+  <div class="card-hover border border-secondary card text-bg-dark m-2">
     <div class="card-body">
       <h3 class="card-title">
         <div v-if="props.loading" class="placeholder-glow">
@@ -48,7 +46,7 @@ onMounted(() => {
           v-else
           @click="truncateDescription = false"
           :class="{
-            'pointer-cursor': truncateDescription,
+            'cursor-pointer': truncateDescription,
           }"
           >{{ props.workflow.short_description }}</span
         >
@@ -91,14 +89,10 @@ onMounted(() => {
 <style scoped>
 .card-hover {
   transition: transform 0.3s ease-out;
-  width: 47%;
+  width: 48%;
 }
 
 .card-hover:hover {
   transform: translate(0, -5px);
 }
-
-.pointer-cursor {
-  cursor: pointer;
-}
 </style>
diff --git a/src/router/index.ts b/src/router/index.ts
index 41c8d18437bf16f0fe9162147ce8cb94392057af..39acd6ecddd838a0a4346340f3dba5d803fe3db6 100644
--- a/src/router/index.ts
+++ b/src/router/index.ts
@@ -18,8 +18,7 @@ const router = createRouter({
             {
               path: ":bucketName/:subFolders*",
               name: "bucket",
-              component: () =>
-                import("../components/object-storage/BucketView.vue"),
+              component: () => import("../views/object-storage/BucketView.vue"),
               props: true,
             },
           ],
diff --git a/src/components/object-storage/BucketView.vue b/src/views/object-storage/BucketView.vue
similarity index 100%
rename from src/components/object-storage/BucketView.vue
rename to src/views/object-storage/BucketView.vue
diff --git a/src/components/object-storage/S3KeyView.vue b/src/views/object-storage/S3KeyView.vue
similarity index 100%
rename from src/components/object-storage/S3KeyView.vue
rename to src/views/object-storage/S3KeyView.vue
diff --git a/src/views/object-storage/S3KeysView.vue b/src/views/object-storage/S3KeysView.vue
index b0d1c10b5b403cd252a21dedebd893a75ff037f6..42766a2e6c7c74142d5cfd5776a41aee760233e6 100644
--- a/src/views/object-storage/S3KeysView.vue
+++ b/src/views/object-storage/S3KeysView.vue
@@ -1,5 +1,5 @@
 <script setup lang="ts">
-import S3KeyView from "@/components/object-storage/S3KeyView.vue";
+import S3KeyView from "@/views/object-storage/S3KeyView.vue";
 import BootstrapIcon from "@/components/BootstrapIcon.vue";
 import { reactive, onMounted, computed } from "vue";
 import type { ComputedRef } from "vue";
diff --git a/src/views/workflows/ListWorkflowsView.vue b/src/views/workflows/ListWorkflowsView.vue
index 8ea76021dd2424a80a1e8aa6fafd51ae90aacf89..211b92019f525f93620bb5137f834fb579b2cf3b 100644
--- a/src/views/workflows/ListWorkflowsView.vue
+++ b/src/views/workflows/ListWorkflowsView.vue
@@ -4,23 +4,53 @@ import type { ComputedRef } from "vue";
 import { useWorkflowStore } from "@/stores/workflows";
 import type { WorkflowOut } from "@/client/workflow";
 import WorkflowCard from "@/components/workflows/WorkflowCard.vue";
+import dayjs from "dayjs";
+import BootstrapIcon from "@/components/BootstrapIcon.vue";
 
 const workflowRepository = useWorkflowStore();
 
 const workflowsState = reactive({
   loading: true,
   filterString: "",
+  sortByAttribute: "name",
+  sortDesc: true,
 } as {
   loading: boolean;
   filterString: string;
+  sortByAttribute: string;
+  sortDesc: boolean;
 });
 
-const filteredWorkflows: ComputedRef<WorkflowOut[]> = computed(() => {
+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
-    ? workflowRepository.workflows.filter((workflow) =>
-        workflow.name.includes(workflowsState.filterString)
-      )
-    : workflowRepository.workflows;
+    ? 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(() => {
@@ -33,17 +63,116 @@ onMounted(() => {
 </script>
 
 <template>
-  <div v-if="!workflowsState.loading" class="d-flex flex-wrap">
-    <workflow-card
-      v-for="workflow in filteredWorkflows"
-      :key="workflow.workflow_id"
-      :workflow="workflow"
-      :loading="false"
+  <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"
+          ><bootstrap-icon icon="search"
+        /></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>
+    <bootstrap-icon
+      :icon="workflowsState.sortDesc ? 'sort-down' : 'sort-up'"
+      @click="workflowsState.sortDesc = !workflowsState.sortDesc"
+      class="fs-4 ms-3 cursor-pointer"
     />
   </div>
-  <div v-else class="d-flex flex-wrap">
+  <div v-if="!workflowsState.loading">
+    <div
+      v-if="workflowRepository.workflows.length === 0"
+      class="text-center fs-2 mt-5"
+    >
+      <bootstrap-icon
+        icon="x-lg"
+        class="mb-5"
+        width="75"
+        height="75"
+        style="color: var(--bs-secondary)"
+      />
+      <br />
+      There are no workflows in the system. Please come again later.
+    </div>
+    <div
+      v-else-if="processedWorkflows.length === 0"
+      class="text-center fs-2 mt-5"
+    >
+      <bootstrap-icon
+        icon="search"
+        class="mb-5"
+        width="75"
+        height="75"
+        style="color: var(--bs-secondary)"
+      />
+      <br />
+      Could not find any Workflows containing<br />'{{
+        workflowsState.filterString
+      }}'
+    </div>
+    <div
+      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"
+      />
+    </div>
+  </div>
+  <div
+    v-else
+    class="d-flex flex-wrap align-items-center justify-content-between"
+  >
     <workflow-card
-      v-for="workflow in 6"
+      v-for="workflow in 4"
       :key="workflow"
       :workflow="{
         name: '',