get data from dataabse and upload/download storage chart

This commit is contained in:
Čarodej
2021-11-30 17:32:25 +01:00
parent 751ebcb7eb
commit c7c81dda34
8 changed files with 238 additions and 64 deletions
+20 -3
View File
@@ -72,7 +72,7 @@
"/chunks/settings-invoices.js": "/chunks/settings-invoices.js?id=aa32489d4652f18b4a8c",
"/chunks/settings-password.js": "/chunks/settings-password.js?id=fc95bc9d31d3e9ee0442",
"/chunks/settings-payment-methods.js": "/chunks/settings-payment-methods.js?id=3a88e55341d1f1ffe12d",
"/chunks/settings-storage.js": "/chunks/settings-storage.js?id=07ab72ae0c586211689e",
"/chunks/settings-storage.js": "/chunks/settings-storage.js?id=4432e911b1e7a7415d4d",
"/chunks/settings-storage~chunks/settings-subscription~chunks/user-storage~chunks/user-subscription.js": "/chunks/settings-storage~chunks/settings-subscription~chunks/user-storage~chunks/user-subscription.js?id=147afaac8c8bacfe6433",
"/chunks/settings-subscription.js": "/chunks/settings-subscription.js?id=cd4f59468aaaca384307",
"/chunks/settings~chunks/settings-password.js": "/chunks/settings~chunks/settings-password.js?id=c33cd2341b9b04a732e5",
@@ -101,7 +101,7 @@
"/chunks/user-detail.js": "/chunks/user-detail.js?id=a55ae1a545a65b92511d",
"/chunks/user-invoices.js": "/chunks/user-invoices.js?id=0f755c7e07ffb441ac72",
"/chunks/user-password.js": "/chunks/user-password.js?id=ce6c12a5b038f5481bd1",
"/chunks/user-storage.js": "/chunks/user-storage.js?id=71b90f0987d1ebe7ead6",
"/chunks/user-storage.js": "/chunks/user-storage.js?id=a915de897147d9efde5b",
"/chunks/user-subscription.js": "/chunks/user-subscription.js?id=82038ce92ca5e1c9ae05",
"/chunks/users.js": "/chunks/users.js?id=308dfaebb01c05f5bed5",
"/vendors~chunks/admin~chunks/admin-account~chunks/app-appearance~chunks/app-billings~chunks/app-email~35bc7519.js": "/vendors~chunks/admin~chunks/admin-account~chunks/app-appearance~chunks/app-billings~chunks/app-email~35bc7519.js?id=ae06aafc3749254fe4aa",
@@ -233,5 +233,22 @@
"/chunks/settings-storage.bc9b0469009df5b5eab3.hot-update.js": "/chunks/settings-storage.bc9b0469009df5b5eab3.hot-update.js",
"/chunks/settings-storage~chunks/settings-subscription~chunks/user-storage~chunks/user-subscription.27b9a61682a249f71c20.hot-update.js": "/chunks/settings-storage~chunks/settings-subscription~chunks/user-storage~chunks/user-subscription.27b9a61682a249f71c20.hot-update.js",
"/chunks/settings-storage.98ffc3f928190cda8a1b.hot-update.js": "/chunks/settings-storage.98ffc3f928190cda8a1b.hot-update.js",
"/chunks/settings-storage.f8bb07f42ef648dd2548.hot-update.js": "/chunks/settings-storage.f8bb07f42ef648dd2548.hot-update.js"
"/chunks/settings-storage.f8bb07f42ef648dd2548.hot-update.js": "/chunks/settings-storage.f8bb07f42ef648dd2548.hot-update.js",
"/chunks/settings-storage.32824a8cada155a6105c.hot-update.js": "/chunks/settings-storage.32824a8cada155a6105c.hot-update.js",
"/chunks/settings-storage.19bb2501c7894e79a6a8.hot-update.js": "/chunks/settings-storage.19bb2501c7894e79a6a8.hot-update.js",
"/chunks/settings-storage.d3f0fe090dd9dc6c9047.hot-update.js": "/chunks/settings-storage.d3f0fe090dd9dc6c9047.hot-update.js",
"/chunks/settings-storage.24d62fa0465b60223e16.hot-update.js": "/chunks/settings-storage.24d62fa0465b60223e16.hot-update.js",
"/chunks/settings-storage.9cf196722f61b21d77e7.hot-update.js": "/chunks/settings-storage.9cf196722f61b21d77e7.hot-update.js",
"/chunks/settings-storage.d08746a159b5b6f24cf5.hot-update.js": "/chunks/settings-storage.d08746a159b5b6f24cf5.hot-update.js",
"/chunks/settings-storage.4c0de25c1c85381273a5.hot-update.js": "/chunks/settings-storage.4c0de25c1c85381273a5.hot-update.js",
"/chunks/settings-storage.5fa08ebf41010316d980.hot-update.js": "/chunks/settings-storage.5fa08ebf41010316d980.hot-update.js",
"/chunks/settings-storage.ad7ce7a580641c99b976.hot-update.js": "/chunks/settings-storage.ad7ce7a580641c99b976.hot-update.js",
"/chunks/settings-storage.24fd0c789730322e24dc.hot-update.js": "/chunks/settings-storage.24fd0c789730322e24dc.hot-update.js",
"/chunks/settings-storage.1ddabb2c5f0f70bc686e.hot-update.js": "/chunks/settings-storage.1ddabb2c5f0f70bc686e.hot-update.js",
"/chunks/settings-storage.6d7197b3b9a6a18be52e.hot-update.js": "/chunks/settings-storage.6d7197b3b9a6a18be52e.hot-update.js",
"/chunks/user-storage.c956ecfce06968b48ec0.hot-update.js": "/chunks/user-storage.c956ecfce06968b48ec0.hot-update.js",
"/chunks/user-storage.0e8d7663b9f8cd40de17.hot-update.js": "/chunks/user-storage.0e8d7663b9f8cd40de17.hot-update.js",
"/chunks/user-storage.4eff070ff2a92236c8b2.hot-update.js": "/chunks/user-storage.4eff070ff2a92236c8b2.hot-update.js",
"/chunks/settings-storage.4ecc7c38e789439da637.hot-update.js": "/chunks/settings-storage.4ecc7c38e789439da637.hot-update.js",
"/chunks/user-storage.4ecc7c38e789439da637.hot-update.js": "/chunks/user-storage.4ecc7c38e789439da637.hot-update.js"
}
@@ -1,17 +1,50 @@
<template>
<PageTab :is-loading="isLoading" v-if="storage">
<div class="card shadow-card">
<div v-if="distribution" 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>
<b class="text-3xl font-extrabold -mt-3 block mb-0.5">
{{ storage.data.attributes.used }}
</b>
<b class="mb-3 block text-sm text-gray-400 mb-5">
{{ $t('Total of') }} {{ storage.data.attributes.capacity }} {{ $t('Used') }}
</b>
<ProgressLine :data="distribution" />
</div>
<div v-if="distribution" class="card shadow-card">
<FormLabel icon="hard-drive">
{{ $t('Upload') }}
</FormLabel>
<b class="text-3xl font-extrabold -mt-3 block mb-0.5">
{{ storage.data.meta.traffic.upload }}
</b>
<b class="mb-3 block text-sm text-gray-400 mb-5">
{{ $t('In last 45 days') }}
</b>
<BarChart :data="storage.data.meta.traffic.chart.upload" color="#FFBD2D" />
</div>
<div v-if="distribution" class="card shadow-card">
<FormLabel icon="hard-drive">
{{ $t('Download') }}
</FormLabel>
<b class="text-3xl font-extrabold -mt-3 block mb-0.5">
{{ storage.data.meta.traffic.download }}
</b>
<b class="mb-3 block text-sm text-gray-400 mb-5">
{{ $t('In last 45 days') }}
</b>
<BarChart :data="storage.data.meta.traffic.chart.download" color="#9d66fe" />
</div>
<div v-if="config.storageLimit && ! user.data.attributes.subscription" class="card shadow-card">
@@ -55,9 +88,10 @@
import ButtonBase from '/resources/js/components/FilesView/ButtonBase'
import SetupBox from '/resources/js/components/Others/Forms/SetupBox'
import {required} from 'vee-validate/dist/rules'
import BarChart from "../../../User/BarChart"
import {events} from '/resources/js/bus'
import {mapGetters} from "vuex"
import axios from 'axios'
import {mapGetters} from "vuex";
export default {
name: 'UserStorage',
@@ -76,6 +110,7 @@
ButtonBase,
SetupBox,
required,
BarChart,
},
computed: {
...mapGetters(['config']),
+19
View File
@@ -0,0 +1,19 @@
<template>
<div class="flex items-end justify-between h-28">
<span
class="w-2.5 block rounded-lg lg:mr-2 mr-1.5"
:style="{height: height + '%', backgroundColor: color}"
v-for="(height, i) in data"
:key="i">
</span>
</div>
</template>
<script>
export default {
name: 'BarChart',
props: {
data: {},
color: {},
}
}
</script>
+13 -16
View File
@@ -21,16 +21,14 @@
</FormLabel>
<b class="text-3xl font-extrabold -mt-3 block mb-0.5">
154.98MB
{{ storage.data.meta.traffic.upload }}
</b>
<b class="mb-3 block text-sm text-gray-400 mb-5">
{{ $t('In last 30 days') }}
{{ $t('In last 45 days') }}
</b>
<div class="flex items-end justify-between h-28">
<span class="w-2.5 block rounded-lg lg:mr-2 mr-1.5" :style="{height: Math.random() * 100 + '%', backgroundColor: '#9d66fe'}" v-for="(item, i) in Array(45).fill(0)" :key="i"></span>
</div>
<BarChart :data="storage.data.meta.traffic.chart.upload" color="#FFBD2D" />
</div>
<div v-if="distribution" class="card shadow-card">
<FormLabel icon="hard-drive">
@@ -38,34 +36,33 @@
</FormLabel>
<b class="text-3xl font-extrabold -mt-3 block mb-0.5">
927.12MB
{{ storage.data.meta.traffic.download }}
</b>
<b class="mb-3 block text-sm text-gray-400 mb-5">
{{ $t('In last 30 days') }}
{{ $t('In last 45 days') }}
</b>
<div class="flex items-end justify-between h-28">
<span class="w-2.5 bg-theme block rounded-lg lg:mr-2 mr-1.5" :style="{height: Math.random() * 100 + '%', backgroundColor: '#ffb822'}" v-for="(item, i) in Array(45).fill(0)" :key="i"></span>
</div>
<BarChart :data="storage.data.meta.traffic.chart.download" color="#9d66fe" />
</div>
</PageTab>
</template>
<script>
import ProgressLine from "../../components/Admin/ProgressLine";
import FormLabel from '/resources/js/components/Others/Forms/FormLabel'
import PageTab from '/resources/js/components/Others/Layout/PageTab'
import Spinner from '/resources/js/components/FilesView/Spinner'
import axios from 'axios'
import FormLabel from '/resources/js/components/Others/Forms/FormLabel'
import PageTab from '/resources/js/components/Others/Layout/PageTab'
import axios from 'axios'
import BarChart from "./BarChart";
export default {
export default {
name: 'Storage',
components: {
BarChart,
ProgressLine,
FormLabel,
PageTab,
Spinner,
},
data() {
return {
@@ -71,6 +71,7 @@ class SetupDevEnvironment extends Command
$this->info('Creating default demo content...');
$this->create_admin_default_content();
$this->generate_traffic();
$this->create_team_folders_content();
$this->create_share_with_me_team_folders_content();
$this->create_share_records();
@@ -118,6 +119,23 @@ class SetupDevEnvironment extends Command
$this->info('Default admin account created. Email: howdy@hi5ve.digital and Password: vuefilemanager');
}
private function generate_traffic(): void
{
$user = User::whereEmail('howdy@hi5ve.digital')
->first();
foreach (range(0, 45) as $day) {
DB::table('traffic')->insert([
'id' => Str::uuid(),
'user_id' => $user->id,
'upload' => random_int(1111111, 9999999),
'download' => random_int(11111111, 99999999),
'created_at' => now()->subDays($day),
'updated_at' => now()->subDays($day),
]);
}
}
/**
* Create default admin account
*/
+6
View File
@@ -3,6 +3,7 @@
namespace App\Users\Models;
use ByteUnits\Metric;
use Domain\Traffic\Models\Traffic;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Str;
use Domain\Files\Models\File;
@@ -186,6 +187,11 @@ class User extends Authenticatable implements MustVerifyEmail
return $this->hasMany(Folder::class);
}
public function traffics(): HasMany
{
return $this->hasMany(Traffic::class);
}
/**
* Send the password reset notification.
*/
+94 -37
View File
@@ -1,8 +1,9 @@
<?php
namespace App\Users\Resources;
use ByteUnits\Metric;
use Domain\Files\Models\File;
use Illuminate\Support\Facades\DB;
use Illuminate\Http\Resources\Json\JsonResource;
class UserStorageResource extends JsonResource
@@ -15,64 +16,120 @@ class UserStorageResource extends JsonResource
*/
public function toArray($request)
{
$document_mimetypes = [
'pdf', 'numbers', 'xlsx', 'xls', 'txt', 'md', 'rtf', 'pptx', 'ppt', 'odt', 'ods', 'odp', 'epub', 'docx', 'doc', 'csv', 'pages',
];
list($images, $audios, $videos, $documents, $others) = $this->get_file_type_distribution();
// Get all images
$images = File::where('user_id', $this->id)
->where('type', 'image')->get()->map(fn ($item) => (int) $item->getRawOriginal('filesize'))->sum();
// Get all audios
$audios = File::where('user_id', $this->id)
->where('type', 'audio')->get()->map(fn ($item) => (int) $item->getRawOriginal('filesize'))->sum();
// Get all videos
$videos = File::where('user_id', $this->id)
->where('type', 'video')->get()->map(fn ($item) => (int) $item->getRawOriginal('filesize'))->sum();
// Get all documents
$documents = File::where('user_id', $this->id)
->whereIn('mimetype', $document_mimetypes)->get()->map(fn ($item) => (int) $item->getRawOriginal('filesize'))->sum();
// Get all other files
$others = File::where('user_id', $this->id)
->whereNotIn('mimetype', $document_mimetypes)
->whereNotIn('type', ['audio', 'video', 'image'])
->get()->map(fn ($item) => (int) $item->getRawOriginal('filesize'))->sum();
list($downloadTotal, $uploadTotal, $upload, $download) = $this->get_traffic_distribution();
return [
'data' => [
'id' => (string) $this->id,
'id' => (string)$this->id,
'type' => 'storage',
'attributes' => [
'used' => Metric::bytes($this->usedCapacity)->format(),
'capacity' => format_gigabytes($this->limitations->max_storage_amount),
'percentage' => (float) get_storage_fill_percentage($this->usedCapacity, $this->limitations->max_storage_amount),
'percentage' => (float)get_storage_fill_percentage($this->usedCapacity, $this->limitations->max_storage_amount),
],
'meta' => [
'images' => [
'meta' => [
'traffic' => [
'chart' => [
'download' => $download,
'upload' => $upload,
],
'download' => Metric::bytes($downloadTotal)->format(),
'upload' => Metric::bytes($uploadTotal)->format(),
],
'images' => [
'used' => Metric::bytes($images)->format(),
'percentage' => (float) get_storage_fill_percentage($images, $this->limitations->max_storage_amount),
'percentage' => (float)get_storage_fill_percentage($images, $this->limitations->max_storage_amount),
],
'audios' => [
'audios' => [
'used' => Metric::bytes($audios)->format(),
'percentage' => (float) get_storage_fill_percentage($audios, $this->limitations->max_storage_amount),
'percentage' => (float)get_storage_fill_percentage($audios, $this->limitations->max_storage_amount),
],
'videos' => [
'videos' => [
'used' => Metric::bytes($videos)->format(),
'percentage' => (float) get_storage_fill_percentage($videos, $this->limitations->max_storage_amount),
'percentage' => (float)get_storage_fill_percentage($videos, $this->limitations->max_storage_amount),
],
'documents' => [
'used' => Metric::bytes($documents)->format(),
'percentage' => (float) get_storage_fill_percentage($documents, $this->limitations->max_storage_amount),
'percentage' => (float)get_storage_fill_percentage($documents, $this->limitations->max_storage_amount),
],
'others' => [
'others' => [
'used' => Metric::bytes($others)->format(),
'percentage' => (float) get_storage_fill_percentage($others, $this->limitations->max_storage_amount),
'percentage' => (float)get_storage_fill_percentage($others, $this->limitations->max_storage_amount),
],
],
],
];
}
private function get_file_type_distribution(): array
{
$document_mimetypes = [
'pdf', 'numbers', 'xlsx', 'xls', 'txt', 'md', 'rtf', 'pptx', 'ppt', 'odt', 'ods', 'odp', 'epub', 'docx', 'doc', 'csv', 'pages',
];
$images = DB::table('files')
->where('user_id', $this->id)
->where('type', 'image')
->sum('filesize');
$audios = DB::table('files')
->where('user_id', $this->id)
->where('type', 'audio')
->sum('filesize');
$videos = DB::table('files')
->where('user_id', $this->id)
->where('type', 'video')
->sum('filesize');
$documents = DB::table('files')
->where('user_id', $this->id)
->whereIn('mimetype', $document_mimetypes)
->sum('filesize');
$others = DB::table('files')
->where('user_id', $this->id)
->whereNotIn('mimetype', $document_mimetypes)
->whereNotIn('type', ['audio', 'video', 'image'])
->sum('filesize');
return [$images, $audios, $videos, $documents, $others];
}
private function get_traffic_distribution(): array
{
$period = now()->subDays(45)->endOfDay();
$uploadMax = \DB::table('traffic')
->where('user_id', $this->id)
->where('created_at', '>', $period)
->max('upload');
$downloadMax = \DB::table('traffic')
->where('user_id', $this->id)
->where('created_at', '>', $period)
->max('download');
$trafficRecords = \DB::table('traffic')
->where('user_id', $this->id)
->where('created_at', '>', $period)
->get();
$downloadTotal = \DB::table('traffic')
->where('user_id', $this->id)
->where('created_at', '>', $period)
->sum('download');
$uploadTotal = \DB::table('traffic')
->where('user_id', $this->id)
->where('created_at', '>', $period)
->sum('upload');
$upload = $trafficRecords->map(fn($record) => round(($record->upload / $uploadMax) * 100, 2));
$download = $trafficRecords->map(fn($record) => round(($record->download / $downloadMax) * 100, 2));
return [$downloadTotal, $uploadTotal, $upload, $download];
}
}
+25
View File
@@ -1,6 +1,7 @@
<?php
namespace Tests\Domain\Traffic;
use Illuminate\Support\Facades\DB;
use Storage;
use Tests\TestCase;
use App\Users\Models\User;
@@ -186,4 +187,28 @@ class TrafficTest extends TestCase
'download' => $document->getSize(),
]);
}
/**
* @test
*/
public function it_get_user_traffic_test()
{
$user = User::factory()
->create();
foreach (range(0, 30) as $day) {
DB::table('traffic')->insert([
'id' => Str::uuid(),
'user_id' => $user->id,
'upload' => random_int(11111111, 99999999),
'download' => random_int(11111111, 99999999),
'created_at' => now()->subDays($day),
'updated_at' => now()->subDays($day),
]);
}
$this->actingAs($user)
->get('/api/user/storage')
->assertOk();
}
}