From 5e7968af595f942ce90bbe370ed062ac66674b1d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20G=C3=B6bel?= <dgoebel@techfak.uni-bielefeld.de> Date: Wed, 8 Mar 2023 15:57:56 +0100 Subject: [PATCH] Migrate to font awesome icons adn drop bootstrap icons #42 --- package-lock.json | 26 ++++++++------- package.json | 4 +-- ...{BootstrapIcon.vue => FontAwesomeIcon.vue} | 19 +++++------ src/components/NavbarTop.vue | 4 +-- src/components/modals/SearchUserModal.vue | 12 +++---- .../object-storage/BucketListItem.vue | 14 ++++---- .../object-storage/modals/PermissionModal.vue | 20 +++++------ src/components/workflows/WorkflowCard.vue | 4 +-- .../workflows/WorkflowWithVersionsCard.vue | 19 ++++++----- src/main.ts | 3 ++ src/views/object-storage/BucketView.vue | 24 +++++++------- src/views/object-storage/BucketsView.vue | 19 ++++++----- src/views/object-storage/S3KeyView.vue | 6 ++-- src/views/object-storage/S3KeysView.vue | 9 +++-- src/views/workflows/ListWorkflowsView.vue | 20 ++++++----- src/views/workflows/WorkflowView.vue | 33 ++++++++++++++----- 16 files changed, 136 insertions(+), 100 deletions(-) rename src/components/{BootstrapIcon.vue => FontAwesomeIcon.vue} (58%) diff --git a/package-lock.json b/package-lock.json index 950dc82..1daf722 100644 --- a/package-lock.json +++ b/package-lock.json @@ -11,9 +11,9 @@ "@aws-sdk/client-s3": "^3.281.0", "@aws-sdk/lib-storage": "^3.281.0", "@aws-sdk/s3-request-presigner": "^3.281.0", + "@fortawesome/fontawesome-free": "^6.3.0", "@popperjs/core": "^2.11.6", "bootstrap": "^5.2.3", - "bootstrap-icons": "^1.10.3", "dayjs": "^1.11.7", "dompurify": "^3.0.1", "filesize": "^10.0.6", @@ -2235,6 +2235,15 @@ "url": "https://opencollective.com/eslint" } }, + "node_modules/@fortawesome/fontawesome-free": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/@fortawesome/fontawesome-free/-/fontawesome-free-6.3.0.tgz", + "integrity": "sha512-qVtd5i1Cc7cdrqnTWqTObKQHjPWAiRwjUPaXObaeNPcy7+WKxJumGBx66rfSFgK6LNpIasVKkEgW8oyf0tmPLA==", + "hasInstallScript": true, + "engines": { + "node": ">=6" + } + }, "node_modules/@humanwhocodes/config-array": { "version": "0.11.7", "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.7.tgz", @@ -2974,11 +2983,6 @@ "@popperjs/core": "^2.11.6" } }, - "node_modules/bootstrap-icons": { - "version": "1.10.3", - "resolved": "https://registry.npmjs.org/bootstrap-icons/-/bootstrap-icons-1.10.3.tgz", - "integrity": "sha512-7Qvj0j0idEm/DdX9Q0CpxAnJYqBCFCiUI6qzSPYfERMcokVuV9Mdm/AJiVZI8+Gawe4h/l6zFcOzvV7oXCZArw==" - }, "node_modules/bowser": { "version": "2.11.0", "resolved": "https://registry.npmjs.org/bowser/-/bowser-2.11.0.tgz", @@ -8589,6 +8593,11 @@ "strip-json-comments": "^3.1.1" } }, + "@fortawesome/fontawesome-free": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/@fortawesome/fontawesome-free/-/fontawesome-free-6.3.0.tgz", + "integrity": "sha512-qVtd5i1Cc7cdrqnTWqTObKQHjPWAiRwjUPaXObaeNPcy7+WKxJumGBx66rfSFgK6LNpIasVKkEgW8oyf0tmPLA==" + }, "@humanwhocodes/config-array": { "version": "0.11.7", "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.7.tgz", @@ -9120,11 +9129,6 @@ "integrity": "sha512-cEKPM+fwb3cT8NzQZYEu4HilJ3anCrWqh3CHAok1p9jXqMPsPTBhU25fBckEJHJ/p+tTxTFTsFQGM+gaHpi3QQ==", "requires": {} }, - "bootstrap-icons": { - "version": "1.10.3", - "resolved": "https://registry.npmjs.org/bootstrap-icons/-/bootstrap-icons-1.10.3.tgz", - "integrity": "sha512-7Qvj0j0idEm/DdX9Q0CpxAnJYqBCFCiUI6qzSPYfERMcokVuV9Mdm/AJiVZI8+Gawe4h/l6zFcOzvV7oXCZArw==" - }, "bowser": { "version": "2.11.0", "resolved": "https://registry.npmjs.org/bowser/-/bowser-2.11.0.tgz", diff --git a/package.json b/package.json index 17eaf9f..ca88bc3 100644 --- a/package.json +++ b/package.json @@ -16,9 +16,9 @@ "@aws-sdk/client-s3": "^3.281.0", "@aws-sdk/lib-storage": "^3.281.0", "@aws-sdk/s3-request-presigner": "^3.281.0", + "@fortawesome/fontawesome-free": "^6.3.0", "@popperjs/core": "^2.11.6", "bootstrap": "^5.2.3", - "bootstrap-icons": "^1.10.3", "dayjs": "^1.11.7", "dompurify": "^3.0.1", "filesize": "^10.0.6", @@ -33,9 +33,9 @@ "@esbuild-plugins/node-modules-polyfill": "^0.1.4", "@rushstack/eslint-patch": "^1.2.0", "@types/bootstrap": "^5.2.6", + "@types/dompurify": "^2.4.0", "@types/node": "^16.11.45", "@types/showdown": "^2.0.0", - "@types/dompurify": "^2.4.0", "@vitejs/plugin-vue": "^3.2.0", "@vue/eslint-config-prettier": "^7.0.0", "@vue/eslint-config-typescript": "^11.0.2", diff --git a/src/components/BootstrapIcon.vue b/src/components/FontAwesomeIcon.vue similarity index 58% rename from src/components/BootstrapIcon.vue rename to src/components/FontAwesomeIcon.vue index 7c57717..e0a4e3d 100644 --- a/src/components/BootstrapIcon.vue +++ b/src/components/FontAwesomeIcon.vue @@ -1,17 +1,16 @@ <template> - <svg - class="bi bi-bootstrap-fill" - :width="props.width" - :height="props.height" - :fill="props.fill" - > - <use v-bind:xlink:href="iconPath + '#' + props.icon" /> - </svg> + <div + class="align-middle" + :class="icon" + :style="{ + width: props.width, + height: props.height, + color: props.fill, + }" + ></div> </template> <script setup lang="ts"> -import iconPath from "bootstrap-icons/bootstrap-icons.svg"; - const props = defineProps({ icon: { type: String, required: true }, width: { type: String, default: "1em", required: false }, diff --git a/src/components/NavbarTop.vue b/src/components/NavbarTop.vue index 2c68c63..b91aaf0 100644 --- a/src/components/NavbarTop.vue +++ b/src/components/NavbarTop.vue @@ -1,5 +1,5 @@ <script setup lang="ts"> -import BootstrapIcon from "@/components/BootstrapIcon.vue"; +import FontAwesomeIcon from "@/components/FontAwesomeIcon.vue"; import { useAuthStore } from "@/stores/auth"; import { useRoute, useRouter } from "vue-router"; import { useCookies } from "vue3-cookies"; @@ -150,7 +150,7 @@ watch( aria-expanded="false" > <strong class="me-2">{{ store.user.display_name }}</strong> - <bootstrap-icon icon="person-circle" class="fs-4" /> + <font-awesome-icon icon="fa-solid fa-circle-user" class="fs-5" /> </a> <ul class="dropdown-menu dropdown-menu-dark text-small shadow" diff --git a/src/components/modals/SearchUserModal.vue b/src/components/modals/SearchUserModal.vue index 9fb35d4..d5b5fcd 100644 --- a/src/components/modals/SearchUserModal.vue +++ b/src/components/modals/SearchUserModal.vue @@ -1,7 +1,7 @@ <script setup lang="ts"> import { reactive, watch } from "vue"; import BootstrapModal from "@/components/modals/BootstrapModal.vue"; -import BootstrapIcon from "@/components/BootstrapIcon.vue"; +import FontAwesomeIcon from "@/components/FontAwesomeIcon.vue"; import { UserService } from "@/client/auth"; import type { User } from "@/client/auth"; import { useAuthStore } from "@/stores/auth"; @@ -82,7 +82,7 @@ function searchUser(name: string) { <template v-slot:body> <div class="input-group mt-2 mb-4"> <span class="input-group-text" id="objects-search-wrapping" - ><bootstrap-icon icon="search" + ><font-awesome-icon icon="fa-solid fa-magnifying-glass" /></span> <input class="form-control" @@ -97,8 +97,8 @@ function searchUser(name: string) { </div> </div> <div v-else-if="formState.error" class="text-center fs-2"> - <bootstrap-icon - icon="x-lg" + <font-awesome-icon + icon="fa-solid fa-x" class="mb-2" width="56" height="56" @@ -122,8 +122,8 @@ function searchUser(name: string) { </button> </div> <div v-else class="text-center fs-2"> - <bootstrap-icon - icon="search" + <font-awesome-icon + icon="fa-solid fa-magnifying-glass" class="mb-2" width="56" height="56" diff --git a/src/components/object-storage/BucketListItem.vue b/src/components/object-storage/BucketListItem.vue index bec5afd..611015d 100644 --- a/src/components/object-storage/BucketListItem.vue +++ b/src/components/object-storage/BucketListItem.vue @@ -4,7 +4,7 @@ import type { BucketPermissionIn, BucketPermissionOut, } from "@/client/s3proxy"; -import BootstrapIcon from "@/components/BootstrapIcon.vue"; +import FontAwesomeIcon from "@/components/FontAwesomeIcon.vue"; import PermissionModal from "@/components/object-storage/modals/PermissionModal.vue"; import BucketDetailModal from "@/components/object-storage/modals/BucketDetailModal.vue"; import dayjs from "dayjs"; @@ -88,18 +88,18 @@ onMounted(() => { > <span class="text-truncate" style="width: 80%">{{ bucket.name }}</span> <div> - <bootstrap-icon + <font-awesome-icon v-if="props.active && permission == null && props.deletable" - icon="trash-fill" + icon="fa-solid fa-trash" class="delete-icon me-2" @click="emit('delete-bucket', bucket.name)" /> - <bootstrap-icon + <font-awesome-icon class="info-icon" data-bs-toggle="modal" :data-bs-target="'#view-bucket-details-modal' + randomIDSuffix" v-if="props.active" - icon="info-circle-fill" + icon="fa-solid fa-circle-info" /> </div> </router-link> @@ -157,12 +157,12 @@ onMounted(() => { color: white; } .delete-icon:hover { - color: var(--bs-danger); + color: var(--bs-danger) !important; } .info-icon { color: white; } .info-icon:hover { - color: var(--bs-info); + color: var(--bs-info) !important; } </style> diff --git a/src/components/object-storage/modals/PermissionModal.vue b/src/components/object-storage/modals/PermissionModal.vue index 30048c8..82bfd4a 100644 --- a/src/components/object-storage/modals/PermissionModal.vue +++ b/src/components/object-storage/modals/PermissionModal.vue @@ -15,7 +15,7 @@ import type { FolderTree } from "@/types/PseudoFolder"; import type { ComputedRef, Ref } from "vue"; import { Permission, BucketPermissionService } from "@/client/s3proxy"; import { Toast } from "bootstrap"; -import BootstrapIcon from "@/components/BootstrapIcon.vue"; +import FontAwesomeIcon from "@/components/FontAwesomeIcon.vue"; // Props // ----------------------------------------------------------------------------- @@ -333,17 +333,17 @@ onMounted(() => { </template> <template v-slot:header v-else> Create new Permission </template> <template v-slot:extra-button> - <bootstrap-icon + <font-awesome-icon v-if="props.deletable" - icon="trash-fill" + icon="fa-solid fa-trash" class="me-2 cursor-pointer" :class="{ 'delete-icon': !formState.loading }" data-bs-toggle="modal" :data-bs-target="'#delete-permission-modal' + randomIDSuffix" /> - <bootstrap-icon + <font-awesome-icon v-if="formState.readonly && props.editable" - icon="pencil-fill" + icon="fa-solid fa-pen" class="pseudo-link cursor-pointer" @click="formState.readonly = false" /> @@ -395,7 +395,7 @@ onMounted(() => { data-bs-toggle="modal" :data-bs-target="'#search-user-modal' + randomIDSuffix" > - <bootstrap-icon icon="search" /> + <font-awesome-icon icon="fa-solid fa-magnifying-glass" /> </button> </div> </div> @@ -499,7 +499,7 @@ onMounted(() => { @click="permission.file_prefix = undefined" :hidden="permission.file_prefix == undefined" > - <bootstrap-icon icon="x-lg" /> + <font-awesome-icon icon="fa-solid fa-x" /> </button> </div> </div> @@ -550,13 +550,13 @@ onMounted(() => { color: var(--bs-secondary); } .pseudo-link:hover { - color: var(--bs-primary); + color: var(--bs-link-hover-color); } .delete-icon { - color: var(--bs-secondary); + color: var(--bs-secondary) !important; } .delete-icon:hover { - color: var(--bs-danger); + color: var(--bs-danger) !important; } </style> diff --git a/src/components/workflows/WorkflowCard.vue b/src/components/workflows/WorkflowCard.vue index 8c16d99..030081c 100644 --- a/src/components/workflows/WorkflowCard.vue +++ b/src/components/workflows/WorkflowCard.vue @@ -1,6 +1,6 @@ <script setup lang="ts"> import type { WorkflowOut, WorkflowVersionReduced } from "@/client/workflow"; -import BootstrapIcon from "@/components/BootstrapIcon.vue"; +import FontAwesomeIcon from "@/components/FontAwesomeIcon.vue"; import dayjs from "dayjs"; import { onMounted, ref, computed } from "vue"; import type { Ref, ComputedRef } from "vue"; @@ -84,7 +84,7 @@ onMounted(() => { class="btn btn-outline-success" role="button" > - <bootstrap-icon class="fs-5" icon="tag-fill" /> + <font-awesome-icon class="fs-5" icon="fa-solid fa-tag" /> {{ latestVersion?.version }} </a> <div v-if="props.loading" class="placeholder-glow w-25"> diff --git a/src/components/workflows/WorkflowWithVersionsCard.vue b/src/components/workflows/WorkflowWithVersionsCard.vue index bd423d0..cd39933 100644 --- a/src/components/workflows/WorkflowWithVersionsCard.vue +++ b/src/components/workflows/WorkflowWithVersionsCard.vue @@ -3,7 +3,7 @@ import type { WorkflowOut } from "@/client/workflow"; import { ref } from "vue"; import type { Ref } from "vue"; import { Status } from "@/client/workflow"; -import BootstrapIcon from "@/components/BootstrapIcon.vue"; +import FontAwesomeIcon from "@/components/FontAwesomeIcon.vue"; import dayjs from "dayjs"; const props = defineProps<{ @@ -13,10 +13,10 @@ const props = defineProps<{ const truncateDescription: Ref<boolean> = ref(true); const statusToIconMapping: Record<string, string> = { - PUBLISHED: "check-circle-fill", - DENIED: "x-lg", - CREATED: "check-circle", - DEPRECATED: "archive-fill", + PUBLISHED: "fa-solid fa-circle-check", + DENIED: "fa-solid fa-x", + CREATED: "fa-solid fa-circle-pause", + DEPRECATED: "fa-solid fa-box-archive", }; </script> @@ -33,7 +33,7 @@ const statusToIconMapping: Record<string, string> = { <button type="button" class="btn btn-success" - :class="{ disabled: props.loading, placeholder: props.loading }" + :class="{ disabled: props.loading }" > Update </button> @@ -71,6 +71,7 @@ const statusToIconMapping: Record<string, string> = { <img v-if="version.icon_url != null" :src="version.icon_url" + alt="Workflow Version Icon" /> </td> <th scope="row" class="fw-bold">{{ version.version }}</th> @@ -82,10 +83,12 @@ const statusToIconMapping: Record<string, string> = { 'text-warning': version.status === Status.DEPRECATED, }" > - <bootstrap-icon :icon="statusToIconMapping[version.status]" /> + <font-awesome-icon + :icon="statusToIconMapping[version.status]" + /> {{ version.status }} </td> - <td>{{ dayjs(version.created_at).format("DD.MM.YYYY") }}</td> + <td>{{ dayjs(version.created_at).format("D MMMM YYYY") }}</td> <td> <router-link class="w-fit mx-0" diff --git a/src/main.ts b/src/main.ts index 91485f9..d7f01cc 100644 --- a/src/main.ts +++ b/src/main.ts @@ -11,6 +11,9 @@ import "dayjs/locale/en-gb"; dayjs.extend(relativeTime); // use plugin import "bootstrap/dist/css/bootstrap.css"; +import "@fortawesome/fontawesome-free/css/fontawesome.css"; +import "@fortawesome/fontawesome-free/css/solid.css"; +import "@fortawesome/fontawesome-free/css/brands.css"; import "./assets/main.css"; diff --git a/src/views/object-storage/BucketView.vue b/src/views/object-storage/BucketView.vue index 7bd9e5e..fdb9a36 100644 --- a/src/views/object-storage/BucketView.vue +++ b/src/views/object-storage/BucketView.vue @@ -11,7 +11,7 @@ import type { S3ObjectWithFolder, } from "@/types/PseudoFolder"; import { ObjectService } from "@/client/s3proxy"; -import BootstrapIcon from "@/components/BootstrapIcon.vue"; +import FontAwesomeIcon from "@/components/FontAwesomeIcon.vue"; import { filesize } from "filesize"; import dayjs from "dayjs"; import { Toast, Tooltip } from "bootstrap"; @@ -580,7 +580,7 @@ watch( <div class="col-8"> <div class="input-group mt-2"> <span class="input-group-text" id="objects-search-wrapping" - ><bootstrap-icon icon="search" + ><font-awesome-icon icon="fa-solid fa-magnifying-glass" /></span> <input type="text" @@ -603,7 +603,7 @@ watch( data-bs-title="Upload Object" data-bs-target="#upload-object-modal" > - <bootstrap-icon icon="upload" fill="white" /> + <font-awesome-icon icon="fa-solid fa-upload" fill="white" /> <span class="visually-hidden">Upload Object</span> </button> <upload-object-modal @@ -623,7 +623,7 @@ watch( data-bs-title="Create Folder" data-bs-target="#create-folder-modal" > - <bootstrap-icon icon="plus-lg" /> + <font-awesome-icon icon="fa-solid fa-plus" /> Folder <span class="visually-hidden">Add Folder</span> </button> @@ -645,7 +645,7 @@ watch( data-bs-title="Create Bucket Permission" data-bs-target="#create-permission-modal" > - <bootstrap-icon icon="person-plus-fill" /> + <font-awesome-icon icon="fa-solid fa-user-plus" /> <span class="visually-hidden">Add Bucket Permission</span> </button> <permission-modal @@ -672,7 +672,7 @@ watch( data-bs-toggle="modal" data-bs-target="#permission-list-modal" > - <bootstrap-icon icon="person-lines-fill" /> + <font-awesome-icon icon="fa-solid fa-users-line" /> <span class="visually-hidden">View Bucket Permissions</span> </button> <permission-list-modal @@ -691,8 +691,8 @@ watch( <div class="pt-3"> <!-- If bucket not found --> <div v-if="objectState.bucketNotFoundError" class="text-center fs-2 mt-5"> - <bootstrap-icon - icon="search" + <font-awesome-icon + icon="fa-solid fa-magnifying-glass" class="mb-3" width="64" height="64" @@ -707,8 +707,8 @@ watch( v-else-if="objectState.bucketPermissionError" class="text-center fs-2 mt-5" > - <bootstrap-icon - icon="folder-x" + <font-awesome-icon + icon="fa-solid fa-folder-xmark" class="mb-3" width="64" height="64" @@ -857,7 +857,7 @@ watch( data-bs-target="#delete-object-modal" :disabled="!writableBucket" > - <bootstrap-icon icon="trash-fill" /> + <font-awesome-icon icon="fa-solid fa-trash" /> <span class="ms-1">Delete</span> </button> </li> @@ -877,7 +877,7 @@ watch( ) " > - <bootstrap-icon icon="trash-fill" class="me-2" /> + <font-awesome-icon icon="fa-solid fa-trash" class="me-2" /> <span>Delete</span> </button> </div> diff --git a/src/views/object-storage/BucketsView.vue b/src/views/object-storage/BucketsView.vue index 15fc387..0db316e 100644 --- a/src/views/object-storage/BucketsView.vue +++ b/src/views/object-storage/BucketsView.vue @@ -3,7 +3,7 @@ import type { ComputedRef } from "vue"; import { computed, onMounted, reactive } from "vue"; import type { BucketOut } from "@/client/s3proxy"; import { useRoute, useRouter } from "vue-router"; -import BootstrapIcon from "@/components/BootstrapIcon.vue"; +import FontAwesomeIcon from "@/components/FontAwesomeIcon.vue"; import CreateBucketModal from "@/components/object-storage/modals/CreateBucketModal.vue"; import DeleteModal from "@/components/modals/DeleteModal.vue"; import BucketListItem from "@/components/object-storage/BucketListItem.vue"; @@ -83,7 +83,10 @@ onMounted(() => { class="btn btn-light" @click.stop.prevent="fetchBuckets" > - <bootstrap-icon icon="arrow-clockwise" class="fs-5" /> + <font-awesome-icon + icon="fa-solid fa-arrow-rotate-right" + class="fs-5" + /> <span class="visually-hidden">Refresh Buckets</span> </button> <button @@ -93,13 +96,13 @@ onMounted(() => { data-bs-toggle="modal" data-bs-target="#create-bucket-modal" > - <bootstrap-icon icon="plus-lg" class="fs-5" /> + <font-awesome-icon icon="fa-solid fa-plus" class="fs-5" /> <span class="visually-hidden">Create Bucket</span> </button> </div> <div class="input-group flex-nowrap mt-2"> <span class="input-group-text" id="buckets-search-wrapping" - ><bootstrap-icon icon="search" + ><font-awesome-icon icon="fa-solid fa-magnifying-glass" /></span> <input type="text" @@ -128,8 +131,8 @@ onMounted(() => { /> </div> <div v-else class="text-center fs-2 mt-5"> - <bootstrap-icon - icon="search" + <font-awesome-icon + icon="fa-solid fa-magnifying-glass" class="mb-2" width="56" height="56" @@ -164,8 +167,8 @@ onMounted(() => { v-if="router.currentRoute.value.name === 'buckets'" class="text-center fs-2 mt-5" > - <bootstrap-icon - icon="hand-index-thumb-fill" + <font-awesome-icon + icon="fa-solid fa-hand-back-point-up" class="mb-5" width="64" height="64" diff --git a/src/views/object-storage/S3KeyView.vue b/src/views/object-storage/S3KeyView.vue index 7985316..7757fb5 100644 --- a/src/views/object-storage/S3KeyView.vue +++ b/src/views/object-storage/S3KeyView.vue @@ -2,7 +2,7 @@ import type { S3Key } from "@/client/s3proxy"; import type { Ref } from "vue"; import { ref, watch } from "vue"; -import BootstrapIcon from "@/components/BootstrapIcon.vue"; +import FontAwesomeIcon from "@/components/FontAwesomeIcon.vue"; import DeleteModal from "@/components/modals/DeleteModal.vue"; const props = defineProps<{ @@ -59,9 +59,9 @@ function deleteKeyTrigger() { :disabled="props.loading" @click="visibleSecret = !visibleSecret" > - <bootstrap-icon + <font-awesome-icon class="fs-5" - :icon="visibleSecret ? 'eye' : 'eye-slash'" + :icon="visibleSecret ? 'fa-solid fa-eye' : 'fa-solid fa-eye-slash'" /> </button> </div> diff --git a/src/views/object-storage/S3KeysView.vue b/src/views/object-storage/S3KeysView.vue index 3d0e964..0ccd0f1 100644 --- a/src/views/object-storage/S3KeysView.vue +++ b/src/views/object-storage/S3KeysView.vue @@ -1,6 +1,6 @@ <script setup lang="ts"> import S3KeyView from "@/views/object-storage/S3KeyView.vue"; -import BootstrapIcon from "@/components/BootstrapIcon.vue"; +import FontAwesomeIcon from "@/components/FontAwesomeIcon.vue"; import { reactive, onMounted, computed } from "vue"; import type { ComputedRef } from "vue"; import type { S3Key } from "@/client/s3proxy"; @@ -118,11 +118,14 @@ onMounted(() => { class="btn btn-light" @click="refreshKeys(authStore.currentUID)" > - <bootstrap-icon icon="arrow-clockwise" class="fs-5" /> + <font-awesome-icon + icon="fa-solid fa-arrow-rotate-right" + class="fs-5" + /> <span class="visually-hidden">Refresh S3 Keys</span> </button> <button type="button" class="btn btn-light" @click="createKey"> - <bootstrap-icon icon="plus-lg" class="fs-5" /> + <font-awesome-icon icon="fa-solid fa-plus" class="fs-5" /> <span class="visually-hidden">Create S3 Key</span> </button> </div> diff --git a/src/views/workflows/ListWorkflowsView.vue b/src/views/workflows/ListWorkflowsView.vue index 8ac24cd..f133a3b 100644 --- a/src/views/workflows/ListWorkflowsView.vue +++ b/src/views/workflows/ListWorkflowsView.vue @@ -6,7 +6,7 @@ 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 BootstrapIcon from "@/components/BootstrapIcon.vue"; +import FontAwesomeIcon from "@/components/FontAwesomeIcon.vue"; const workflowRepository = useWorkflowStore(); @@ -72,7 +72,7 @@ onMounted(() => { <div class="col-5 me-auto"> <div class="input-group"> <span class="input-group-text" id="workflows-search-wrapping" - ><bootstrap-icon icon="search" + ><font-awesome-icon icon="fa-solid fa-magnifying-glass" /></span> <input type="text" @@ -119,8 +119,12 @@ onMounted(() => { >Latest Release</label > </div> - <bootstrap-icon - :icon="workflowsState.sortDesc ? 'sort-down' : 'sort-up'" + <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" /> @@ -130,8 +134,8 @@ onMounted(() => { v-if="workflowRepository.workflows.length === 0" class="text-center fs-2 mt-5" > - <bootstrap-icon - icon="x-lg" + <font-awesome-icon + icon="fa-solid fa-x" class="my-5" width="75" height="75" @@ -143,8 +147,8 @@ onMounted(() => { v-else-if="processedWorkflows.length === 0" class="text-center fs-2 mt-5" > - <bootstrap-icon - icon="search" + <font-awesome-icon + icon="fa-solid fa-magnifying-glass" class="my-5" width="75" height="75" diff --git a/src/views/workflows/WorkflowView.vue b/src/views/workflows/WorkflowView.vue index bf1eaeb..8cd5816 100644 --- a/src/views/workflows/WorkflowView.vue +++ b/src/views/workflows/WorkflowView.vue @@ -4,7 +4,7 @@ import { computed, onMounted, reactive, watch } from "vue"; import type { WorkflowOut, WorkflowVersionReduced } from "@/client/workflow"; import { Status, WorkflowService } from "@/client/workflow"; import { useRoute, useRouter } from "vue-router"; -import BootstrapIcon from "@/components/BootstrapIcon.vue"; +import FontAwesomeIcon from "@/components/FontAwesomeIcon.vue"; import dayjs from "dayjs"; const props = defineProps<{ @@ -75,7 +75,7 @@ function updateWorkflow(workflowId: string) { WorkflowService.workflowGetWorkflow(workflowId) .then((workflow) => { workflowState.workflow = workflow; - if (!workflowState.initialOpen) { + if (!workflowState.initialOpen || route.params.versionId == null) { workflowState.activeVersionId = workflow.versions[workflow.versions.length - 1].git_commit_hash; } else { @@ -110,6 +110,20 @@ const versionLaunchable: ComputedRef<boolean> = computed( () => activeVersion.value?.status == Status.PUBLISHED ?? false ); +const gitIcon: ComputedRef<string> = computed(() => { + let gitProvider = "git"; + if (workflowState.workflow !== undefined) { + if (workflowState.workflow.repository_url.includes("github")) { + gitProvider = "github"; + } else if (workflowState.workflow.repository_url.includes("gitlab")) { + gitProvider = "gitlab"; + } else if (workflowState.workflow.repository_url.includes("bitbucket")) { + gitProvider = "bitbucket"; + } + } + return "fa-brands fa-".concat(gitProvider); +}); + onMounted(() => { updateWorkflow(props.workflowId); }); @@ -171,12 +185,15 @@ onMounted(() => { :class="{ disabled: !versionLaunchable }" href="#" > - <bootstrap-icon icon="rocket-takeoff-fill" class="me-2" /> + <font-awesome-icon icon="fa-solid fa-rocket" class="me-2" /> <span class="align-middle">Launch {{ activeVersionString }}</span> </a> - <div class="input-group w-fit position-absolute end-0"> + <div + v-if="latestVersion != null" + class="input-group w-fit position-absolute end-0" + > <span class="input-group-text px-2" id="workflow-version-wrapping" - ><bootstrap-icon icon="tags-fill" class="text-secondary" + ><font-awesome-icon icon="fa-solid fa-tags" class="text-secondary" /></span> <select class="form-select form-select-sm" @@ -200,7 +217,7 @@ onMounted(() => { target="_blank" class="text-secondary text-decoration-none mx-auto w-fit p-0" > - <bootstrap-icon icon="git" class="me-1" /> + <font-awesome-icon :icon="gitIcon" class="me-1" /> <span class="align-middle"> {{ workflowState.workflow.repository_url }}</span ></a @@ -209,8 +226,8 @@ onMounted(() => { </div> <router-view v-if="workflowState.loading || workflowState.workflow != null" /> <div v-else class="text-center fs-1 mt-5"> - <bootstrap-icon - icon="search" + <font-awesome-icon + icon="fa-solid fa-magnifying-glass" class="my-5" width="85" height="85" -- GitLab