123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153 |
- <template>
- <NcAppNavigationItem v-if="storageStats"
- :aria-label="t('files', 'Storage informations')"
- :class="{ 'app-navigation-entry__settings-quota--not-unlimited': storageStats.quota >= 0}"
- :loading="loadingStorageStats"
- :name="storageStatsTitle"
- :title="storageStatsTooltip"
- class="app-navigation-entry__settings-quota"
- data-cy-files-navigation-settings-quota
- @click.stop.prevent="debounceUpdateStorageStats">
- <ChartPie slot="icon" :size="20" />
-
- <!-- Progress bar -->
- <NcProgressBar v-if="storageStats.quota >= 0"
- slot="extra"
- :error="storageStats.relative > 80"
- :value="Math.min(storageStats.relative, 100)" />
- </NcAppNavigationItem>
- </template>
-
- <script>
- import { formatFileSize } from '@nextcloud/files'
- import { generateUrl } from '@nextcloud/router'
- import { loadState } from '@nextcloud/initial-state'
- import { showError } from '@nextcloud/dialogs'
- import { debounce, throttle } from 'throttle-debounce'
- import { translate } from '@nextcloud/l10n'
- import axios from '@nextcloud/axios'
- import ChartPie from 'vue-material-design-icons/ChartPie.vue'
- import NcAppNavigationItem from '@nextcloud/vue/dist/Components/NcAppNavigationItem.js'
- import NcProgressBar from '@nextcloud/vue/dist/Components/NcProgressBar.js'
-
- import logger from '../logger.js'
- import { subscribe } from '@nextcloud/event-bus'
-
- export default {
- name: 'NavigationQuota',
-
- components: {
- ChartPie,
- NcAppNavigationItem,
- NcProgressBar,
- },
-
- data() {
- return {
- loadingStorageStats: false,
- storageStats: loadState('files', 'storageStats', null),
- }
- },
-
- computed: {
- storageStatsTitle() {
- const usedQuotaByte = formatFileSize(this.storageStats?.used)
- const quotaByte = formatFileSize(this.storageStats?.quota)
-
- // If no quota set
- if (this.storageStats?.quota < 0) {
- return this.t('files', '{usedQuotaByte} used', { usedQuotaByte })
- }
-
- return this.t('files', '{used} of {quota} used', {
- used: usedQuotaByte,
- quota: quotaByte,
- })
- },
- storageStatsTooltip() {
- if (!this.storageStats.relative) {
- return ''
- }
-
- return this.t('files', '{relative}% used', this.storageStats)
- },
- },
-
- beforeMount() {
- /**
- * Update storage stats every minute
- * TODO: remove when all views are migrated to Vue
- */
- setInterval(this.throttleUpdateStorageStats, 60 * 1000)
-
- subscribe('files:file:created', this.throttleUpdateStorageStats)
- subscribe('files:file:deleted', this.throttleUpdateStorageStats)
- subscribe('files:file:moved', this.throttleUpdateStorageStats)
- subscribe('files:file:updated', this.throttleUpdateStorageStats)
-
- subscribe('files:folder:created', this.throttleUpdateStorageStats)
- subscribe('files:folder:deleted', this.throttleUpdateStorageStats)
- subscribe('files:folder:moved', this.throttleUpdateStorageStats)
- subscribe('files:folder:updated', this.throttleUpdateStorageStats)
- },
-
- methods: {
- // From user input
- debounceUpdateStorageStats: debounce(200, function(event) {
- this.updateStorageStats(event)
- }),
- // From interval or event bus
- throttleUpdateStorageStats: throttle(1000, function(event) {
- this.updateStorageStats(event)
- }),
-
- /**
- * Update the storage stats
- * Throttled at max 1 refresh per minute
- *
- * @param {Event} [event = null] if user interaction
- */
- async updateStorageStats(event = null) {
- if (this.loadingStorageStats) {
- return
- }
-
- this.loadingStorageStats = true
- try {
- const response = await axios.get(generateUrl('/apps/files/api/v1/stats'))
- if (!response?.data?.data) {
- throw new Error('Invalid storage stats')
- }
- this.storageStats = response.data.data
- } catch (error) {
- logger.error('Could not refresh storage stats', { error })
- // Only show to the user if it was manually triggered
- if (event) {
- showError(t('files', 'Could not refresh storage stats'))
- }
- } finally {
- this.loadingStorageStats = false
- }
- },
-
- t: translate,
- },
- }
- </script>
-
- <style lang="scss" scoped>
- // User storage stats display
- .app-navigation-entry__settings-quota {
- // Align title with progress and icon
- &--not-unlimited::v-deep .app-navigation-entry__title {
- margin-top: -4px;
- }
-
- progress {
- position: absolute;
- bottom: 10px;
- margin-left: 44px;
- width: calc(100% - 44px - 22px);
- }
- }
- </style>
|