storage page refactoring

This commit is contained in:
Čarodej
2021-11-23 15:53:18 +01:00
parent c5aadd3c6e
commit 946dfa7d99
17 changed files with 448 additions and 298 deletions

View File

@@ -0,0 +1,68 @@
<template>
<div class="label">
<span :class="['label-dot', color]"></span>
<b class="label-title">
{{ title }}
</b>
</div>
</template>
<script>
export default {
name: 'DotLabel',
props: [
'color',
'title',
],
}
</script>
<style lang="scss" scoped>
.label {
display: flex;
align-items: center;
.label-dot {
margin-right: 10px;
width: 8px;
height: 8px;
display: block;
border-radius: 8px;
flex: none;
&.success {
background: #0ABB87;
}
&.danger {
background: #fd397a;
}
&.warning {
background: #ffb822;
}
&.info {
background: #5578eb;
}
&.primary {
background: red;
}
&.purple {
background: #9d66fe;
}
&.secondary {
background: #e1e1ef;
}
}
.label-title {
font-size: 16px;
font-weight: 700;
}
}
</style>

View File

@@ -0,0 +1,117 @@
<template>
<div class="progress-wrapper">
<div class="chart">
<div v-for="(chart, i) in data" :key="i" :style="{width: chart.progress + '%'}" class="chart-wrapper">
<!--<DotLabel class="label" :class="{'offset-top': chart.progress < 5}" :color="chart.color" :title="chart.value" />-->
<span :class="['chart-progress', chart.color]"></span>
</div>
</div>
<footer>
<DotLabel v-for="(chart, i) in data" :key="i" :color="chart.color" :title="chart.title" />
</footer>
</div>
</template>
<script>
import DotLabel from "./DotLabel";
export default {
name: 'ProgressLine',
props: [
'data',
],
components: {
DotLabel
}
}
</script>
<style lang="scss" scoped>
.progress-wrapper {
.chart {
display: flex;
align-items: center;
margin-bottom: 14px;
.chart-wrapper {
.label {
justify-content: flex-end;
padding-right: 5px;
margin-bottom: 10px;
&.offset-top {
//@include transform(translateY(50px));
}
}
&:nth-child(1) {
.chart-progress {
border-bottom-left-radius: 8px;
border-top-left-radius: 8px;
border-right: 2px solid white;
}
}
.chart-progress {
border-right: 2px solid white;
}
&:nth-child(6) {
.chart-progress {
border-bottom-right-radius: 8px;
border-top-right-radius: 8px;
}
}
}
.chart-progress {
width: 100%;
height: 8px;
display: block;
&.success {
background: #0ABB87;
box-shadow: 0 3px 10px rgba(#0ABB87, 0.5);
}
&.danger {
background: #fd397a;
box-shadow: 0 3px 10px rgba(#fd397a, 0.5);
}
&.warning {
background: #ffb822;
box-shadow: 0 3px 10px rgba(#ffb822, 0.5);
}
&.info {
background: #5578eb;
box-shadow: 0 3px 10px rgba(#5578eb, 0.5);
}
&.purple {
background: #9d66fe;
box-shadow: 0 3px 10px rgba(#9d66fe, 0.5);
}
&.secondary {
background: #e1e1ef;
box-shadow: 0 3px 10px rgba(#e1e1ef, 0.5);
}
}
}
footer {
display: flex;
align-items: center;
.label {
margin-right: 22px;
}
}
}
</style>

View File

@@ -2,6 +2,7 @@
<div class="form-label">
<edit-2-icon v-if="!icon" size="22" class="icon text-theme dark-text-theme" />
<settings-icon v-if="icon === 'settings'" size="22" class="icon text-theme dark-text-theme" />
<hard-drive-icon v-if="icon === 'hard-drive'" size="22" class="icon text-theme dark-text-theme" />
<smartphone-icon v-if="icon === 'smartphone'" size="22" class="icon text-theme dark-text-theme" />
<key-icon v-if="icon === 'key'" size="22" class="icon text-theme dark-text-theme" />
<b class="label">
@@ -12,6 +13,7 @@
<script>
import {
HardDriveIcon,
KeyIcon,
Edit2Icon,
SettingsIcon,
@@ -25,6 +27,7 @@
KeyIcon,
Edit2Icon,
SettingsIcon,
HardDriveIcon,
SmartphoneIcon,
}
}

View File

@@ -1,203 +0,0 @@
<template>
<article class="detail-storage-item" :class="type">
<div class="header-storage-item">
<div class="icon">
<image-icon v-if="type == 'images'" size="23"></image-icon>
<video-icon v-if="type == 'videos'" size="23"></video-icon>
<music-icon v-if="type == 'audios'" size="23"></music-icon>
<file-text-icon v-if="type == 'documents'" size="23"></file-text-icon>
<file-icon v-if="type == 'others'" size="23"></file-icon>
<hard-drive-icon v-if="type == 'disk'" size="23"></hard-drive-icon>
</div>
<div class="title">
<b class="type">{{ title }}</b>
<span class="total-size">{{ used }}</span>
</div>
</div>
<ProgressBar class="storage-progress" :progress="percentage" />
</article>
</template>
<script>
import ProgressBar from '/resources/js/components/FilesView/ProgressBar'
import { ImageIcon, VideoIcon, FileTextIcon, FileIcon, HardDriveIcon, MusicIcon } from 'vue-feather-icons'
export default {
name: 'StorageItemDetail',
props: ['percentage', 'title', 'type', 'used'],
components: {
HardDriveIcon,
FileTextIcon,
ProgressBar,
MusicIcon,
VideoIcon,
ImageIcon,
FileIcon,
},
}
</script>
<style lang="scss" scoped>
@import '/resources/sass/vuefilemanager/_variables';
@import '/resources/sass/vuefilemanager/_mixins';
.detail-storage-item {
margin-bottom: 35px;
&.disk {
.icon {
path, line, polyline, rect, circle, polygon {
stroke: $text;
}
}
.storage-progress {
/deep/ span {
background: $text;
}
}
}
&.images {
.icon {
path, line, polyline, rect, circle, polygon {
stroke: $purple;
}
}
.storage-progress {
/deep/ span {
background: $purple;
}
}
}
&.videos {
.icon {
path, line, polyline, rect, circle, polygon {
stroke: $yellow;
}
}
.storage-progress {
/deep/ span {
background: $yellow;
}
}
}
&.audios {
.icon {
path, line, polyline, rect, circle, polygon {
stroke: $pink;
}
}
.storage-progress {
/deep/ span {
background: $pink;
}
}
}
&.documents {
.icon {
path, line, polyline, rect, circle, polygon {
stroke: $red;
}
}
.storage-progress {
/deep/ span {
background: $red;
}
}
}
&.others {
.icon {
path, line, polyline, rect, circle, polygon {
stroke: $text;
}
}
.storage-progress {
/deep/ span {
background: $text;
}
}
}
}
.header-storage-item {
display: flex;
align-items: flex-start;
margin-bottom: 10px;
.icon {
width: 35px;
}
.type {
@include font-size(15);
color: $text;
}
.total-size {
@include font-size(10);
display: block;
color: $text-muted;
}
}
.dark {
.header-storage-item {
.type {
color: $dark_mode_text_primary;
}
.total-size {
color: $dark_mode_text_secondary;
}
}
.detail-storage-item {
&.others, &.disk {
.icon {
path, line, polyline, rect, circle, polygon {
stroke: lighten($dark_mode_foreground, 15%);
}
}
.storage-progress {
/deep/ span {
background: lighten($dark_mode_foreground, 15%);
}
}
}
}
}
</style>

View File

@@ -1,6 +1,6 @@
import i18n from '/resources/js/i18n/index'
import store from '../store/index'
import {debounce, isArray} from "lodash";
import {debounce, isArray, orderBy} from "lodash";
import {events} from '../bus'
import axios from 'axios'
@@ -69,6 +69,55 @@ const FunctionHelpers = {
})
}
Vue.prototype.$mapStorageUsage = function (storage) {
let distribution = [
{
progress: storage.data.meta.images.percentage,
color: 'success',
value: storage.data.meta.images.used,
title: 'Images'
},
{
progress: storage.data.meta.videos.percentage,
color: 'danger',
value: storage.data.meta.videos.used,
title: 'Videos'
},
{
progress: storage.data.meta.audios.percentage,
color: 'warning',
value: storage.data.meta.audios.used,
title: 'Audios'
},
{
progress: storage.data.meta.documents.percentage,
color: 'info',
value: storage.data.meta.documents.used,
title: 'Documents'
},
{
progress: storage.data.meta.others.percentage,
color: 'purple',
value: storage.data.meta.others.used,
title: 'Others'
},
]
// Order distribution by it's size
distribution = orderBy(distribution, ['progress'], ['desc'])
// Push at the end empty space data
distribution.push({
progress: 100 - storage.data.attributes.percentage,
color: 'secondary',
value: storage.data.meta.others.used,
title: 'Empty'
})
return distribution
}
Vue.prototype.$getImage = function (source) {
return source ? this.$store.getters.config.host + '/' + source : ''
}

View File

@@ -49,7 +49,6 @@
import AppInputSwitch from "../../../../components/Admin/AppInputSwitch";
import AppInputText from "../../../../components/Admin/AppInputText";
import {ValidationProvider, ValidationObserver} from 'vee-validate/dist/vee-validate.full'
import StorageItemDetail from '/resources/js/components/Others/StorageItemDetail'
import PageTabGroup from '/resources/js/components/Others/Layout/PageTabGroup'
import SelectInput from '/resources/js/components/Others/Forms/SelectInput'
import ImageInput from '/resources/js/components/Others/Forms/ImageInput'
@@ -68,7 +67,6 @@
AppInputText,
ValidationObserver,
ValidationProvider,
StorageItemDetail,
PageTabGroup,
SelectInput,
ImageInput,

View File

@@ -50,7 +50,6 @@
<script>
import AppInputText from "../../../../components/Admin/AppInputText";
import {ValidationProvider, ValidationObserver} from 'vee-validate/dist/vee-validate.full'
import StorageItemDetail from '/resources/js/components/Others/StorageItemDetail'
import PageTabGroup from '/resources/js/components/Others/Layout/PageTabGroup'
import SelectInput from '/resources/js/components/Others/Forms/SelectInput'
import ImageInput from '/resources/js/components/Others/Forms/ImageInput'
@@ -68,7 +67,6 @@
components: {
ValidationObserver,
ValidationProvider,
StorageItemDetail,
AppInputText,
PageTabGroup,
SelectInput,

View File

@@ -45,7 +45,6 @@
<script>
import AppInputText from "../../../../components/Admin/AppInputText";
import {ValidationProvider, ValidationObserver} from 'vee-validate/dist/vee-validate.full'
import StorageItemDetail from '/resources/js/components/Others/StorageItemDetail'
import PageTabGroup from '/resources/js/components/Others/Layout/PageTabGroup'
import SelectInput from '/resources/js/components/Others/Forms/SelectInput'
import ImageInput from '/resources/js/components/Others/Forms/ImageInput'
@@ -64,7 +63,6 @@
AppInputText,
ValidationObserver,
ValidationProvider,
StorageItemDetail,
PageTabGroup,
SelectInput,
ImageInput,

View File

@@ -246,7 +246,6 @@
import AppInputSwitch from "../../../../components/Admin/AppInputSwitch";
import AppInputText from "../../../../components/Admin/AppInputText";
import { ValidationProvider, ValidationObserver } from 'vee-validate/dist/vee-validate.full'
import StorageItemDetail from '/resources/js/components/Others/StorageItemDetail'
import PageTabGroup from '/resources/js/components/Others/Layout/PageTabGroup'
import SelectInput from '/resources/js/components/Others/Forms/SelectInput'
import SwitchInput from '/resources/js/components/Others/Forms/SwitchInput'
@@ -267,7 +266,6 @@ export default {
AppInputText,
ValidationObserver,
ValidationProvider,
StorageItemDetail,
PageTabGroup,
SwitchInput,
SelectInput,

View File

@@ -82,7 +82,6 @@
import AppInputSwitch from "../../../../components/Admin/AppInputSwitch";
import AppInputText from "../../../../components/Admin/AppInputText";
import {ValidationProvider, ValidationObserver} from 'vee-validate/dist/vee-validate.full'
import StorageItemDetail from '/resources/js/components/Others/StorageItemDetail'
import PageTabGroup from '/resources/js/components/Others/Layout/PageTabGroup'
import SelectInput from '/resources/js/components/Others/Forms/SelectInput'
import SwitchInput from '/resources/js/components/Others/Forms/SwitchInput'
@@ -103,7 +102,6 @@
AppInputText,
ValidationObserver,
ValidationProvider,
StorageItemDetail,
PageTabGroup,
SwitchInput,
SelectInput,

View File

@@ -71,7 +71,6 @@
<script>
import AppInputText from "../../../../components/Admin/AppInputText";
import {ValidationProvider, ValidationObserver} from 'vee-validate/dist/vee-validate.full'
import StorageItemDetail from '/resources/js/components/Others/StorageItemDetail'
import PageTabGroup from '/resources/js/components/Others/Layout/PageTabGroup'
import SelectInput from '/resources/js/components/Others/Forms/SelectInput'
import SwitchInput from '/resources/js/components/Others/Forms/SwitchInput'
@@ -94,7 +93,6 @@
AppInputText,
ValidationObserver,
ValidationProvider,
StorageItemDetail,
PageTabGroup,
SwitchInput,
SelectInput,

View File

@@ -59,7 +59,6 @@
<script>
import {ValidationProvider, ValidationObserver} from 'vee-validate/dist/vee-validate.full'
import StorageItemDetail from '/resources/js/components/Others/StorageItemDetail'
import PageTabGroup from '/resources/js/components/Others/Layout/PageTabGroup'
import SwitchInput from '/resources/js/components/Others/Forms/SwitchInput'
import SelectInput from '/resources/js/components/Others/Forms/SelectInput'
@@ -78,7 +77,6 @@
components: {
ValidationProvider,
ValidationObserver,
StorageItemDetail,
PageTabGroup,
SwitchInput,
SelectInput,

View File

@@ -34,7 +34,6 @@
<script>
import CardNavigation from "../../../components/Admin/CardNavigation";
import {UserIcon, HardDriveIcon, LockIcon, Trash2Icon, FileTextIcon, CreditCardIcon} from 'vue-feather-icons'
import StorageItemDetail from '/resources/js/components/Others/StorageItemDetail'
import MobileHeader from '/resources/js/components/Mobile/MobileHeader'
import SectionTitle from '/resources/js/components/Others/SectionTitle'
import PageHeader from '/resources/js/components/Others/PageHeader'
@@ -46,7 +45,6 @@
export default {
name: 'Profile',
components: {
StorageItemDetail,
CardNavigation,
CreditCardIcon,
HardDriveIcon,

View File

@@ -105,7 +105,6 @@
import PageTabGroup from '/resources/js/components/Others/Layout/PageTabGroup'
import PageTab from '/resources/js/components/Others/Layout/PageTab'
import {ValidationProvider, ValidationObserver} from 'vee-validate/dist/vee-validate.full'
import StorageItemDetail from '/resources/js/components/Others/StorageItemDetail'
import SelectInput from '/resources/js/components/Others/Forms/SelectInput'
import FormLabel from '/resources/js/components/Others/Forms/FormLabel'
import ButtonBase from '/resources/js/components/FilesView/ButtonBase'
@@ -128,7 +127,6 @@
FormLabel,
ValidationProvider,
ValidationObserver,
StorageItemDetail,
SelectInput,
ButtonBase,
SetupBox,

View File

@@ -1,6 +1,19 @@
<template>
<PageTab :is-loading="isLoading" v-if="storage">
<div class="card shadow-card">
<FormLabel icon="hard-drive">
{{ $t('Storage Usage') }}
</FormLabel>
<div v-if="distribution">
<b class="mb-3 block text-sm text-gray-400">
{{ $t('Total') }} {{ storage.data.attributes.used }} {{ $t('of') }} {{ storage.data.attributes.capacity }} {{ $t('Used') }}
</b>
<ProgressLine :data="distribution" />
</div>
</div>
<div v-if="config.storageLimit && ! user.data.attributes.subscription" class="card shadow-card">
<FormLabel>
{{ $t('user_box_storage.title') }}
@@ -28,32 +41,17 @@
</ValidationProvider>
</ValidationObserver>
</div>
<PageTabGroup>
<FormLabel>{{ $t('storage.sec_details') }}</FormLabel>
<StorageItemDetail
type="disk"
:title="$t('storage.total_used', {used: storage.attributes.used})"
:percentage="storage.attributes.percentage"
:used="$t('storage.total_capacity', {capacity: storage.attributes.capacity})"
/>
<StorageItemDetail type="images" :title="$t('storage.images')" :percentage="storage.meta.images.percentage" :used="storage.meta.images.used" />
<StorageItemDetail type="videos" :title="$t('storage.videos')" :percentage="storage.meta.videos.percentage" :used="storage.meta.videos.used" />
<StorageItemDetail type="audios" :title="$t('storage.audios')" :percentage="storage.meta.audios.percentage" :used="storage.meta.audios.used" />
<StorageItemDetail type="documents" :title="$t('storage.documents')" :percentage="storage.meta.documents.percentage" :used="storage.meta.documents.used" />
<StorageItemDetail type="others" :title="$t('storage.others')" :percentage="storage.meta.others.percentage" :used="storage.meta.others.used" />
</PageTabGroup>
</PageTab>
</template>
<script>
import ProgressLine from "../../../../components/Admin/ProgressLine";
import AppInputText from "../../../../components/Admin/AppInputText";
import FormLabel from '/resources/js/components/Others/Forms/FormLabel'
import InfoBox from '/resources/js/components/Others/Forms/InfoBox'
import PageTabGroup from '/resources/js/components/Others/Layout/PageTabGroup'
import PageTab from '/resources/js/components/Others/Layout/PageTab'
import {ValidationProvider, ValidationObserver} from 'vee-validate/dist/vee-validate.full'
import StorageItemDetail from '/resources/js/components/Others/StorageItemDetail'
import ButtonBase from '/resources/js/components/FilesView/ButtonBase'
import SetupBox from '/resources/js/components/Others/Forms/SetupBox'
import {required} from 'vee-validate/dist/rules'
@@ -67,6 +65,7 @@
'user'
],
components: {
ProgressLine,
AppInputText,
PageTabGroup,
FormLabel,
@@ -74,7 +73,6 @@
InfoBox,
ValidationProvider,
ValidationObserver,
StorageItemDetail,
ButtonBase,
SetupBox,
required,
@@ -88,6 +86,7 @@
isSendingRequest: false,
capacity: undefined,
storage: undefined,
distribution: undefined,
}
},
methods: {
@@ -147,7 +146,10 @@
getStorageDetails() {
axios.get('/api/admin/users/' + this.$route.params.id + '/storage')
.then(response => {
this.storage = response.data.data
this.distribution = this.$mapStorageUsage(response.data)
this.storage = response.data
this.isLoading = false
})
}

View File

@@ -1,53 +1,49 @@
<template>
<PageTab v-if="storage">
<PageTabGroup>
<FormLabel>{{ $t('storage.sec_capacity') }}</FormLabel>
<StorageItemDetail type="disk" :title="$t('storage.total_used', {used: storage.attributes.used})" :percentage="storage.attributes.percentage" :used="$t('storage.total_capacity', {capacity: storage.attributes.capacity})"/>
</PageTabGroup>
<PageTabGroup>
<FormLabel>{{ $t('storage.sec_details') }}</FormLabel>
<StorageItemDetail type="images" :title="$t('storage.images')" :percentage="storage.meta.images.percentage" :used="storage.meta.images.used" />
<StorageItemDetail type="videos" :title="$t('storage.videos')" :percentage="storage.meta.videos.percentage" :used="storage.meta.videos.used" />
<StorageItemDetail type="audios" :title="$t('storage.audios')" :percentage="storage.meta.audios.percentage" :used="storage.meta.audios.used" />
<StorageItemDetail type="documents" :title="$t('storage.documents')" :percentage="storage.meta.documents.percentage" :used="storage.meta.documents.used" />
<StorageItemDetail type="others" :title="$t('storage.others')" :percentage="storage.meta.others.percentage" :used="storage.meta.others.used" />
</PageTabGroup>
<PageTab>
<div class="card shadow-card">
<FormLabel icon="hard-drive">
{{ $t('Storage Usage') }}
</FormLabel>
<div v-if="distribution">
<b class="mb-3 block text-sm text-gray-400">
{{ $t('Total') }} {{ storage.data.attributes.used }} {{ $t('of') }} {{ storage.data.attributes.capacity }} {{ $t('Used') }}
</b>
<ProgressLine :data="distribution" />
</div>
</div>
</PageTab>
</template>
<script>
import ProgressLine from "../../components/Admin/ProgressLine";
import FormLabel from '/resources/js/components/Others/Forms/FormLabel'
import PageTabGroup from '/resources/js/components/Others/Layout/PageTabGroup'
import PageTab from '/resources/js/components/Others/Layout/PageTab'
import StorageItemDetail from '/resources/js/components/Others/StorageItemDetail'
import MobileHeader from '/resources/js/components/Mobile/MobileHeader'
import SectionTitle from '/resources/js/components/Others/SectionTitle'
import PageHeader from '/resources/js/components/Others/PageHeader'
import Spinner from '/resources/js/components/FilesView/Spinner'
import axios from 'axios'
export default {
name: 'Storage',
components: {
PageTabGroup,
ProgressLine,
FormLabel,
PageTab,
StorageItemDetail,
SectionTitle,
MobileHeader,
PageHeader,
Spinner,
},
data() {
return {
isLoading: true,
storage: undefined,
distribution: undefined,
storage: undefined
}
},
created() {
axios.get('/api/user/storage')
.then(response => {
this.storage = response.data.data
this.distribution = this.$mapStorageUsage(response.data)
this.storage = response.data
this.isLoading = false
})
}