diff options
-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> |