diff options
author | Ferdinand Thiessen <opensource@fthiessen.de> | 2025-01-14 17:55:10 +0100 |
---|---|---|
committer | Ferdinand Thiessen <opensource@fthiessen.de> | 2025-01-14 21:51:39 +0100 |
commit | bbde7681520ded0dee0b999d69e5b50789a7ac15 (patch) | |
tree | f9354c96781b72f42e55b3d63f40b15b6d5d81e5 /apps/dashboard/src | |
parent | 91f568e01b1b91e08874a087ba2e17a9312f11ef (diff) | |
download | nextcloud-server-bbde7681520ded0dee0b999d69e5b50789a7ac15.tar.gz nextcloud-server-bbde7681520ded0dee0b999d69e5b50789a7ac15.zip |
fix(dashboard): Correctly handle non-rounded icons for dashboard widgets
Signed-off-by: Ferdinand Thiessen <opensource@fthiessen.de>
Diffstat (limited to 'apps/dashboard/src')
-rw-r--r-- | apps/dashboard/src/DashboardApp.vue | 4 | ||||
-rw-r--r-- | apps/dashboard/src/components/ApiDashboardWidget.vue | 29 | ||||
-rw-r--r-- | apps/dashboard/src/components/ApiDashboardWidgetItem.vue | 68 |
3 files changed, 84 insertions, 17 deletions
diff --git a/apps/dashboard/src/DashboardApp.vue b/apps/dashboard/src/DashboardApp.vue index 864571842cc..055f1e68cb6 100644 --- a/apps/dashboard/src/DashboardApp.vue +++ b/apps/dashboard/src/DashboardApp.vue @@ -461,8 +461,8 @@ export default { } }, async fetchApiWidgets() { - const response = await axios.get(generateOcsUrl('/apps/dashboard/api/v1/widgets')) - this.apiWidgets = response.data.ocs.data + const { data } = await axios.get(generateOcsUrl('/apps/dashboard/api/v1/widgets')) + this.apiWidgets = data.ocs.data }, async fetchApiWidgetItems(widgetIds, merge = false) { try { diff --git a/apps/dashboard/src/components/ApiDashboardWidget.vue b/apps/dashboard/src/components/ApiDashboardWidget.vue index e82b977b041..22834abadd5 100644 --- a/apps/dashboard/src/components/ApiDashboardWidget.vue +++ b/apps/dashboard/src/components/ApiDashboardWidget.vue @@ -10,16 +10,7 @@ :show-items-and-empty-content="!!halfEmptyContentMessage" :half-empty-content-message="halfEmptyContentMessage"> <template #default="{ item }"> - <NcDashboardWidgetItem :target-url="item.link" - :overlay-icon-url="item.overlayIconUrl ? item.overlayIconUrl : ''" - :main-text="item.title" - :sub-text="item.subtitle"> - <template #avatar> - <template v-if="item.iconUrl"> - <NcAvatar :size="44" :url="item.iconUrl" /> - </template> - </template> - </NcDashboardWidgetItem> + <ApiDashboardWidgetItem :item="item" :icon-size="iconSize" :rounded-icons="widget.item_icons_round" /> </template> <template #empty-content> <NcEmptyContent v-if="items.length === 0" @@ -39,23 +30,21 @@ <script> import { - NcAvatar, NcDashboardWidget, - NcDashboardWidgetItem, NcEmptyContent, NcButton, } from '@nextcloud/vue' import CheckIcon from 'vue-material-design-icons/Check.vue' +import ApiDashboardWidgetItem from './ApiDashboardWidgetItem.vue' export default { name: 'ApiDashboardWidget', components: { - NcAvatar, + ApiDashboardWidgetItem, + CheckIcon, NcDashboardWidget, - NcDashboardWidgetItem, NcEmptyContent, NcButton, - CheckIcon, }, props: { widget: { @@ -71,6 +60,11 @@ export default { required: true, }, }, + data() { + return { + iconSize: 44, + } + }, computed: { /** @return {object[]} */ items() { @@ -115,5 +109,10 @@ export default { return this.moreButton?.link }, }, + mounted() { + const size = window.getComputedStyle(document.body).getPropertyValue('--default-clickable-area') + const numeric = Number.parseFloat(size) + this.iconSize = Number.isNaN(numeric) ? 44 : numeric + }, } </script> diff --git a/apps/dashboard/src/components/ApiDashboardWidgetItem.vue b/apps/dashboard/src/components/ApiDashboardWidgetItem.vue new file mode 100644 index 00000000000..e38f745f82a --- /dev/null +++ b/apps/dashboard/src/components/ApiDashboardWidgetItem.vue @@ -0,0 +1,68 @@ +<!-- + - SPDX-FileCopyrightText: 2025 Nextcloud GmbH and Nextcloud contributors + - SPDX-License-Identifier: AGPL-3.0-or-later + --> +<script setup lang="ts"> +import { ref } from 'vue' +import NcAvatar from '@nextcloud/vue/dist/Components/NcAvatar.js' +import NcDashboardWidgetItem from '@nextcloud/vue/dist/Components/NcDashboardWidgetItem.js' +import IconFile from 'vue-material-design-icons/File.vue' + +defineProps({ + item: { + type: Object, + required: true, + }, + iconSize: { + type: Number, + required: true, + }, + roundedIcons: { + type: Boolean, + default: true, + }, +}) + +/** + * True as soon as the image is loaded + */ +const imageLoaded = ref(false) +/** + * True if the image failed to load and we should show a fallback + */ +const loadingImageFailed = ref(false) +</script> + +<template> + <NcDashboardWidgetItem :target-url="item.link" + :overlay-icon-url="item.overlayIconUrl ? item.overlayIconUrl : ''" + :main-text="item.title" + :sub-text="item.subtitle"> + <template #avatar> + <template v-if="item.iconUrl"> + <NcAvatar v-if="roundedIcons" + :size="iconSize" + :url="item.iconUrl" /> + <template v-else> + <img v-show="!loadingImageFailed" + alt="" + class="api-dashboard-widget-item__icon" + :class="{'hidden-visually': !imageLoaded }" + :src="item.iconUrl" + @error="loadingImageFailed = true" + @load="imageLoaded = true"> + <!-- Placeholder while the image is loaded and also the fallback if the URL is broken --> + <IconFile v-if="!imageLoaded" + :size="iconSize" /> + </template> + </template> + </template> + </NcDashboardWidgetItem> +</template> + +<style scoped> +.api-dashboard-widget-item__icon { + height: var(--default-clickable-area); + width: var(--default-clickable-area); +} +</style> |