mirror of
https://github.com/VueFileManager/vuefilemanager.git
synced 2026-05-13 08:45:01 +00:00
Merge branch 'dev'
* dev: v1.5-beta.3 v1.5-beta.2 v1.5-beta.1 v1.5-alpha.11 v1.5-alpha.10 v1.5-alpha.9 v1.5-alpha.8 v1.5-alpha.7 v1.5-alpha.6 v1.5-alpha.5 v1.5-alpha.4 v1.5-alpha.3 v1.5-alpha.2 v1.5-alpha.1
This commit is contained in:
@@ -55,3 +55,5 @@ MIX_PUSHER_APP_CLUSTER="${PUSHER_APP_CLUSTER}"
|
|||||||
|
|
||||||
PASSPORT_CLIENT_ID=
|
PASSPORT_CLIENT_ID=
|
||||||
PASSPORT_CLIENT_SECRET=
|
PASSPORT_CLIENT_SECRET=
|
||||||
|
|
||||||
|
APP_DEPLOY_SECRET=
|
||||||
@@ -1,6 +1,10 @@
|
|||||||
### Documentation
|
### Documentation
|
||||||
[Read online documentation](https://vuefilemanager.com/docs/)
|
[Read online documentation](https://vuefilemanager.com/docs/)
|
||||||
|
|
||||||
|
### Demo & dev preview links
|
||||||
|
* For visit demo version click here [demo.vuefilemanager.com](https://demo.vuefilemanager.com/)
|
||||||
|
* For visit dev version click here [dev.vuefilemanager.com](https://dev.vuefilemanager.com/) (It's auto deployed dev branch. Can be unstable and not ready for production)
|
||||||
|
|
||||||
### Installation setup
|
### Installation setup
|
||||||
|
|
||||||
Run these commands to install vendors:
|
Run these commands to install vendors:
|
||||||
|
|||||||
@@ -0,0 +1,66 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Console\Commands;
|
||||||
|
|
||||||
|
use Illuminate\Console\Command;
|
||||||
|
use Illuminate\Support\Facades\Log;
|
||||||
|
|
||||||
|
class Deploy extends Command
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* The name and signature of the console command.
|
||||||
|
*
|
||||||
|
* @var string
|
||||||
|
*/
|
||||||
|
protected $signature = 'deploy:production';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The console command description.
|
||||||
|
*
|
||||||
|
* @var string
|
||||||
|
*/
|
||||||
|
protected $description = 'Automatic deployment for production';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a new command instance.
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function __construct()
|
||||||
|
{
|
||||||
|
parent::__construct();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Execute the console command.
|
||||||
|
*
|
||||||
|
* @return mixed
|
||||||
|
*/
|
||||||
|
public function handle()
|
||||||
|
{
|
||||||
|
// Start deployment
|
||||||
|
$this->info('Running auto deployment');
|
||||||
|
$this->call('down');
|
||||||
|
|
||||||
|
// Exec commands
|
||||||
|
exec('git pull origin ' . config('app.deploy_branch'));
|
||||||
|
exec('composer update --no-interaction --prefer-dist');
|
||||||
|
$this->migrateDatabase();
|
||||||
|
|
||||||
|
// Stop deployment
|
||||||
|
$this->call('up');
|
||||||
|
$this->info('Everything is done, congratulations! 🥳🥳🥳');
|
||||||
|
|
||||||
|
Log::info('Application was updated!');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Migrate database
|
||||||
|
*/
|
||||||
|
public function migrateDatabase()
|
||||||
|
{
|
||||||
|
$this->call('migrate', [
|
||||||
|
'--force' => true,
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -2,6 +2,7 @@
|
|||||||
|
|
||||||
namespace App\Console;
|
namespace App\Console;
|
||||||
|
|
||||||
|
use App\Console\Commands\Deploy;
|
||||||
use App\Console\Commands\SetupDevEnvironment;
|
use App\Console\Commands\SetupDevEnvironment;
|
||||||
use App\Console\Commands\SetupProductionEnvironment;
|
use App\Console\Commands\SetupProductionEnvironment;
|
||||||
use Illuminate\Console\Scheduling\Schedule;
|
use Illuminate\Console\Scheduling\Schedule;
|
||||||
@@ -17,6 +18,7 @@ class Kernel extends ConsoleKernel
|
|||||||
protected $commands = [
|
protected $commands = [
|
||||||
SetupProductionEnvironment::class,
|
SetupProductionEnvironment::class,
|
||||||
SetupDevEnvironment::class,
|
SetupDevEnvironment::class,
|
||||||
|
Deploy::class,
|
||||||
];
|
];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -0,0 +1,44 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Http\Controllers;
|
||||||
|
|
||||||
|
use Illuminate\Http\Request;
|
||||||
|
use Artisan;
|
||||||
|
use Illuminate\Support\Facades\Log;
|
||||||
|
use Illuminate\Validation\UnauthorizedException;
|
||||||
|
use Symfony\Component\HttpKernel\Exception\BadRequestHttpException;
|
||||||
|
|
||||||
|
class DeployController extends Controller
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Get web hook payload and verify request
|
||||||
|
*
|
||||||
|
* @param Request $request
|
||||||
|
* @return \Illuminate\Contracts\Routing\ResponseFactory|\Illuminate\Http\Response
|
||||||
|
*/
|
||||||
|
public function github(Request $request) {
|
||||||
|
|
||||||
|
if (($signature = $request->headers->get('X-Hub-Signature')) == null) {
|
||||||
|
throw new BadRequestHttpException('Header not set');
|
||||||
|
}
|
||||||
|
|
||||||
|
$signature_parts = explode('=', $signature);
|
||||||
|
|
||||||
|
if (count($signature_parts) != 2) {
|
||||||
|
throw new BadRequestHttpException('signature has invalid format');
|
||||||
|
}
|
||||||
|
|
||||||
|
$known_signature = hash_hmac('sha1', $request->getContent(), config('app.deploy_secret'));
|
||||||
|
|
||||||
|
if (! hash_equals($known_signature, $signature_parts[1])) {
|
||||||
|
throw new UnauthorizedException('Could not verify request signature ' . $signature_parts[1]);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Run deploying
|
||||||
|
Artisan::call('deploy:production');
|
||||||
|
|
||||||
|
Log::info('The GitHub webhook was accepted');
|
||||||
|
|
||||||
|
return response('The GitHub webhook was accepted', 202);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -3,6 +3,7 @@
|
|||||||
namespace App\Http\Controllers\FileBrowser;
|
namespace App\Http\Controllers\FileBrowser;
|
||||||
|
|
||||||
use App\Http\Requests\FileBrowser\SearchRequest;
|
use App\Http\Requests\FileBrowser\SearchRequest;
|
||||||
|
use App\User;
|
||||||
use Illuminate\Support\Facades\Validator;
|
use Illuminate\Support\Facades\Validator;
|
||||||
use Illuminate\Support\Facades\Auth;
|
use Illuminate\Support\Facades\Auth;
|
||||||
use App\Http\Controllers\Controller;
|
use App\Http\Controllers\Controller;
|
||||||
@@ -27,17 +28,19 @@ class BrowseController extends Controller
|
|||||||
|
|
||||||
// Get folders and files
|
// Get folders and files
|
||||||
$folders_trashed = FileManagerFolder::onlyTrashed()
|
$folders_trashed = FileManagerFolder::onlyTrashed()
|
||||||
->with(['trashed_folders'])
|
->with(['trashed_folders', 'parent'])
|
||||||
->where('user_id', $user_id)
|
->where('user_id', $user_id)
|
||||||
->get(['parent_id', 'unique_id', 'name']);
|
->get(['parent_id', 'unique_id', 'name']);
|
||||||
|
|
||||||
$folders = FileManagerFolder::onlyTrashed()
|
$folders = FileManagerFolder::onlyTrashed()
|
||||||
|
->with(['parent'])
|
||||||
->where('user_id', $user_id)
|
->where('user_id', $user_id)
|
||||||
->whereIn('unique_id', filter_folders_ids($folders_trashed))
|
->whereIn('unique_id', filter_folders_ids($folders_trashed))
|
||||||
->get();
|
->get();
|
||||||
|
|
||||||
// Get files trashed
|
// Get files trashed
|
||||||
$files_trashed = FileManagerFile::onlyTrashed()
|
$files_trashed = FileManagerFile::onlyTrashed()
|
||||||
|
->with(['parent'])
|
||||||
->where('user_id', $user_id)
|
->where('user_id', $user_id)
|
||||||
->whereNotIn('folder_id', array_values(array_unique(recursiveFind($folders_trashed->toArray(), 'unique_id'))))
|
->whereNotIn('folder_id', array_values(array_unique(recursiveFind($folders_trashed->toArray(), 'unique_id'))))
|
||||||
->get();
|
->get();
|
||||||
@@ -80,6 +83,35 @@ class BrowseController extends Controller
|
|||||||
return collect([$folders, $files])->collapse();
|
return collect([$folders, $files])->collapse();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get latest user uploads
|
||||||
|
*
|
||||||
|
* @return mixed
|
||||||
|
*/
|
||||||
|
public function latest() {
|
||||||
|
|
||||||
|
// Get User
|
||||||
|
$user = User::with(['latest_uploads'])
|
||||||
|
->where('id', Auth::id())
|
||||||
|
->first();
|
||||||
|
|
||||||
|
return $user->latest_uploads->makeHidden(['user_id', 'basename']);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get participant uploads
|
||||||
|
*
|
||||||
|
* @return mixed
|
||||||
|
*/
|
||||||
|
public function participant_uploads() {
|
||||||
|
|
||||||
|
// Get User
|
||||||
|
$uploads = FileManagerFile::with(['parent'])->where('user_id', Auth::id())
|
||||||
|
->whereUserScope('editor')->orderBy('created_at', 'DESC')->get();
|
||||||
|
|
||||||
|
return $uploads;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get directory with files
|
* Get directory with files
|
||||||
*
|
*
|
||||||
@@ -97,14 +129,14 @@ class BrowseController extends Controller
|
|||||||
|
|
||||||
// Get folders and files
|
// Get folders and files
|
||||||
$folders = FileManagerFolder::onlyTrashed()
|
$folders = FileManagerFolder::onlyTrashed()
|
||||||
->where('user_id', $user_id)
|
|
||||||
->with('parent')
|
->with('parent')
|
||||||
|
->where('user_id', $user_id)
|
||||||
->where('parent_id', $unique_id)
|
->where('parent_id', $unique_id)
|
||||||
->get();
|
->get();
|
||||||
|
|
||||||
$files = FileManagerFile::onlyTrashed()
|
$files = FileManagerFile::onlyTrashed()
|
||||||
->where('user_id', $user_id)
|
|
||||||
->with('parent')
|
->with('parent')
|
||||||
|
->where('user_id', $user_id)
|
||||||
->where('folder_id', $unique_id)
|
->where('folder_id', $unique_id)
|
||||||
->get();
|
->get();
|
||||||
|
|
||||||
@@ -121,6 +153,7 @@ class BrowseController extends Controller
|
|||||||
$files = FileManagerFile::with(['parent', 'shared:token,id,item_id,permission,protected'])
|
$files = FileManagerFile::with(['parent', 'shared:token,id,item_id,permission,protected'])
|
||||||
->where('user_id', $user_id)
|
->where('user_id', $user_id)
|
||||||
->where('folder_id', $unique_id)
|
->where('folder_id', $unique_id)
|
||||||
|
->orderBy('created_at', 'DESC')
|
||||||
->get();
|
->get();
|
||||||
|
|
||||||
// Collect folders and files to single array
|
// Collect folders and files to single array
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ use App\Http\Controllers\Controller;
|
|||||||
use App\Http\Requests\Share\AuthenticateShareRequest;
|
use App\Http\Requests\Share\AuthenticateShareRequest;
|
||||||
use App\Http\Resources\ShareResource;
|
use App\Http\Resources\ShareResource;
|
||||||
use App\Http\Tools\Guardian;
|
use App\Http\Tools\Guardian;
|
||||||
|
use http\Env\Response;
|
||||||
use Illuminate\Contracts\View\Factory;
|
use Illuminate\Contracts\View\Factory;
|
||||||
use Illuminate\Support\Facades\Cookie;
|
use Illuminate\Support\Facades\Cookie;
|
||||||
use Illuminate\Support\Facades\DB;
|
use Illuminate\Support\Facades\DB;
|
||||||
@@ -17,6 +18,7 @@ use App\FileManagerFolder;
|
|||||||
use App\FileManagerFile;
|
use App\FileManagerFile;
|
||||||
use App\User;
|
use App\User;
|
||||||
use App\Share;
|
use App\Share;
|
||||||
|
use Illuminate\Support\Facades\Storage;
|
||||||
|
|
||||||
class FileSharingController extends Controller
|
class FileSharingController extends Controller
|
||||||
{
|
{
|
||||||
@@ -32,7 +34,7 @@ class FileSharingController extends Controller
|
|||||||
$shared = Share::where(\DB::raw('BINARY `token`'), $token)
|
$shared = Share::where(\DB::raw('BINARY `token`'), $token)
|
||||||
->first();
|
->first();
|
||||||
|
|
||||||
if (!$shared) {
|
if (! $shared) {
|
||||||
return view("index");
|
return view("index");
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -46,10 +48,51 @@ class FileSharingController extends Controller
|
|||||||
Cookie::queue('shared_token', $token, 43200);
|
Cookie::queue('shared_token', $token, 43200);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Check if shared is image file and then show it
|
||||||
|
if ($shared->type === 'file' && ! $shared->protected) {
|
||||||
|
|
||||||
|
$image = FileManagerFile::where('user_id', $shared->user_id)
|
||||||
|
->where('type', 'image')
|
||||||
|
->where('unique_id', $shared->item_id)
|
||||||
|
->first();
|
||||||
|
|
||||||
|
if ($image) {
|
||||||
|
return $this->show_image($image);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Return page index
|
// Return page index
|
||||||
return view("index");
|
return view("index");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get image from storage and show it
|
||||||
|
*
|
||||||
|
* @param $file
|
||||||
|
* @return \Symfony\Component\HttpFoundation\StreamedResponse
|
||||||
|
*/
|
||||||
|
private function show_image($file)
|
||||||
|
{
|
||||||
|
// Format pretty filename
|
||||||
|
$file_pretty_name = $file->name . '.' . $file->mimetype;
|
||||||
|
|
||||||
|
// Get file path
|
||||||
|
$path = '/file-manager/' . $file->basename;
|
||||||
|
|
||||||
|
// Check if file exist
|
||||||
|
if (!Storage::exists($path)) abort(404);
|
||||||
|
|
||||||
|
$header = [
|
||||||
|
"Content-Type" => Storage::mimeType($path),
|
||||||
|
"Content-Length" => Storage::size($path),
|
||||||
|
"Accept-Ranges" => "bytes",
|
||||||
|
"Content-Range" => "bytes 0-600/" . Storage::size($path),
|
||||||
|
];
|
||||||
|
|
||||||
|
// Get file
|
||||||
|
return Storage::response($path, $file_pretty_name, $header);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Check Password for protected item
|
* Check Password for protected item
|
||||||
*
|
*
|
||||||
|
|||||||
@@ -2,6 +2,9 @@
|
|||||||
|
|
||||||
namespace App\Http\Controllers\User;
|
namespace App\Http\Controllers\User;
|
||||||
|
|
||||||
|
use App\FileManagerFile;
|
||||||
|
use App\FileManagerFolder;
|
||||||
|
use App\Http\Resources\StorageDetailResource;
|
||||||
use App\Http\Tools\Demo;
|
use App\Http\Tools\Demo;
|
||||||
use Illuminate\Contracts\Routing\ResponseFactory;
|
use Illuminate\Contracts\Routing\ResponseFactory;
|
||||||
use Illuminate\Support\Facades\Validator;
|
use Illuminate\Support\Facades\Validator;
|
||||||
@@ -26,11 +29,17 @@ class AccountController extends Controller
|
|||||||
->where('id', Auth::id())
|
->where('id', Auth::id())
|
||||||
->first();
|
->first();
|
||||||
|
|
||||||
|
// Get folder tree
|
||||||
|
$tree = FileManagerFolder::with(['folders.shared', 'shared:token,id,item_id,permission,protected'])
|
||||||
|
->where('parent_id', 0)
|
||||||
|
->where('user_id', $user->id)
|
||||||
|
->get();
|
||||||
|
|
||||||
return [
|
return [
|
||||||
'user' => $user->only(['name', 'email', 'avatar']),
|
'user' => $user->only(['name', 'email', 'avatar']),
|
||||||
'favourites' => $user->favourites->makeHidden(['pivot']),
|
'favourites' => $user->favourites->makeHidden(['pivot']),
|
||||||
'latest_uploads' => $user->latest_uploads->makeHidden(['user_id', 'basename']),
|
'tree' => $tree,
|
||||||
'storage' => [
|
'storage' => [
|
||||||
'used' => Metric::bytes($user->used_capacity)->format(),
|
'used' => Metric::bytes($user->used_capacity)->format(),
|
||||||
'capacity' => format_gigabytes(config('vuefilemanager.user_storage_capacity')),
|
'capacity' => format_gigabytes(config('vuefilemanager.user_storage_capacity')),
|
||||||
'percentage' => get_storage_fill_percentage($user->used_capacity, config('vuefilemanager.user_storage_capacity')),
|
'percentage' => get_storage_fill_percentage($user->used_capacity, config('vuefilemanager.user_storage_capacity')),
|
||||||
@@ -38,6 +47,89 @@ class AccountController extends Controller
|
|||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get storage details
|
||||||
|
*
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
public function storage()
|
||||||
|
{
|
||||||
|
$document_mimetypes = [
|
||||||
|
'pdf', 'numbers', 'xlsx', 'xls', 'txt', 'md', 'rtf', 'pptx', 'ppt', 'odt', 'ods', 'odp', 'epub', 'docx', 'doc', 'csv', 'pages'
|
||||||
|
];
|
||||||
|
|
||||||
|
$user = Auth::user();
|
||||||
|
$storage_capacity = config('vuefilemanager.user_storage_capacity');
|
||||||
|
|
||||||
|
$images = FileManagerFile::where('user_id', $user->id)
|
||||||
|
->where('type', 'image')->get()->map(function ($item) {
|
||||||
|
return (int)$item->getOriginal('filesize');
|
||||||
|
})->sum();
|
||||||
|
|
||||||
|
$audios = FileManagerFile::where('user_id', $user->id)
|
||||||
|
->where('type', 'audio')->get()->map(function ($item) {
|
||||||
|
return (int)$item->getOriginal('filesize');
|
||||||
|
})->sum();
|
||||||
|
|
||||||
|
$videos = FileManagerFile::where('user_id', $user->id)
|
||||||
|
->where('type', 'video')->get()->map(function ($item) {
|
||||||
|
return (int)$item->getOriginal('filesize');
|
||||||
|
})->sum();
|
||||||
|
|
||||||
|
$documents = FileManagerFile::where('user_id', $user->id)
|
||||||
|
->whereIn('mimetype', $document_mimetypes)->get()->map(function ($item) {
|
||||||
|
return (int)$item->getOriginal('filesize');
|
||||||
|
})->sum();
|
||||||
|
|
||||||
|
$others = FileManagerFile::where('user_id', $user->id)
|
||||||
|
->whereNotIn('mimetype', $document_mimetypes)
|
||||||
|
->whereNotIn('type', ['audio', 'video', 'image'])
|
||||||
|
->get()->map(function ($item) {
|
||||||
|
return (int)$item->getOriginal('filesize');
|
||||||
|
})->sum();
|
||||||
|
|
||||||
|
$usage = collect([
|
||||||
|
'images' => [
|
||||||
|
'used' => $images,
|
||||||
|
'percentage' => get_storage_fill_percentage($images, $storage_capacity),
|
||||||
|
],
|
||||||
|
'audios' => [
|
||||||
|
'used' => $audios,
|
||||||
|
'percentage' => get_storage_fill_percentage($audios, $storage_capacity),
|
||||||
|
],
|
||||||
|
'videos' => [
|
||||||
|
'used' => $videos,
|
||||||
|
'percentage' => get_storage_fill_percentage($videos, $storage_capacity),
|
||||||
|
],
|
||||||
|
'documents' => [
|
||||||
|
'used' => $documents,
|
||||||
|
'percentage' => get_storage_fill_percentage($documents, $storage_capacity),
|
||||||
|
],
|
||||||
|
'others' => [
|
||||||
|
'used' => $others,
|
||||||
|
'percentage' => get_storage_fill_percentage($others, $storage_capacity),
|
||||||
|
],
|
||||||
|
]);
|
||||||
|
|
||||||
|
return [
|
||||||
|
'data' => [
|
||||||
|
'id' => '1',
|
||||||
|
'type' => 'disk',
|
||||||
|
'attributes' => [
|
||||||
|
'used' => Metric::bytes($user->used_capacity)->format(),
|
||||||
|
'capacity' => format_gigabytes($storage_capacity),
|
||||||
|
'percentage' => get_storage_fill_percentage($user->used_capacity, $storage_capacity),
|
||||||
|
],
|
||||||
|
'relationships' => $usage->map(function ($item) {
|
||||||
|
return [
|
||||||
|
'used' => Metric::bytes($item['used'])->format(),
|
||||||
|
'percentage' => $item['percentage']
|
||||||
|
];
|
||||||
|
})
|
||||||
|
]
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Update user profile
|
* Update user profile
|
||||||
*
|
*
|
||||||
@@ -48,9 +140,9 @@ class AccountController extends Controller
|
|||||||
{
|
{
|
||||||
// Validate request
|
// Validate request
|
||||||
$validator = Validator::make($request->all(), [
|
$validator = Validator::make($request->all(), [
|
||||||
'avatar' => 'file',
|
'avatar' => 'file',
|
||||||
'name' => 'string',
|
'name' => 'string',
|
||||||
'value' => 'string',
|
'value' => 'string',
|
||||||
]);
|
]);
|
||||||
|
|
||||||
// Return error
|
// Return error
|
||||||
|
|||||||
@@ -19,6 +19,6 @@ class VerifyCsrfToken extends Middleware
|
|||||||
* @var array
|
* @var array
|
||||||
*/
|
*/
|
||||||
protected $except = [
|
protected $except = [
|
||||||
//
|
'/deploy',
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -230,7 +230,7 @@ class Editor
|
|||||||
$image = Image::make($file->getRealPath())->orientate();
|
$image = Image::make($file->getRealPath())->orientate();
|
||||||
|
|
||||||
// Resize image
|
// Resize image
|
||||||
$image->resize(256, null, function ($constraint) {
|
$image->resize(564, null, function ($constraint) {
|
||||||
$constraint->aspectRatio();
|
$constraint->aspectRatio();
|
||||||
})->stream();
|
})->stream();
|
||||||
|
|
||||||
|
|||||||
+2
-2
@@ -135,7 +135,7 @@ class User extends Authenticatable
|
|||||||
*/
|
*/
|
||||||
public function favourites()
|
public function favourites()
|
||||||
{
|
{
|
||||||
return $this->belongsToMany(FileManagerFolder::class, 'favourite_folder', 'user_id', 'folder_unique_id', 'id', 'unique_id')->select(['unique_id', 'name', 'type']);
|
return $this->belongsToMany(FileManagerFolder::class, 'favourite_folder', 'user_id', 'folder_unique_id', 'id', 'unique_id')->with('shared:token,id,item_id,permission,protected');
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -145,7 +145,7 @@ class User extends Authenticatable
|
|||||||
*/
|
*/
|
||||||
public function latest_uploads() {
|
public function latest_uploads() {
|
||||||
|
|
||||||
return $this->hasMany(FileManagerFile::class)->orderBy('created_at', 'DESC')->take(7);
|
return $this->hasMany(FileManagerFile::class)->with(['parent'])->orderBy('created_at', 'DESC')->take(40);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -233,6 +233,9 @@ return [
|
|||||||
|
|
||||||
],
|
],
|
||||||
|
|
||||||
|
'deploy_secret' => env('APP_DEPLOY_SECRET'),
|
||||||
|
'deploy_branch' => env('APP_DEPLOY_BRANCH'),
|
||||||
|
|
||||||
'debug_blacklist' => [
|
'debug_blacklist' => [
|
||||||
'_ENV' => [
|
'_ENV' => [
|
||||||
'APP_KEY',
|
'APP_KEY',
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
return [
|
return [
|
||||||
|
|
||||||
'version' => '1.4.2',
|
'version' => '1.5',
|
||||||
|
|
||||||
// Your app name
|
// Your app name
|
||||||
'app_name' => 'VueFileManager',
|
'app_name' => 'VueFileManager',
|
||||||
@@ -17,5 +17,5 @@ return [
|
|||||||
'limit_storage_by_capacity' => true,
|
'limit_storage_by_capacity' => true,
|
||||||
|
|
||||||
// Define user storage capacity in MB. E.g. value 2000 is 2.00GB
|
// Define user storage capacity in MB. E.g. value 2000 is 2.00GB
|
||||||
'user_storage_capacity' => 300,
|
'user_storage_capacity' => 5000,
|
||||||
];
|
];
|
||||||
Generated
+13
@@ -1671,6 +1671,11 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"babel-helper-vue-jsx-merge-props": {
|
||||||
|
"version": "2.0.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/babel-helper-vue-jsx-merge-props/-/babel-helper-vue-jsx-merge-props-2.0.3.tgz",
|
||||||
|
"integrity": "sha512-gsLiKK7Qrb7zYJNgiXKpXblxbV5ffSwR0f5whkPAaBAR4fhi6bwRZxX9wBlIc5M/v8CCkXUbXZL4N/nSE97cqg=="
|
||||||
|
},
|
||||||
"babel-loader": {
|
"babel-loader": {
|
||||||
"version": "8.1.0",
|
"version": "8.1.0",
|
||||||
"resolved": "https://registry.npmjs.org/babel-loader/-/babel-loader-8.1.0.tgz",
|
"resolved": "https://registry.npmjs.org/babel-loader/-/babel-loader-8.1.0.tgz",
|
||||||
@@ -10359,6 +10364,14 @@
|
|||||||
"resolved": "https://registry.npmjs.org/vue/-/vue-2.6.11.tgz",
|
"resolved": "https://registry.npmjs.org/vue/-/vue-2.6.11.tgz",
|
||||||
"integrity": "sha512-VfPwgcGABbGAue9+sfrD4PuwFar7gPb1yl1UK1MwXoQPAw0BKSqWfoYCT/ThFrdEVWoI51dBuyCoiNU9bZDZxQ=="
|
"integrity": "sha512-VfPwgcGABbGAue9+sfrD4PuwFar7gPb1yl1UK1MwXoQPAw0BKSqWfoYCT/ThFrdEVWoI51dBuyCoiNU9bZDZxQ=="
|
||||||
},
|
},
|
||||||
|
"vue-feather-icons": {
|
||||||
|
"version": "5.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/vue-feather-icons/-/vue-feather-icons-5.0.0.tgz",
|
||||||
|
"integrity": "sha512-uvi2l3i0aeRRzG3vX24/AH+8BkcXkSJboAv8XkUZ6aPkEC9n6LXDcKp5/ho+3moVQ9wlga3N6BjL89pmkHBzPw==",
|
||||||
|
"requires": {
|
||||||
|
"babel-helper-vue-jsx-merge-props": "^2.0.2"
|
||||||
|
}
|
||||||
|
},
|
||||||
"vue-hot-reload-api": {
|
"vue-hot-reload-api": {
|
||||||
"version": "2.3.4",
|
"version": "2.3.4",
|
||||||
"resolved": "https://registry.npmjs.org/vue-hot-reload-api/-/vue-hot-reload-api-2.3.4.tgz",
|
"resolved": "https://registry.npmjs.org/vue-hot-reload-api/-/vue-hot-reload-api-2.3.4.tgz",
|
||||||
|
|||||||
@@ -26,6 +26,7 @@
|
|||||||
"node-sass": "^4.14.0",
|
"node-sass": "^4.14.0",
|
||||||
"vee-validate": "^3.3.0",
|
"vee-validate": "^3.3.0",
|
||||||
"vue": "^2.6.10",
|
"vue": "^2.6.10",
|
||||||
|
"vue-feather-icons": "^5.0.0",
|
||||||
"vue-i18n": "^8.17.4",
|
"vue-i18n": "^8.17.4",
|
||||||
"vue-router": "^3.1.6",
|
"vue-router": "^3.1.6",
|
||||||
"vuex": "^3.3.0"
|
"vuex": "^3.3.0"
|
||||||
|
|||||||
Vendored
+1
-3
File diff suppressed because one or more lines are too long
Vendored
+1
-1
File diff suppressed because one or more lines are too long
+65
-28
@@ -1,57 +1,61 @@
|
|||||||
<template>
|
<template>
|
||||||
<div id="vue-file-manager" :class="appSize">
|
<div id="vue-file-manager" :class="appSize" v-cloak>
|
||||||
|
|
||||||
<!--System alerts-->
|
<!--System alerts-->
|
||||||
<Alert />
|
<Alert/>
|
||||||
|
|
||||||
<div id="application-wrapper" v-if="layout === 'authorized'">
|
<div id="application-wrapper" v-if="layout === 'authorized'">
|
||||||
|
|
||||||
|
<MobileNavigation />
|
||||||
|
|
||||||
<!--Share Item setup-->
|
<!--Share Item setup-->
|
||||||
<ShareCreate />
|
<ShareCreate/>
|
||||||
<ShareEdit />
|
<ShareEdit/>
|
||||||
|
|
||||||
<!--Move item setup-->
|
<!--Move item setup-->
|
||||||
<MoveItem />
|
<MoveItem/>
|
||||||
|
|
||||||
<!--Mobile Menu-->
|
<!--Mobile Menu-->
|
||||||
<MobileMenu />
|
<MobileMenu/>
|
||||||
|
|
||||||
<!--Navigation Sidebar-->
|
<!--Navigation Sidebar-->
|
||||||
<Sidebar/>
|
<MenuBar/>
|
||||||
|
|
||||||
<!--File page-->
|
<!--File page-->
|
||||||
<router-view/>
|
<router-view :class="{'is-scaled-down': isScaledDown}"/>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<router-view v-if="layout === 'unauthorized'"/>
|
<router-view v-if="layout === 'unauthorized'"/>
|
||||||
|
|
||||||
<!--Background vignette-->
|
<!--Background vignette-->
|
||||||
<Vignette />
|
<Vignette/>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
|
import MobileNavigation from '@/components/Others/MobileNavigation'
|
||||||
import MobileMenu from '@/components/FilesView/MobileMenu'
|
import MobileMenu from '@/components/FilesView/MobileMenu'
|
||||||
import ShareCreate from '@/components/Others/ShareCreate'
|
import ShareCreate from '@/components/Others/ShareCreate'
|
||||||
import ShareEdit from '@/components/Others/ShareEdit'
|
import ShareEdit from '@/components/Others/ShareEdit'
|
||||||
import MoveItem from '@/components/Others/MoveItem'
|
import MoveItem from '@/components/Others/MoveItem'
|
||||||
import Vignette from '@/components/Others/Vignette'
|
import Vignette from '@/components/Others/Vignette'
|
||||||
import Sidebar from '@/components/Sidebar/Sidebar'
|
import MenuBar from '@/components/Sidebar/MenuBar'
|
||||||
import Alert from '@/components/FilesView/Alert'
|
import Alert from '@/components/FilesView/Alert'
|
||||||
import {ResizeSensor} from 'css-element-queries'
|
import {ResizeSensor} from 'css-element-queries'
|
||||||
import { includes } from 'lodash'
|
import {includes} from 'lodash'
|
||||||
import {mapGetters} from 'vuex'
|
import {mapGetters} from 'vuex'
|
||||||
import {events} from "./bus"
|
import {events} from "./bus"
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'app',
|
name: 'app',
|
||||||
components: {
|
components: {
|
||||||
|
MobileNavigation,
|
||||||
ShareCreate,
|
ShareCreate,
|
||||||
MobileMenu,
|
MobileMenu,
|
||||||
ShareEdit,
|
ShareEdit,
|
||||||
MoveItem,
|
MoveItem,
|
||||||
Vignette,
|
Vignette,
|
||||||
Sidebar,
|
MenuBar,
|
||||||
Alert,
|
Alert,
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
@@ -66,6 +70,11 @@
|
|||||||
return 'authorized'
|
return 'authorized'
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
isScaledDown: false,
|
||||||
|
}
|
||||||
|
},
|
||||||
methods: {
|
methods: {
|
||||||
handleAppResize() {
|
handleAppResize() {
|
||||||
let appView = document.getElementById('vue-file-manager')
|
let appView = document.getElementById('vue-file-manager')
|
||||||
@@ -80,20 +89,41 @@
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
beforeMount() {
|
beforeMount() {
|
||||||
|
|
||||||
// Store config to vuex
|
// Store config to vuex
|
||||||
this.$store.commit('SET_AUTHORIZED', this.$root.$data.config.hasAuthCookie)
|
this.$store.commit('INIT', {
|
||||||
this.$store.commit('SET_CONFIG', this.$root.$data.config)
|
authCookie: this.$root.$data.config.hasAuthCookie,
|
||||||
|
config: this.$root.$data.config,
|
||||||
|
rootDirectory: {
|
||||||
|
name: this.$t('locations.home'),
|
||||||
|
location: 'base',
|
||||||
|
unique_id: 0,
|
||||||
|
}
|
||||||
|
})
|
||||||
},
|
},
|
||||||
mounted() {
|
mounted() {
|
||||||
// Handle VueFileManager width
|
// Handle VueFileManager width
|
||||||
var VueFileManager = document.getElementById('vue-file-manager');
|
var VueFileManager = document.getElementById('vue-file-manager');
|
||||||
new ResizeSensor(VueFileManager, this.handleAppResize);
|
new ResizeSensor(VueFileManager, this.handleAppResize);
|
||||||
|
|
||||||
|
// Handle mobile navigation scale animation
|
||||||
|
events.$on('show:mobile-navigation', () => this.isScaledDown = true)
|
||||||
|
events.$on('hide:mobile-navigation', () => this.isScaledDown = false)
|
||||||
|
events.$on('mobileMenu:show', () => this.isScaledDown = true)
|
||||||
|
events.$on('fileItem:deselect', () => this.isScaledDown = false)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss">
|
<style lang="scss">
|
||||||
@import "@assets/app.scss";
|
@import url('https://fonts.googleapis.com/css2?family=Nunito:wght@200;300;400;600;700;900&display=swap');
|
||||||
|
@import '@assets/vue-file-manager/_variables';
|
||||||
|
@import '@assets/vue-file-manager/_mixins';
|
||||||
|
|
||||||
|
[v-cloak],
|
||||||
|
[v-cloak] > * {
|
||||||
|
display: none
|
||||||
|
}
|
||||||
|
|
||||||
* {
|
* {
|
||||||
outline: 0;
|
outline: 0;
|
||||||
@@ -107,19 +137,6 @@
|
|||||||
font-size: 16px;
|
font-size: 16px;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Dark mode support
|
|
||||||
@media (prefers-color-scheme: dark) {
|
|
||||||
|
|
||||||
body, html {
|
|
||||||
background: $dark_mode_background;
|
|
||||||
color: $dark_mode_text_primary;
|
|
||||||
|
|
||||||
img {
|
|
||||||
opacity: .8;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#auth {
|
#auth {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
@@ -131,4 +148,24 @@
|
|||||||
height: 100%;
|
height: 100%;
|
||||||
overflow-y: auto;
|
overflow-y: auto;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@media only screen and (max-width: 690px) {
|
||||||
|
|
||||||
|
.is-scaled-down {
|
||||||
|
@include transform(scale(0.95));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Dark mode support
|
||||||
|
@media (prefers-color-scheme: dark) {
|
||||||
|
|
||||||
|
body, html {
|
||||||
|
background: $dark_mode_background;
|
||||||
|
color: $dark_mode_text_primary;
|
||||||
|
|
||||||
|
img {
|
||||||
|
opacity: .95;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
@@ -28,7 +28,8 @@
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped lang="scss">
|
<style scoped lang="scss">
|
||||||
@import "@assets/app.scss";
|
@import '@assets/vue-file-manager/_variables';
|
||||||
|
@import '@assets/vue-file-manager/_mixins';
|
||||||
|
|
||||||
.button {
|
.button {
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
|
|||||||
@@ -19,8 +19,3 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped lang="scss">
|
|
||||||
|
|
||||||
|
|
||||||
</style>
|
|
||||||
|
|||||||
@@ -11,7 +11,6 @@
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped lang="scss">
|
<style scoped lang="scss">
|
||||||
@import "@assets/app.scss";
|
|
||||||
|
|
||||||
#auth {
|
#auth {
|
||||||
height: 100%;
|
height: 100%;
|
||||||
|
|||||||
@@ -88,7 +88,8 @@
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped lang="scss">
|
<style scoped lang="scss">
|
||||||
@import "@assets/app.scss";
|
@import '@assets/vue-file-manager/_variables';
|
||||||
|
@import '@assets/vue-file-manager/_mixins';
|
||||||
|
|
||||||
.popup {
|
.popup {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
|
|||||||
@@ -15,10 +15,11 @@
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped lang="scss">
|
<style scoped lang="scss">
|
||||||
@import "@assets/app.scss";
|
@import '@assets/vue-file-manager/_variables';
|
||||||
|
@import '@assets/vue-file-manager/_mixins';
|
||||||
|
|
||||||
.button-base {
|
.button-base {
|
||||||
@include font-size(16);
|
@include font-size(15);
|
||||||
font-weight: 700;
|
font-weight: 700;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
transition: 0.15s all ease;
|
transition: 0.15s all ease;
|
||||||
|
|||||||
@@ -31,10 +31,11 @@
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped lang="scss">
|
<style scoped lang="scss">
|
||||||
@import "@assets/app.scss";
|
@import '@assets/vue-file-manager/_variables';
|
||||||
|
@import '@assets/vue-file-manager/_mixins';
|
||||||
|
|
||||||
.button-base {
|
.button-base {
|
||||||
@include font-size(16);
|
@include font-size(15);
|
||||||
font-weight: 700;
|
font-weight: 700;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
transition: 0.15s all ease;
|
transition: 0.15s all ease;
|
||||||
|
|||||||
@@ -7,105 +7,272 @@
|
|||||||
ref="contextmenu"
|
ref="contextmenu"
|
||||||
>
|
>
|
||||||
<!--ContextMenu for trash location-->
|
<!--ContextMenu for trash location-->
|
||||||
<ul v-if="$isThisLocation(['trash', 'trash-root']) && $checkPermission('master')" class="menu-options" ref="list">
|
<div v-if="$isThisLocation(['trash', 'trash-root']) && $checkPermission('master')" id="menu-list" class="menu-options">
|
||||||
<li class="menu-option" @click="deleteItem" v-if="item">
|
<ul class="menu-option-group">
|
||||||
{{ $t('context_menu.delete') }}
|
<li class="menu-option" @click="$store.dispatch('restoreItem', item)" v-if="item">
|
||||||
</li>
|
<div class="icon">
|
||||||
<li class="menu-option" @click="$store.dispatch('restoreItem', item)" v-if="item">
|
<life-buoy-icon size="17"></life-buoy-icon>
|
||||||
{{ $t('context_menu.restore') }}
|
</div>
|
||||||
</li>
|
<div class="text-label">
|
||||||
<li class="menu-option" @click="$store.dispatch('emptyTrash')">
|
{{ $t('context_menu.restore') }}
|
||||||
{{ $t('context_menu.empty_trash') }}
|
</div>
|
||||||
</li>
|
</li>
|
||||||
<li class="menu-option" @click="ItemDetail" v-if="item">
|
<li class="menu-option" @click="deleteItem" v-if="item">
|
||||||
{{ $t('context_menu.detail') }}
|
<div class="icon">
|
||||||
</li>
|
<trash-2-icon size="17"></trash-2-icon>
|
||||||
<li class="menu-option" @click="downloadItem" v-if="! isFolder && item">
|
</div>
|
||||||
{{ $t('context_menu.download') }}
|
<div class="text-label">
|
||||||
</li>
|
{{ $t('context_menu.delete') }}
|
||||||
</ul>
|
</div>
|
||||||
|
</li>
|
||||||
|
<li class="menu-option" @click="$store.dispatch('emptyTrash')">
|
||||||
|
<div class="icon">
|
||||||
|
<trash-icon size="17"></trash-icon>
|
||||||
|
</div>
|
||||||
|
<div class="text-label">
|
||||||
|
{{ $t('context_menu.empty_trash') }}
|
||||||
|
</div>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
<ul class="menu-option-group" v-if="item">
|
||||||
|
<li class="menu-option" @click="ItemDetail">
|
||||||
|
<div class="icon">
|
||||||
|
<eye-icon size="17"></eye-icon>
|
||||||
|
</div>
|
||||||
|
<div class="text-label">
|
||||||
|
{{ $t('context_menu.detail') }}
|
||||||
|
</div>
|
||||||
|
</li>
|
||||||
|
<li class="menu-option" @click="downloadItem" v-if="! isFolder">
|
||||||
|
<div class="icon">
|
||||||
|
<download-cloud-icon size="17"></download-cloud-icon>
|
||||||
|
</div>
|
||||||
|
<div class="text-label">
|
||||||
|
{{ $t('context_menu.download') }}
|
||||||
|
</div>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
|
||||||
<!--ContextMenu for Base location with MASTER permission-->
|
<!--ContextMenu for Base location with MASTER permission-->
|
||||||
<ul v-if="$isThisLocation(['shared']) && $checkPermission('master')" class="menu-options" ref="list">
|
<div v-if="$isThisLocation(['shared']) && $checkPermission('master')" id="menu-list" class="menu-options">
|
||||||
<li class="menu-option" @click="addToFavourites" v-if="item && isFolder">
|
<ul class="menu-option-group" v-if="item && isFolder">
|
||||||
{{ isInFavourites ? $t('context_menu.remove_from_favourites') : $t('context_menu.add_to_favourites') }}
|
<li class="menu-option" @click="addToFavourites">
|
||||||
</li>
|
<div class="icon">
|
||||||
<li class="menu-option" @click="deleteItem" v-if="item">
|
<star-icon size="17"></star-icon>
|
||||||
{{ $t('context_menu.delete') }}
|
</div>
|
||||||
</li>
|
<div class="text-label">
|
||||||
<li class="menu-option" @click="shareItem" v-if="item">
|
{{ isInFavourites ? $t('context_menu.remove_from_favourites') : $t('context_menu.add_to_favourites') }}
|
||||||
{{ item.shared ? $t('context_menu.share_edit') : $t('context_menu.share') }}
|
</div>
|
||||||
</li>
|
</li>
|
||||||
<li class="menu-option" @click="ItemDetail" v-if="item">
|
</ul>
|
||||||
{{ $t('context_menu.detail') }}
|
<ul class="menu-option-group" v-if="item">
|
||||||
</li>
|
<li class="menu-option" @click="shareItem">
|
||||||
<li class="menu-option" @click="downloadItem" v-if="! isFolder && item">
|
<div class="icon">
|
||||||
{{ $t('context_menu.download') }}
|
<link-icon size="17"></link-icon>
|
||||||
</li>
|
</div>
|
||||||
</ul>
|
<div class="text-label">
|
||||||
|
{{ item.shared ? $t('context_menu.share_edit') : $t('context_menu.share') }}
|
||||||
|
</div>
|
||||||
|
</li>
|
||||||
|
<li class="menu-option" @click="deleteItem">
|
||||||
|
<div class="icon">
|
||||||
|
<trash-2-icon size="17"></trash-2-icon>
|
||||||
|
</div>
|
||||||
|
<div class="text-label">
|
||||||
|
{{ $t('context_menu.delete') }}
|
||||||
|
</div>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
<ul class="menu-option-group" v-if="item">
|
||||||
|
<li class="menu-option" @click="ItemDetail" v-if="item">
|
||||||
|
<div class="icon">
|
||||||
|
<eye-icon size="17"></eye-icon>
|
||||||
|
</div>
|
||||||
|
<div class="text-label">
|
||||||
|
{{ $t('context_menu.detail') }}
|
||||||
|
</div>
|
||||||
|
</li>
|
||||||
|
<li class="menu-option" @click="downloadItem" v-if="! isFolder">
|
||||||
|
<div class="icon">
|
||||||
|
<download-cloud-icon size="17"></download-cloud-icon>
|
||||||
|
</div>
|
||||||
|
<div class="text-label">
|
||||||
|
{{ $t('context_menu.download') }}
|
||||||
|
</div>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
|
||||||
<!--ContextMenu for Base location with MASTER permission-->
|
<!--ContextMenu for Base location with MASTER permission-->
|
||||||
<ul v-if="$isThisLocation(['base']) && $checkPermission('master')" class="menu-options" ref="list">
|
<div v-if="$isThisLocation(['base', 'participant_uploads', 'latest']) && $checkPermission('master')" id="menu-list" class="menu-options">
|
||||||
<li class="menu-option" @click="addToFavourites" v-if="item && isFolder">
|
|
||||||
{{ isInFavourites ? $t('context_menu.remove_from_favourites') : $t('context_menu.add_to_favourites') }}
|
<ul class="menu-option-group" v-if="! $isThisLocation(['participant_uploads', 'latest'])">
|
||||||
</li>
|
<li class="menu-option" @click="addToFavourites" v-if="item && isFolder">
|
||||||
<li class="menu-option" @click="createFolder">
|
<div class="icon">
|
||||||
{{ $t('context_menu.create_folder') }}
|
<star-icon size="17"></star-icon>
|
||||||
</li>
|
</div>
|
||||||
<li class="menu-option" @click="deleteItem" v-if="item">
|
<div class="text-label">
|
||||||
{{ $t('context_menu.delete') }}
|
{{ isInFavourites ? $t('context_menu.remove_from_favourites') : $t('context_menu.add_to_favourites') }}
|
||||||
</li>
|
</div>
|
||||||
<li class="menu-option" @click="moveItem" v-if="item">
|
</li>
|
||||||
{{ $t('context_menu.move') }}
|
<li class="menu-option" @click="createFolder">
|
||||||
</li>
|
<div class="icon">
|
||||||
<li class="menu-option" @click="shareItem" v-if="item">
|
<folder-plus-icon size="17"></folder-plus-icon>
|
||||||
{{ item.shared ? $t('context_menu.share_edit') : $t('context_menu.share') }}
|
</div>
|
||||||
</li>
|
<div class="text-label">
|
||||||
<li class="menu-option" @click="ItemDetail" v-if="item">
|
{{ $t('context_menu.create_folder') }}
|
||||||
{{ $t('context_menu.detail') }}
|
</div>
|
||||||
</li>
|
</li>
|
||||||
<li class="menu-option" @click="downloadItem" v-if="! isFolder && item">
|
</ul>
|
||||||
{{ $t('context_menu.download') }}
|
<ul class="menu-option-group" v-if="item">
|
||||||
</li>
|
<li class="menu-option" @click="moveItem">
|
||||||
</ul>
|
<div class="icon">
|
||||||
|
<corner-down-right-icon size="17"></corner-down-right-icon>
|
||||||
|
</div>
|
||||||
|
<div class="text-label">
|
||||||
|
{{ $t('context_menu.move') }}
|
||||||
|
</div>
|
||||||
|
</li>
|
||||||
|
<li class="menu-option" @click="shareItem">
|
||||||
|
<div class="icon">
|
||||||
|
<link-icon size="17"></link-icon>
|
||||||
|
</div>
|
||||||
|
<div class="text-label">
|
||||||
|
{{ item.shared ? $t('context_menu.share_edit') : $t('context_menu.share') }}
|
||||||
|
</div>
|
||||||
|
</li>
|
||||||
|
<li class="menu-option" @click="deleteItem">
|
||||||
|
<div class="icon">
|
||||||
|
<trash-2-icon size="17"></trash-2-icon>
|
||||||
|
</div>
|
||||||
|
<div class="text-label">
|
||||||
|
{{ $t('context_menu.delete') }}
|
||||||
|
</div>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
<ul class="menu-option-group" v-if="item">
|
||||||
|
<li class="menu-option" @click="ItemDetail">
|
||||||
|
<div class="icon">
|
||||||
|
<eye-icon size="17"></eye-icon>
|
||||||
|
</div>
|
||||||
|
<div class="text-label">
|
||||||
|
{{ $t('context_menu.detail') }}
|
||||||
|
</div>
|
||||||
|
</li>
|
||||||
|
<li class="menu-option" @click="downloadItem" v-if="! isFolder">
|
||||||
|
<div class="icon">
|
||||||
|
<download-cloud-icon size="17"></download-cloud-icon>
|
||||||
|
</div>
|
||||||
|
<div class="text-label">
|
||||||
|
{{ $t('context_menu.download') }}
|
||||||
|
</div>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
|
||||||
<!--ContextMenu for Base location with EDITOR permission-->
|
<!--ContextMenu for Base location with EDITOR permission-->
|
||||||
<ul v-if="$isThisLocation(['base', 'public']) && $checkPermission('editor')" class="menu-options" ref="list">
|
<div v-if="$isThisLocation(['base', 'public']) && $checkPermission('editor')" id="menu-list" class="menu-options">
|
||||||
<li class="menu-option" @click="createFolder">
|
<ul class="menu-option-group">
|
||||||
{{ $t('context_menu.create_folder') }}
|
<li class="menu-option" @click="createFolder">
|
||||||
</li>
|
<div class="icon">
|
||||||
<li class="menu-option" @click="deleteItem" v-if="item">
|
<folder-plus-icon size="17"></folder-plus-icon>
|
||||||
{{ $t('context_menu.delete') }}
|
</div>
|
||||||
</li>
|
<div class="text-label">
|
||||||
<li class="menu-option" @click="moveItem" v-if="item">
|
{{ $t('context_menu.create_folder') }}
|
||||||
{{ $t('context_menu.move') }}
|
</div>
|
||||||
</li>
|
</li>
|
||||||
<li class="menu-option" @click="ItemDetail" v-if="item">
|
</ul>
|
||||||
{{ $t('context_menu.detail') }}
|
<ul class="menu-option-group" v-if="item">
|
||||||
</li>
|
<li class="menu-option" @click="moveItem">
|
||||||
<li class="menu-option" @click="downloadItem" v-if="! isFolder && item">
|
<div class="icon">
|
||||||
{{ $t('context_menu.download') }}
|
<corner-down-right-icon size="17"></corner-down-right-icon>
|
||||||
</li>
|
</div>
|
||||||
</ul>
|
<div class="text-label">
|
||||||
|
{{ $t('context_menu.move') }}
|
||||||
|
</div>
|
||||||
|
</li>
|
||||||
|
<li class="menu-option" @click="deleteItem">
|
||||||
|
<div class="icon">
|
||||||
|
<trash-2-icon size="17"></trash-2-icon>
|
||||||
|
</div>
|
||||||
|
<div class="text-label">
|
||||||
|
{{ $t('context_menu.delete') }}
|
||||||
|
</div>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
<ul class="menu-option-group" v-if="item">
|
||||||
|
<li class="menu-option" @click="ItemDetail">
|
||||||
|
<div class="icon">
|
||||||
|
<eye-icon size="17"></eye-icon>
|
||||||
|
</div>
|
||||||
|
<div class="text-label">
|
||||||
|
{{ $t('context_menu.detail') }}
|
||||||
|
</div>
|
||||||
|
</li>
|
||||||
|
<li class="menu-option" @click="downloadItem" v-if="! isFolder">
|
||||||
|
<div class="icon">
|
||||||
|
<download-cloud-icon size="17"></download-cloud-icon>
|
||||||
|
</div>
|
||||||
|
<div class="text-label">
|
||||||
|
{{ $t('context_menu.download') }}
|
||||||
|
</div>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
|
||||||
<!--ContextMenu for Base location with VISITOR permission-->
|
<!--ContextMenu for Base location with VISITOR permission-->
|
||||||
<ul v-if="$isThisLocation(['base', 'public']) && $checkPermission('visitor')" class="menu-options" ref="list">
|
<div v-if="$isThisLocation(['base', 'public']) && $checkPermission('visitor')" id="menu-list" class="menu-options">
|
||||||
<li class="menu-option" @click="ItemDetail" v-if="item">
|
<ul class="menu-option-group" v-if="item">
|
||||||
{{ $t('context_menu.detail') }}
|
<li class="menu-option" @click="ItemDetail">
|
||||||
</li>
|
<div class="icon">
|
||||||
<li class="menu-option" @click="downloadItem" v-if="! isFolder && item">
|
<eye-icon size="17"></eye-icon>
|
||||||
{{ $t('context_menu.download') }}
|
</div>
|
||||||
</li>
|
<div class="text-label">
|
||||||
</ul>
|
{{ $t('context_menu.detail') }}
|
||||||
|
</div>
|
||||||
|
</li>
|
||||||
|
<li class="menu-option" @click="downloadItem" v-if="! isFolder">
|
||||||
|
<div class="icon">
|
||||||
|
<download-cloud-icon size="17"></download-cloud-icon>
|
||||||
|
</div>
|
||||||
|
<div class="text-label">
|
||||||
|
{{ $t('context_menu.download') }}
|
||||||
|
</div>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
|
import {
|
||||||
|
CornerDownRightIcon,
|
||||||
|
DownloadCloudIcon,
|
||||||
|
FolderPlusIcon,
|
||||||
|
LifeBuoyIcon,
|
||||||
|
Trash2Icon,
|
||||||
|
TrashIcon,
|
||||||
|
StarIcon,
|
||||||
|
LinkIcon,
|
||||||
|
EyeIcon,
|
||||||
|
} from 'vue-feather-icons'
|
||||||
import {mapGetters} from 'vuex'
|
import {mapGetters} from 'vuex'
|
||||||
import {events} from '@/bus'
|
import {events} from '@/bus'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'ContextMenu',
|
name: 'ContextMenu',
|
||||||
|
components: {
|
||||||
|
CornerDownRightIcon,
|
||||||
|
DownloadCloudIcon,
|
||||||
|
FolderPlusIcon,
|
||||||
|
LifeBuoyIcon,
|
||||||
|
Trash2Icon,
|
||||||
|
TrashIcon,
|
||||||
|
LinkIcon,
|
||||||
|
StarIcon,
|
||||||
|
EyeIcon,
|
||||||
|
},
|
||||||
computed: {
|
computed: {
|
||||||
...mapGetters(['app']),
|
...mapGetters(['app']),
|
||||||
isFolder() {
|
isFolder() {
|
||||||
@@ -145,7 +312,7 @@
|
|||||||
},
|
},
|
||||||
addToFavourites() {
|
addToFavourites() {
|
||||||
// Check if folder is in favourites and then add/remove from favourites
|
// Check if folder is in favourites and then add/remove from favourites
|
||||||
if (this.app.favourites && ! this.app.favourites.find(el => el.unique_id == this.item.unique_id)) {
|
if (this.app.favourites && !this.app.favourites.find(el => el.unique_id == this.item.unique_id)) {
|
||||||
this.$store.dispatch('addToFavourites', this.item)
|
this.$store.dispatch('addToFavourites', this.item)
|
||||||
} else {
|
} else {
|
||||||
this.$store.dispatch('removeFromFavourites', this.item)
|
this.$store.dispatch('removeFromFavourites', this.item)
|
||||||
@@ -159,6 +326,7 @@
|
|||||||
)
|
)
|
||||||
},
|
},
|
||||||
ItemDetail() {
|
ItemDetail() {
|
||||||
|
|
||||||
// Dispatch load file info detail
|
// Dispatch load file info detail
|
||||||
this.$store.commit('GET_FILEINFO_DETAIL', this.item)
|
this.$store.commit('GET_FILEINFO_DETAIL', this.item)
|
||||||
|
|
||||||
@@ -180,8 +348,20 @@
|
|||||||
// Reset item container
|
// Reset item container
|
||||||
this.item = undefined
|
this.item = undefined
|
||||||
},
|
},
|
||||||
showContextMenu(event, item) {
|
showFolderActionsMenu() {
|
||||||
let VerticalOffsetArea = item && this.$refs.list.children ? this.$refs.list.children.length * 50 : 50
|
let container = document.getElementById('folder-actions')
|
||||||
|
|
||||||
|
this.positionX = container.offsetLeft + 16
|
||||||
|
this.positionY = container.offsetTop + 30
|
||||||
|
|
||||||
|
// Show context menu
|
||||||
|
this.isVisible = true
|
||||||
|
},
|
||||||
|
showContextMenu(event) {
|
||||||
|
let parent = document.getElementById('menu-list')
|
||||||
|
let nodesSameClass = parent.getElementsByClassName("menu-option")
|
||||||
|
|
||||||
|
let VerticalOffsetArea = nodesSameClass.length * 50
|
||||||
let HorizontalOffsetArea = 190
|
let HorizontalOffsetArea = 190
|
||||||
|
|
||||||
let container = document.getElementById('files-view')
|
let container = document.getElementById('files-view')
|
||||||
@@ -220,15 +400,42 @@
|
|||||||
})
|
})
|
||||||
|
|
||||||
events.$on('contextMenu:hide', () => (this.closeAndResetContextMenu()))
|
events.$on('contextMenu:hide', () => (this.closeAndResetContextMenu()))
|
||||||
|
|
||||||
|
events.$on('folder:actions', folder => {
|
||||||
|
|
||||||
|
// Store item
|
||||||
|
this.item = folder
|
||||||
|
|
||||||
|
if (this.isVisible)
|
||||||
|
this.isVisible = false
|
||||||
|
else
|
||||||
|
this.showFolderActionsMenu()
|
||||||
|
|
||||||
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped lang="scss">
|
<style scoped lang="scss">
|
||||||
@import "@assets/app.scss";
|
@import '@assets/vue-file-manager/_variables';
|
||||||
|
@import '@assets/vue-file-manager/_mixins';
|
||||||
|
|
||||||
|
.menu-option {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
|
||||||
|
.icon {
|
||||||
|
margin-right: 20px;
|
||||||
|
line-height: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.text-label {
|
||||||
|
@include font-size(16);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
.contextmenu {
|
.contextmenu {
|
||||||
min-width: 190px;
|
min-width: 250px;
|
||||||
position: absolute;
|
position: absolute;
|
||||||
z-index: 99;
|
z-index: 99;
|
||||||
box-shadow: $shadow;
|
box-shadow: $shadow;
|
||||||
@@ -239,26 +446,47 @@
|
|||||||
&.showed {
|
&.showed {
|
||||||
display: block;
|
display: block;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
.menu-options {
|
.menu-options {
|
||||||
list-style: none;
|
list-style: none;
|
||||||
|
width: 100%;
|
||||||
|
margin: 0;
|
||||||
|
padding: 0;
|
||||||
|
|
||||||
|
.menu-option-group {
|
||||||
|
padding: 5px 0;
|
||||||
|
border-bottom: 1px solid $light_mode_border;
|
||||||
|
|
||||||
|
&:first-child {
|
||||||
|
padding-top: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
&:last-child {
|
||||||
|
padding-bottom: 0;
|
||||||
|
border-bottom: none;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.menu-option {
|
||||||
|
white-space: nowrap;
|
||||||
|
font-weight: 700;
|
||||||
|
@include font-size(14);
|
||||||
|
padding: 15px 20px;
|
||||||
|
cursor: pointer;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
margin: 0;
|
color: $text;
|
||||||
padding: 0;
|
|
||||||
|
|
||||||
.menu-option {
|
&:hover {
|
||||||
white-space: nowrap;
|
background: $light_background;
|
||||||
font-weight: 700;
|
|
||||||
@include font-size(15);
|
|
||||||
padding: 15px 30px;
|
|
||||||
cursor: pointer;
|
|
||||||
width: 100%;
|
|
||||||
color: $text;
|
|
||||||
|
|
||||||
&:hover {
|
.text-label {
|
||||||
background: $light_background;
|
|
||||||
color: $theme;
|
color: $theme;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
path, line, polyline, rect, circle, polygon {
|
||||||
|
stroke: $theme;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -268,11 +496,18 @@
|
|||||||
.contextmenu {
|
.contextmenu {
|
||||||
background: $dark_mode_foreground;
|
background: $dark_mode_foreground;
|
||||||
|
|
||||||
.menu-options .menu-option {
|
.menu-options {
|
||||||
color: $dark_mode_text_primary;
|
|
||||||
|
|
||||||
&:hover {
|
.menu-option-group {
|
||||||
background: $dark_mode_background;
|
border-color: $dark_mode_border_color;
|
||||||
|
}
|
||||||
|
|
||||||
|
.menu-option {
|
||||||
|
color: $dark_mode_text_primary;
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
background: rgba($theme, 0.1);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,24 +1,24 @@
|
|||||||
<template>
|
<template>
|
||||||
<div id="desktop-toolbar" v-if="! $isMinimalScale()">
|
<div id="desktop-toolbar">
|
||||||
<div class="toolbar-wrapper">
|
<div class="toolbar-wrapper">
|
||||||
|
|
||||||
<!-- Go back-->
|
<!-- Go back-->
|
||||||
<div class="toolbar-go-back" v-if="homeDirectory">
|
<div class="toolbar-go-back" v-if="homeDirectory">
|
||||||
<div @click="goBack" class="go-back-button">
|
<div @click="goBack" class="go-back-button">
|
||||||
<FontAwesomeIcon
|
<chevron-left-icon size="17" :class="{'is-active': browseHistory.length > 1}" class="icon-back"></chevron-left-icon>
|
||||||
v-if="browseHistory.length > 0"
|
|
||||||
class="icon-back"
|
|
||||||
icon="chevron-left"
|
|
||||||
></FontAwesomeIcon>
|
|
||||||
<span class="back-directory-title">
|
<span class="back-directory-title">
|
||||||
{{ directoryName }}
|
{{ directoryName }}
|
||||||
</span>
|
</span>
|
||||||
|
|
||||||
|
<span @click.stop="folderActions" v-if="browseHistory.length > 1 && $isThisLocation(['base', 'public'])" class="folder-options" id="folder-actions">
|
||||||
|
<more-horizontal-icon size="14" class="icon-more"></more-horizontal-icon>
|
||||||
|
</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- Tools-->
|
<!-- Tools-->
|
||||||
<div class="toolbar-tools">
|
<div class="toolbar-tools">
|
||||||
|
|
||||||
<!--Search bar-->
|
<!--Search bar-->
|
||||||
<div class="toolbar-button-wrapper">
|
<div class="toolbar-button-wrapper">
|
||||||
<SearchBar/>
|
<SearchBar/>
|
||||||
@@ -27,21 +27,40 @@
|
|||||||
<!--Files controlls-->
|
<!--Files controlls-->
|
||||||
<div class="toolbar-button-wrapper" v-if="$checkPermission(['master', 'editor'])">
|
<div class="toolbar-button-wrapper" v-if="$checkPermission(['master', 'editor'])">
|
||||||
<ToolbarButtonUpload
|
<ToolbarButtonUpload
|
||||||
source="upload"
|
:class="{'is-inactive': canUploadInView}"
|
||||||
:action="$t('actions.upload')"
|
:action="$t('actions.upload')"
|
||||||
/>
|
/>
|
||||||
<ToolbarButton
|
<ToolbarButton
|
||||||
source="trash-alt"
|
:class="{'is-inactive': canCreateFolderInView}"
|
||||||
:action="$t('actions.delete')"
|
|
||||||
@click.native="deleteItems"
|
|
||||||
/>
|
|
||||||
<ToolbarButton
|
|
||||||
@click.native="createFolder"
|
@click.native="createFolder"
|
||||||
source="folder-plus"
|
source="folder-plus"
|
||||||
:action="$t('actions.create_folder')"
|
:action="$t('actions.create_folder')"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<div class="toolbar-button-wrapper"
|
||||||
|
v-if="$checkPermission(['master', 'editor'])">
|
||||||
|
<ToolbarButton
|
||||||
|
source="move"
|
||||||
|
:class="{'is-inactive': canMoveInView}"
|
||||||
|
:action="$t('actions.move')"
|
||||||
|
@click.native="moveItem"
|
||||||
|
/>
|
||||||
|
<ToolbarButton
|
||||||
|
v-if="! $isThisLocation(['public'])"
|
||||||
|
source="share"
|
||||||
|
:class="{'is-inactive': canShareInView}"
|
||||||
|
:action="$t('actions.share')"
|
||||||
|
@click.native="shareItem"
|
||||||
|
/>
|
||||||
|
<ToolbarButton
|
||||||
|
source="trash"
|
||||||
|
:class="{'is-inactive': canDeleteInView}"
|
||||||
|
:action="$t('actions.delete')"
|
||||||
|
@click.native="deleteItem"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
|
||||||
<!--View options-->
|
<!--View options-->
|
||||||
<div class="toolbar-button-wrapper">
|
<div class="toolbar-button-wrapper">
|
||||||
<ToolbarButton
|
<ToolbarButton
|
||||||
@@ -63,89 +82,108 @@
|
|||||||
|
|
||||||
<script>
|
<script>
|
||||||
import ToolbarButtonUpload from '@/components/FilesView/ToolbarButtonUpload'
|
import ToolbarButtonUpload from '@/components/FilesView/ToolbarButtonUpload'
|
||||||
|
import { ChevronLeftIcon, MoreHorizontalIcon } from 'vue-feather-icons'
|
||||||
import UploadProgress from '@/components/FilesView/UploadProgress'
|
import UploadProgress from '@/components/FilesView/UploadProgress'
|
||||||
import ToolbarButton from '@/components/FilesView/ToolbarButton'
|
import ToolbarButton from '@/components/FilesView/ToolbarButton'
|
||||||
import SearchBar from '@/components/FilesView/SearchBar'
|
import SearchBar from '@/components/FilesView/SearchBar'
|
||||||
import {mapGetters} from 'vuex'
|
import {mapGetters} from 'vuex'
|
||||||
import {events} from '@/bus'
|
import {events} from '@/bus'
|
||||||
|
import {last} from 'lodash'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'ToolBar',
|
name: 'ToolBar',
|
||||||
components: {
|
components: {
|
||||||
ToolbarButtonUpload,
|
ToolbarButtonUpload,
|
||||||
|
MoreHorizontalIcon,
|
||||||
|
ChevronLeftIcon,
|
||||||
UploadProgress,
|
UploadProgress,
|
||||||
ToolbarButton,
|
ToolbarButton,
|
||||||
SearchBar
|
SearchBar
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
...mapGetters([
|
...mapGetters([
|
||||||
|
'FilePreviewType',
|
||||||
'fileInfoVisible',
|
'fileInfoVisible',
|
||||||
'fileInfoDetail',
|
'fileInfoDetail',
|
||||||
'currentFolder',
|
'currentFolder',
|
||||||
'browseHistory',
|
'browseHistory',
|
||||||
'homeDirectory',
|
'homeDirectory',
|
||||||
'FilePreviewType',
|
|
||||||
]),
|
]),
|
||||||
directoryName() {
|
directoryName() {
|
||||||
return this.currentFolder ? this.currentFolder.name : this.homeDirectory.name
|
return this.currentFolder ? this.currentFolder.name : this.homeDirectory.name
|
||||||
},
|
},
|
||||||
previousFolder() {
|
|
||||||
const length = this.browseHistory.length - 2
|
|
||||||
|
|
||||||
return this.browseHistory[length] ? this.browseHistory[length] : this.homeDirectory
|
|
||||||
},
|
|
||||||
preview() {
|
preview() {
|
||||||
return this.FilePreviewType === 'list' ? 'th' : 'th-list'
|
return this.FilePreviewType === 'list' ? 'th' : 'th-list'
|
||||||
},
|
},
|
||||||
},
|
canCreateFolderInView() {
|
||||||
data() {
|
return ! this.$isThisLocation(['base', 'public'])
|
||||||
return {
|
},
|
||||||
isSidebarMenu: false,
|
canDeleteInView() {
|
||||||
|
return ! this.$isThisLocation(['trash', 'trash-root', 'base', 'participant_uploads', 'latest', 'shared', 'public'])
|
||||||
|
},
|
||||||
|
canUploadInView() {
|
||||||
|
return ! this.$isThisLocation(['base', 'public'])
|
||||||
|
},
|
||||||
|
canMoveInView() {
|
||||||
|
return ! this.$isThisLocation(['base', 'participant_uploads', 'latest', 'shared', 'public'])
|
||||||
|
},
|
||||||
|
canShareInView() {
|
||||||
|
return ! this.$isThisLocation(['base', 'participant_uploads', 'latest', 'shared', 'public'])
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
showSidebarMenu() {
|
|
||||||
this.isSidebarMenu = ! this.isSidebarMenu
|
|
||||||
events.$emit('show:sidebar')
|
|
||||||
},
|
|
||||||
goBack() {
|
goBack() {
|
||||||
|
// Get previous folder
|
||||||
|
let previousFolder = last(this.browseHistory)
|
||||||
|
|
||||||
if (this.previousFolder.location === 'trash-root') {
|
if (! previousFolder)
|
||||||
|
return
|
||||||
|
|
||||||
|
if (previousFolder.location === 'trash-root') {
|
||||||
this.$store.dispatch('getTrash')
|
this.$store.dispatch('getTrash')
|
||||||
this.$store.commit('FLUSH_BROWSER_HISTORY')
|
|
||||||
|
} else if (previousFolder.location === 'shared') {
|
||||||
|
this.$store.dispatch('getShared')
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
if ( this.$isThisLocation('public') ) {
|
if ( this.$isThisLocation('public') ) {
|
||||||
this.$store.dispatch('browseShared', [this.previousFolder, true])
|
this.$store.dispatch('browseShared', [{folder: previousFolder, back: true, init: false}])
|
||||||
} else {
|
} else {
|
||||||
this.$store.dispatch('getFolder', [this.previousFolder, true])
|
this.$store.dispatch('getFolder', [{folder: previousFolder, back: true, init: false}])
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
deleteItems() {
|
folderActions() {
|
||||||
|
events.$emit('folder:actions', this.currentFolder)
|
||||||
|
},
|
||||||
|
deleteItem() {
|
||||||
events.$emit('items:delete')
|
events.$emit('items:delete')
|
||||||
},
|
},
|
||||||
createFolder() {
|
createFolder() {
|
||||||
if (! this.$isThisLocation(['trash', 'trash-root']))
|
this.$createFolder()
|
||||||
this.$createFolder()
|
},
|
||||||
|
moveItem() {
|
||||||
|
events.$emit('popup:open', {name: 'move', item: this.fileInfoDetail})
|
||||||
|
},
|
||||||
|
shareItem() {
|
||||||
|
if (this.fileInfoDetail.shared) {
|
||||||
|
events.$emit('popup:open', {name: 'share-edit', item: this.fileInfoDetail})
|
||||||
|
} else {
|
||||||
|
events.$emit('popup:open', {name: 'share-create', item: this.fileInfoDetail})
|
||||||
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
created() {
|
|
||||||
// Listen for hide sidebar
|
|
||||||
events.$on('show:content', () => {
|
|
||||||
if (this.isSidebarMenu) this.isSidebarMenu = false
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped lang="scss">
|
<style scoped lang="scss">
|
||||||
@import "@assets/app.scss";
|
@import '@assets/vue-file-manager/_variables';
|
||||||
|
@import '@assets/vue-file-manager/_mixins';
|
||||||
|
|
||||||
.toolbar-wrapper {
|
.toolbar-wrapper {
|
||||||
padding-top: 15px;
|
padding-top: 10px;
|
||||||
padding-bottom: 15px;
|
padding-bottom: 10px;
|
||||||
display: flex;
|
display: flex;
|
||||||
position: relative;
|
position: relative;
|
||||||
z-index: 2;
|
z-index: 2;
|
||||||
@@ -171,13 +209,48 @@
|
|||||||
.icon-back {
|
.icon-back {
|
||||||
vertical-align: middle;
|
vertical-align: middle;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
margin-right: 12px;
|
margin-right: 6px;
|
||||||
|
opacity: 0.15;
|
||||||
|
pointer-events: none;
|
||||||
|
@include transition(150ms);
|
||||||
|
|
||||||
|
&.is-active {
|
||||||
|
opacity: 1;
|
||||||
|
pointer-events: initial;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.toolbar-go-back {
|
.toolbar-go-back {
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
|
|
||||||
|
.folder-options {
|
||||||
|
vertical-align: middle;
|
||||||
|
margin-left: 6px;
|
||||||
|
padding: 1px 4px;
|
||||||
|
line-height: 0;
|
||||||
|
border-radius: 3px;
|
||||||
|
@include transition(150ms);
|
||||||
|
|
||||||
|
svg circle {
|
||||||
|
@include transition(150ms);
|
||||||
|
}
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
background: $light_background;
|
||||||
|
|
||||||
|
svg circle {
|
||||||
|
stroke: $theme;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon-more {
|
||||||
|
vertical-align: middle;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
.back-directory-title {
|
.back-directory-title {
|
||||||
|
@include font-size(15);
|
||||||
line-height: 1;
|
line-height: 1;
|
||||||
font-weight: 700;
|
font-weight: 700;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
@@ -201,7 +274,7 @@
|
|||||||
text-align: right;
|
text-align: right;
|
||||||
|
|
||||||
.toolbar-button-wrapper {
|
.toolbar-button-wrapper {
|
||||||
margin-left: 75px;
|
margin-left: 28px;
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
vertical-align: middle;
|
vertical-align: middle;
|
||||||
|
|
||||||
@@ -210,8 +283,21 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
button {
|
.button {
|
||||||
margin-left: 20px;
|
margin-left: 5px;
|
||||||
|
|
||||||
|
&.active {
|
||||||
|
/deep/ svg {
|
||||||
|
line, circle {
|
||||||
|
stroke: $theme;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&.is-inactive {
|
||||||
|
opacity: 0.25;
|
||||||
|
pointer-events: none;
|
||||||
|
}
|
||||||
|
|
||||||
&:first-child {
|
&:first-child {
|
||||||
margin-left: 0;
|
margin-left: 0;
|
||||||
@@ -219,6 +305,33 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@media only screen and (max-width: 1024px) {
|
||||||
|
|
||||||
|
.toolbar-go-back .back-directory-title {
|
||||||
|
max-width: 120px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.toolbar-tools {
|
||||||
|
|
||||||
|
.button {
|
||||||
|
margin-left: 0;
|
||||||
|
height: 40px;
|
||||||
|
width: 40px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.toolbar-button-wrapper {
|
||||||
|
margin-left: 25px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@media only screen and (max-width: 960px) {
|
||||||
|
|
||||||
|
#desktop-toolbar {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@media (prefers-color-scheme: dark) {
|
@media (prefers-color-scheme: dark) {
|
||||||
.toolbar .directory-name {
|
.toolbar .directory-name {
|
||||||
color: $dark_mode_text_primary;
|
color: $dark_mode_text_primary;
|
||||||
@@ -229,6 +342,13 @@
|
|||||||
.back-directory-title {
|
.back-directory-title {
|
||||||
color: $dark_mode_text_primary;
|
color: $dark_mode_text_primary;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.folder-options {
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
background: $dark_mode_foreground;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
@@ -1,21 +1,27 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="empty-message">
|
<div class="empty-message">
|
||||||
<div class="message">
|
<div class="message">
|
||||||
<FontAwesomeIcon class="icon" :icon="icon"/>
|
<eye-off-icon v-if="icon === 'eye-off'" size="36" class="icon"></eye-off-icon>
|
||||||
<p>{{ message }}</p>
|
<p>{{ message }}</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
|
import { EyeOffIcon } from 'vue-feather-icons'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'EmptyMessage',
|
name: 'EmptyMessage',
|
||||||
props: ['icon', 'message']
|
props: ['icon', 'message'],
|
||||||
|
components: {
|
||||||
|
EyeOffIcon
|
||||||
|
}
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped lang="scss">
|
<style scoped lang="scss">
|
||||||
@import "@assets/app.scss";
|
@import '@assets/vue-file-manager/_variables';
|
||||||
|
@import '@assets/vue-file-manager/_mixins';
|
||||||
|
|
||||||
.empty-message {
|
.empty-message {
|
||||||
text-align: center;
|
text-align: center;
|
||||||
@@ -29,17 +35,14 @@
|
|||||||
p {
|
p {
|
||||||
margin-top: 10px;
|
margin-top: 10px;
|
||||||
max-width: 130px;
|
max-width: 130px;
|
||||||
@include font-size(14);
|
@include font-size(13);
|
||||||
font-weight: 500;
|
font-weight: 500;
|
||||||
color: $text-muted;
|
color: $text-muted;
|
||||||
}
|
}
|
||||||
|
|
||||||
.icon {
|
.icon {
|
||||||
@include font-size(36);
|
path, line, polyline, rect, circle {
|
||||||
color: $text;
|
stroke: $text;
|
||||||
|
|
||||||
path {
|
|
||||||
fill: $text;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -47,8 +50,9 @@
|
|||||||
|
|
||||||
@media (prefers-color-scheme: dark) {
|
@media (prefers-color-scheme: dark) {
|
||||||
.empty-message .message .icon {
|
.empty-message .message .icon {
|
||||||
path {
|
|
||||||
fill: $dark_mode_text_secondary;
|
path, line, polyline, rect, circle {
|
||||||
|
stroke: $dark_mode_text_secondary;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -12,13 +12,17 @@
|
|||||||
<h1 class="title">{{ $t('empty_page.title') }}</h1>
|
<h1 class="title">{{ $t('empty_page.title') }}</h1>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<!--Trash empty message-->
|
||||||
|
<div class="text-content" v-if="$isThisLocation(['participant_uploads']) && ! isLoading">
|
||||||
|
<h1 class="title">{{ $t('messages.nothing_from_participants') }}</h1>
|
||||||
|
</div>
|
||||||
|
|
||||||
<!--Base file browser empty message-->
|
<!--Base file browser empty message-->
|
||||||
<div class="text-content" v-if="$isThisLocation(['base', 'public']) && !isLoading">
|
<div class="text-content" v-if="$isThisLocation(['base', 'public', 'latest']) && !isLoading">
|
||||||
<h1 class="title">{{ $t('empty_page.title') }}</h1>
|
<h1 class="title">{{ $t('empty_page.title') }}</h1>
|
||||||
<p v-if="$checkPermission(['master', 'editor'])" class="description">{{ $t('empty_page.description') }}</p>
|
<p v-if="$checkPermission(['master', 'editor'])" class="description">{{ $t('empty_page.description') }}</p>
|
||||||
<ButtonUpload
|
<ButtonUpload
|
||||||
v-if="$checkPermission(['master', 'editor'])"
|
v-if="$checkPermission(['master', 'editor'])"
|
||||||
@input.native="$uploadFiles"
|
|
||||||
button-style="theme"
|
button-style="theme"
|
||||||
>
|
>
|
||||||
{{ $t('empty_page.call_to_action') }}
|
{{ $t('empty_page.call_to_action') }}
|
||||||
@@ -55,7 +59,8 @@
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped lang="scss">
|
<style scoped lang="scss">
|
||||||
@import "@assets/app.scss";
|
@import '@assets/vue-file-manager/_variables';
|
||||||
|
@import '@assets/vue-file-manager/_mixins';
|
||||||
|
|
||||||
.empty-page {
|
.empty-page {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
@@ -79,14 +84,14 @@
|
|||||||
margin: 30px 0;
|
margin: 30px 0;
|
||||||
|
|
||||||
.title {
|
.title {
|
||||||
@include font-size(24);
|
@include font-size(20);
|
||||||
color: $text;
|
color: $text;
|
||||||
font-weight: 700;
|
font-weight: 700;
|
||||||
margin: 0;
|
margin: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
.description {
|
.description {
|
||||||
@include font-size(15);
|
@include font-size(13);
|
||||||
color: $text-muted;
|
color: $text-muted;
|
||||||
margin-bottom: 20px;
|
margin-bottom: 20px;
|
||||||
display: block;
|
display: block;
|
||||||
|
|||||||
@@ -15,7 +15,7 @@
|
|||||||
<MobileToolbar />
|
<MobileToolbar />
|
||||||
|
|
||||||
<!--Searchbar-->
|
<!--Searchbar-->
|
||||||
<SearchBar v-if="$isMinimalScale()" class="mobile-search"/>
|
<SearchBar class="mobile-search" />
|
||||||
|
|
||||||
<!--Mobile Actions-->
|
<!--Mobile Actions-->
|
||||||
<MobileActions />
|
<MobileActions />
|
||||||
@@ -77,7 +77,7 @@
|
|||||||
<FileInfoPanel v-if="fileInfoDetail"/>
|
<FileInfoPanel v-if="fileInfoDetail"/>
|
||||||
|
|
||||||
<!--If file info panel empty show message-->
|
<!--If file info panel empty show message-->
|
||||||
<EmptyMessage v-if="!fileInfoDetail" :message="$t('messages.nothing_to_preview')" icon="eye-slash"/>
|
<EmptyMessage v-if="!fileInfoDetail" :message="$t('messages.nothing_to_preview')" icon="eye-off"/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
@@ -209,7 +209,8 @@
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped lang="scss">
|
<style scoped lang="scss">
|
||||||
@import "@assets/app.scss";
|
@import '@assets/vue-file-manager/_variables';
|
||||||
|
@import '@assets/vue-file-manager/_mixins';
|
||||||
|
|
||||||
.button-upload {
|
.button-upload {
|
||||||
display: block;
|
display: block;
|
||||||
@@ -218,6 +219,7 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
.mobile-search {
|
.mobile-search {
|
||||||
|
display: none;
|
||||||
margin-bottom: 10px;
|
margin-bottom: 10px;
|
||||||
margin-top: 10px;
|
margin-top: 10px;
|
||||||
}
|
}
|
||||||
@@ -276,11 +278,70 @@
|
|||||||
transform: translateX(-20px);
|
transform: translateX(-20px);
|
||||||
}
|
}
|
||||||
|
|
||||||
.file-leave-active {
|
@media only screen and (min-width: 960px) {
|
||||||
position: absolute;
|
|
||||||
|
.file-content {
|
||||||
|
position: absolute;
|
||||||
|
top: 72px;
|
||||||
|
left: 15px;
|
||||||
|
right: 15px;
|
||||||
|
bottom: 0;
|
||||||
|
@include transition;
|
||||||
|
|
||||||
|
&.is-offset {
|
||||||
|
margin-top: 50px;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@media only screen and (max-width: 660px) {
|
@media only screen and (max-width: 960px) {
|
||||||
|
|
||||||
|
.file-info-container {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.mobile-search {
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@media only screen and (max-width: 690px) {
|
||||||
|
|
||||||
|
.files-container {
|
||||||
|
padding-left: 15px;
|
||||||
|
padding-right: 15px;
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
right: 0;
|
||||||
|
bottom: 0;
|
||||||
|
position: fixed;
|
||||||
|
overflow-y: auto;
|
||||||
|
|
||||||
|
.file-list {
|
||||||
|
|
||||||
|
&.grid {
|
||||||
|
grid-template-columns: repeat(auto-fill, 120px);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.file-content {
|
||||||
|
position: absolute;
|
||||||
|
top: 0;
|
||||||
|
left: 0px;
|
||||||
|
right: 0px;
|
||||||
|
bottom: 0;
|
||||||
|
@include transition;
|
||||||
|
|
||||||
|
&.is-offset {
|
||||||
|
margin-top: 50px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.mobile-search {
|
||||||
|
margin-bottom: 0;
|
||||||
|
}
|
||||||
|
|
||||||
.file-info-container {
|
.file-info-container {
|
||||||
display: none;
|
display: none;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,12 +7,15 @@
|
|||||||
<div class="flex">
|
<div class="flex">
|
||||||
<div class="icon">
|
<div class="icon">
|
||||||
<div class="icon-preview">
|
<div class="icon-preview">
|
||||||
<FontAwesomeIcon :icon="filePreviewIcon"></FontAwesomeIcon>
|
<image-icon v-if="fileType === 'image'" size="21"></image-icon>
|
||||||
|
<video-icon v-if="fileType === 'video'" size="21"></video-icon>
|
||||||
|
<folder-icon v-if="fileType === 'folder'" size="21"></folder-icon>
|
||||||
|
<file-icon v-if="fileType === 'file'" size="21"></file-icon>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="file-info">
|
<div class="file-info">
|
||||||
<span ref="name" class="name">{{ fileInfoDetail.name }}</span>
|
<span ref="name" class="name">{{ fileInfoDetail.name }}</span>
|
||||||
<span class="mimetype" v-if="fileInfoDetail.mimetype">{{ fileInfoDetail.mimetype }}</span>
|
<span class="mimetype" v-if="fileInfoDetail.mimetype">.{{ fileInfoDetail.mimetype }}</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -42,8 +45,8 @@
|
|||||||
<li v-if="$checkPermission(['master'])" class="list-info-item">
|
<li v-if="$checkPermission(['master'])" class="list-info-item">
|
||||||
<b>{{ $t('file_detail.where') }}</b>
|
<b>{{ $t('file_detail.where') }}</b>
|
||||||
<div class="action-button" @click="moveItem">
|
<div class="action-button" @click="moveItem">
|
||||||
<FontAwesomeIcon class="icon" icon="pencil-alt" />
|
|
||||||
<span>{{ fileInfoDetail.parent ? fileInfoDetail.parent.name : $t('locations.home') }}</span>
|
<span>{{ fileInfoDetail.parent ? fileInfoDetail.parent.name : $t('locations.home') }}</span>
|
||||||
|
<edit-2-icon size="10" class="edit-icon"></edit-2-icon>
|
||||||
</div>
|
</div>
|
||||||
</li>
|
</li>
|
||||||
|
|
||||||
@@ -51,11 +54,13 @@
|
|||||||
<li v-if="$checkPermission('master') && fileInfoDetail.shared" class="list-info-item">
|
<li v-if="$checkPermission('master') && fileInfoDetail.shared" class="list-info-item">
|
||||||
<b>{{ $t('file_detail.shared') }}</b>
|
<b>{{ $t('file_detail.shared') }}</b>
|
||||||
<div class="action-button" @click="shareItemOptions">
|
<div class="action-button" @click="shareItemOptions">
|
||||||
<FontAwesomeIcon class="icon" :icon="sharedIcon" />
|
|
||||||
<span>{{ sharedInfo }}</span>
|
<span>{{ sharedInfo }}</span>
|
||||||
|
<edit-2-icon size="10" class="edit-icon"></edit-2-icon>
|
||||||
</div>
|
</div>
|
||||||
<div class="sharelink">
|
<div class="sharelink">
|
||||||
<FontAwesomeIcon class="lock-icon" :icon="lockIcon" @click="shareItemOptions" />
|
<lock-icon v-if="isLocked" @click="shareItemOptions" class="lock-icon" size="17"></lock-icon>
|
||||||
|
<unlock-icon v-if="! isLocked" @click="shareItemOptions" class="lock-icon" size="17"></unlock-icon>
|
||||||
|
|
||||||
<CopyInput class="copy-sharelink" size="small" :value="fileInfoDetail.shared.link" />
|
<CopyInput class="copy-sharelink" size="small" :value="fileInfoDetail.shared.link" />
|
||||||
</div>
|
</div>
|
||||||
</li>
|
</li>
|
||||||
@@ -64,6 +69,7 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
|
import { Edit2Icon, LockIcon, UnlockIcon, ImageIcon, VideoIcon, FolderIcon, FileIcon } from 'vue-feather-icons'
|
||||||
import FilePreview from '@/components/FilesView/FilePreview'
|
import FilePreview from '@/components/FilesView/FilePreview'
|
||||||
import CopyInput from '@/components/Others/Forms/CopyInput'
|
import CopyInput from '@/components/Others/Forms/CopyInput'
|
||||||
import {mapGetters} from 'vuex'
|
import {mapGetters} from 'vuex'
|
||||||
@@ -73,12 +79,20 @@
|
|||||||
name: 'FileInfoPanel',
|
name: 'FileInfoPanel',
|
||||||
components: {
|
components: {
|
||||||
FilePreview,
|
FilePreview,
|
||||||
|
FolderIcon,
|
||||||
|
UnlockIcon,
|
||||||
|
VideoIcon,
|
||||||
CopyInput,
|
CopyInput,
|
||||||
|
ImageIcon,
|
||||||
|
FileIcon,
|
||||||
|
Edit2Icon,
|
||||||
|
LockIcon,
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
...mapGetters(['fileInfoDetail', 'permissionOptions']),
|
...mapGetters(['fileInfoDetail', 'permissionOptions']),
|
||||||
filePreviewIcon() {
|
fileType() {
|
||||||
switch (this.fileInfoDetail.type) {
|
return this.fileInfoDetail.type
|
||||||
|
/* switch () {
|
||||||
case 'folder':
|
case 'folder':
|
||||||
return 'folder'
|
return 'folder'
|
||||||
break;
|
break;
|
||||||
@@ -94,7 +108,7 @@
|
|||||||
case 'file':
|
case 'file':
|
||||||
return 'file-audio'
|
return 'file-audio'
|
||||||
break;
|
break;
|
||||||
}
|
}*/
|
||||||
},
|
},
|
||||||
sharedInfo() {
|
sharedInfo() {
|
||||||
|
|
||||||
@@ -117,8 +131,8 @@
|
|||||||
return 'download'
|
return 'download'
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
lockIcon() {
|
isLocked() {
|
||||||
return this.fileInfoDetail.shared.protected ? 'lock' : 'lock-open'
|
return this.fileInfoDetail.shared.protected
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
@@ -135,15 +149,14 @@
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped lang="scss">
|
<style scoped lang="scss">
|
||||||
@import "@assets/app.scss";
|
@import '@assets/vue-file-manager/_variables';
|
||||||
|
@import '@assets/vue-file-manager/_mixins';
|
||||||
|
|
||||||
.file-info-content {
|
.file-info-content {
|
||||||
padding-bottom: 20px;
|
padding-bottom: 20px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.file-headline {
|
.file-headline {
|
||||||
background: $light_background;
|
|
||||||
padding: 12px;
|
|
||||||
margin-bottom: 20px;
|
margin-bottom: 20px;
|
||||||
border-radius: 8px;
|
border-radius: 8px;
|
||||||
|
|
||||||
@@ -153,37 +166,19 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
.icon-preview {
|
.icon-preview {
|
||||||
height: 42px;
|
|
||||||
width: 42px;
|
|
||||||
border-radius: 8px;
|
|
||||||
display: inline-flex;
|
display: inline-flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
padding: 0;
|
padding: 0;
|
||||||
background: white;
|
|
||||||
text-align: center;
|
text-align: center;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
white-space: nowrap;
|
white-space: nowrap;
|
||||||
outline: none;
|
outline: none;
|
||||||
border: none;
|
border: none;
|
||||||
|
|
||||||
/deep/ svg {
|
|
||||||
@include font-size(22);
|
|
||||||
|
|
||||||
path {
|
|
||||||
fill: $theme;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
&:hover {
|
|
||||||
.icon path {
|
|
||||||
fill: $theme;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.file-info {
|
.file-info {
|
||||||
padding-left: 12px;
|
padding-left: 10px;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
word-break: break-all;
|
word-break: break-all;
|
||||||
|
|
||||||
@@ -196,7 +191,7 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
.mimetype {
|
.mimetype {
|
||||||
@include font-size(14);
|
@include font-size(12);
|
||||||
font-weight: 600;
|
font-weight: 600;
|
||||||
color: $theme;
|
color: $theme;
|
||||||
display: block;
|
display: block;
|
||||||
@@ -205,11 +200,10 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
.list-info {
|
.list-info {
|
||||||
padding-left: 12px;
|
|
||||||
|
|
||||||
.list-info-item {
|
.list-info-item {
|
||||||
display: block;
|
display: block;
|
||||||
padding-top: 15px;
|
padding-top: 20px;
|
||||||
|
|
||||||
&:first-child {
|
&:first-child {
|
||||||
padding-top: 0;
|
padding-top: 0;
|
||||||
@@ -218,14 +212,9 @@
|
|||||||
.action-button {
|
.action-button {
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
|
|
||||||
.icon {
|
.edit-icon {
|
||||||
@include font-size(10);
|
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
margin-right: 2px;
|
margin-left: 3px;
|
||||||
|
|
||||||
path {
|
|
||||||
fill: $theme;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -252,22 +241,10 @@
|
|||||||
margin-top: 10px;
|
margin-top: 10px;
|
||||||
|
|
||||||
.lock-icon {
|
.lock-icon {
|
||||||
@include font-size(10);
|
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
width: 10px;
|
width: 15px;
|
||||||
margin-right: 9px;
|
margin-right: 9px;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
|
|
||||||
path {
|
|
||||||
fill: $text;
|
|
||||||
}
|
|
||||||
|
|
||||||
&:hover {
|
|
||||||
|
|
||||||
path {
|
|
||||||
fill: $theme;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.copy-sharelink {
|
.copy-sharelink {
|
||||||
@@ -278,11 +255,6 @@
|
|||||||
@media (prefers-color-scheme: dark) {
|
@media (prefers-color-scheme: dark) {
|
||||||
|
|
||||||
.file-headline {
|
.file-headline {
|
||||||
background: $dark_mode_foreground;
|
|
||||||
|
|
||||||
.icon-preview {
|
|
||||||
background: $dark_mode_background;
|
|
||||||
}
|
|
||||||
|
|
||||||
.file-info {
|
.file-info {
|
||||||
|
|
||||||
@@ -313,14 +285,10 @@
|
|||||||
|
|
||||||
.lock-icon {
|
.lock-icon {
|
||||||
|
|
||||||
path {
|
|
||||||
fill: $dark_mode_text_primary;
|
|
||||||
}
|
|
||||||
|
|
||||||
&:hover {
|
&:hover {
|
||||||
|
|
||||||
path {
|
path, rect {
|
||||||
fill: $theme;
|
stroke: $theme;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -52,12 +52,12 @@
|
|||||||
|
|
||||||
<!--Shared Icon-->
|
<!--Shared Icon-->
|
||||||
<div v-if="$checkPermission('master') && data.shared" class="item-shared">
|
<div v-if="$checkPermission('master') && data.shared" class="item-shared">
|
||||||
<FontAwesomeIcon class="shared-icon" icon="share"/>
|
<link-icon size="12" class="shared-icon"></link-icon>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!--Participant owner Icon-->
|
<!--Participant owner Icon-->
|
||||||
<div v-if="$checkPermission('master') && data.user_scope !== 'master'" class="item-shared">
|
<div v-if="$checkPermission('master') && data.user_scope !== 'master'" class="item-shared">
|
||||||
<FontAwesomeIcon class="shared-icon" icon="user-edit"/>
|
<user-plus-icon size="12" class="shared-icon"></user-plus-icon>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!--Filesize-->
|
<!--Filesize-->
|
||||||
@@ -79,6 +79,7 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
|
import { LinkIcon, UserPlusIcon } from 'vue-feather-icons'
|
||||||
import {debounce} from 'lodash'
|
import {debounce} from 'lodash'
|
||||||
import {mapGetters} from 'vuex'
|
import {mapGetters} from 'vuex'
|
||||||
import {events} from '@/bus'
|
import {events} from '@/bus'
|
||||||
@@ -86,6 +87,10 @@
|
|||||||
export default {
|
export default {
|
||||||
name: 'FileItemGrid',
|
name: 'FileItemGrid',
|
||||||
props: ['data'],
|
props: ['data'],
|
||||||
|
components: {
|
||||||
|
UserPlusIcon,
|
||||||
|
LinkIcon,
|
||||||
|
},
|
||||||
computed: {
|
computed: {
|
||||||
...mapGetters([
|
...mapGetters([
|
||||||
'FilePreviewType', 'sharedDetail'
|
'FilePreviewType', 'sharedDetail'
|
||||||
@@ -155,9 +160,9 @@
|
|||||||
|
|
||||||
// Go to folder
|
// Go to folder
|
||||||
if (this.$isThisLocation('public')) {
|
if (this.$isThisLocation('public')) {
|
||||||
this.$store.dispatch('browseShared', [this.data, false])
|
this.$store.dispatch('browseShared', [{folder: this.data, back: false, init: false}])
|
||||||
} else {
|
} else {
|
||||||
this.$store.dispatch('getFolder', [this.data, false])
|
this.$store.dispatch('getFolder', [{folder: this.data, back: false, init: false}])
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -187,11 +192,11 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (this.isFolder) {
|
if (this.isFolder) {
|
||||||
// Go to folder
|
|
||||||
if (this.$isThisLocation('public')) {
|
if (this.$isThisLocation('public')) {
|
||||||
this.$store.dispatch('browseShared', [this.data, false])
|
this.$store.dispatch('browseShared', [{folder: this.data, back: false, init: false}])
|
||||||
} else {
|
} else {
|
||||||
this.$store.dispatch('getFolder', [this.data, false])
|
this.$store.dispatch('getFolder', [{folder: this.data, back: false, init: false}])
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -224,7 +229,8 @@
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped lang="scss">
|
<style scoped lang="scss">
|
||||||
@import "@assets/app.scss";
|
@import '@assets/vue-file-manager/_variables';
|
||||||
|
@import '@assets/vue-file-manager/_mixins';
|
||||||
|
|
||||||
.show-actions {
|
.show-actions {
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
@@ -240,6 +246,7 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
.file-wrapper {
|
.file-wrapper {
|
||||||
|
user-select: none;
|
||||||
position: relative;
|
position: relative;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
@@ -254,9 +261,9 @@
|
|||||||
|
|
||||||
.item-size,
|
.item-size,
|
||||||
.item-length {
|
.item-length {
|
||||||
@include font-size(12);
|
@include font-size(11);
|
||||||
font-weight: 400;
|
font-weight: 400;
|
||||||
color: $text-muted;
|
color: rgba($text, 0.7);
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -275,10 +282,10 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
.shared-icon {
|
.shared-icon {
|
||||||
@include font-size(9);
|
vertical-align: middle;
|
||||||
|
|
||||||
path {
|
path, circle, line {
|
||||||
fill: $theme;
|
stroke: $theme;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -367,6 +374,7 @@
|
|||||||
left: 0;
|
left: 0;
|
||||||
right: 0;
|
right: 0;
|
||||||
color: $theme;
|
color: $theme;
|
||||||
|
@include font-size(12);
|
||||||
font-weight: 600;
|
font-weight: 600;
|
||||||
user-select: none;
|
user-select: none;
|
||||||
max-width: 65px;
|
max-width: 65px;
|
||||||
@@ -404,14 +412,75 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@media only screen and (max-width: 960px) {
|
||||||
|
|
||||||
|
.file-wrapper {
|
||||||
|
|
||||||
|
.icon-item {
|
||||||
|
margin-bottom: 15px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@media only screen and (max-width: 690px) {
|
||||||
|
.file-wrapper {
|
||||||
|
|
||||||
|
.file-item {
|
||||||
|
width: 120px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon-item {
|
||||||
|
margin-bottom: 10px;
|
||||||
|
height: 90px;
|
||||||
|
|
||||||
|
.file-icon {
|
||||||
|
@include font-size(75);
|
||||||
|
}
|
||||||
|
|
||||||
|
.file-icon-text {
|
||||||
|
@include font-size(12);
|
||||||
|
}
|
||||||
|
|
||||||
|
.folder-icon {
|
||||||
|
@include font-size(75);
|
||||||
|
margin-top: 0;
|
||||||
|
margin-bottom: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.image {
|
||||||
|
width: 90px;
|
||||||
|
height: 90px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.item-name .name {
|
||||||
|
@include font-size(13);
|
||||||
|
line-height: .9;
|
||||||
|
max-height: 30px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@media (prefers-color-scheme: dark) {
|
@media (prefers-color-scheme: dark) {
|
||||||
.file-wrapper {
|
.file-wrapper {
|
||||||
|
|
||||||
.icon-item .file-icon {
|
.icon-item {
|
||||||
|
|
||||||
path {
|
.file-icon {
|
||||||
fill: $dark_mode_foreground;
|
|
||||||
stroke: #2F3C54;
|
path {
|
||||||
|
fill: $dark_mode_foreground;
|
||||||
|
stroke: #2F3C54;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.folder-icon {
|
||||||
|
|
||||||
|
&.is-deleted {
|
||||||
|
path {
|
||||||
|
fill: lighten($dark_mode_foreground, 5%);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -430,9 +499,18 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.item-name .name {
|
.item-name {
|
||||||
color: $dark_mode_text_primary;
|
|
||||||
|
.name {
|
||||||
|
color: $dark_mode_text_primary;
|
||||||
|
}
|
||||||
|
|
||||||
|
.item-size,
|
||||||
|
.item-length {
|
||||||
|
color: $dark_mode_text_secondary;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -51,12 +51,12 @@
|
|||||||
|
|
||||||
<!--Shared Icon-->
|
<!--Shared Icon-->
|
||||||
<div v-if="$checkPermission('master') && data.shared" class="item-shared">
|
<div v-if="$checkPermission('master') && data.shared" class="item-shared">
|
||||||
<FontAwesomeIcon class="shared-icon" icon="share"/>
|
<link-icon size="12" class="shared-icon"></link-icon>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!--Participant owner Icon-->
|
<!--Participant owner Icon-->
|
||||||
<div v-if="$checkPermission('master') && data.user_scope !== 'master'" class="item-shared">
|
<div v-if="$checkPermission('master') && data.user_scope !== 'master'" class="item-shared">
|
||||||
<FontAwesomeIcon class="shared-icon" icon="user-edit"/>
|
<user-plus-icon size="12" class="shared-icon"></user-plus-icon>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!--Filesize and timestamp-->
|
<!--Filesize and timestamp-->
|
||||||
@@ -80,6 +80,7 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
|
import { LinkIcon, UserPlusIcon } from 'vue-feather-icons'
|
||||||
import {debounce} from 'lodash'
|
import {debounce} from 'lodash'
|
||||||
import {mapGetters} from 'vuex'
|
import {mapGetters} from 'vuex'
|
||||||
import {events} from '@/bus'
|
import {events} from '@/bus'
|
||||||
@@ -87,6 +88,10 @@
|
|||||||
export default {
|
export default {
|
||||||
name: 'FileItemList',
|
name: 'FileItemList',
|
||||||
props: ['data'],
|
props: ['data'],
|
||||||
|
components: {
|
||||||
|
UserPlusIcon,
|
||||||
|
LinkIcon,
|
||||||
|
},
|
||||||
computed: {
|
computed: {
|
||||||
...mapGetters(['FilePreviewType']),
|
...mapGetters(['FilePreviewType']),
|
||||||
isFolder() {
|
isFolder() {
|
||||||
@@ -164,9 +169,9 @@
|
|||||||
|
|
||||||
// Go to folder
|
// Go to folder
|
||||||
if (this.$isThisLocation('public')) {
|
if (this.$isThisLocation('public')) {
|
||||||
this.$store.dispatch('browseShared', [this.data, false])
|
this.$store.dispatch('browseShared', [{folder: this.data, back: false, init: false}])
|
||||||
} else {
|
} else {
|
||||||
this.$store.dispatch('getFolder', [this.data, false])
|
this.$store.dispatch('getFolder', [{folder: this.data, back: false, init: false}])
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -194,9 +199,9 @@
|
|||||||
if (this.isFolder) {
|
if (this.isFolder) {
|
||||||
|
|
||||||
if (this.$isThisLocation('public')) {
|
if (this.$isThisLocation('public')) {
|
||||||
this.$store.dispatch('browseShared', [this.data, false])
|
this.$store.dispatch('browseShared', [{folder: this.data, back: false, init: false}])
|
||||||
} else {
|
} else {
|
||||||
this.$store.dispatch('getFolder', [this.data, false])
|
this.$store.dispatch('getFolder', [{folder: this.data, back: false, init: false}])
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -229,9 +234,11 @@
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped lang="scss">
|
<style scoped lang="scss">
|
||||||
@import "@assets/app.scss";
|
@import '@assets/vue-file-manager/_variables';
|
||||||
|
@import '@assets/vue-file-manager/_mixins';
|
||||||
|
|
||||||
.file-wrapper {
|
.file-wrapper {
|
||||||
|
user-select: none;
|
||||||
position: relative;
|
position: relative;
|
||||||
|
|
||||||
&:hover {
|
&:hover {
|
||||||
@@ -278,19 +285,19 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
.shared-icon {
|
.shared-icon {
|
||||||
@include font-size(9);
|
vertical-align: middle;
|
||||||
|
|
||||||
path {
|
path, circle, line {
|
||||||
fill: $theme;
|
stroke: $theme;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.item-size,
|
.item-size,
|
||||||
.item-length {
|
.item-length {
|
||||||
@include font-size(12);
|
@include font-size(11);
|
||||||
font-weight: 400;
|
font-weight: 400;
|
||||||
color: $text-muted;
|
color: rgba($text, 0.7);
|
||||||
}
|
}
|
||||||
|
|
||||||
.name {
|
.name {
|
||||||
@@ -412,16 +419,29 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
@media (prefers-color-scheme: dark) {
|
@media (prefers-color-scheme: dark) {
|
||||||
|
|
||||||
.file-wrapper {
|
.file-wrapper {
|
||||||
|
|
||||||
.icon-item .file-icon {
|
.icon-item {
|
||||||
|
.file-icon {
|
||||||
|
|
||||||
path {
|
path {
|
||||||
fill: $dark_mode_foreground;
|
fill: $dark_mode_foreground;
|
||||||
stroke: #2F3C54;
|
stroke: #2F3C54;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.folder-icon {
|
||||||
|
|
||||||
|
&.is-deleted {
|
||||||
|
path {
|
||||||
|
fill: lighten($dark_mode_foreground, 5%);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
.file-item {
|
.file-item {
|
||||||
|
|
||||||
&:hover,
|
&:hover,
|
||||||
@@ -437,8 +457,16 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.item-name .name {
|
.item-name {
|
||||||
color: $dark_mode_text_primary;
|
|
||||||
|
.name {
|
||||||
|
color: $dark_mode_text_primary;
|
||||||
|
}
|
||||||
|
|
||||||
|
.item-size,
|
||||||
|
.item-length {
|
||||||
|
color: $dark_mode_text_secondary;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -26,7 +26,8 @@
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped lang="scss">
|
<style scoped lang="scss">
|
||||||
@import "@assets/app.scss";
|
@import '@assets/vue-file-manager/_variables';
|
||||||
|
@import '@assets/vue-file-manager/_mixins';
|
||||||
|
|
||||||
.preview {
|
.preview {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
|
|||||||
@@ -1,24 +1,37 @@
|
|||||||
<template>
|
<template>
|
||||||
<button class="mobile-action-button">
|
<button class="mobile-action-button">
|
||||||
<FontAwesomeIcon class="icon" :icon="icon"></FontAwesomeIcon>
|
<div class="flex">
|
||||||
<span class="label">
|
<folder-plus-icon v-if="icon === 'folder-plus'" size="15" class="icon"></folder-plus-icon>
|
||||||
<slot></slot>
|
<list-icon v-if="icon === 'th-list'" size="15" class="icon"></list-icon>
|
||||||
</span>
|
<trash-icon v-if="icon === 'trash'" size="15" class="icon"></trash-icon>
|
||||||
|
<grid-icon v-if="icon === 'th'" size="15" class="icon"></grid-icon>
|
||||||
|
<span class="label">
|
||||||
|
<slot></slot>
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
</button>
|
</button>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
|
import { FolderPlusIcon, ListIcon, GridIcon, TrashIcon } from 'vue-feather-icons'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'MobileActionButton',
|
name: 'MobileActionButton',
|
||||||
props: [
|
props: [
|
||||||
'icon'
|
'icon'
|
||||||
],
|
],
|
||||||
|
components: {
|
||||||
|
FolderPlusIcon,
|
||||||
|
TrashIcon,
|
||||||
|
ListIcon,
|
||||||
|
GridIcon,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped lang="scss">
|
<style scoped lang="scss">
|
||||||
@import "@assets/app.scss";
|
@import '@assets/vue-file-manager/_variables';
|
||||||
|
@import '@assets/vue-file-manager/_mixins';
|
||||||
|
|
||||||
.mobile-action-button {
|
.mobile-action-button {
|
||||||
background: $light_background;
|
background: $light_background;
|
||||||
@@ -28,6 +41,11 @@
|
|||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
border: none;
|
border: none;
|
||||||
|
|
||||||
|
.flex {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
.icon {
|
.icon {
|
||||||
margin-right: 10px;
|
margin-right: 10px;
|
||||||
@include font-size(14);
|
@include font-size(14);
|
||||||
@@ -44,8 +62,8 @@
|
|||||||
.mobile-action-button {
|
.mobile-action-button {
|
||||||
background: $dark_mode_foreground;
|
background: $dark_mode_foreground;
|
||||||
|
|
||||||
.icon path {
|
path, line, polyline, rect, circle {
|
||||||
fill: $theme;
|
stroke: $theme;
|
||||||
}
|
}
|
||||||
|
|
||||||
.label {
|
.label {
|
||||||
|
|||||||
@@ -1,31 +1,29 @@
|
|||||||
<template>
|
<template>
|
||||||
<button class="mobile-action-button">
|
<button class="mobile-action-button">
|
||||||
<FontAwesomeIcon class="icon" :icon="icon"></FontAwesomeIcon>
|
<div class="flex">
|
||||||
<label label="file" class="label button file-input button-base">
|
<upload-cloud-icon class="icon" size="15"></upload-cloud-icon>
|
||||||
<slot></slot>
|
<label label="file" class="label button file-input button-base">
|
||||||
<input
|
<slot></slot>
|
||||||
accept="*"
|
<input
|
||||||
v-show="false"
|
@change="emmitFiles"
|
||||||
@change="emmitFiles"
|
v-show="false"
|
||||||
id="file"
|
id="file"
|
||||||
type="file"
|
type="file"
|
||||||
name="files[]"
|
name="files[]"
|
||||||
multiple
|
multiple
|
||||||
/>
|
/>
|
||||||
</label>
|
</label>
|
||||||
|
</div>
|
||||||
</button>
|
</button>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
|
import { UploadCloudIcon } from 'vue-feather-icons'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'MobileActionButtonUpload',
|
name: 'MobileActionButtonUpload',
|
||||||
props: [
|
components: {
|
||||||
'icon'
|
UploadCloudIcon,
|
||||||
],
|
|
||||||
data() {
|
|
||||||
return {
|
|
||||||
files: undefined
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
emmitFiles(e) {
|
emmitFiles(e) {
|
||||||
@@ -36,8 +34,8 @@
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped lang="scss">
|
<style scoped lang="scss">
|
||||||
@import "@assets/app.scss";
|
@import '@assets/vue-file-manager/_variables';
|
||||||
|
@import '@assets/vue-file-manager/_mixins';
|
||||||
|
|
||||||
.mobile-action-button {
|
.mobile-action-button {
|
||||||
background: $light_background;
|
background: $light_background;
|
||||||
@@ -47,12 +45,19 @@
|
|||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
border: none;
|
border: none;
|
||||||
|
|
||||||
|
.flex {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
.icon {
|
.icon {
|
||||||
margin-right: 8px;
|
vertical-align: middle;
|
||||||
|
margin-right: 10px;
|
||||||
@include font-size(14);
|
@include font-size(14);
|
||||||
}
|
}
|
||||||
|
|
||||||
.label {
|
.label {
|
||||||
|
vertical-align: middle;
|
||||||
@include font-size(14);
|
@include font-size(14);
|
||||||
font-weight: 700;
|
font-weight: 700;
|
||||||
color: $text;
|
color: $text;
|
||||||
@@ -63,8 +68,8 @@
|
|||||||
.mobile-action-button {
|
.mobile-action-button {
|
||||||
background: $dark_mode_foreground;
|
background: $dark_mode_foreground;
|
||||||
|
|
||||||
.icon path {
|
path, line, polyline, rect, circle {
|
||||||
fill: $theme;
|
stroke: $theme;
|
||||||
}
|
}
|
||||||
|
|
||||||
.label {
|
.label {
|
||||||
|
|||||||
@@ -1,22 +1,22 @@
|
|||||||
<template>
|
<template>
|
||||||
<div id="mobile-actions-wrapper" v-if="$isMinimalScale()">
|
<div id="mobile-actions-wrapper">
|
||||||
|
|
||||||
<!--Actions for trash location with MASTER permission--->
|
<!--Actions for trash location with MASTER permission--->
|
||||||
<div v-if="$isThisLocation(['trash', 'trash-root']) && $checkPermission('master')" class="mobile-actions">
|
<div v-if="$isThisLocation(['trash', 'trash-root']) && $checkPermission('master')" class="mobile-actions">
|
||||||
<MobileActionButton @click.native="switchPreview" :icon="previewIcon">
|
<MobileActionButton @click.native="switchPreview" :icon="previewIcon">
|
||||||
{{ previewText }}
|
{{ previewText }}
|
||||||
</MobileActionButton>
|
</MobileActionButton>
|
||||||
<MobileActionButton @click.native="$store.dispatch('emptyTrash')" icon="trash-alt">
|
<MobileActionButton @click.native="$store.dispatch('emptyTrash')" icon="trash">
|
||||||
{{ $t('context_menu.empty_trash') }}
|
{{ $t('context_menu.empty_trash') }}
|
||||||
</MobileActionButton>
|
</MobileActionButton>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!--ContextMenu for Base location with MASTER permission-->
|
<!--ContextMenu for Base location with MASTER permission-->
|
||||||
<div v-if="$isThisLocation(['base', 'shared', 'public']) && $checkPermission(['master', 'editor'])" class="mobile-actions">
|
<div v-if="$isThisLocation(['base', 'public']) && $checkPermission(['master', 'editor'])" class="mobile-actions">
|
||||||
<MobileActionButton @click.native="createFolder" icon="folder-plus">
|
<MobileActionButton @click.native="createFolder" icon="folder-plus">
|
||||||
{{ $t('context_menu.add_folder') }}
|
{{ $t('context_menu.add_folder') }}
|
||||||
</MobileActionButton>
|
</MobileActionButton>
|
||||||
<MobileActionButtonUpload @input.native="$uploadFiles" icon="upload">
|
<MobileActionButtonUpload>
|
||||||
{{ $t('context_menu.upload') }}
|
{{ $t('context_menu.upload') }}
|
||||||
</MobileActionButtonUpload>
|
</MobileActionButtonUpload>
|
||||||
<MobileActionButton @click.native="switchPreview" :icon="previewIcon">
|
<MobileActionButton @click.native="switchPreview" :icon="previewIcon">
|
||||||
@@ -25,7 +25,7 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!--ContextMenu for Base location with VISITOR permission-->
|
<!--ContextMenu for Base location with VISITOR permission-->
|
||||||
<div v-if="$isThisLocation(['base', 'shared', 'public']) && $checkPermission('visitor')" class="mobile-actions">
|
<div v-if="($isThisLocation(['base', 'shared', 'public']) && $checkPermission('visitor')) || ($isThisLocation(['latest', 'shared']) && $checkPermission('master'))" class="mobile-actions">
|
||||||
<MobileActionButton @click.native="switchPreview" :icon="previewIcon">
|
<MobileActionButton @click.native="switchPreview" :icon="previewIcon">
|
||||||
{{ previewText }}
|
{{ previewText }}
|
||||||
</MobileActionButton>
|
</MobileActionButton>
|
||||||
@@ -81,10 +81,11 @@
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped lang="scss">
|
<style scoped lang="scss">
|
||||||
@import "@assets/app.scss";
|
@import '@assets/vue-file-manager/_variables';
|
||||||
|
@import '@assets/vue-file-manager/_mixins';
|
||||||
|
|
||||||
#mobile-actions-wrapper {
|
#mobile-actions-wrapper {
|
||||||
|
display: none;
|
||||||
background: white;
|
background: white;
|
||||||
position: sticky;
|
position: sticky;
|
||||||
top: 35px;
|
top: 35px;
|
||||||
@@ -98,6 +99,13 @@
|
|||||||
overflow-x: auto;
|
overflow-x: auto;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@media only screen and (max-width: 960px) {
|
||||||
|
|
||||||
|
#mobile-actions-wrapper {
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@media (prefers-color-scheme: dark) {
|
@media (prefers-color-scheme: dark) {
|
||||||
#mobile-actions-wrapper {
|
#mobile-actions-wrapper {
|
||||||
background: $dark_mode_background;
|
background: $dark_mode_background;
|
||||||
|
|||||||
@@ -9,79 +9,213 @@
|
|||||||
>
|
>
|
||||||
<div class="menu-wrapper">
|
<div class="menu-wrapper">
|
||||||
|
|
||||||
|
<!--Item Thumbnail-->
|
||||||
|
<ThumbnailItem class="item-thumbnail" :item="fileInfoDetail" info="metadata"/>
|
||||||
|
|
||||||
<!--Mobile for trash location-->
|
<!--Mobile for trash location-->
|
||||||
<ul v-if="$isThisLocation(['trash', 'trash-root']) && $checkPermission('master')" class="menu-options">
|
<div v-if="$isThisLocation(['trash', 'trash-root']) && $checkPermission('master')" class="menu-options">
|
||||||
<li class="menu-option" @click="$store.dispatch('restoreItem', fileInfoDetail)" v-if="fileInfoDetail">
|
|
||||||
{{ $t('context_menu.restore') }}
|
<ul class="menu-option-group">
|
||||||
</li>
|
<li class="menu-option" @click="$store.dispatch('restoreItem', fileInfoDetail)" v-if="fileInfoDetail">
|
||||||
<li class="menu-option" @click="downloadItem" v-if="! isFolder">
|
<div class="icon">
|
||||||
{{ $t('context_menu.download') }}
|
<life-buoy-icon size="17"></life-buoy-icon>
|
||||||
</li>
|
</div>
|
||||||
<li class="menu-option delete" @click="deleteItem" v-if="fileInfoDetail">
|
<div class="text-label">
|
||||||
{{ $t('context_menu.delete') }}
|
{{ $t('context_menu.restore') }}
|
||||||
</li>
|
</div>
|
||||||
</ul>
|
</li>
|
||||||
|
<li class="menu-option delete" @click="deleteItem" v-if="fileInfoDetail">
|
||||||
|
<div class="icon">
|
||||||
|
<trash-2-icon size="17"></trash-2-icon>
|
||||||
|
</div>
|
||||||
|
<div class="text-label">
|
||||||
|
{{ $t('context_menu.delete') }}
|
||||||
|
</div>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
|
||||||
|
<ul class="menu-option-group" v-if="! isFolder">
|
||||||
|
<li class="menu-option" @click="downloadItem">
|
||||||
|
<div class="icon">
|
||||||
|
<download-cloud-icon size="17"></download-cloud-icon>
|
||||||
|
</div>
|
||||||
|
<div class="text-label">
|
||||||
|
{{ $t('context_menu.download') }}
|
||||||
|
</div>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
|
||||||
<!--Mobile for Base location-->
|
<!--Mobile for Base location-->
|
||||||
<ul v-if="$isThisLocation(['shared']) && $checkPermission('master')" class="menu-options">
|
<div v-if="$isThisLocation(['shared']) && $checkPermission('master')" class="menu-options">
|
||||||
<li class="menu-option" @click="addToFavourites" v-if="fileInfoDetail && isFolder">
|
|
||||||
{{ isInFavourites ? $t('context_menu.remove_from_favourites') : $t('context_menu.add_to_favourites') }}
|
<ul class="menu-option-group">
|
||||||
</li>
|
<li class="menu-option" @click="addToFavourites" v-if="fileInfoDetail && isFolder">
|
||||||
<li class="menu-option" @click="renameItem" v-if="fileInfoDetail">
|
<div class="icon">
|
||||||
{{ $t('context_menu.rename') }}
|
<star-icon size="17"></star-icon>
|
||||||
</li>
|
</div>
|
||||||
<li class="menu-option" @click="shareItem" v-if="fileInfoDetail">
|
<div class="text-label">
|
||||||
{{ fileInfoDetail.shared ? $t('context_menu.share_edit') : $t('context_menu.share') }}
|
{{ isInFavourites ? $t('context_menu.remove_from_favourites') :
|
||||||
</li>
|
$t('context_menu.add_to_favourites') }}
|
||||||
<li class="menu-option" @click="downloadItem" v-if="! isFolder">
|
</div>
|
||||||
{{ $t('context_menu.download') }}
|
</li>
|
||||||
</li>
|
</ul>
|
||||||
<li class="menu-option delete" @click="deleteItem" v-if="fileInfoDetail">
|
|
||||||
{{ $t('context_menu.delete') }}
|
<ul class="menu-option-group">
|
||||||
</li>
|
<li class="menu-option" @click="renameItem" v-if="fileInfoDetail">
|
||||||
</ul>
|
<div class="icon">
|
||||||
|
<edit-2-icon size="17"></edit-2-icon>
|
||||||
|
</div>
|
||||||
|
<div class="text-label">
|
||||||
|
{{ $t('context_menu.rename') }}
|
||||||
|
</div>
|
||||||
|
</li>
|
||||||
|
<li class="menu-option" @click="shareItem" v-if="fileInfoDetail">
|
||||||
|
<div class="icon">
|
||||||
|
<link-icon size="17"></link-icon>
|
||||||
|
</div>
|
||||||
|
<div class="text-label">
|
||||||
|
{{ fileInfoDetail.shared ? $t('context_menu.share_edit') : $t('context_menu.share') }}
|
||||||
|
</div>
|
||||||
|
</li>
|
||||||
|
<li class="menu-option delete" @click="deleteItem" v-if="fileInfoDetail">
|
||||||
|
<div class="icon">
|
||||||
|
<trash-2-icon size="17"></trash-2-icon>
|
||||||
|
</div>
|
||||||
|
<div class="text-label">
|
||||||
|
{{ $t('context_menu.delete') }}
|
||||||
|
</div>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
|
||||||
|
<ul class="menu-option-group">
|
||||||
|
<li class="menu-option" @click="downloadItem" v-if="! isFolder">
|
||||||
|
<div class="icon">
|
||||||
|
<download-cloud-icon size="17"></download-cloud-icon>
|
||||||
|
</div>
|
||||||
|
<div class="text-label">
|
||||||
|
{{ $t('context_menu.download') }}
|
||||||
|
</div>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
|
||||||
<!--Mobile for Base location-->
|
<!--Mobile for Base location-->
|
||||||
<ul v-if="$isThisLocation(['base']) && $checkPermission('master')" class="menu-options">
|
<div v-if="$isThisLocation(['base', 'participant_uploads', 'latest']) && $checkPermission('master')" class="menu-options">
|
||||||
<li class="menu-option" @click="addToFavourites" v-if="fileInfoDetail && isFolder">
|
<ul class="menu-option-group" v-if="fileInfoDetail && isFolder">
|
||||||
{{ isInFavourites ? $t('context_menu.remove_from_favourites') : $t('context_menu.add_to_favourites') }}
|
<li class="menu-option" @click="addToFavourites">
|
||||||
</li>
|
<div class="icon">
|
||||||
<li class="menu-option" @click="renameItem" v-if="fileInfoDetail">
|
<star-icon size="17"></star-icon>
|
||||||
{{ $t('context_menu.rename') }}
|
</div>
|
||||||
</li>
|
<div class="text-label">
|
||||||
<li class="menu-option" @click="moveItem" v-if="fileInfoDetail">
|
{{ isInFavourites ? $t('context_menu.remove_from_favourites') :
|
||||||
{{ $t('context_menu.move') }}
|
$t('context_menu.add_to_favourites') }}
|
||||||
</li>
|
</div>
|
||||||
<li class="menu-option" @click="shareItem" v-if="fileInfoDetail">
|
</li>
|
||||||
{{ fileInfoDetail.shared ? $t('context_menu.share_edit') : $t('context_menu.share') }}
|
</ul>
|
||||||
</li>
|
|
||||||
<li class="menu-option" @click="downloadItem" v-if="! isFolder">
|
<ul class="menu-option-group">
|
||||||
{{ $t('context_menu.download') }}
|
<li class="menu-option" @click="renameItem" v-if="fileInfoDetail">
|
||||||
</li>
|
<div class="icon">
|
||||||
<li class="menu-option delete" @click="deleteItem" v-if="fileInfoDetail">
|
<edit-2-icon size="17"></edit-2-icon>
|
||||||
{{ $t('context_menu.delete') }}
|
</div>
|
||||||
</li>
|
<div class="text-label">
|
||||||
</ul>
|
{{ $t('context_menu.rename') }}
|
||||||
|
</div>
|
||||||
|
</li>
|
||||||
|
<li class="menu-option" @click="moveItem" v-if="fileInfoDetail">
|
||||||
|
<div class="icon">
|
||||||
|
<corner-down-right-icon size="17"></corner-down-right-icon>
|
||||||
|
</div>
|
||||||
|
<div class="text-label">
|
||||||
|
{{ $t('context_menu.move') }}
|
||||||
|
</div>
|
||||||
|
</li>
|
||||||
|
<li class="menu-option" @click="shareItem" v-if="fileInfoDetail">
|
||||||
|
<div class="icon">
|
||||||
|
<link-icon size="17"></link-icon>
|
||||||
|
</div>
|
||||||
|
<div class="text-label">
|
||||||
|
{{ fileInfoDetail.shared ? $t('context_menu.share_edit') : $t('context_menu.share') }}
|
||||||
|
</div>
|
||||||
|
</li>
|
||||||
|
<li class="menu-option delete" @click="deleteItem" v-if="fileInfoDetail">
|
||||||
|
<div class="icon">
|
||||||
|
<trash-2-icon size="17"></trash-2-icon>
|
||||||
|
</div>
|
||||||
|
<div class="text-label">
|
||||||
|
{{ $t('context_menu.delete') }}
|
||||||
|
</div>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
|
||||||
|
<ul class="menu-option-group">
|
||||||
|
<li class="menu-option" @click="downloadItem" v-if="! isFolder">
|
||||||
|
<div class="icon">
|
||||||
|
<download-cloud-icon size="17"></download-cloud-icon>
|
||||||
|
</div>
|
||||||
|
<div class="text-label">
|
||||||
|
{{ $t('context_menu.download') }}
|
||||||
|
</div>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
|
||||||
<!--Mobile for Base location with EDITOR permission-->
|
<!--Mobile for Base location with EDITOR permission-->
|
||||||
<ul v-if="$isThisLocation(['base', 'public']) && $checkPermission('editor')" class="menu-options">
|
<div v-if="$isThisLocation(['base', 'public']) && $checkPermission('editor')" class="menu-options">
|
||||||
<li class="menu-option" @click="renameItem" v-if="fileInfoDetail">
|
|
||||||
{{ $t('context_menu.rename') }}
|
<ul class="menu-option-group">
|
||||||
</li>
|
<li class="menu-option" @click="renameItem" v-if="fileInfoDetail">
|
||||||
<li class="menu-option" @click="moveItem" v-if="fileInfoDetail">
|
<div class="icon">
|
||||||
{{ $t('context_menu.move') }}
|
<edit-2-icon size="17"></edit-2-icon>
|
||||||
</li>
|
</div>
|
||||||
<li class="menu-option" @click="downloadItem" v-if="! isFolder">
|
<div class="text-label">
|
||||||
{{ $t('context_menu.download') }}
|
{{ $t('context_menu.rename') }}
|
||||||
</li>
|
</div>
|
||||||
</ul>
|
</li>
|
||||||
|
<li class="menu-option" @click="moveItem" v-if="fileInfoDetail">
|
||||||
|
<div class="icon">
|
||||||
|
<corner-down-right-icon size="17"></corner-down-right-icon>
|
||||||
|
</div>
|
||||||
|
<div class="text-label">
|
||||||
|
{{ $t('context_menu.move') }}
|
||||||
|
</div>
|
||||||
|
</li>
|
||||||
|
<li class="menu-option" @click="deleteItem">
|
||||||
|
<div class="icon">
|
||||||
|
<trash-2-icon size="17"></trash-2-icon>
|
||||||
|
</div>
|
||||||
|
<div class="text-label">
|
||||||
|
{{ $t('context_menu.delete') }}
|
||||||
|
</div>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
|
||||||
|
<ul class="menu-option-group">
|
||||||
|
<li class="menu-option" @click="downloadItem" v-if="! isFolder">
|
||||||
|
<div class="icon">
|
||||||
|
<download-cloud-icon size="17"></download-cloud-icon>
|
||||||
|
</div>
|
||||||
|
<div class="text-label">
|
||||||
|
{{ $t('context_menu.download') }}
|
||||||
|
</div>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
|
||||||
<!--Mobile for Base location with VISITOR permission-->
|
<!--Mobile for Base location with VISITOR permission-->
|
||||||
<ul v-if="$isThisLocation(['base', 'public']) && $checkPermission('visitor')" class="menu-options">
|
<div v-if="$isThisLocation(['base', 'public']) && $checkPermission('visitor')" class="menu-options">
|
||||||
<li class="menu-option" @click="downloadItem" v-if="! isFolder">
|
<ul class="menu-option-group">
|
||||||
{{ $t('context_menu.download') }}
|
<li class="menu-option" @click="downloadItem" v-if="! isFolder">
|
||||||
</li>
|
<div class="icon">
|
||||||
</ul>
|
<download-cloud-icon size="17"></download-cloud-icon>
|
||||||
|
</div>
|
||||||
|
<div class="text-label">
|
||||||
|
{{ $t('context_menu.download') }}
|
||||||
|
</div>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</transition>
|
</transition>
|
||||||
@@ -92,11 +226,37 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
|
import ThumbnailItem from '@/components/Others/ThumbnailItem'
|
||||||
|
import {
|
||||||
|
CornerDownRightIcon,
|
||||||
|
DownloadCloudIcon,
|
||||||
|
FolderPlusIcon,
|
||||||
|
LifeBuoyIcon,
|
||||||
|
Trash2Icon,
|
||||||
|
Edit2Icon,
|
||||||
|
TrashIcon,
|
||||||
|
StarIcon,
|
||||||
|
LinkIcon,
|
||||||
|
EyeIcon,
|
||||||
|
} from 'vue-feather-icons'
|
||||||
import {events} from '@/bus'
|
import {events} from '@/bus'
|
||||||
import {mapGetters} from 'vuex'
|
import {mapGetters} from 'vuex'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'MobileMenu',
|
name: 'MobileMenu',
|
||||||
|
components: {
|
||||||
|
CornerDownRightIcon,
|
||||||
|
DownloadCloudIcon,
|
||||||
|
FolderPlusIcon,
|
||||||
|
ThumbnailItem,
|
||||||
|
LifeBuoyIcon,
|
||||||
|
Trash2Icon,
|
||||||
|
Edit2Icon,
|
||||||
|
TrashIcon,
|
||||||
|
LinkIcon,
|
||||||
|
StarIcon,
|
||||||
|
EyeIcon,
|
||||||
|
},
|
||||||
computed: {
|
computed: {
|
||||||
...mapGetters(['fileInfoDetail', 'app']),
|
...mapGetters(['fileInfoDetail', 'app']),
|
||||||
isInFavourites() {
|
isInFavourites() {
|
||||||
@@ -139,14 +299,12 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
downloadItem() {
|
downloadItem() {
|
||||||
// Download file
|
|
||||||
this.$downloadFile(
|
this.$downloadFile(
|
||||||
this.fileInfoDetail.file_url,
|
this.fileInfoDetail.file_url,
|
||||||
this.fileInfoDetail.name + '.' + this.fileInfoDetail.mimetype
|
this.fileInfoDetail.name + '.' + this.fileInfoDetail.mimetype
|
||||||
)
|
)
|
||||||
},
|
},
|
||||||
deleteItem() {
|
deleteItem() {
|
||||||
// Dispatch remove item
|
|
||||||
this.$store.dispatch('deleteItem', this.fileInfoDetail)
|
this.$store.dispatch('deleteItem', this.fileInfoDetail)
|
||||||
},
|
},
|
||||||
renameItem() {
|
renameItem() {
|
||||||
@@ -194,10 +352,25 @@
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped lang="scss">
|
<style scoped lang="scss">
|
||||||
@import "@assets/app.scss";
|
@import '@assets/vue-file-manager/_variables';
|
||||||
|
@import '@assets/vue-file-manager/_mixins';
|
||||||
|
|
||||||
|
.menu-option {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
|
||||||
|
.icon {
|
||||||
|
margin-right: 20px;
|
||||||
|
line-height: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.text-label {
|
||||||
|
@include font-size(16);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
.vignette {
|
.vignette {
|
||||||
background: rgba(0, 0, 0, 0.15);
|
background: rgba(0, 0, 0, 0.35);
|
||||||
position: absolute;
|
position: absolute;
|
||||||
top: 0;
|
top: 0;
|
||||||
right: 0;
|
right: 0;
|
||||||
@@ -215,29 +388,46 @@
|
|||||||
right: 0;
|
right: 0;
|
||||||
z-index: 99;
|
z-index: 99;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
|
background: white;
|
||||||
|
border-top-left-radius: 12px;
|
||||||
|
border-top-right-radius: 12px;
|
||||||
|
|
||||||
&.showed {
|
&.showed {
|
||||||
display: block;
|
display: block;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.item-thumbnail {
|
||||||
|
padding: 20px 20px 10px;
|
||||||
|
margin-bottom: 0px;
|
||||||
|
}
|
||||||
|
|
||||||
.menu-options {
|
.menu-options {
|
||||||
margin-top: 10px;
|
margin-top: 10px;
|
||||||
box-shadow: $shadow;
|
|
||||||
background: white;
|
|
||||||
border-top-left-radius: 8px;
|
|
||||||
border-top-right-radius: 8px;
|
|
||||||
list-style: none;
|
list-style: none;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
|
|
||||||
|
.menu-option-group {
|
||||||
|
padding: 5px 0;
|
||||||
|
border-bottom: 1px solid $light_mode_border;
|
||||||
|
|
||||||
|
&:first-child {
|
||||||
|
padding-top: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
&:last-child {
|
||||||
|
padding-bottom: 0;
|
||||||
|
border-bottom: none;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
.menu-option {
|
.menu-option {
|
||||||
font-weight: 700;
|
font-weight: 700;
|
||||||
letter-spacing: 0.15px;
|
letter-spacing: 0.15px;
|
||||||
@include font-size(15);
|
@include font-size(14);
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
padding: 20px 10px;
|
padding: 17px 20px;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
border-bottom: 1px solid $light_mode_border;
|
|
||||||
|
|
||||||
&:last-child {
|
&:last-child {
|
||||||
border: none;
|
border: none;
|
||||||
@@ -253,12 +443,16 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
.options {
|
.options {
|
||||||
|
background: $dark_mode_background;
|
||||||
|
|
||||||
.menu-options {
|
.menu-options {
|
||||||
background: $dark_mode_background;
|
background: $dark_mode_background;
|
||||||
|
|
||||||
.menu-option {
|
.menu-option-group {
|
||||||
border-color: $dark_mode_border_color;
|
border-color: $dark_mode_border_color;
|
||||||
|
}
|
||||||
|
|
||||||
|
.menu-option {
|
||||||
color: $dark_mode_text_primary;
|
color: $dark_mode_text_primary;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,13 +1,9 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="mobile-toolbar" v-if="$isMinimalScale()">
|
<div class="mobile-toolbar">
|
||||||
|
|
||||||
<!-- Go back-->
|
<!-- Go back-->
|
||||||
<div @click="goBack" class="go-back-button">
|
<div @click="goBack" class="go-back-button">
|
||||||
<FontAwesomeIcon
|
<chevron-left-icon size="17" :class="{'is-visible': browseHistory.length > 1}" class="icon-back"></chevron-left-icon>
|
||||||
:class="{'is-visible': browseHistory.length > 0}"
|
|
||||||
class="icon-back"
|
|
||||||
icon="chevron-left"
|
|
||||||
></FontAwesomeIcon>
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!--Folder Title-->
|
<!--Folder Title-->
|
||||||
@@ -15,8 +11,8 @@
|
|||||||
|
|
||||||
<!--More Actions-->
|
<!--More Actions-->
|
||||||
<div class="more-actions-button">
|
<div class="more-actions-button">
|
||||||
<div class="tap-area" @click="showSidebarMenu" v-if="$checkPermission('master')">
|
<div class="tap-area" @click="showMobileNavigation" v-if="$checkPermission('master')">
|
||||||
<FontAwesomeIcon icon="bars" v-if="isSmallAppSize"></FontAwesomeIcon>
|
<menu-icon size="17"></menu-icon>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -26,15 +22,19 @@
|
|||||||
import ToolbarButtonUpload from '@/components/FilesView/ToolbarButtonUpload'
|
import ToolbarButtonUpload from '@/components/FilesView/ToolbarButtonUpload'
|
||||||
import ToolbarButton from '@/components/FilesView/ToolbarButton'
|
import ToolbarButton from '@/components/FilesView/ToolbarButton'
|
||||||
import SearchBar from '@/components/FilesView/SearchBar'
|
import SearchBar from '@/components/FilesView/SearchBar'
|
||||||
|
import { MenuIcon, ChevronLeftIcon } from 'vue-feather-icons'
|
||||||
import {mapGetters} from 'vuex'
|
import {mapGetters} from 'vuex'
|
||||||
import {events} from '@/bus'
|
import {events} from '@/bus'
|
||||||
|
import {last} from 'lodash'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'MobileToolBar',
|
name: 'MobileToolBar',
|
||||||
components: {
|
components: {
|
||||||
ToolbarButtonUpload,
|
ToolbarButtonUpload,
|
||||||
|
ChevronLeftIcon,
|
||||||
ToolbarButton,
|
ToolbarButton,
|
||||||
SearchBar
|
SearchBar,
|
||||||
|
MenuIcon,
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
...mapGetters([
|
...mapGetters([
|
||||||
@@ -49,36 +49,30 @@
|
|||||||
directoryName() {
|
directoryName() {
|
||||||
return this.currentFolder ? this.currentFolder.name : this.homeDirectory.name
|
return this.currentFolder ? this.currentFolder.name : this.homeDirectory.name
|
||||||
},
|
},
|
||||||
previousFolder() {
|
|
||||||
const length = this.browseHistory.length - 2
|
|
||||||
|
|
||||||
return this.browseHistory[length] ? this.browseHistory[length] : this.homeDirectory
|
|
||||||
},
|
|
||||||
isSmallAppSize() {
|
isSmallAppSize() {
|
||||||
return this.appSize === 'small'
|
return this.appSize === 'small'
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
data() {
|
|
||||||
return {
|
|
||||||
isSidebarMenu: false,
|
|
||||||
}
|
|
||||||
},
|
|
||||||
methods: {
|
methods: {
|
||||||
showSidebarMenu() {
|
showMobileNavigation() {
|
||||||
this.isSidebarMenu = ! this.isSidebarMenu
|
events.$emit('show:mobile-navigation')
|
||||||
events.$emit('show:sidebar')
|
|
||||||
},
|
},
|
||||||
goBack() {
|
goBack() {
|
||||||
|
|
||||||
if (this.previousFolder.location === 'trash-root') {
|
let previousFolder = last(this.browseHistory)
|
||||||
|
|
||||||
|
if (previousFolder.location === 'trash-root') {
|
||||||
this.$store.dispatch('getTrash')
|
this.$store.dispatch('getTrash')
|
||||||
this.$store.commit('FLUSH_BROWSER_HISTORY')
|
|
||||||
|
} else if (previousFolder.location === 'shared') {
|
||||||
|
this.$store.dispatch('getShared')
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
if ( this.$isThisLocation('public') ) {
|
if ( this.$isThisLocation('public') ) {
|
||||||
this.$store.dispatch('browseShared', [this.previousFolder, true])
|
this.$store.dispatch('browseShared', [{folder: previousFolder, back: true, init: false}])
|
||||||
} else {
|
} else {
|
||||||
this.$store.dispatch('getFolder', [this.previousFolder, true])
|
this.$store.dispatch('getFolder', [{folder: previousFolder, back: true, init: false}])
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -93,13 +87,13 @@
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped lang="scss">
|
<style scoped lang="scss">
|
||||||
@import "@assets/app.scss";
|
@import '@assets/vue-file-manager/_variables';
|
||||||
|
@import '@assets/vue-file-manager/_mixins';
|
||||||
|
|
||||||
.mobile-toolbar {
|
.mobile-toolbar {
|
||||||
background: white;
|
background: white;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
display: flex;
|
display: none;
|
||||||
padding: 10px 0;
|
padding: 10px 0;
|
||||||
position: sticky;
|
position: sticky;
|
||||||
top: 0;
|
top: 0;
|
||||||
@@ -121,6 +115,7 @@
|
|||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
opacity: 0;
|
opacity: 0;
|
||||||
visibility: hidden;
|
visibility: hidden;
|
||||||
|
margin-top: -2px;
|
||||||
|
|
||||||
&.is-visible {
|
&.is-visible {
|
||||||
opacity: 1;
|
opacity: 1;
|
||||||
@@ -154,10 +149,21 @@
|
|||||||
position: absolute;
|
position: absolute;
|
||||||
right: -10px;
|
right: -10px;
|
||||||
top: -20px;
|
top: -20px;
|
||||||
|
|
||||||
|
path, line, polyline, rect, circle {
|
||||||
|
stroke: $text;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@media only screen and (max-width: 960px) {
|
||||||
|
|
||||||
|
.mobile-toolbar {
|
||||||
|
display: flex;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@media (prefers-color-scheme: dark) {
|
@media (prefers-color-scheme: dark) {
|
||||||
|
|
||||||
.mobile-toolbar {
|
.mobile-toolbar {
|
||||||
@@ -167,8 +173,11 @@
|
|||||||
color: $dark_mode_text_primary;
|
color: $dark_mode_text_primary;
|
||||||
}
|
}
|
||||||
|
|
||||||
.more-actions-button svg path {
|
.more-actions-button .tap-area {
|
||||||
fill: $dark_mode_text_primary;
|
|
||||||
|
path, line, polyline, rect, circle {
|
||||||
|
stroke: $dark_mode_text_primary;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -12,7 +12,8 @@ export default {
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped lang="scss">
|
<style scoped lang="scss">
|
||||||
@import "@assets/app.scss";
|
@import '@assets/vue-file-manager/_variables';
|
||||||
|
@import '@assets/vue-file-manager/_mixins';
|
||||||
|
|
||||||
.progress-bar {
|
.progress-bar {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
|
|||||||
@@ -1,5 +1,11 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="search-bar">
|
<div class="search-bar">
|
||||||
|
<div class="icon" v-if="!isQuery">
|
||||||
|
<search-icon size="19"></search-icon>
|
||||||
|
</div>
|
||||||
|
<div class="icon" v-if="isQuery" @click="resetQuery">
|
||||||
|
<x-icon class="pointer" size="19"></x-icon>
|
||||||
|
</div>
|
||||||
<input
|
<input
|
||||||
v-model="query"
|
v-model="query"
|
||||||
class="query"
|
class="query"
|
||||||
@@ -7,22 +13,21 @@
|
|||||||
name="query"
|
name="query"
|
||||||
:placeholder="$t('inputs.placeholder_search_files')"
|
:placeholder="$t('inputs.placeholder_search_files')"
|
||||||
/>
|
/>
|
||||||
<div class="icon" v-if="!isQuery">
|
|
||||||
<FontAwesomeIcon icon="search"></FontAwesomeIcon>
|
|
||||||
</div>
|
|
||||||
<div class="icon" v-if="isQuery" @click="resetQuery">
|
|
||||||
<FontAwesomeIcon icon="times" class="pointer"></FontAwesomeIcon>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
|
import { SearchIcon, XIcon } from 'vue-feather-icons'
|
||||||
import {mapGetters} from 'vuex'
|
import {mapGetters} from 'vuex'
|
||||||
import {debounce} from 'lodash'
|
import {debounce} from 'lodash'
|
||||||
import {events} from '@/bus'
|
import {events} from '@/bus'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'SearchBar',
|
name: 'SearchBar',
|
||||||
|
components: {
|
||||||
|
SearchIcon,
|
||||||
|
XIcon,
|
||||||
|
},
|
||||||
computed: {
|
computed: {
|
||||||
...mapGetters(['currentFolder']),
|
...mapGetters(['currentFolder']),
|
||||||
isQuery() {
|
isQuery() {
|
||||||
@@ -52,9 +57,9 @@
|
|||||||
|
|
||||||
// Get back after delete query to previosly folder
|
// Get back after delete query to previosly folder
|
||||||
if ( this.$isThisLocation('public') ) {
|
if ( this.$isThisLocation('public') ) {
|
||||||
this.$store.dispatch('browseShared', [this.currentFolder, true])
|
this.$store.dispatch('browseShared', [{folder: this.currentFolder, back: true, init: false}])
|
||||||
} else {
|
} else {
|
||||||
this.$store.dispatch('getFolder', [this.currentFolder, true])
|
this.$store.dispatch('getFolder', [{folder: this.currentFolder, back: true, init: false}])
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -69,20 +74,20 @@
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped lang="scss">
|
<style scoped lang="scss">
|
||||||
@import "@assets/app.scss";
|
@import '@assets/vue-file-manager/_variables';
|
||||||
|
@import '@assets/vue-file-manager/_mixins';
|
||||||
|
|
||||||
.search-bar {
|
.search-bar {
|
||||||
position: relative;
|
position: relative;
|
||||||
|
|
||||||
input {
|
input {
|
||||||
//width: 100%;
|
background: transparent;
|
||||||
background: $light_background;
|
|
||||||
border-radius: 8px;
|
border-radius: 8px;
|
||||||
outline: 0;
|
outline: 0;
|
||||||
padding: 9px 20px;
|
padding: 9px 20px 9px 43px;
|
||||||
font-weight: 100;
|
font-weight: 400;
|
||||||
@include font-size(16);
|
@include font-size(16);
|
||||||
min-width: 380px;
|
min-width: 175px;
|
||||||
transition: 0.15s all ease;
|
transition: 0.15s all ease;
|
||||||
border: 1px solid white;
|
border: 1px solid white;
|
||||||
-webkit-appearance: none;
|
-webkit-appearance: none;
|
||||||
@@ -90,7 +95,7 @@
|
|||||||
&::placeholder {
|
&::placeholder {
|
||||||
color: $text;
|
color: $text;
|
||||||
@include font-size(14);
|
@include font-size(14);
|
||||||
font-weight: 400;
|
font-weight: 500;
|
||||||
}
|
}
|
||||||
|
|
||||||
&:focus {
|
&:focus {
|
||||||
@@ -108,8 +113,8 @@
|
|||||||
.icon {
|
.icon {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
top: 0;
|
top: 0;
|
||||||
right: 0;
|
left: 0;
|
||||||
padding: 10px 15px;
|
padding: 11px 15px;
|
||||||
|
|
||||||
.pointer {
|
.pointer {
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
@@ -117,11 +122,42 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@media only screen and (max-width: 1024px) {
|
||||||
|
|
||||||
|
.search-bar input {
|
||||||
|
max-width: 190px;
|
||||||
|
padding-right: 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@media only screen and (max-width: 690px) {
|
||||||
|
|
||||||
|
.search-bar {
|
||||||
|
|
||||||
|
input {
|
||||||
|
min-width: initial;
|
||||||
|
width: 100%;
|
||||||
|
max-width: initial;
|
||||||
|
padding: 9px 20px 9px 30px;
|
||||||
|
|
||||||
|
&:focus {
|
||||||
|
border: 1px solid transparent;
|
||||||
|
box-shadow: none;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon {
|
||||||
|
padding: 11px 15px 11px 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
@media (prefers-color-scheme: dark) {
|
@media (prefers-color-scheme: dark) {
|
||||||
.search-bar {
|
.search-bar {
|
||||||
input {
|
input {
|
||||||
background: $dark_mode_foreground;
|
border-color: transparent;
|
||||||
border-color: $dark_mode_foreground;
|
color: $dark_mode_text_primary;
|
||||||
|
|
||||||
&::placeholder {
|
&::placeholder {
|
||||||
color: $dark_mode_text_secondary;
|
color: $dark_mode_text_secondary;
|
||||||
|
|||||||
@@ -11,7 +11,8 @@
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped lang="scss">
|
<style scoped lang="scss">
|
||||||
@import "@assets/app.scss";
|
@import '@assets/vue-file-manager/_variables';
|
||||||
|
@import '@assets/vue-file-manager/_mixins';
|
||||||
|
|
||||||
#loading-bar-spinner.spinner {
|
#loading-bar-spinner.spinner {
|
||||||
left: 50%;
|
left: 50%;
|
||||||
|
|||||||
@@ -1,18 +1,36 @@
|
|||||||
<template>
|
<template>
|
||||||
<button class="button" :title="action">
|
<button class="button" :title="action">
|
||||||
<FontAwesomeIcon class="icon" :icon="source"></FontAwesomeIcon>
|
<corner-down-right-icon v-if="source === 'move'" size="19"></corner-down-right-icon>
|
||||||
|
<folder-plus-icon v-if="source === 'folder-plus'" size="19"></folder-plus-icon>
|
||||||
|
<trash-2-icon v-if="source === 'trash'" size="19"></trash-2-icon>
|
||||||
|
<list-icon v-if="source === 'th-list'" size="19"></list-icon>
|
||||||
|
<info-icon v-if="source === 'info'" size="19"></info-icon>
|
||||||
|
<grid-icon v-if="source === 'th'" size="19"></grid-icon>
|
||||||
|
<link-icon v-if="source === 'share'" size="19"></link-icon>
|
||||||
</button>
|
</button>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
|
import {FolderPlusIcon, Trash2Icon, GridIcon, ListIcon, InfoIcon, CornerDownRightIcon, LinkIcon} from 'vue-feather-icons'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'ToolbarButton',
|
name: 'ToolbarButton',
|
||||||
props: ['source', 'action']
|
props: ['source', 'action'],
|
||||||
|
components: {
|
||||||
|
CornerDownRightIcon,
|
||||||
|
FolderPlusIcon,
|
||||||
|
Trash2Icon,
|
||||||
|
ListIcon,
|
||||||
|
GridIcon,
|
||||||
|
InfoIcon,
|
||||||
|
LinkIcon,
|
||||||
|
},
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped lang="scss">
|
<style scoped lang="scss">
|
||||||
@import "@assets/app.scss";
|
@import '@assets/vue-file-manager/_variables';
|
||||||
|
@import '@assets/vue-file-manager/_mixins';
|
||||||
|
|
||||||
.button {
|
.button {
|
||||||
height: 42px;
|
height: 42px;
|
||||||
@@ -22,42 +40,36 @@
|
|||||||
align-items: center;
|
align-items: center;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
padding: 0;
|
padding: 0;
|
||||||
background: $light_background;
|
|
||||||
text-align: center;
|
text-align: center;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
white-space: nowrap;
|
white-space: nowrap;
|
||||||
outline: none;
|
outline: none;
|
||||||
border: none;
|
border: none;
|
||||||
|
@include transition(150ms);
|
||||||
.icon {
|
background: transparent;
|
||||||
@include font-size(16);
|
|
||||||
}
|
|
||||||
|
|
||||||
&:hover {
|
&:hover {
|
||||||
background: rgba($theme, .1);
|
background: $light_background;
|
||||||
|
|
||||||
/deep/ svg path {
|
path, line, polyline, rect, circle {
|
||||||
@include transition;
|
@include transition(150ms);
|
||||||
fill: $theme;
|
stroke: $theme;
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
&.active {
|
|
||||||
background: rgba($theme, .1);
|
|
||||||
|
|
||||||
/deep/ svg path {
|
|
||||||
fill: $theme;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@media (prefers-color-scheme: dark) {
|
@media (prefers-color-scheme: dark) {
|
||||||
.button {
|
|
||||||
background: $dark_mode_foreground;
|
|
||||||
}
|
|
||||||
|
|
||||||
.icon path {
|
.button {
|
||||||
fill: $dark_mode_text_primary;
|
background: transparent;
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
background: $dark_mode_foreground;
|
||||||
|
}
|
||||||
|
|
||||||
|
path, line, polyline, rect, circle {
|
||||||
|
stroke: $dark_mode_text_primary;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
<template>
|
<template>
|
||||||
<label label="file" class="button file-input">
|
<label label="file" class="button file-input">
|
||||||
<FontAwesomeIcon class="icon" :icon="source"></FontAwesomeIcon>
|
<upload-cloud-icon size="17"></upload-cloud-icon>
|
||||||
<input
|
<input
|
||||||
@change="emmitFiles"
|
@change="emmitFiles"
|
||||||
v-show="false"
|
v-show="false"
|
||||||
@@ -8,15 +8,19 @@
|
|||||||
type="file"
|
type="file"
|
||||||
name="files[]"
|
name="files[]"
|
||||||
multiple
|
multiple
|
||||||
:disabled="$isThisLocation(['trash', 'trash-root'])"
|
|
||||||
/>
|
/>
|
||||||
</label>
|
</label>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
|
import { UploadCloudIcon } from 'vue-feather-icons'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'ToolbarButtonUpload',
|
name: 'ToolbarButtonUpload',
|
||||||
props: ['source', 'action'],
|
props: ['action'],
|
||||||
|
components: {
|
||||||
|
UploadCloudIcon,
|
||||||
|
},
|
||||||
methods: {
|
methods: {
|
||||||
emmitFiles(e) {
|
emmitFiles(e) {
|
||||||
this.$uploadFiles(e.target.files)
|
this.$uploadFiles(e.target.files)
|
||||||
@@ -26,7 +30,8 @@
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped lang="scss">
|
<style scoped lang="scss">
|
||||||
@import "@assets/app.scss";
|
@import '@assets/vue-file-manager/_variables';
|
||||||
|
@import '@assets/vue-file-manager/_mixins';
|
||||||
|
|
||||||
.button {
|
.button {
|
||||||
height: 42px;
|
height: 42px;
|
||||||
@@ -36,7 +41,6 @@
|
|||||||
align-items: center;
|
align-items: center;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
padding: 0;
|
padding: 0;
|
||||||
background: $light_background;
|
|
||||||
text-align: center;
|
text-align: center;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
white-space: nowrap;
|
white-space: nowrap;
|
||||||
@@ -44,26 +48,27 @@
|
|||||||
border: none;
|
border: none;
|
||||||
|
|
||||||
&:hover {
|
&:hover {
|
||||||
background: rgba($theme, .1);
|
background: $light_background;
|
||||||
|
|
||||||
/deep/ svg path {
|
path, line, polyline, rect, circle {
|
||||||
@include transition;
|
@include transition(150ms);
|
||||||
fill: $theme;
|
stroke: $theme;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.icon {
|
|
||||||
@include font-size(16);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@media (prefers-color-scheme: dark) {
|
@media (prefers-color-scheme: dark) {
|
||||||
.button {
|
|
||||||
background: $dark_mode_foreground;
|
|
||||||
}
|
|
||||||
|
|
||||||
.icon path {
|
.button {
|
||||||
fill: $dark_mode_text_primary;
|
background: transparent;
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
background: $dark_mode_foreground;
|
||||||
|
}
|
||||||
|
|
||||||
|
path, line, polyline, rect, circle {
|
||||||
|
stroke: $dark_mode_text_primary;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
@@ -25,7 +25,8 @@
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped lang="scss">
|
<style scoped lang="scss">
|
||||||
@import "@assets/app.scss";
|
@import '@assets/vue-file-manager/_variables';
|
||||||
|
@import '@assets/vue-file-manager/_mixins';
|
||||||
|
|
||||||
.info-panel-enter-active,
|
.info-panel-enter-active,
|
||||||
.info-panel-leave-active {
|
.info-panel-leave-active {
|
||||||
|
|||||||
@@ -0,0 +1,121 @@
|
|||||||
|
<template>
|
||||||
|
<ul class="link-group">
|
||||||
|
<router-link :to="{name: link.routeName}" v-for="(link, i) in navigation" :key="i" v-if="link.isVisible" :class="link.icon" class="link-item" @click.native="$emit('menu', link.icon)">
|
||||||
|
<div class="menu-icon">
|
||||||
|
<hard-drive-icon v-if="link.icon === 'hard-drive'" size="17"></hard-drive-icon>
|
||||||
|
<share-icon v-if="link.icon === 'share'" size="17"></share-icon>
|
||||||
|
<trash2-icon v-if="link.icon === 'trash'" size="17"></trash2-icon>
|
||||||
|
<power-icon v-if="link.icon === 'power'" size="17"></power-icon>
|
||||||
|
<settings-icon v-if="link.icon === 'settings'" size="17"></settings-icon>
|
||||||
|
<upload-cloud-icon v-if="link.icon === 'latest'" size="17"></upload-cloud-icon>
|
||||||
|
<user-icon v-if="link.icon === 'user'" size="17"></user-icon>
|
||||||
|
<lock-icon v-if="link.icon === 'lock'" size="17"></lock-icon>
|
||||||
|
</div>
|
||||||
|
<b class="menu-link">
|
||||||
|
<span>{{ link.title }}</span>
|
||||||
|
<chevron-right-icon size="15" class="arrow-right"></chevron-right-icon>
|
||||||
|
</b>
|
||||||
|
</router-link>
|
||||||
|
</ul>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import {
|
||||||
|
ChevronRightIcon,
|
||||||
|
UploadCloudIcon,
|
||||||
|
HardDriveIcon,
|
||||||
|
SettingsIcon,
|
||||||
|
Trash2Icon,
|
||||||
|
PowerIcon,
|
||||||
|
ShareIcon,
|
||||||
|
UserIcon,
|
||||||
|
LockIcon,
|
||||||
|
} from 'vue-feather-icons'
|
||||||
|
|
||||||
|
export default {
|
||||||
|
name: 'MenuBar',
|
||||||
|
components: {
|
||||||
|
ChevronRightIcon,
|
||||||
|
UploadCloudIcon,
|
||||||
|
HardDriveIcon,
|
||||||
|
SettingsIcon,
|
||||||
|
Trash2Icon,
|
||||||
|
PowerIcon,
|
||||||
|
ShareIcon,
|
||||||
|
LockIcon,
|
||||||
|
UserIcon,
|
||||||
|
},
|
||||||
|
props: [
|
||||||
|
'navigation'
|
||||||
|
],
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped lang="scss">
|
||||||
|
@import '@assets/vue-file-manager/_variables';
|
||||||
|
@import '@assets/vue-file-manager/_mixins';
|
||||||
|
|
||||||
|
.link-item {
|
||||||
|
display: flex;
|
||||||
|
text-decoration: none;
|
||||||
|
padding: 17px 0;
|
||||||
|
width: 100%;
|
||||||
|
|
||||||
|
&.power {
|
||||||
|
|
||||||
|
.menu-icon {
|
||||||
|
|
||||||
|
path, line, polyline, rect, circle {
|
||||||
|
stroke: $red;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.menu-link {
|
||||||
|
color: $red;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.menu-icon {
|
||||||
|
display: block;
|
||||||
|
margin-right: 20px;
|
||||||
|
|
||||||
|
svg {
|
||||||
|
margin-top: -1px;
|
||||||
|
vertical-align: middle;
|
||||||
|
}
|
||||||
|
|
||||||
|
path, line, polyline, rect, circle {
|
||||||
|
stroke: $text;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.menu-link {
|
||||||
|
width: 100%;
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
align-items: center;
|
||||||
|
color: $text;
|
||||||
|
|
||||||
|
span {
|
||||||
|
@include font-size(14);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (prefers-color-scheme: dark) {
|
||||||
|
.link-item {
|
||||||
|
|
||||||
|
.menu-icon {
|
||||||
|
|
||||||
|
path, line, polyline, rect, circle {
|
||||||
|
stroke: $dark_mode_text_primary;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.menu-link {
|
||||||
|
color: $dark_mode_text_primary;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
</style>
|
||||||
@@ -0,0 +1,108 @@
|
|||||||
|
<template>
|
||||||
|
<header class="mobile-header">
|
||||||
|
|
||||||
|
<!-- Go back-->
|
||||||
|
<div @click="goBack" class="go-back">
|
||||||
|
<chevron-left-icon size="17" class="icon"></chevron-left-icon>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!--Folder Title-->
|
||||||
|
<div class="location-name">{{ $router.currentRoute.meta.title }}</div>
|
||||||
|
|
||||||
|
<!--More Actions-->
|
||||||
|
<div @click="showMobileNavigation" class="mobile-menu">
|
||||||
|
<menu-icon size="17" class="icon"></menu-icon>
|
||||||
|
</div>
|
||||||
|
</header>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import {events} from '@/bus'
|
||||||
|
|
||||||
|
import {
|
||||||
|
ChevronLeftIcon,
|
||||||
|
MenuIcon,
|
||||||
|
} from 'vue-feather-icons'
|
||||||
|
|
||||||
|
export default {
|
||||||
|
name: 'MenuBar',
|
||||||
|
components: {
|
||||||
|
ChevronLeftIcon,
|
||||||
|
MenuIcon,
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
showMobileNavigation() {
|
||||||
|
events.$emit('show:mobile-navigation')
|
||||||
|
},
|
||||||
|
goBack() {
|
||||||
|
this.$router.back();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped lang="scss">
|
||||||
|
@import '@assets/vue-file-manager/_variables';
|
||||||
|
@import '@assets/vue-file-manager/_mixins';
|
||||||
|
|
||||||
|
.mobile-header {
|
||||||
|
padding: 10px 15px;
|
||||||
|
text-align: center;
|
||||||
|
background: white;
|
||||||
|
position: sticky;
|
||||||
|
display: none;
|
||||||
|
z-index: 6;
|
||||||
|
top: 0;
|
||||||
|
|
||||||
|
> div {
|
||||||
|
flex-grow: 1;
|
||||||
|
align-self: center;
|
||||||
|
white-space: nowrap;
|
||||||
|
}
|
||||||
|
|
||||||
|
.go-back {
|
||||||
|
text-align: left;
|
||||||
|
}
|
||||||
|
|
||||||
|
.location-name {
|
||||||
|
line-height: 1;
|
||||||
|
text-align: center;
|
||||||
|
width: 100%;
|
||||||
|
vertical-align: middle;
|
||||||
|
@include font-size(15);
|
||||||
|
color: $text;
|
||||||
|
font-weight: 700;
|
||||||
|
max-width: 220px;
|
||||||
|
overflow: hidden;
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
display: inline-block;
|
||||||
|
}
|
||||||
|
|
||||||
|
.mobile-menu {
|
||||||
|
text-align: right;
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon {
|
||||||
|
vertical-align: middle;
|
||||||
|
margin-top: -4px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@media only screen and (max-width: 690px) {
|
||||||
|
.mobile-header {
|
||||||
|
display: flex;
|
||||||
|
margin-bottom: 25px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (prefers-color-scheme: dark) {
|
||||||
|
.mobile-header {
|
||||||
|
background: $dark_mode_background;
|
||||||
|
|
||||||
|
.location-name {
|
||||||
|
color: $dark_mode_text_primary;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
</style>
|
||||||
@@ -15,7 +15,8 @@
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped>
|
||||||
@import "@assets/app.scss";
|
@import '@assets/vue-file-manager/_variables';
|
||||||
|
@import '@assets/vue-file-manager/_mixins';
|
||||||
|
|
||||||
.action-button {
|
.action-button {
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
|
|||||||
@@ -0,0 +1,63 @@
|
|||||||
|
<template>
|
||||||
|
<div @click="fileViewClick"
|
||||||
|
@contextmenu.prevent.capture="contextMenu($event, undefined)"
|
||||||
|
id="files-view">
|
||||||
|
<ContextMenu/>
|
||||||
|
<DesktopToolbar/>
|
||||||
|
<FileBrowser/>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import DesktopToolbar from '@/components/FilesView/DesktopToolbar'
|
||||||
|
import FileBrowser from '@/components/FilesView/FileBrowser'
|
||||||
|
import ContextMenu from '@/components/FilesView/ContextMenu'
|
||||||
|
import {ResizeSensor} from 'css-element-queries'
|
||||||
|
import {mapGetters} from 'vuex'
|
||||||
|
import {events} from '@/bus'
|
||||||
|
|
||||||
|
export default {
|
||||||
|
name: 'FilesView',
|
||||||
|
components: {
|
||||||
|
DesktopToolbar,
|
||||||
|
FileBrowser,
|
||||||
|
ContextMenu,
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
...mapGetters(['config']),
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
fileViewClick() {
|
||||||
|
events.$emit('contextMenu:hide')
|
||||||
|
},
|
||||||
|
contextMenu(event, item) {
|
||||||
|
events.$emit('contextMenu:show', event, item)
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss">
|
||||||
|
@import '@assets/vue-file-manager/_variables';
|
||||||
|
@import '@assets/vue-file-manager/_mixins';
|
||||||
|
|
||||||
|
#files-view {
|
||||||
|
font-family: 'Nunito', sans-serif;
|
||||||
|
font-size: 16px;
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
position: relative;
|
||||||
|
min-width: 320px;
|
||||||
|
overflow-x: hidden;
|
||||||
|
padding-left: 15px;
|
||||||
|
padding-right: 15px;
|
||||||
|
}
|
||||||
|
|
||||||
|
@media only screen and (max-width: 690px) {
|
||||||
|
#files-view {
|
||||||
|
padding-left: 0;
|
||||||
|
padding-right: 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
</style>
|
||||||
@@ -2,15 +2,22 @@
|
|||||||
<div class="inline-wrapper icon-append copy-input" :class="size" @click="copyUrl">
|
<div class="inline-wrapper icon-append copy-input" :class="size" @click="copyUrl">
|
||||||
<input ref="sel" :value="value" id="link-input" type="text" class="input-text" readonly>
|
<input ref="sel" :value="value" id="link-input" type="text" class="input-text" readonly>
|
||||||
<div class="icon">
|
<div class="icon">
|
||||||
<FontAwesomeIcon :icon="isCopiedLink ? 'check' : 'link'"/>
|
<link-icon v-if="! isCopiedLink" size="14"></link-icon>
|
||||||
|
<check-icon v-if="isCopiedLink" size="14"></check-icon>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
|
import { LinkIcon, CheckIcon } from 'vue-feather-icons'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'CopyInput',
|
name: 'CopyInput',
|
||||||
props: ['size', 'value'],
|
props: ['size', 'value'],
|
||||||
|
components: {
|
||||||
|
CheckIcon,
|
||||||
|
LinkIcon,
|
||||||
|
},
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
isCopiedLink: false,
|
isCopiedLink: false,
|
||||||
@@ -40,8 +47,10 @@
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped>
|
||||||
@import "@assets/app.scss";
|
@import '@assets/vue-file-manager/_variables';
|
||||||
|
@import '@assets/vue-file-manager/_mixins';
|
||||||
@import "@assets/vue-file-manager/_inapp-forms.scss";
|
@import "@assets/vue-file-manager/_inapp-forms.scss";
|
||||||
|
@import "@assets/vue-file-manager/_forms.scss";
|
||||||
|
|
||||||
// Single page
|
// Single page
|
||||||
.copy-input {
|
.copy-input {
|
||||||
@@ -51,8 +60,7 @@
|
|||||||
&.icon-append {
|
&.icon-append {
|
||||||
|
|
||||||
.icon {
|
.icon {
|
||||||
padding: 8px 10px;
|
padding: 10px;
|
||||||
@include font-size(11);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -81,9 +89,6 @@
|
|||||||
.copy-input {
|
.copy-input {
|
||||||
input {
|
input {
|
||||||
color: $dark_mode_text_primary;
|
color: $dark_mode_text_primary;
|
||||||
|
|
||||||
&:disabled {
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,7 +7,8 @@
|
|||||||
<!--If is selected-->
|
<!--If is selected-->
|
||||||
<div class="selected" v-if="selected">
|
<div class="selected" v-if="selected">
|
||||||
<div class="option-icon" v-if="selected.icon">
|
<div class="option-icon" v-if="selected.icon">
|
||||||
<FontAwesomeIcon :icon="selected.icon" />
|
<user-icon v-if="selected.icon === 'user'" size="14"></user-icon>
|
||||||
|
<edit2-icon v-if="selected.icon === 'user-edit'" size="14"></edit2-icon>
|
||||||
</div>
|
</div>
|
||||||
<span class="option-value">{{ selected.label }}</span>
|
<span class="option-value">{{ selected.label }}</span>
|
||||||
</div>
|
</div>
|
||||||
@@ -17,7 +18,7 @@
|
|||||||
<span class="option-value placehoder">{{ placeholder }}</span>
|
<span class="option-value placehoder">{{ placeholder }}</span>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<FontAwesomeIcon icon="chevron-down" class="chevron"/>
|
<chevron-down-icon size="19" class="chevron"></chevron-down-icon>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!--Options-->
|
<!--Options-->
|
||||||
@@ -25,7 +26,8 @@
|
|||||||
<ul class="input-options" v-if="isOpen">
|
<ul class="input-options" v-if="isOpen">
|
||||||
<li class="option-item" @click="selectOption(option)" v-for="(option, i) in options" :key="i">
|
<li class="option-item" @click="selectOption(option)" v-for="(option, i) in options" :key="i">
|
||||||
<div class="option-icon" v-if="option.icon">
|
<div class="option-icon" v-if="option.icon">
|
||||||
<FontAwesomeIcon :icon="option.icon" />
|
<user-icon v-if="option.icon === 'user'" size="14"></user-icon>
|
||||||
|
<edit2-icon v-if="option.icon === 'user-edit'" size="14"></edit2-icon>
|
||||||
</div>
|
</div>
|
||||||
<span class="option-value">{{ option.label }}</span>
|
<span class="option-value">{{ option.label }}</span>
|
||||||
</li>
|
</li>
|
||||||
@@ -35,9 +37,16 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
|
import { ChevronDownIcon, Edit2Icon, UserIcon } from 'vue-feather-icons'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name:'SelectInput',
|
name:'SelectInput',
|
||||||
props: ['options', 'isError', 'default', 'placeholder'],
|
props: ['options', 'isError', 'default', 'placeholder'],
|
||||||
|
components: {
|
||||||
|
Edit2Icon,
|
||||||
|
UserIcon,
|
||||||
|
ChevronDownIcon
|
||||||
|
},
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
selected: undefined,
|
selected: undefined,
|
||||||
@@ -69,7 +78,8 @@
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped>
|
||||||
@import "@assets/app.scss";
|
@import '@assets/vue-file-manager/_variables';
|
||||||
|
@import '@assets/vue-file-manager/_mixins';
|
||||||
|
|
||||||
.select {
|
.select {
|
||||||
position: relative;
|
position: relative;
|
||||||
@@ -77,7 +87,7 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
.input-options {
|
.input-options {
|
||||||
background: $light_background;
|
background: $light_mode_input_background;
|
||||||
border-radius: 8px;
|
border-radius: 8px;
|
||||||
position: absolute;
|
position: absolute;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
@@ -105,7 +115,7 @@
|
|||||||
|
|
||||||
.input-area {
|
.input-area {
|
||||||
justify-content: space-between;
|
justify-content: space-between;
|
||||||
background: $light_background;
|
background: $light_mode_input_background;
|
||||||
border: 1px solid transparent;
|
border: 1px solid transparent;
|
||||||
@include transition(150ms);
|
@include transition(150ms);
|
||||||
align-items: center;
|
align-items: center;
|
||||||
@@ -138,16 +148,22 @@
|
|||||||
.option-icon {
|
.option-icon {
|
||||||
width: 20px;
|
width: 20px;
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
@include font-size(12);
|
@include font-size(10);
|
||||||
|
|
||||||
|
svg {
|
||||||
|
margin-top: -4px;
|
||||||
|
vertical-align: middle;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.option-value {
|
.option-value {
|
||||||
@include font-size(15);
|
@include font-size(14);
|
||||||
font-weight: 700;
|
font-weight: 700;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
|
vertical-align: middle;
|
||||||
|
|
||||||
&.placehoder {
|
&.placehoder {
|
||||||
color: $light_text;
|
color: rgba($text, 0.5);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -39,7 +39,8 @@
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped>
|
||||||
@import "@assets/app.scss";
|
@import '@assets/vue-file-manager/_variables';
|
||||||
|
@import '@assets/vue-file-manager/_mixins';
|
||||||
|
|
||||||
.input-wrapper {
|
.input-wrapper {
|
||||||
display: flex;
|
display: flex;
|
||||||
|
|||||||
@@ -0,0 +1,183 @@
|
|||||||
|
<template>
|
||||||
|
<div class="mobile-main-navigation">
|
||||||
|
<transition name="context-menu">
|
||||||
|
<nav v-if="isVisible" class="mobile-navigation">
|
||||||
|
|
||||||
|
<!--User Info-->
|
||||||
|
<div class="user-info">
|
||||||
|
<UserAvatar size="large" />
|
||||||
|
<UserHeadline/>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!--Navigation-->
|
||||||
|
<MenuItemList :navigation="navigation" @menu="action" />
|
||||||
|
</nav>
|
||||||
|
</transition>
|
||||||
|
<transition name="fade">
|
||||||
|
<div v-show="isVisible" class="vignette" @click="closeAndResetContextMenu"></div>
|
||||||
|
</transition>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import UserHeadline from '@/components/Sidebar/UserHeadline'
|
||||||
|
import MenuItemList from '@/components/Mobile/MenuItemList'
|
||||||
|
import UserAvatar from '@/components/Others/UserAvatar'
|
||||||
|
import {mapGetters} from 'vuex'
|
||||||
|
import {events} from '@/bus'
|
||||||
|
|
||||||
|
export default {
|
||||||
|
name: 'MenuBar',
|
||||||
|
components: {
|
||||||
|
MenuItemList,
|
||||||
|
UserHeadline,
|
||||||
|
UserAvatar,
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
...mapGetters(['app', 'homeDirectory']),
|
||||||
|
},
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
isVisible: false,
|
||||||
|
navigation: [
|
||||||
|
{
|
||||||
|
icon: 'hard-drive',
|
||||||
|
title: this.$t('menu.files'),
|
||||||
|
routeName: 'Files',
|
||||||
|
isVisible: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
icon: 'latest',
|
||||||
|
title: this.$t('menu.latest'),
|
||||||
|
routeName: 'Files',
|
||||||
|
isVisible: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
icon: 'share',
|
||||||
|
title: this.$t('menu.shared'),
|
||||||
|
routeName: 'SharedFiles',
|
||||||
|
isVisible: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
icon: 'trash',
|
||||||
|
title: this.$t('menu.trash'),
|
||||||
|
routeName: 'Trash',
|
||||||
|
isVisible: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
icon: 'settings',
|
||||||
|
title: this.$t('menu.settings'),
|
||||||
|
routeName: 'MobileSettings',
|
||||||
|
isVisible: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
icon: 'power',
|
||||||
|
title: this.$t('menu.logout'),
|
||||||
|
routeName: 'LogOut',
|
||||||
|
isVisible: true,
|
||||||
|
},
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
action(name) {
|
||||||
|
|
||||||
|
if (name === 'latest') {
|
||||||
|
this.$store.dispatch('getLatest')
|
||||||
|
}
|
||||||
|
|
||||||
|
if (name === 'hard-drive') {
|
||||||
|
this.$store.dispatch('getFolder', [{folder: this.homeDirectory, back: false, init: true}])
|
||||||
|
}
|
||||||
|
|
||||||
|
this.closeAndResetContextMenu()
|
||||||
|
},
|
||||||
|
closeAndResetContextMenu() {
|
||||||
|
this.isVisible = false
|
||||||
|
|
||||||
|
events.$emit('hide:mobile-navigation')
|
||||||
|
}
|
||||||
|
},
|
||||||
|
created() {
|
||||||
|
events.$on('show:mobile-navigation', () => {
|
||||||
|
this.isVisible = true
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped lang="scss">
|
||||||
|
@import '@assets/vue-file-manager/_variables';
|
||||||
|
@import '@assets/vue-file-manager/_mixins';
|
||||||
|
|
||||||
|
.mobile-navigation {
|
||||||
|
padding: 20px;
|
||||||
|
width: 100%;
|
||||||
|
position: absolute;
|
||||||
|
bottom: 0;
|
||||||
|
left: 0;
|
||||||
|
right: 0;
|
||||||
|
z-index: 99;
|
||||||
|
background: white;
|
||||||
|
border-top-left-radius: 12px;
|
||||||
|
border-top-right-radius: 12px;
|
||||||
|
min-height: 440px;
|
||||||
|
max-height: 80%;
|
||||||
|
overflow-y: auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
.vignette {
|
||||||
|
background: rgba(0, 0, 0, 0.35);
|
||||||
|
position: absolute;
|
||||||
|
top: 0;
|
||||||
|
right: 0;
|
||||||
|
bottom: 0;
|
||||||
|
left: 0;
|
||||||
|
z-index: 9;
|
||||||
|
cursor: pointer;
|
||||||
|
opacity: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
.user-info {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
margin-bottom: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
@media only screen and (max-width: 690px) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (prefers-color-scheme: dark) {
|
||||||
|
.mobile-navigation {
|
||||||
|
background: $dark_mode_background;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Transition
|
||||||
|
.context-menu-enter-active,
|
||||||
|
.fade-enter-active {
|
||||||
|
transition: all 200ms;
|
||||||
|
}
|
||||||
|
|
||||||
|
.context-menu-leave-active,
|
||||||
|
.fade-leave-active {
|
||||||
|
transition: all 200ms;
|
||||||
|
}
|
||||||
|
|
||||||
|
.fade-enter,
|
||||||
|
.fade-leave-to {
|
||||||
|
opacity: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.context-menu-enter,
|
||||||
|
.context-menu-leave-to {
|
||||||
|
opacity: 0;
|
||||||
|
transform: translateY(100%);
|
||||||
|
}
|
||||||
|
|
||||||
|
.context-menu-leave-active {
|
||||||
|
position: absolute;
|
||||||
|
}
|
||||||
|
|
||||||
|
</style>
|
||||||
@@ -1,7 +1,7 @@
|
|||||||
<template>
|
<template>
|
||||||
<PopupWrapper name="move">
|
<PopupWrapper name="move">
|
||||||
<!--Title-->
|
<!--Title-->
|
||||||
<PopupHeader :title="$t('popup_move_item.title')" />
|
<PopupHeader :title="$t('popup_move_item.title')" icon="move" />
|
||||||
|
|
||||||
<!--Content-->
|
<!--Content-->
|
||||||
<PopupContent type="height-limited" v-if="pickedItem">
|
<PopupContent type="height-limited" v-if="pickedItem">
|
||||||
@@ -123,7 +123,6 @@
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped lang="scss">
|
<style scoped lang="scss">
|
||||||
@import "@assets/app.scss";
|
|
||||||
|
|
||||||
.item-thumbnail {
|
.item-thumbnail {
|
||||||
margin-bottom: 20px;
|
margin-bottom: 20px;
|
||||||
|
|||||||
@@ -36,19 +36,20 @@
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped>
|
||||||
@import "@assets/app.scss";
|
@import '@assets/vue-file-manager/_variables';
|
||||||
|
@import '@assets/vue-file-manager/_mixins';
|
||||||
|
|
||||||
.page-header {
|
.page-header {
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
padding: 20px 30px;
|
|
||||||
background: white;
|
background: white;
|
||||||
position: sticky;
|
|
||||||
top: 0;
|
|
||||||
z-index: 9;
|
z-index: 9;
|
||||||
|
max-width: 700px;
|
||||||
|
width: 100%;
|
||||||
|
margin: 20px auto 30px;
|
||||||
|
|
||||||
.title {
|
.title {
|
||||||
@include font-size(22);
|
@include font-size(18);
|
||||||
font-weight: 700;
|
font-weight: 700;
|
||||||
color: $text;
|
color: $text;
|
||||||
}
|
}
|
||||||
@@ -64,6 +65,7 @@
|
|||||||
|
|
||||||
.page-header {
|
.page-header {
|
||||||
padding: 20px 15px;
|
padding: 20px 15px;
|
||||||
|
margin: 0;
|
||||||
|
|
||||||
.title {
|
.title {
|
||||||
@include font-size(18);
|
@include font-size(18);
|
||||||
@@ -71,6 +73,12 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@media only screen and (max-width: 690px) {
|
||||||
|
.page-header {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@media (prefers-color-scheme: dark) {
|
@media (prefers-color-scheme: dark) {
|
||||||
|
|
||||||
.page-header {
|
.page-header {
|
||||||
|
|||||||
@@ -11,7 +11,8 @@
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped>
|
||||||
@import "@assets/app.scss";
|
@import '@assets/vue-file-manager/_variables';
|
||||||
|
@import '@assets/vue-file-manager/_mixins';
|
||||||
|
|
||||||
.actions {
|
.actions {
|
||||||
padding: 20px;
|
padding: 20px;
|
||||||
|
|||||||
@@ -14,7 +14,8 @@
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped>
|
||||||
@import "@assets/app.scss";
|
@import '@assets/vue-file-manager/_variables';
|
||||||
|
@import '@assets/vue-file-manager/_mixins';
|
||||||
|
|
||||||
.popup-content {
|
.popup-content {
|
||||||
|
|
||||||
|
|||||||
@@ -1,26 +1,58 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="popup-header">
|
<div class="popup-header">
|
||||||
<h1 class="title">{{ title }}</h1>
|
<div class="icon">
|
||||||
|
<corner-down-right-icon v-if="icon === 'move'" size="15" class="title-icon"></corner-down-right-icon>
|
||||||
|
<link-icon v-if="icon === 'share'" size="17" class="title-icon"></link-icon>
|
||||||
|
</div>
|
||||||
|
<div class="label">
|
||||||
|
<h1 class="title">{{ title }}</h1>
|
||||||
|
<x-icon @click="closePopup" size="22" class="close-icon"></x-icon>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
|
import { CornerDownRightIcon, LinkIcon, XIcon } from 'vue-feather-icons'
|
||||||
|
import {events} from '@/bus'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'PopupHeader',
|
name: 'PopupHeader',
|
||||||
props: [
|
props: [
|
||||||
'title'
|
'title', 'icon'
|
||||||
]
|
],
|
||||||
|
components: {
|
||||||
|
CornerDownRightIcon,
|
||||||
|
LinkIcon,
|
||||||
|
XIcon,
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
closePopup() {
|
||||||
|
events.$emit('popup:close')
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped>
|
||||||
@import "@assets/app.scss";
|
@import '@assets/vue-file-manager/_variables';
|
||||||
|
@import '@assets/vue-file-manager/_mixins';
|
||||||
|
|
||||||
.popup-header {
|
.popup-header {
|
||||||
padding: 20px;
|
padding: 20px;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
|
||||||
|
.icon {
|
||||||
|
margin-right: 10px;
|
||||||
|
line-height: 0;
|
||||||
|
|
||||||
|
path, line, polyline, rect, circle {
|
||||||
|
stroke: $theme;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
.title {
|
.title {
|
||||||
@include font-size(18);
|
@include font-size(17);
|
||||||
font-weight: 700;
|
font-weight: 700;
|
||||||
color: $text;
|
color: $text;
|
||||||
}
|
}
|
||||||
@@ -30,6 +62,27 @@
|
|||||||
color: #8b8f9a;
|
color: #8b8f9a;
|
||||||
margin-top: 5px;
|
margin-top: 5px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.label {
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
width: 100%;
|
||||||
|
align-items: center;
|
||||||
|
|
||||||
|
.close-icon {
|
||||||
|
padding: 1px 4px;
|
||||||
|
border-radius: 6px;
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
background: $light_background;
|
||||||
|
|
||||||
|
line {
|
||||||
|
stroke: $theme;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.small {
|
.small {
|
||||||
@@ -38,8 +91,23 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@media only screen and (max-width: 690px) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
@media (prefers-color-scheme: dark) {
|
@media (prefers-color-scheme: dark) {
|
||||||
.popup-header {
|
.popup-header {
|
||||||
|
|
||||||
|
.label {
|
||||||
|
.close-icon {
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
background: $dark_mode_foreground;
|
||||||
|
}
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
.title {
|
.title {
|
||||||
color: $dark_mode_text_primary;
|
color: $dark_mode_text_primary;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
<template>
|
<template>
|
||||||
<transition name="popup">
|
<transition name="popup">
|
||||||
<div class="popup" @click.self="closePopup" v-show="isVisibleWrapper">
|
<div class="popup" @click.self="closePopup" v-if="isVisibleWrapper">
|
||||||
<div class="popup-wrapper">
|
<div class="popup-wrapper">
|
||||||
<slot></slot>
|
<slot></slot>
|
||||||
</div>
|
</div>
|
||||||
@@ -46,7 +46,8 @@
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped>
|
||||||
@import "@assets/app.scss";
|
@import '@assets/vue-file-manager/_variables';
|
||||||
|
@import '@assets/vue-file-manager/_mixins';
|
||||||
|
|
||||||
.popup {
|
.popup {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
@@ -129,6 +130,15 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@media only screen and (max-width: 690px) {
|
||||||
|
|
||||||
|
.popup-wrapper {
|
||||||
|
left: 15px;
|
||||||
|
right: 15px;
|
||||||
|
padding: 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@media (prefers-color-scheme: dark) {
|
@media (prefers-color-scheme: dark) {
|
||||||
.popup-wrapper {
|
.popup-wrapper {
|
||||||
background: $dark_mode_background;
|
background: $dark_mode_background;
|
||||||
|
|||||||
@@ -0,0 +1,34 @@
|
|||||||
|
<template>
|
||||||
|
<b class="text-label">
|
||||||
|
<slot></slot>
|
||||||
|
</b>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
export default {
|
||||||
|
name: 'SectionTitle',
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
@import '@assets/vue-file-manager/_variables';
|
||||||
|
@import '@assets/vue-file-manager/_mixins';
|
||||||
|
|
||||||
|
.text-label {
|
||||||
|
@include font-size(12);
|
||||||
|
color: #AFAFAF;
|
||||||
|
font-weight: 700;
|
||||||
|
display: block;
|
||||||
|
margin-bottom: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
@media only screen and (max-width: 1024px) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (prefers-color-scheme: dark) {
|
||||||
|
.text-label {
|
||||||
|
color: $theme;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
@@ -1,7 +1,7 @@
|
|||||||
<template>
|
<template>
|
||||||
<PopupWrapper name="share-create">
|
<PopupWrapper name="share-create">
|
||||||
<!--Title-->
|
<!--Title-->
|
||||||
<PopupHeader :title="$t('popup_share_create.title', {item: itemTypeTitle})" />
|
<PopupHeader :title="$t('popup_share_create.title', {item: itemTypeTitle})" icon="share" />
|
||||||
|
|
||||||
<!--Content-->
|
<!--Content-->
|
||||||
<PopupContent>
|
<PopupContent>
|
||||||
@@ -181,8 +181,6 @@
|
|||||||
|
|
||||||
// Restore data
|
// Restore data
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
this.isGeneratedShared = false
|
|
||||||
this.shareLink = undefined
|
|
||||||
this.shareOptions = {
|
this.shareOptions = {
|
||||||
permission: undefined,
|
permission: undefined,
|
||||||
password: undefined,
|
password: undefined,
|
||||||
@@ -190,6 +188,8 @@
|
|||||||
type: undefined,
|
type: undefined,
|
||||||
unique_id: undefined,
|
unique_id: undefined,
|
||||||
}
|
}
|
||||||
|
this.isGeneratedShared = false
|
||||||
|
this.shareLink = undefined
|
||||||
}, 150)
|
}, 150)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@@ -197,8 +197,8 @@
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped lang="scss">
|
<style scoped lang="scss">
|
||||||
@import "@assets/app.scss";
|
|
||||||
@import "@assets/vue-file-manager/_inapp-forms.scss";
|
@import "@assets/vue-file-manager/_inapp-forms.scss";
|
||||||
|
@import '@assets/vue-file-manager/_forms';
|
||||||
|
|
||||||
.input-wrapper {
|
.input-wrapper {
|
||||||
|
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
<template>
|
<template>
|
||||||
<PopupWrapper name="share-edit">
|
<PopupWrapper name="share-edit">
|
||||||
<!--Title-->
|
<!--Title-->
|
||||||
<PopupHeader :title="$t('popup_share_edit.title')" />
|
<PopupHeader :title="$t('popup_share_edit.title')" icon="share" />
|
||||||
|
|
||||||
<!--Content-->
|
<!--Content-->
|
||||||
<PopupContent v-if="pickedItem && pickedItem.shared">
|
<PopupContent v-if="pickedItem && pickedItem.shared">
|
||||||
@@ -243,8 +243,8 @@
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped lang="scss">
|
<style scoped lang="scss">
|
||||||
@import "@assets/app.scss";
|
|
||||||
@import "@assets/vue-file-manager/_inapp-forms.scss";
|
@import "@assets/vue-file-manager/_inapp-forms.scss";
|
||||||
|
@import '@assets/vue-file-manager/_forms';
|
||||||
|
|
||||||
.input-wrapper {
|
.input-wrapper {
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,203 @@
|
|||||||
|
<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 '@/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 '@assets/vue-file-manager/_variables';
|
||||||
|
@import '@assets/vue-file-manager/_mixins';
|
||||||
|
|
||||||
|
.detail-storage-item {
|
||||||
|
margin-bottom: 35px;
|
||||||
|
|
||||||
|
&.disk {
|
||||||
|
|
||||||
|
.icon {
|
||||||
|
|
||||||
|
path, line, polyline, rect, circle, polygon {
|
||||||
|
stroke: $theme;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.storage-progress {
|
||||||
|
|
||||||
|
/deep/ span {
|
||||||
|
background: $theme;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&.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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (prefers-color-scheme: dark) {
|
||||||
|
|
||||||
|
.header-storage-item {
|
||||||
|
.type {
|
||||||
|
color: $dark_mode_text_primary;
|
||||||
|
}
|
||||||
|
|
||||||
|
.total-size {
|
||||||
|
color: $dark_mode_text_secondary;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.detail-storage-item {
|
||||||
|
|
||||||
|
&.others {
|
||||||
|
|
||||||
|
.icon {
|
||||||
|
|
||||||
|
path, line, polyline, rect, circle, polygon {
|
||||||
|
stroke: lighten($dark_mode_foreground, 15%);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.storage-progress {
|
||||||
|
|
||||||
|
/deep/ span {
|
||||||
|
background: lighten($dark_mode_foreground, 15%);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
@@ -11,17 +11,24 @@
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped>
|
||||||
@import "@assets/app.scss";
|
@import '@assets/vue-file-manager/_variables';
|
||||||
|
@import '@assets/vue-file-manager/_mixins';
|
||||||
|
|
||||||
.text-label {
|
.text-label {
|
||||||
@include font-size(10);
|
padding-left: 25px;
|
||||||
color: $theme;
|
@include font-size(12);
|
||||||
text-transform: uppercase;
|
color: #AFAFAF;
|
||||||
font-weight: 900;
|
font-weight: 700;
|
||||||
display: block;
|
display: block;
|
||||||
margin-bottom: 5px;
|
margin-bottom: 5px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@media only screen and (max-width: 1024px) {
|
||||||
|
.text-label {
|
||||||
|
padding-left: 20px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@media (prefers-color-scheme: dark) {
|
@media (prefers-color-scheme: dark) {
|
||||||
.text-label {
|
.text-label {
|
||||||
color: $theme;
|
color: $theme;
|
||||||
|
|||||||
@@ -11,14 +11,14 @@
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped>
|
||||||
@import "@assets/app.scss";
|
@import '@assets/vue-file-manager/_variables';
|
||||||
|
@import '@assets/vue-file-manager/_mixins';
|
||||||
|
|
||||||
.theme-label {
|
.theme-label {
|
||||||
@include font-size(14);
|
@include font-size(14);
|
||||||
color: $theme;
|
color: $theme;
|
||||||
text-transform: uppercase;
|
font-weight: 600;
|
||||||
font-weight: 900;
|
|
||||||
display: block;
|
display: block;
|
||||||
margin-bottom: 5px;
|
margin-bottom: 20px;
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
@@ -24,7 +24,7 @@
|
|||||||
<span class="name">{{ item.name }}</span>
|
<span class="name">{{ item.name }}</span>
|
||||||
|
|
||||||
<div v-if="info === 'location'">
|
<div v-if="info === 'location'">
|
||||||
<span class="subtitle">{{ $t('item_thumbnail.original_location') }}: {{ currentFolder.name }}</span>
|
<span class="subtitle">{{ $t('item_thumbnail.original_location') }}: {{ itemLocation }}</span>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div v-if="info === 'metadata'">
|
<div v-if="info === 'metadata'">
|
||||||
@@ -56,12 +56,16 @@
|
|||||||
isImage() {
|
isImage() {
|
||||||
return this.item.type === 'image'
|
return this.item.type === 'image'
|
||||||
},
|
},
|
||||||
|
itemLocation() {
|
||||||
|
return this.item.parent ? this.item.parent.name : this.$t('locations.home')
|
||||||
|
}
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped lang="scss">
|
<style scoped lang="scss">
|
||||||
@import "@assets/app.scss";
|
@import '@assets/vue-file-manager/_variables';
|
||||||
|
@import '@assets/vue-file-manager/_mixins';
|
||||||
|
|
||||||
.file-item {
|
.file-item {
|
||||||
display: flex;
|
display: flex;
|
||||||
@@ -77,15 +81,9 @@
|
|||||||
white-space: nowrap;
|
white-space: nowrap;
|
||||||
|
|
||||||
.item-size,
|
.item-size,
|
||||||
.item-length {
|
.item-length,
|
||||||
@include font-size(12);
|
|
||||||
font-weight: 400;
|
|
||||||
color: $text-muted;
|
|
||||||
display: block;
|
|
||||||
}
|
|
||||||
|
|
||||||
.subtitle {
|
.subtitle {
|
||||||
@include font-size(11);
|
@include font-size(12);
|
||||||
font-weight: 400;
|
font-weight: 400;
|
||||||
color: $text-muted;
|
color: $text-muted;
|
||||||
display: block;
|
display: block;
|
||||||
@@ -104,7 +102,7 @@
|
|||||||
|
|
||||||
.icon-item {
|
.icon-item {
|
||||||
position: relative;
|
position: relative;
|
||||||
min-width: 40px;
|
min-width: 52px;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
line-height: 0;
|
line-height: 0;
|
||||||
|
|
||||||
@@ -129,7 +127,7 @@
|
|||||||
.file-icon-text {
|
.file-icon-text {
|
||||||
line-height: 1;
|
line-height: 1;
|
||||||
top: 40%;
|
top: 40%;
|
||||||
@include font-size(9);
|
@include font-size(8);
|
||||||
margin: 0 auto;
|
margin: 0 auto;
|
||||||
position: absolute;
|
position: absolute;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
@@ -150,8 +148,8 @@
|
|||||||
user-select: none;
|
user-select: none;
|
||||||
max-width: 100%;
|
max-width: 100%;
|
||||||
border-radius: 5px;
|
border-radius: 5px;
|
||||||
width: 36px;
|
width: 52px;
|
||||||
height: 36px;
|
height: 52px;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -159,7 +157,7 @@
|
|||||||
.small {
|
.small {
|
||||||
.file-item {
|
.file-item {
|
||||||
padding: 0 15px;
|
padding: 0 15px;
|
||||||
margin-bottom: 25px;
|
margin-bottom: 20px;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -170,13 +168,22 @@
|
|||||||
.icon-item .file-icon {
|
.icon-item .file-icon {
|
||||||
|
|
||||||
path {
|
path {
|
||||||
fill: $dark_mode_background;
|
fill: $dark_mode_foreground;
|
||||||
stroke: #2F3C54;
|
stroke: #2F3C54;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.item-name .name {
|
.item-name {
|
||||||
color: $dark_mode_text_primary;
|
|
||||||
|
.name {
|
||||||
|
color: $dark_mode_text_primary;
|
||||||
|
}
|
||||||
|
|
||||||
|
.item-size,
|
||||||
|
.item-length,
|
||||||
|
.subtitle {
|
||||||
|
color: $dark_mode_text_secondary;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,9 +2,10 @@
|
|||||||
<!--Folder Icon-->
|
<!--Folder Icon-->
|
||||||
<div class="folder-item-wrapper">
|
<div class="folder-item-wrapper">
|
||||||
|
|
||||||
<div class="folder-item" :class="{'is-selected': isSelected}" @click="showTree" :style="indent">
|
<div class="folder-item" :class="{'is-selected': isSelected}" @click="getFolder" :style="indent">
|
||||||
<FontAwesomeIcon class="icon-chevron" :class="{'is-opened': isVisible, 'is-visible': nodes.folders.length !== 0}" icon="chevron-right"/>
|
<chevron-right-icon @click.stop="showTree" size="17" class="icon-arrow" :class="{'is-opened': isVisible, 'is-visible': nodes.folders.length !== 0}"></chevron-right-icon>
|
||||||
<FontAwesomeIcon class="icon" :icon="directoryIcon"/>
|
<hard-drive-icon v-if="nodes.location === 'base'" size="17" class="icon"></hard-drive-icon>
|
||||||
|
<folder-icon v-if="nodes.location !== 'base'" size="17" class="icon"></folder-icon>
|
||||||
<span class="label">{{ nodes.name }}</span>
|
<span class="label">{{ nodes.name }}</span>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@@ -14,6 +15,7 @@
|
|||||||
|
|
||||||
<script>
|
<script>
|
||||||
import TreeMenu from '@/components/Others/TreeMenu'
|
import TreeMenu from '@/components/Others/TreeMenu'
|
||||||
|
import {FolderIcon, ChevronRightIcon, HardDriveIcon} from 'vue-feather-icons'
|
||||||
import {events} from "@/bus"
|
import {events} from "@/bus"
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
@@ -22,20 +24,15 @@
|
|||||||
'nodes', 'depth'
|
'nodes', 'depth'
|
||||||
],
|
],
|
||||||
components: {
|
components: {
|
||||||
|
ChevronRightIcon,
|
||||||
|
HardDriveIcon,
|
||||||
|
FolderIcon,
|
||||||
TreeMenu,
|
TreeMenu,
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
indent() {
|
indent() {
|
||||||
return { paddingLeft: this.depth * 25 + 'px' }
|
return { paddingLeft: this.depth * 20 + 'px' }
|
||||||
},
|
},
|
||||||
directoryIcon() {
|
|
||||||
|
|
||||||
if (this.nodes.location === 'base') {
|
|
||||||
return 'hdd'
|
|
||||||
} else {
|
|
||||||
return 'folder'
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
@@ -44,10 +41,12 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
|
getFolder() {
|
||||||
|
events.$emit('show-folder-item', this.nodes)
|
||||||
|
events.$emit('pick-folder', this.nodes)
|
||||||
|
},
|
||||||
showTree() {
|
showTree() {
|
||||||
this.isVisible = ! this.isVisible
|
this.isVisible = ! this.isVisible
|
||||||
|
|
||||||
events.$emit('pick-folder', this.nodes)
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
created() {
|
created() {
|
||||||
@@ -61,36 +60,46 @@
|
|||||||
|
|
||||||
if (this.nodes.unique_id == node.unique_id) this.isSelected = true
|
if (this.nodes.unique_id == node.unique_id) this.isSelected = true
|
||||||
})
|
})
|
||||||
|
|
||||||
|
// Select clicked folder
|
||||||
|
events.$on('show-folder-item', node => {
|
||||||
|
this.isSelected = false
|
||||||
|
|
||||||
|
if (this.nodes.unique_id == node.unique_id)
|
||||||
|
this.isSelected = true
|
||||||
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped>
|
||||||
@import "@assets/app.scss";
|
@import '@assets/vue-file-manager/_variables';
|
||||||
|
@import '@assets/vue-file-manager/_mixins';
|
||||||
|
|
||||||
.folder-item {
|
.folder-item {
|
||||||
|
user-select: none;
|
||||||
display: block;
|
display: block;
|
||||||
padding: 15px 20px;
|
padding: 8px 23px;
|
||||||
@include transition(150ms);
|
@include transition(150ms);
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
position: relative;
|
position: relative;
|
||||||
white-space: nowrap;
|
white-space: nowrap;
|
||||||
border-bottom: 1px solid $light_mode_border;
|
|
||||||
|
|
||||||
.icon {
|
.icon {
|
||||||
@include font-size(18);
|
line-height: 0;
|
||||||
|
width: 15px;
|
||||||
margin-right: 9px;
|
margin-right: 9px;
|
||||||
vertical-align: middle;
|
vertical-align: middle;
|
||||||
|
margin-top: -1px;
|
||||||
|
|
||||||
path {
|
path, line, polyline, rect, circle {
|
||||||
fill: $text;
|
@include transition(150ms);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.icon-chevron {
|
.icon-arrow {
|
||||||
@include transition(300ms);
|
@include transition(300ms);
|
||||||
@include font-size(13);
|
margin-right: 4px;
|
||||||
margin-right: 9px;
|
|
||||||
vertical-align: middle;
|
vertical-align: middle;
|
||||||
opacity: 0;
|
opacity: 0;
|
||||||
|
|
||||||
@@ -101,14 +110,11 @@
|
|||||||
&.is-opened {
|
&.is-opened {
|
||||||
@include transform(rotate(90deg));
|
@include transform(rotate(90deg));
|
||||||
}
|
}
|
||||||
|
|
||||||
path {
|
|
||||||
fill: rgba($text, 0.25);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.label {
|
.label {
|
||||||
@include font-size(15);
|
@include transition(150ms);
|
||||||
|
@include font-size(13);
|
||||||
font-weight: 700;
|
font-weight: 700;
|
||||||
vertical-align: middle;
|
vertical-align: middle;
|
||||||
white-space: nowrap;
|
white-space: nowrap;
|
||||||
@@ -118,16 +124,12 @@
|
|||||||
color: $text;
|
color: $text;
|
||||||
}
|
}
|
||||||
|
|
||||||
&:hover {
|
&:hover,
|
||||||
background: $light_background;
|
|
||||||
}
|
|
||||||
|
|
||||||
&.is-selected {
|
&.is-selected {
|
||||||
background: rgba($theme, .1);
|
|
||||||
|
|
||||||
.icon {
|
.icon {
|
||||||
path {
|
path, line, polyline, rect, circle {
|
||||||
fill: $theme;
|
stroke: $theme;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -141,33 +143,18 @@
|
|||||||
@media (prefers-color-scheme: dark) {
|
@media (prefers-color-scheme: dark) {
|
||||||
|
|
||||||
.folder-item {
|
.folder-item {
|
||||||
border-bottom: 1px solid $dark_mode_border_color;
|
|
||||||
|
|
||||||
.label {
|
.label {
|
||||||
color: $dark_mode_text_primary;
|
color: $dark_mode_text_primary;
|
||||||
}
|
}
|
||||||
|
|
||||||
&:hover {
|
&:hover {
|
||||||
background: $dark_mode_foreground;
|
background: rgba($theme, .1);
|
||||||
}
|
}
|
||||||
|
|
||||||
&.is-selected {
|
&.is-selected {
|
||||||
background: rgba($theme, .1);
|
background: rgba($theme, .1);
|
||||||
}
|
}
|
||||||
|
|
||||||
.icon {
|
|
||||||
|
|
||||||
path {
|
|
||||||
fill: lighten($dark_mode_foreground, 10%);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.icon-chevron {
|
|
||||||
|
|
||||||
path {
|
|
||||||
fill: $theme;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
&.is-selected {
|
&.is-selected {
|
||||||
|
|||||||
@@ -0,0 +1,182 @@
|
|||||||
|
<template>
|
||||||
|
<transition name="folder">
|
||||||
|
<div class="folder-item-wrapper">
|
||||||
|
|
||||||
|
<div class="folder-item" :class="{'is-selected': isSelected}" :style="indent" @click="getFolder">
|
||||||
|
<chevron-right-icon @click.stop="showTree" size="17" class="icon-arrow"
|
||||||
|
:class="{'is-opened': isVisible, 'is-visible': nodes.folders.length !== 0}"></chevron-right-icon>
|
||||||
|
<folder-icon size="17" class="icon"></folder-icon>
|
||||||
|
<span class="label">{{ nodes.name }}</span>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<TreeMenuNavigator :depth="depth + 1" v-if="isVisible" :nodes="item" v-for="item in nodes.folders"
|
||||||
|
:key="item.unique_id"/>
|
||||||
|
</div>
|
||||||
|
</transition>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import TreeMenuNavigator from '@/components/Others/TreeMenuNavigator'
|
||||||
|
import {FolderIcon, ChevronRightIcon} from 'vue-feather-icons'
|
||||||
|
import {events} from "@/bus"
|
||||||
|
|
||||||
|
export default {
|
||||||
|
name: 'TreeMenuNavigator',
|
||||||
|
props: [
|
||||||
|
'nodes', 'depth'
|
||||||
|
],
|
||||||
|
components: {
|
||||||
|
TreeMenuNavigator,
|
||||||
|
ChevronRightIcon,
|
||||||
|
FolderIcon,
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
indent() {
|
||||||
|
|
||||||
|
let offset = window.innerWidth <= 1024 ? 17 : 22;
|
||||||
|
|
||||||
|
let value = this.depth == 0 ? offset : offset + (this.depth * 20);
|
||||||
|
|
||||||
|
return {paddingLeft: value + 'px'}
|
||||||
|
},
|
||||||
|
},
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
isVisible: false,
|
||||||
|
isSelected: false,
|
||||||
|
}
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
getFolder() {
|
||||||
|
|
||||||
|
events.$emit('show-folder', this.nodes)
|
||||||
|
|
||||||
|
// Get folder content
|
||||||
|
this.$store.dispatch('getFolder', [{folder: this.nodes, back: false, init: false}])
|
||||||
|
},
|
||||||
|
showTree() {
|
||||||
|
this.isVisible = !this.isVisible
|
||||||
|
}
|
||||||
|
},
|
||||||
|
created() {
|
||||||
|
|
||||||
|
// Select clicked folder
|
||||||
|
events.$on('show-folder', node => {
|
||||||
|
this.isSelected = false
|
||||||
|
|
||||||
|
if (this.nodes.unique_id == node.unique_id)
|
||||||
|
this.isSelected = true
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
@import '@assets/vue-file-manager/_variables';
|
||||||
|
@import '@assets/vue-file-manager/_mixins';
|
||||||
|
|
||||||
|
.folder-item {
|
||||||
|
display: block;
|
||||||
|
padding: 8px 0;
|
||||||
|
@include transition(150ms);
|
||||||
|
cursor: pointer;
|
||||||
|
position: relative;
|
||||||
|
white-space: nowrap;
|
||||||
|
width: 100%;
|
||||||
|
|
||||||
|
.icon {
|
||||||
|
line-height: 0;
|
||||||
|
width: 15px;
|
||||||
|
margin-right: 9px;
|
||||||
|
vertical-align: middle;
|
||||||
|
margin-top: -1px;
|
||||||
|
|
||||||
|
path, line, polyline, rect, circle {
|
||||||
|
@include transition(150ms);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon-arrow {
|
||||||
|
@include transition(300ms);
|
||||||
|
margin-right: 4px;
|
||||||
|
vertical-align: middle;
|
||||||
|
opacity: 0;
|
||||||
|
|
||||||
|
&.is-visible {
|
||||||
|
opacity: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
&.is-opened {
|
||||||
|
@include transform(rotate(90deg));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.label {
|
||||||
|
@include transition(150ms);
|
||||||
|
@include font-size(13);
|
||||||
|
font-weight: 700;
|
||||||
|
vertical-align: middle;
|
||||||
|
white-space: nowrap;
|
||||||
|
overflow: hidden;
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
display: inline-block;
|
||||||
|
color: $text;
|
||||||
|
max-width: 130px;
|
||||||
|
}
|
||||||
|
|
||||||
|
&:hover,
|
||||||
|
&.is-selected {
|
||||||
|
|
||||||
|
.icon {
|
||||||
|
path, line, polyline, rect, circle {
|
||||||
|
stroke: $theme;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.label {
|
||||||
|
color: $theme;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@media only screen and (max-width: 1024px) {
|
||||||
|
|
||||||
|
.folder-item {
|
||||||
|
padding: 8px 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Dark mode
|
||||||
|
@media (prefers-color-scheme: dark) {
|
||||||
|
|
||||||
|
.folder-item {
|
||||||
|
|
||||||
|
.label {
|
||||||
|
color: $dark_mode_text_primary;
|
||||||
|
}
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
background: rgba($theme, .1);
|
||||||
|
}
|
||||||
|
|
||||||
|
&.is-selected {
|
||||||
|
background: rgba($theme, .1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&.is-selected {
|
||||||
|
background: rgba($theme, .1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (prefers-color-scheme: dark) and (max-width: 690px) {
|
||||||
|
.folder-item {
|
||||||
|
|
||||||
|
&:hover,
|
||||||
|
&.is-selected {
|
||||||
|
background: rgba($theme, .1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
</style>
|
||||||
@@ -0,0 +1,47 @@
|
|||||||
|
<template>
|
||||||
|
<div class="user-avatar" :class="size">
|
||||||
|
<img :src="app.user.avatar" :alt="app.user.name">
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import {mapGetters} from 'vuex'
|
||||||
|
|
||||||
|
export default {
|
||||||
|
name: 'UserAvatar',
|
||||||
|
props: [
|
||||||
|
'size'
|
||||||
|
],
|
||||||
|
computed: {
|
||||||
|
...mapGetters(['app']),
|
||||||
|
},
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
@import '@assets/vue-file-manager/_variables';
|
||||||
|
@import '@assets/vue-file-manager/_mixins';
|
||||||
|
|
||||||
|
.user-avatar {
|
||||||
|
line-height: 0;
|
||||||
|
|
||||||
|
img {
|
||||||
|
border-radius: 6px;
|
||||||
|
width: 40px;
|
||||||
|
height: 40px;
|
||||||
|
}
|
||||||
|
|
||||||
|
&.large {
|
||||||
|
|
||||||
|
img {
|
||||||
|
border-radius: 9px;
|
||||||
|
width: 52px;
|
||||||
|
height: 52px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (prefers-color-scheme: dark) {
|
||||||
|
|
||||||
|
}
|
||||||
|
</style>
|
||||||
@@ -60,7 +60,8 @@
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped>
|
||||||
@import "@assets/app.scss";
|
@import '@assets/vue-file-manager/_variables';
|
||||||
|
@import '@assets/vue-file-manager/_mixins';
|
||||||
|
|
||||||
.dropzone {
|
.dropzone {
|
||||||
position: relative;
|
position: relative;
|
||||||
@@ -79,12 +80,10 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
.image-preview {
|
.image-preview {
|
||||||
width: 75px;
|
width: 56px;
|
||||||
height: 75px;
|
height: 56px;
|
||||||
object-fit: cover;
|
object-fit: cover;
|
||||||
border-radius: 8px;
|
border-radius: 8px;
|
||||||
border: 1px dashed $theme;
|
|
||||||
padding: 2px;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
@@ -34,7 +34,8 @@
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped>
|
||||||
@import "@assets/app.scss";
|
@import '@assets/vue-file-manager/_variables';
|
||||||
|
@import '@assets/vue-file-manager/_mixins';
|
||||||
|
|
||||||
.vignette {
|
.vignette {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
|
|||||||
@@ -0,0 +1,25 @@
|
|||||||
|
<template>
|
||||||
|
<div class="content-group">
|
||||||
|
<TextLabel>{{ title }}</TextLabel>
|
||||||
|
<slot></slot>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import TextLabel from '@/components/Others/TextLabel'
|
||||||
|
|
||||||
|
export default {
|
||||||
|
name: 'ContentGroup',
|
||||||
|
props: ['title'],
|
||||||
|
components: {
|
||||||
|
TextLabel,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped lang="scss">
|
||||||
|
|
||||||
|
.content-group {
|
||||||
|
margin-bottom: 30px;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
@@ -0,0 +1,43 @@
|
|||||||
|
<template>
|
||||||
|
<section class="content-sidebar">
|
||||||
|
<slot></slot>
|
||||||
|
</section>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
export default {
|
||||||
|
name: 'ContentSidebar',
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped lang="scss">
|
||||||
|
@import '@assets/vue-file-manager/_variables';
|
||||||
|
@import '@assets/vue-file-manager/_mixins';
|
||||||
|
|
||||||
|
.content-sidebar {
|
||||||
|
background: linear-gradient(0deg, rgba(246, 245, 241, 0.4) 0%, rgba(243, 244, 246, 0.4) 100%);
|
||||||
|
user-select: none;
|
||||||
|
padding-top: 25px;
|
||||||
|
overflow-y: auto;
|
||||||
|
flex: 0 0 225px;
|
||||||
|
}
|
||||||
|
|
||||||
|
@media only screen and (max-width: 1024px) {
|
||||||
|
.content-sidebar {
|
||||||
|
flex: 0 0 205px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@media only screen and (max-width: 690px) {
|
||||||
|
.content-sidebar {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (prefers-color-scheme: dark) {
|
||||||
|
|
||||||
|
.content-sidebar {
|
||||||
|
background: rgba($dark_mode_foreground, 0.2);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
@@ -1,183 +0,0 @@
|
|||||||
<template>
|
|
||||||
<div class="file-item">
|
|
||||||
|
|
||||||
<!--Thumbnail for item-->
|
|
||||||
<div class="icon-item">
|
|
||||||
|
|
||||||
<!--If is file or image, then link item-->
|
|
||||||
<span v-if="isFile" class="file-icon-text">{{ file.mimetype }}</span>
|
|
||||||
|
|
||||||
<!--Folder thumbnail-->
|
|
||||||
<FontAwesomeIcon v-if="isFile" class="file-icon" icon="file" />
|
|
||||||
|
|
||||||
<!--Image thumbnail-->
|
|
||||||
<img v-if="isImage" class="image" :src="file.thumbnail" :alt="file.name" />
|
|
||||||
|
|
||||||
<!--Else show only folder icon-->
|
|
||||||
<FontAwesomeIcon v-if="isFolder" class="folder-icon" icon="folder" />
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<!--Name-->
|
|
||||||
<div class="item-name">
|
|
||||||
|
|
||||||
<!--Name-->
|
|
||||||
<span class="name" >{{ file.name }}</span>
|
|
||||||
|
|
||||||
<!--Other attributes-->
|
|
||||||
<span v-if="! isFolder" class="item-size">{{ file.filesize }}</span>
|
|
||||||
|
|
||||||
<span v-if="isFolder" class="item-length">{{ file.items == 0 ? $t('folder.empty') : $tc('folder.item_counts', folderItems) }}, {{ file.created_at }}</span>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script>
|
|
||||||
|
|
||||||
export default {
|
|
||||||
name: 'FileListItemThumbnail',
|
|
||||||
props: ['file'],
|
|
||||||
computed: {
|
|
||||||
isFolder() {
|
|
||||||
return this.file.type === 'folder'
|
|
||||||
},
|
|
||||||
isFile() {
|
|
||||||
return this.file.type !== 'folder' && this.file.type !== 'image'
|
|
||||||
},
|
|
||||||
isImage() {
|
|
||||||
return this.file.type === 'image'
|
|
||||||
}
|
|
||||||
},
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<style scoped lang="scss">
|
|
||||||
@import "@assets/app.scss";
|
|
||||||
|
|
||||||
.file-item {
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
padding: 10px 15px;
|
|
||||||
@include transition(150ms);
|
|
||||||
cursor: pointer;
|
|
||||||
|
|
||||||
&:hover {
|
|
||||||
background: rgba($theme, .1);
|
|
||||||
|
|
||||||
.item-name .name {
|
|
||||||
color: $theme;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.item-name {
|
|
||||||
display: block;
|
|
||||||
margin-left: 10px;
|
|
||||||
width: 100%;
|
|
||||||
overflow: hidden;
|
|
||||||
text-overflow: ellipsis;
|
|
||||||
white-space: nowrap;
|
|
||||||
|
|
||||||
.item-size,
|
|
||||||
.item-length {
|
|
||||||
@include font-size(11);
|
|
||||||
font-weight: 400;
|
|
||||||
color: $text-muted;
|
|
||||||
display: block;
|
|
||||||
}
|
|
||||||
|
|
||||||
.name {
|
|
||||||
white-space: nowrap;
|
|
||||||
}
|
|
||||||
|
|
||||||
.name {
|
|
||||||
color: $text;
|
|
||||||
@include font-size(14);
|
|
||||||
font-weight: 700;
|
|
||||||
max-height: 40px;
|
|
||||||
overflow: hidden;
|
|
||||||
text-overflow: ellipsis;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.icon-item {
|
|
||||||
position: relative;
|
|
||||||
min-width: 40px;
|
|
||||||
text-align: center;
|
|
||||||
line-height: 0;
|
|
||||||
|
|
||||||
.file-icon {
|
|
||||||
@include font-size(35);
|
|
||||||
|
|
||||||
path {
|
|
||||||
fill: #fafafc;
|
|
||||||
stroke: #dfe0e8;
|
|
||||||
stroke-width: 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.file-icon-text {
|
|
||||||
top: 40%;
|
|
||||||
@include font-size(9);
|
|
||||||
line-height: 1;
|
|
||||||
margin: 0 auto;
|
|
||||||
position: absolute;
|
|
||||||
text-align: center;
|
|
||||||
left: 0;
|
|
||||||
right: 0;
|
|
||||||
color: $theme;
|
|
||||||
font-weight: 600;
|
|
||||||
user-select: none;
|
|
||||||
max-width: 20px;
|
|
||||||
max-height: 20px;
|
|
||||||
overflow: hidden;
|
|
||||||
text-overflow: ellipsis;
|
|
||||||
white-space: nowrap;
|
|
||||||
}
|
|
||||||
|
|
||||||
.image {
|
|
||||||
object-fit: cover;
|
|
||||||
user-select: none;
|
|
||||||
max-width: 100%;
|
|
||||||
border-radius: 5px;
|
|
||||||
width: 36px;
|
|
||||||
height: 36px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@media (prefers-color-scheme: dark) {
|
|
||||||
|
|
||||||
.file-item {
|
|
||||||
|
|
||||||
.icon-item .file-icon {
|
|
||||||
|
|
||||||
path {
|
|
||||||
fill: $dark_mode_background;
|
|
||||||
stroke: #2F3C54;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
&:hover,
|
|
||||||
&.is-clicked {
|
|
||||||
background: rgba($theme, .1);
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
.item-name .name {
|
|
||||||
color: $dark_mode_text_primary;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@media (max-width: 690px) and (prefers-color-scheme: dark){
|
|
||||||
.file-item {
|
|
||||||
|
|
||||||
.icon-item .file-icon {
|
|
||||||
|
|
||||||
path {
|
|
||||||
fill: $dark_mode_foreground;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
@@ -0,0 +1,216 @@
|
|||||||
|
<template>
|
||||||
|
<nav class="menu-bar" v-if="app">
|
||||||
|
|
||||||
|
<!--Navigation Icons-->
|
||||||
|
<div class="icon-navigation menu">
|
||||||
|
|
||||||
|
<router-link :to="{name: 'Profile'}" class="icon-navigation-item user">
|
||||||
|
<UserAvatar />
|
||||||
|
</router-link>
|
||||||
|
|
||||||
|
<router-link :to="{name: 'Files'}" :title="$t('locations.home')" class="icon-navigation-item home">
|
||||||
|
<div class="button-icon">
|
||||||
|
<hard-drive-icon size="19"></hard-drive-icon>
|
||||||
|
</div>
|
||||||
|
</router-link>
|
||||||
|
|
||||||
|
<router-link :to="{name: 'SharedFiles'}" :title="$t('locations.shared')" class="icon-navigation-item shared">
|
||||||
|
<div class="button-icon">
|
||||||
|
<share-icon size="19"></share-icon>
|
||||||
|
</div>
|
||||||
|
</router-link>
|
||||||
|
|
||||||
|
<router-link :to="{name: 'Trash'}" :title="$t('locations.trash')" class="icon-navigation-item trash">
|
||||||
|
<div class="button-icon">
|
||||||
|
<trash-2-icon size="19"></trash-2-icon>
|
||||||
|
</div>
|
||||||
|
</router-link>
|
||||||
|
|
||||||
|
<router-link :to="{name: 'Profile'}" :class="{'is-active': $isThisRoute($route, ['Password', 'Profile', 'Storage'])}" class="icon-navigation-item settings">
|
||||||
|
<div class="button-icon">
|
||||||
|
<settings-icon size="19"></settings-icon>
|
||||||
|
</div>
|
||||||
|
</router-link>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!--User avatar & Logout-->
|
||||||
|
<ul class="icon-navigation logout">
|
||||||
|
<li @click="$store.dispatch('logOut')" class="icon-navigation-item">
|
||||||
|
<div class="button-icon">
|
||||||
|
<power-icon size="19"></power-icon>
|
||||||
|
</div>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</nav>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import UserAvatar from '@/components/Others/UserAvatar'
|
||||||
|
import {mapGetters} from 'vuex'
|
||||||
|
import {
|
||||||
|
HardDriveIcon,
|
||||||
|
SettingsIcon,
|
||||||
|
Trash2Icon,
|
||||||
|
PowerIcon,
|
||||||
|
ShareIcon,
|
||||||
|
} from 'vue-feather-icons'
|
||||||
|
|
||||||
|
export default {
|
||||||
|
name: 'MenuBar',
|
||||||
|
components: {
|
||||||
|
HardDriveIcon,
|
||||||
|
SettingsIcon,
|
||||||
|
UserAvatar,
|
||||||
|
Trash2Icon,
|
||||||
|
PowerIcon,
|
||||||
|
ShareIcon,
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
...mapGetters(['app']),
|
||||||
|
},
|
||||||
|
mounted() {
|
||||||
|
this.$store.dispatch('getAppData')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped lang="scss">
|
||||||
|
@import '@assets/vue-file-manager/_variables';
|
||||||
|
@import '@assets/vue-file-manager/_mixins';
|
||||||
|
|
||||||
|
.menu-bar {
|
||||||
|
background: linear-gradient(180deg, rgba(246, 245, 241, 0.8) 0%, rgba(243, 244, 246, 0.8) 100%);
|
||||||
|
user-select: none;
|
||||||
|
padding-top: 25px;
|
||||||
|
display: grid;
|
||||||
|
width: 72px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon-navigation {
|
||||||
|
text-align: center;
|
||||||
|
|
||||||
|
&.menu {
|
||||||
|
margin-bottom: auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
&.logout {
|
||||||
|
margin-top: auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon-navigation-item {
|
||||||
|
display: block;
|
||||||
|
margin-bottom: 10px;
|
||||||
|
|
||||||
|
&.user {
|
||||||
|
margin-bottom: 20px;
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.button-icon {
|
||||||
|
cursor: pointer;
|
||||||
|
border-radius: 4px;
|
||||||
|
padding: 12px;
|
||||||
|
display: inline-block;
|
||||||
|
line-height: 0;
|
||||||
|
@include transition(150ms);
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
background: darken($light_background, 5%);
|
||||||
|
}
|
||||||
|
|
||||||
|
path, line, polyline, rect, circle {
|
||||||
|
@include transition(150ms);
|
||||||
|
stroke: black;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.router-link-active,
|
||||||
|
.is-active {
|
||||||
|
|
||||||
|
&.home {
|
||||||
|
.button-icon {
|
||||||
|
background: rgba($theme, 0.1);
|
||||||
|
|
||||||
|
path, line, polyline, rect, circle {
|
||||||
|
stroke: $theme;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&.shared {
|
||||||
|
.button-icon {
|
||||||
|
background: rgba($yellow, 0.1);
|
||||||
|
|
||||||
|
path, line, polyline, rect, circle {
|
||||||
|
stroke: $yellow;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&.trash {
|
||||||
|
.button-icon {
|
||||||
|
background: rgba($red, 0.1);
|
||||||
|
|
||||||
|
path, line, polyline, rect, circle {
|
||||||
|
stroke: $red;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&.settings {
|
||||||
|
.button-icon {
|
||||||
|
background: rgba($purple, 0.1);
|
||||||
|
|
||||||
|
path, line, polyline, rect, circle {
|
||||||
|
stroke: $purple;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@media only screen and (max-width: 1024px) {
|
||||||
|
.menu-bar {
|
||||||
|
width: 60px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon-navigation {
|
||||||
|
|
||||||
|
.icon-navigation-item {
|
||||||
|
margin-bottom: 15px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.button-icon {
|
||||||
|
padding: 8px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@media only screen and (max-width: 690px) {
|
||||||
|
.menu-bar {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (prefers-color-scheme: dark) {
|
||||||
|
|
||||||
|
.icon-navigation {
|
||||||
|
|
||||||
|
.button-icon {
|
||||||
|
&:hover {
|
||||||
|
background: $dark_mode_background;
|
||||||
|
}
|
||||||
|
|
||||||
|
path, line, polyline, rect, circle {
|
||||||
|
stroke: $dark_mode_text_primary;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.menu-bar {
|
||||||
|
background: $dark_mode_foreground;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
</style>
|
||||||
@@ -1,460 +0,0 @@
|
|||||||
<template>
|
|
||||||
<transition name="sidebar">
|
|
||||||
<div id="sidebar" v-if="app && (isVisibleSidebar || ! isSmallAppSize)">
|
|
||||||
|
|
||||||
<!--User Headline-->
|
|
||||||
<UserHeadline/>
|
|
||||||
|
|
||||||
<!--Content-->
|
|
||||||
<div class="content-scroller">
|
|
||||||
|
|
||||||
<!--Locations-->
|
|
||||||
<div class="menu-list-wrapper">
|
|
||||||
<TextLabel>{{ $t('sidebar.locations') }}</TextLabel>
|
|
||||||
<ul class="menu-list">
|
|
||||||
<li class="menu-list-item" :class="{'is-active': isBaseLocation}" @click="goHome">
|
|
||||||
<FontAwesomeIcon class="icon" icon="hdd"/>
|
|
||||||
<span class="label">{{ $t('locations.home') }}</span>
|
|
||||||
</li>
|
|
||||||
<li class="menu-list-item" :class="{'is-active': isSharedLocation}" @click="getShared">
|
|
||||||
<FontAwesomeIcon class="icon" icon="share"/>
|
|
||||||
<span class="label">{{ $t('locations.shared') }}</span>
|
|
||||||
</li>
|
|
||||||
<li class="menu-list-item" :class="{'is-active': isTrashLocation}" @click="getTrash">
|
|
||||||
<FontAwesomeIcon class="icon" icon="trash-alt"/>
|
|
||||||
<span class="label">{{ $t('locations.trash') }}</span>
|
|
||||||
</li>
|
|
||||||
</ul>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<!--Favourites-->
|
|
||||||
<div class="menu-list-wrapper favourites"
|
|
||||||
@dragover.prevent="dragEnter"
|
|
||||||
@dragleave="dragLeave"
|
|
||||||
@drop="dragFinish($event)"
|
|
||||||
:class="{ 'is-dragenter': area }"
|
|
||||||
>
|
|
||||||
<TextLabel>{{ $t('sidebar.favourites') }}</TextLabel>
|
|
||||||
<transition-group tag="ul" class="menu-list" name="folder-item">
|
|
||||||
<li class="empty-list" v-if="app.favourites.length == 0" :key="0">
|
|
||||||
{{ $t('sidebar.favourites_empty') }}
|
|
||||||
</li>
|
|
||||||
|
|
||||||
<li @click.stop="openFolder(folder)" class="menu-list-item" v-for="folder in app.favourites"
|
|
||||||
:key="folder.unique_id">
|
|
||||||
<div>
|
|
||||||
<FontAwesomeIcon class="icon" icon="folder"/>
|
|
||||||
<span class="label">{{ folder.name }}</span>
|
|
||||||
</div>
|
|
||||||
<FontAwesomeIcon @click.stop="removeFavourite(folder)" v-if="! $isMobile()" class="delete-icon" icon="times"/>
|
|
||||||
</li>
|
|
||||||
</transition-group>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<!--Last Uploads-->
|
|
||||||
<div class="menu-list-wrapper">
|
|
||||||
<TextLabel>{{ $t('sidebar.latest') }}</TextLabel>
|
|
||||||
|
|
||||||
<p class="empty-list" v-if="app.latest_uploads.length == 0">{{ $t('sidebar.latest_empty') }}</p>
|
|
||||||
|
|
||||||
<FileListItemThumbnail @dblclick.native="downloadFile(item)" @click.native="showFileDetail(item)" :file="item" v-for="item in app.latest_uploads" :key="item.unique_id"/>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<!--Storage Size Info-->
|
|
||||||
<StorageSize v-if="config.storageLimit"/>
|
|
||||||
|
|
||||||
<!--Mobile logout button-->
|
|
||||||
<div v-if="isSmallAppSize" class="log-out-button">
|
|
||||||
<ButtonBase @click.native="$store.dispatch('logOut')" button-style="danger">{{ $t('context_menu.log_out') }}</ButtonBase>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</transition>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script>
|
|
||||||
import FileListItemThumbnail from '@/components/Sidebar/FileListItemThumbnail'
|
|
||||||
import UserHeadline from '@/components/Sidebar/UserHeadline'
|
|
||||||
import ButtonBase from '@/components/FilesView/ButtonBase'
|
|
||||||
import StorageSize from '@/components/Sidebar/StorageSize'
|
|
||||||
import TextLabel from '@/components/Others/TextLabel'
|
|
||||||
import {mapGetters} from 'vuex'
|
|
||||||
import {events} from '@/bus'
|
|
||||||
|
|
||||||
export default {
|
|
||||||
name: 'Sidebar',
|
|
||||||
components: {
|
|
||||||
FileListItemThumbnail,
|
|
||||||
UserHeadline,
|
|
||||||
StorageSize,
|
|
||||||
ButtonBase,
|
|
||||||
TextLabel,
|
|
||||||
},
|
|
||||||
computed: {
|
|
||||||
...mapGetters(['homeDirectory', 'app', 'appSize', 'config', 'currentFolder']),
|
|
||||||
isTrashLocation() {
|
|
||||||
return this.currentFolder && this.currentFolder.location === 'trash-root' || this.currentFolder && this.currentFolder.location === 'trash'
|
|
||||||
},
|
|
||||||
isBaseLocation() {
|
|
||||||
return this.currentFolder && this.currentFolder.location === 'base'
|
|
||||||
},
|
|
||||||
isSharedLocation() {
|
|
||||||
return this.currentFolder && this.currentFolder.location === 'shared'
|
|
||||||
},
|
|
||||||
isSmallAppSize() {
|
|
||||||
return this.appSize === 'small'
|
|
||||||
}
|
|
||||||
},
|
|
||||||
data() {
|
|
||||||
return {
|
|
||||||
area: false,
|
|
||||||
draggedItem: undefined,
|
|
||||||
isVisibleSidebar: false,
|
|
||||||
}
|
|
||||||
},
|
|
||||||
methods: {
|
|
||||||
getShared() {
|
|
||||||
this.$store.dispatch('getShared')
|
|
||||||
},
|
|
||||||
getTrash() {
|
|
||||||
this.$store.dispatch('getTrash')
|
|
||||||
},
|
|
||||||
goHome() {
|
|
||||||
this.$store.commit('FLUSH_BROWSER_HISTORY')
|
|
||||||
this.$store.dispatch('getFolder', [this.homeDirectory, true])
|
|
||||||
},
|
|
||||||
openFolder(folder) {
|
|
||||||
|
|
||||||
// Go to folder
|
|
||||||
this.$store.dispatch('getFolder', [folder, false])
|
|
||||||
},
|
|
||||||
downloadFile(file) {
|
|
||||||
|
|
||||||
this.$downloadFile(file.file_url, file.name + '.' + file.mimetype)
|
|
||||||
},
|
|
||||||
showFileDetail(file) {
|
|
||||||
// Dispatch load file info detail
|
|
||||||
this.$store.dispatch('getFileDetail', file)
|
|
||||||
|
|
||||||
// Show panel if is not open
|
|
||||||
this.$store.dispatch('fileInfoToggle', true)
|
|
||||||
},
|
|
||||||
dragEnter() {
|
|
||||||
if (this.draggedItem && this.draggedItem.type !== 'folder') return
|
|
||||||
|
|
||||||
this.area = true
|
|
||||||
},
|
|
||||||
dragLeave() {
|
|
||||||
this.area = false
|
|
||||||
},
|
|
||||||
dragFinish() {
|
|
||||||
this.area = false
|
|
||||||
|
|
||||||
// Check if draged item is folder
|
|
||||||
if (this.draggedItem && this.draggedItem.type !== 'folder') return
|
|
||||||
|
|
||||||
// Check if folder exist in favourites
|
|
||||||
if (this.app.favourites.find(folder => folder.unique_id == this.draggedItem.unique_id)) return
|
|
||||||
|
|
||||||
// Store favourites folder
|
|
||||||
this.$store.dispatch('addToFavourites', this.draggedItem)
|
|
||||||
|
|
||||||
},
|
|
||||||
removeFavourite(folder) {
|
|
||||||
|
|
||||||
// Remove favourites folder
|
|
||||||
this.$store.dispatch('removeFromFavourites', folder)
|
|
||||||
}
|
|
||||||
},
|
|
||||||
mounted() {
|
|
||||||
this.$store.dispatch('getAppData')
|
|
||||||
|
|
||||||
// Listen for dragstart folder items
|
|
||||||
events.$on('dragstart', (item) => this.draggedItem = item)
|
|
||||||
|
|
||||||
// Listen for show sidebar
|
|
||||||
events.$on('show:sidebar', () => {
|
|
||||||
this.isVisibleSidebar = !this.isVisibleSidebar
|
|
||||||
})
|
|
||||||
|
|
||||||
// Listen for hide sidebar
|
|
||||||
events.$on('show:content', () => {
|
|
||||||
if (this.isVisibleSidebar) this.isVisibleSidebar = false
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<style scoped lang="scss">
|
|
||||||
@import "@assets/app.scss";
|
|
||||||
|
|
||||||
#sidebar {
|
|
||||||
position: relative;
|
|
||||||
flex: 0 0 265px;
|
|
||||||
background: $light_background;
|
|
||||||
}
|
|
||||||
|
|
||||||
.content-scroller {
|
|
||||||
bottom: 50px;
|
|
||||||
position: absolute;
|
|
||||||
top: 75px;
|
|
||||||
left: 0;
|
|
||||||
right: 0;
|
|
||||||
overflow-x: auto;
|
|
||||||
|
|
||||||
.menu-list-wrapper:first-of-type {
|
|
||||||
margin-top: 20px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.text-label {
|
|
||||||
margin-left: 15px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.menu-list-wrapper {
|
|
||||||
margin-bottom: 20px;
|
|
||||||
|
|
||||||
.menu-list {
|
|
||||||
|
|
||||||
.menu-list-item {
|
|
||||||
display: block;
|
|
||||||
padding: 8px 15px 8px 25px;
|
|
||||||
@include transition(150ms);
|
|
||||||
cursor: pointer;
|
|
||||||
position: relative;
|
|
||||||
white-space: nowrap;
|
|
||||||
|
|
||||||
.icon {
|
|
||||||
@include font-size(13);
|
|
||||||
width: 15px;
|
|
||||||
margin-right: 9px;
|
|
||||||
vertical-align: middle;
|
|
||||||
|
|
||||||
path {
|
|
||||||
fill: $text;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.delete-icon {
|
|
||||||
display: none;
|
|
||||||
position: absolute;
|
|
||||||
right: 15px;
|
|
||||||
top: 50%;
|
|
||||||
@include transform(translateY(-50%));
|
|
||||||
@include font-size(12);
|
|
||||||
|
|
||||||
path {
|
|
||||||
fill: $text-muted;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.label {
|
|
||||||
@include font-size(14);
|
|
||||||
font-weight: 700;
|
|
||||||
vertical-align: middle;
|
|
||||||
white-space: nowrap;
|
|
||||||
max-width: 210px;
|
|
||||||
overflow: hidden;
|
|
||||||
text-overflow: ellipsis;
|
|
||||||
display: inline-block;
|
|
||||||
}
|
|
||||||
|
|
||||||
&:hover,
|
|
||||||
&.is-active {
|
|
||||||
background: rgba($theme, .1);
|
|
||||||
|
|
||||||
.icon {
|
|
||||||
path {
|
|
||||||
fill: $theme;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.label {
|
|
||||||
color: $theme;
|
|
||||||
}
|
|
||||||
|
|
||||||
.delete-icon {
|
|
||||||
display: block;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
&.favourites {
|
|
||||||
|
|
||||||
&.is-dragenter {
|
|
||||||
|
|
||||||
.menu-list {
|
|
||||||
border: 2px dashed $theme;
|
|
||||||
border-radius: 8px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.menu-list {
|
|
||||||
border: 2px dashed transparent;
|
|
||||||
|
|
||||||
.menu-list-item {
|
|
||||||
padding: 8px 23px;
|
|
||||||
|
|
||||||
.icon {
|
|
||||||
margin-right: 5px;
|
|
||||||
@include font-size(14);
|
|
||||||
width: 20px;
|
|
||||||
|
|
||||||
path {
|
|
||||||
fill: $theme;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
&:hover {
|
|
||||||
background: rgba($theme, .1);
|
|
||||||
|
|
||||||
.icon {
|
|
||||||
path {
|
|
||||||
fill: $theme;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.empty-list {
|
|
||||||
@include font-size(12);
|
|
||||||
color: $text-muted;
|
|
||||||
display: block;
|
|
||||||
padding: 15px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.log-out-button {
|
|
||||||
margin-top: 15px;
|
|
||||||
padding: 15px;
|
|
||||||
|
|
||||||
button {
|
|
||||||
width: 100%;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@media only screen and (max-width: 1024px) {
|
|
||||||
|
|
||||||
#sidebar {
|
|
||||||
flex: 0 0 265px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.menu-list-wrapper .menu-list .menu-list-item .label {
|
|
||||||
max-width: 190px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@media only screen and (max-width: 690px) {
|
|
||||||
|
|
||||||
.content-scroller {
|
|
||||||
bottom: initial;
|
|
||||||
position: relative;
|
|
||||||
top: initial;
|
|
||||||
overflow-x: initial;
|
|
||||||
}
|
|
||||||
|
|
||||||
#sidebar {
|
|
||||||
position: absolute;
|
|
||||||
overflow-y: auto;
|
|
||||||
top: 0;
|
|
||||||
left: 0;
|
|
||||||
right: 0;
|
|
||||||
z-index: 99;
|
|
||||||
bottom: 0;
|
|
||||||
background: white;
|
|
||||||
opacity: 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
.menu-list-wrapper {
|
|
||||||
|
|
||||||
&.favourites {
|
|
||||||
|
|
||||||
.menu-list .menu-list-item {
|
|
||||||
padding: 10px 26px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.menu-list .menu-list-item {
|
|
||||||
padding: 10px 26px;
|
|
||||||
|
|
||||||
.label {
|
|
||||||
@include font-size(14);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.log-out-button {
|
|
||||||
margin-top: 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@media (prefers-color-scheme: dark) {
|
|
||||||
|
|
||||||
#sidebar {
|
|
||||||
background: $dark_mode_background;
|
|
||||||
}
|
|
||||||
|
|
||||||
.menu-list-wrapper {
|
|
||||||
|
|
||||||
.menu-list .menu-list-item {
|
|
||||||
|
|
||||||
.label {
|
|
||||||
color: $dark_mode_text_primary;
|
|
||||||
}
|
|
||||||
|
|
||||||
.icon {
|
|
||||||
|
|
||||||
path {
|
|
||||||
fill: lighten($dark_mode_foreground, 10%);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
&:hover {
|
|
||||||
background: rgba($theme, .1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@media (prefers-color-scheme: dark) and (max-width: 690px) {
|
|
||||||
#sidebar {
|
|
||||||
background: $dark_mode_background;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.sidebar-enter-active {
|
|
||||||
transition: all 300ms ease;
|
|
||||||
}
|
|
||||||
|
|
||||||
.sidebar-enter /* .list-leave-active below version 2.1.8 */
|
|
||||||
{
|
|
||||||
opacity: 0;
|
|
||||||
transform: translateX(-100%);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Transition
|
|
||||||
.folder-item-move {
|
|
||||||
transition: transform 300s ease;
|
|
||||||
}
|
|
||||||
|
|
||||||
.folder-item-enter-active {
|
|
||||||
transition: all 300ms ease;
|
|
||||||
}
|
|
||||||
|
|
||||||
.folder-item-leave-active {
|
|
||||||
transition: all 300ms;
|
|
||||||
}
|
|
||||||
|
|
||||||
.folder-item-enter, .folder-item-leave-to /* .list-leave-active below version 2.1.8 */
|
|
||||||
{
|
|
||||||
opacity: 0;
|
|
||||||
transform: translateX(30px);
|
|
||||||
}
|
|
||||||
|
|
||||||
.folder-item-leave-active {
|
|
||||||
position: absolute;
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
@@ -1,88 +0,0 @@
|
|||||||
<template>
|
|
||||||
<div class="storage-size" v-if="app">
|
|
||||||
<div class="storage-info">
|
|
||||||
<span class="title">{{ $t('storage.title') }}</span>
|
|
||||||
<span class="size">{{ $t('storage.used', {used: app.storage.used, capacity: app.storage.capacity}) }}</span>
|
|
||||||
</div>
|
|
||||||
<ProgressBar :progress="app.storage.percentage" :class="{'is-exceeded': app.storage.percentage > 100}"/>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script>
|
|
||||||
import ProgressBar from '@/components/FilesView/ProgressBar'
|
|
||||||
import { mapGetters } from 'vuex'
|
|
||||||
|
|
||||||
export default {
|
|
||||||
name: 'StorageSize',
|
|
||||||
components: {
|
|
||||||
ProgressBar,
|
|
||||||
},
|
|
||||||
computed: {
|
|
||||||
...mapGetters(['app']),
|
|
||||||
},
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<style scoped lang="scss">
|
|
||||||
@import "@assets/app.scss";
|
|
||||||
|
|
||||||
.storage-size {
|
|
||||||
position: absolute;
|
|
||||||
bottom: 0;
|
|
||||||
left: 0;
|
|
||||||
right: 0;
|
|
||||||
margin: 15px;
|
|
||||||
border-radius: 8px;
|
|
||||||
|
|
||||||
.storage-info {
|
|
||||||
display: flex;
|
|
||||||
flex-wrap: nowrap;
|
|
||||||
align-items: center;
|
|
||||||
|
|
||||||
span {
|
|
||||||
width: 100%;
|
|
||||||
white-space: nowrap;
|
|
||||||
}
|
|
||||||
|
|
||||||
.title {
|
|
||||||
@include font-size(14);
|
|
||||||
font-weight: 700;
|
|
||||||
color: $text;
|
|
||||||
}
|
|
||||||
|
|
||||||
.size {
|
|
||||||
@include font-size(12);
|
|
||||||
text-align: right;
|
|
||||||
color: $text-muted;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.progress-bar {
|
|
||||||
|
|
||||||
&.is-exceeded /deep/ span {
|
|
||||||
background: $danger;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@media only screen and (max-width: 690px) {
|
|
||||||
|
|
||||||
.storage-size {
|
|
||||||
position: relative;
|
|
||||||
margin-bottom: 0;
|
|
||||||
|
|
||||||
.size {
|
|
||||||
@include font-size(10);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@media (prefers-color-scheme: dark) {
|
|
||||||
.storage-size {
|
|
||||||
|
|
||||||
.storage-info .title {
|
|
||||||
color: $dark_mode_text_primary;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
@@ -1,26 +1,7 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="user-headline-wrapper" v-if="app">
|
<div class="user-meta" v-if="app">
|
||||||
<div class="user-headline" @click="openMenu">
|
<b class="name">{{ app.user.name }}</b>
|
||||||
<div class="user-avatar">
|
<span class="email">{{ app.user.email }}</span>
|
||||||
<img :src="app.user.avatar" :alt="app.user.name">
|
|
||||||
</div>
|
|
||||||
<div class="user-name">
|
|
||||||
<b class="name">{{ app.user.name }}</b>
|
|
||||||
<span class="email">{{ app.user.email }}</span>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<transition name="user-menu">
|
|
||||||
<div class="user-menu" v-if="isOpenedMenu">
|
|
||||||
<ul class="menu-options" @click="closeMenu">
|
|
||||||
<li class="menu-option">
|
|
||||||
<router-link :to="{name: 'Profile'}">
|
|
||||||
{{ $t('context_menu.profile_settings') }}
|
|
||||||
</router-link>
|
|
||||||
</li>
|
|
||||||
<li class="menu-option" @click="$store.dispatch('logOut')">{{ $t('context_menu.log_out') }}</li>
|
|
||||||
</ul>
|
|
||||||
</div>
|
|
||||||
</transition>
|
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
@@ -31,198 +12,36 @@
|
|||||||
export default {
|
export default {
|
||||||
name: 'UserHeadline',
|
name: 'UserHeadline',
|
||||||
computed: {
|
computed: {
|
||||||
...mapGetters(['app', 'appSize']),
|
...mapGetters(['app']),
|
||||||
isSmallAppSize() {
|
|
||||||
return this.appSize === 'small'
|
|
||||||
}
|
|
||||||
},
|
|
||||||
data() {
|
|
||||||
return {
|
|
||||||
isOpenedMenu: false,
|
|
||||||
}
|
|
||||||
},
|
|
||||||
methods: {
|
|
||||||
openMenu() {
|
|
||||||
|
|
||||||
// If is mobile, then go to user settings page, else, open menu
|
|
||||||
if ( this.isSmallAppSize ) {
|
|
||||||
|
|
||||||
events.$emit('show:sidebar')
|
|
||||||
this.$router.push({name: 'Profile'})
|
|
||||||
|
|
||||||
} else {
|
|
||||||
|
|
||||||
this.isOpenedMenu = !this.isOpenedMenu
|
|
||||||
}
|
|
||||||
|
|
||||||
},
|
|
||||||
closeMenu() {
|
|
||||||
this.isOpenedMenu = !this.isOpenedMenu
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped lang="scss">
|
<style scoped lang="scss">
|
||||||
@import "@assets/app.scss";
|
@import '@assets/vue-file-manager/_variables';
|
||||||
|
@import '@assets/vue-file-manager/_mixins';
|
||||||
|
|
||||||
.user-headline-wrapper {
|
.user-meta {
|
||||||
position: relative;
|
padding-left: 20px;
|
||||||
}
|
|
||||||
|
|
||||||
.user-headline {
|
|
||||||
position: absolute;
|
|
||||||
top: 0;
|
|
||||||
left: 0;
|
|
||||||
right: 0;
|
|
||||||
margin: 15px;
|
|
||||||
padding: 5px;
|
|
||||||
user-select: none;
|
|
||||||
border-radius: 8px;
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
cursor: pointer;
|
|
||||||
@include transition(150ms);
|
|
||||||
background: darken($light_background, 3%);
|
|
||||||
|
|
||||||
&:active {
|
|
||||||
transform: scale(0.95);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.user-name {
|
|
||||||
|
|
||||||
.name, .email {
|
|
||||||
white-space: nowrap;
|
|
||||||
width: 180px;
|
|
||||||
overflow: hidden;
|
|
||||||
text-overflow: ellipsis;
|
|
||||||
}
|
|
||||||
|
|
||||||
.name {
|
.name {
|
||||||
display: block;
|
display: block;
|
||||||
@include font-size(17);
|
@include font-size(18);
|
||||||
line-height: 1;
|
|
||||||
color: $text;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.email {
|
.email {
|
||||||
@include font-size(13);
|
|
||||||
color: $theme;
|
|
||||||
display: block;
|
display: block;
|
||||||
margin-top: 2px;
|
@include font-size(12);
|
||||||
|
color: $theme;
|
||||||
font-weight: 600;
|
font-weight: 600;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.user-avatar {
|
|
||||||
line-height: 0;
|
|
||||||
margin-right: 15px;
|
|
||||||
|
|
||||||
img {
|
|
||||||
width: 50px;
|
|
||||||
height: 50px;
|
|
||||||
object-fit: cover;
|
|
||||||
border-radius: 8px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.user-menu {
|
|
||||||
position: absolute;
|
|
||||||
top: 75px;
|
|
||||||
left: 0;
|
|
||||||
right: 0;
|
|
||||||
margin: 15px;
|
|
||||||
z-index: 9;
|
|
||||||
}
|
|
||||||
|
|
||||||
.menu-options {
|
|
||||||
list-style: none;
|
|
||||||
width: 100%;
|
|
||||||
margin: 0;
|
|
||||||
padding: 0;
|
|
||||||
box-shadow: $shadow;
|
|
||||||
background: white;
|
|
||||||
border-radius: 8px;
|
|
||||||
|
|
||||||
.menu-option {
|
|
||||||
font-weight: 700;
|
|
||||||
@include font-size(15);
|
|
||||||
padding: 15px 30px;
|
|
||||||
cursor: pointer;
|
|
||||||
width: 100%;
|
|
||||||
color: $text;
|
|
||||||
|
|
||||||
a {
|
|
||||||
text-decoration: none;
|
|
||||||
color: $text;
|
|
||||||
}
|
|
||||||
|
|
||||||
&:hover {
|
|
||||||
background: $light_background;
|
|
||||||
color: $theme;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@media only screen and (max-width: 690px) {
|
@media only screen and (max-width: 690px) {
|
||||||
|
|
||||||
.user-headline {
|
|
||||||
position: relative;
|
|
||||||
margin-bottom: 40px;
|
|
||||||
background: transparent;
|
|
||||||
padding: 0;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@media (prefers-color-scheme: dark) {
|
@media (prefers-color-scheme: dark) {
|
||||||
|
|
||||||
.user-headline {
|
|
||||||
background: $dark_mode_background;
|
|
||||||
padding: 0;
|
|
||||||
|
|
||||||
&:hover {
|
|
||||||
background: transparent;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.user-name {
|
|
||||||
|
|
||||||
.name {
|
|
||||||
color: $dark_mode_text_primary;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.menu-options {
|
|
||||||
background: $dark_mode_background;
|
|
||||||
|
|
||||||
.menu-option {
|
|
||||||
color: $dark_mode_text_primary;
|
|
||||||
|
|
||||||
a {
|
|
||||||
color: $dark_mode_text_primary;
|
|
||||||
}
|
|
||||||
|
|
||||||
&:hover {
|
|
||||||
background: $dark_mode_foreground;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Transition
|
|
||||||
.user-menu-enter-active {
|
|
||||||
transition: all 150ms ease;
|
|
||||||
}
|
|
||||||
|
|
||||||
.user-menu-leave-active {
|
|
||||||
transition: all 150ms ease;
|
|
||||||
}
|
|
||||||
|
|
||||||
.user-menu-enter,
|
|
||||||
.user-menu-leave-to {
|
|
||||||
opacity: 0;
|
|
||||||
transform: translateY(-35%);
|
|
||||||
}
|
|
||||||
|
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
Vendored
+10
@@ -2,6 +2,7 @@ import store from './store/index'
|
|||||||
import {debounce, includes} from "lodash";
|
import {debounce, includes} from "lodash";
|
||||||
import {events} from './bus'
|
import {events} from './bus'
|
||||||
import axios from 'axios'
|
import axios from 'axios'
|
||||||
|
import router from '@/router'
|
||||||
|
|
||||||
const Helpers = {
|
const Helpers = {
|
||||||
install(Vue) {
|
install(Vue) {
|
||||||
@@ -88,6 +89,10 @@ const Helpers = {
|
|||||||
// Append form data
|
// Append form data
|
||||||
formData.append('parent_id', rootFolder)
|
formData.append('parent_id', rootFolder)
|
||||||
|
|
||||||
|
console.log(i);
|
||||||
|
console.log(files[i]);
|
||||||
|
console.log(formData);
|
||||||
|
|
||||||
// Upload data
|
// Upload data
|
||||||
await store.dispatch('uploadFiles', formData)
|
await store.dispatch('uploadFiles', formData)
|
||||||
.then(() => {
|
.then(() => {
|
||||||
@@ -233,6 +238,11 @@ const Helpers = {
|
|||||||
events.$emit('popup:close')
|
events.$emit('popup:close')
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Vue.prototype.$isThisRoute = function(route, locations) {
|
||||||
|
|
||||||
|
return includes(locations, route.name)
|
||||||
|
}
|
||||||
|
|
||||||
Vue.prototype.$isThisLocation = function(location) {
|
Vue.prototype.$isThisLocation = function(location) {
|
||||||
|
|
||||||
// Get current location
|
// Get current location
|
||||||
|
|||||||
Vendored
+2
-2
@@ -2,7 +2,7 @@ import Vue from 'vue';
|
|||||||
import VueI18n from 'vue-i18n';
|
import VueI18n from 'vue-i18n';
|
||||||
|
|
||||||
import en from './lang/en.json'
|
import en from './lang/en.json'
|
||||||
//import sk from './lang/sk.json'
|
import sk from './lang/sk.json'
|
||||||
//import cn from './lang/cn.json'
|
//import cn from './lang/cn.json'
|
||||||
|
|
||||||
Vue.use(VueI18n);
|
Vue.use(VueI18n);
|
||||||
@@ -10,7 +10,7 @@ Vue.use(VueI18n);
|
|||||||
const i18n = new VueI18n({
|
const i18n = new VueI18n({
|
||||||
locale: config.locale,
|
locale: config.locale,
|
||||||
messages: Object.assign({
|
messages: Object.assign({
|
||||||
en
|
en, sk
|
||||||
}),
|
}),
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@@ -2,8 +2,13 @@
|
|||||||
"routes": {
|
"routes": {
|
||||||
"create_new_password": "创建新密码"
|
"create_new_password": "创建新密码"
|
||||||
},
|
},
|
||||||
|
"routes_title": {
|
||||||
|
"profile": "User Profile",
|
||||||
|
"settings_password": "Change Password",
|
||||||
|
"settings_storage": "Storage",
|
||||||
|
"settings_mobile": "Settings"
|
||||||
|
},
|
||||||
"profile": {
|
"profile": {
|
||||||
"page_title": "用户信息",
|
|
||||||
"store_pass": "保存您的密码",
|
"store_pass": "保存您的密码",
|
||||||
"change_pass": "修改您的密码",
|
"change_pass": "修改您的密码",
|
||||||
"profile_info": "用户信息",
|
"profile_info": "用户信息",
|
||||||
@@ -78,8 +83,9 @@
|
|||||||
"placeholder_search_files": "搜索文件"
|
"placeholder_search_files": "搜索文件"
|
||||||
},
|
},
|
||||||
"messages": {
|
"messages": {
|
||||||
|
"nothing_from_participants": "You don't have any uploads from other users.",
|
||||||
"nothing_to_preview": "没有任何信息可以预览。",
|
"nothing_to_preview": "没有任何信息可以预览。",
|
||||||
"nothing_was_found": "没找到任何信息"
|
"nothing_was_found": "没找到任何信息。"
|
||||||
},
|
},
|
||||||
"locations": {
|
"locations": {
|
||||||
"shared": "已分享",
|
"shared": "已分享",
|
||||||
@@ -111,8 +117,15 @@
|
|||||||
"of": "of"
|
"of": "of"
|
||||||
},
|
},
|
||||||
"storage": {
|
"storage": {
|
||||||
"used": "{used} 在 {capacity} 已使用",
|
"sec_capacity": "Storage Capacity",
|
||||||
"title": "存储空间"
|
"sec_details": "Capacity Used Details",
|
||||||
|
"total_used": "Total used {used}",
|
||||||
|
"total_capacity": "Your storage capacity {capacity}",
|
||||||
|
"images": "Images",
|
||||||
|
"videos": "Videos",
|
||||||
|
"audios": "Audios",
|
||||||
|
"documents": "Documents",
|
||||||
|
"others": "Others"
|
||||||
},
|
},
|
||||||
"folder": {
|
"folder": {
|
||||||
"item_counts": "{count} 个文件 | {count} 个文件",
|
"item_counts": "{count} 个文件 | {count} 个文件",
|
||||||
@@ -144,13 +157,28 @@
|
|||||||
"share": "分享",
|
"share": "分享",
|
||||||
"move": "移动"
|
"move": "移动"
|
||||||
},
|
},
|
||||||
|
"menu": {
|
||||||
|
"files": "Files",
|
||||||
|
"latest": "Recent Uploads",
|
||||||
|
"shared": "Shared Files",
|
||||||
|
"trash": "Trash",
|
||||||
|
"settings": "Settings",
|
||||||
|
"logout": "Log Out",
|
||||||
|
"profile": "Profile Settings",
|
||||||
|
"password": "Password",
|
||||||
|
"storage": "Storage"
|
||||||
|
},
|
||||||
"sidebar": {
|
"sidebar": {
|
||||||
"shared": "已分享",
|
|
||||||
"locations": "位置",
|
|
||||||
"favourites": "收藏",
|
"favourites": "收藏",
|
||||||
"favourites_empty": "将您想要收藏的文件夹拖动至此",
|
"favourites_empty": "将您想要收藏的文件夹拖动至此",
|
||||||
"latest": "最新上传",
|
"folders_empty": "Create some new folder.",
|
||||||
"latest_empty": "您并没有最新上传的记录"
|
"latest": "Recent Uploads",
|
||||||
|
"home": "Home",
|
||||||
|
"tools_title": "Tools",
|
||||||
|
"locations_title": "Base",
|
||||||
|
"navigator_title": "Navigator",
|
||||||
|
"my_shared": "My Shared Items",
|
||||||
|
"participant_uploads": "Participant Uploads"
|
||||||
},
|
},
|
||||||
"popup_rename": {
|
"popup_rename": {
|
||||||
"title": "修改文件/夹名称"
|
"title": "修改文件/夹名称"
|
||||||
@@ -208,7 +236,9 @@
|
|||||||
"create_folder": "穿件文件夹",
|
"create_folder": "穿件文件夹",
|
||||||
"preview": "更改预览",
|
"preview": "更改预览",
|
||||||
"upload": "上传文件",
|
"upload": "上传文件",
|
||||||
"delete": "删除内容"
|
"delete": "删除内容",
|
||||||
|
"move": "Move item",
|
||||||
|
"share": "Share item"
|
||||||
},
|
},
|
||||||
"types": {
|
"types": {
|
||||||
"folder": "文件夹",
|
"folder": "文件夹",
|
||||||
|
|||||||
@@ -2,12 +2,17 @@
|
|||||||
"routes": {
|
"routes": {
|
||||||
"create_new_password": "create-new-password"
|
"create_new_password": "create-new-password"
|
||||||
},
|
},
|
||||||
|
"routes_title": {
|
||||||
|
"profile": "User Profile",
|
||||||
|
"settings_password": "Change Password",
|
||||||
|
"settings_storage": "Storage",
|
||||||
|
"settings_mobile": "Settings"
|
||||||
|
},
|
||||||
"profile": {
|
"profile": {
|
||||||
"page_title": "User Profile",
|
|
||||||
"store_pass": "Store New Password",
|
"store_pass": "Store New Password",
|
||||||
"change_pass": "Change Password",
|
"change_pass": "Change Password",
|
||||||
"profile_info": "Profile Information",
|
"profile_info": "Profile Information",
|
||||||
"photo_description": "Change Your Profile Picture",
|
"photo_description": "Change your avatar",
|
||||||
"photo_supported": "Supported formats are .png, .jpg, .jpeg."
|
"photo_supported": "Supported formats are .png, .jpg, .jpeg."
|
||||||
},
|
},
|
||||||
"page_registration": {
|
"page_registration": {
|
||||||
@@ -18,7 +23,7 @@
|
|||||||
"label_name": "Full Name:",
|
"label_name": "Full Name:",
|
||||||
"placeholder_name": "Type your full name",
|
"placeholder_name": "Type your full name",
|
||||||
"label_pass": "Create password:",
|
"label_pass": "Create password:",
|
||||||
"placeholder_pass": "Your new password",
|
"placeholder_pass": "New password",
|
||||||
"label_confirm_pass": "Confirm password:",
|
"label_confirm_pass": "Confirm password:",
|
||||||
"placeholder_confirm_pass": "Confirm your new password",
|
"placeholder_confirm_pass": "Confirm your new password",
|
||||||
"button_create_account": "Create Account",
|
"button_create_account": "Create Account",
|
||||||
@@ -40,8 +45,8 @@
|
|||||||
"subtitle": "Create your new password here:",
|
"subtitle": "Create your new password here:",
|
||||||
"button_update": "Update Password",
|
"button_update": "Update Password",
|
||||||
"label_email": "Email:",
|
"label_email": "Email:",
|
||||||
"label_new_pass": "Your new password",
|
"label_new_pass": "New password",
|
||||||
"label_confirm_pass": "Confirm new password"
|
"label_confirm_pass": "Confirm password"
|
||||||
},
|
},
|
||||||
"page_forgotten_password": {
|
"page_forgotten_password": {
|
||||||
"title": "Forgotten Password?",
|
"title": "Forgotten Password?",
|
||||||
@@ -75,11 +80,12 @@
|
|||||||
"progress": "Uploading files {current}/{total}"
|
"progress": "Uploading files {current}/{total}"
|
||||||
},
|
},
|
||||||
"inputs": {
|
"inputs": {
|
||||||
"placeholder_search_files": "Search files…"
|
"placeholder_search_files": "Search files or folders..."
|
||||||
},
|
},
|
||||||
"messages": {
|
"messages": {
|
||||||
|
"nothing_from_participants": "You don't have any uploads from other users.",
|
||||||
"nothing_to_preview": "There is nothing to preview.",
|
"nothing_to_preview": "There is nothing to preview.",
|
||||||
"nothing_was_found": "Nothing was found"
|
"nothing_was_found": "Nothing was found."
|
||||||
},
|
},
|
||||||
"locations": {
|
"locations": {
|
||||||
"shared": "Shared",
|
"shared": "Shared",
|
||||||
@@ -111,8 +117,15 @@
|
|||||||
"of": "of"
|
"of": "of"
|
||||||
},
|
},
|
||||||
"storage": {
|
"storage": {
|
||||||
"used": "{used} of {capacity} Used",
|
"sec_capacity": "Storage Capacity",
|
||||||
"title": "Storage"
|
"sec_details": "Capacity Used Details",
|
||||||
|
"total_used": "Total used {used}",
|
||||||
|
"total_capacity": "Your storage capacity {capacity}",
|
||||||
|
"images": "Images",
|
||||||
|
"videos": "Videos",
|
||||||
|
"audios": "Audios",
|
||||||
|
"documents": "Documents",
|
||||||
|
"others": "Others"
|
||||||
},
|
},
|
||||||
"folder": {
|
"folder": {
|
||||||
"item_counts": "{count} Item | {count} Items",
|
"item_counts": "{count} Item | {count} Items",
|
||||||
@@ -144,13 +157,28 @@
|
|||||||
"share": "Share",
|
"share": "Share",
|
||||||
"move": "Move"
|
"move": "Move"
|
||||||
},
|
},
|
||||||
|
"menu": {
|
||||||
|
"files": "Files",
|
||||||
|
"latest": "Recent Uploads",
|
||||||
|
"shared": "Shared Files",
|
||||||
|
"trash": "Trash",
|
||||||
|
"settings": "Settings",
|
||||||
|
"logout": "Log Out",
|
||||||
|
"profile": "Profile Settings",
|
||||||
|
"password": "Password",
|
||||||
|
"storage": "Storage"
|
||||||
|
},
|
||||||
"sidebar": {
|
"sidebar": {
|
||||||
"shared": "Shared",
|
|
||||||
"locations": "Locations",
|
|
||||||
"favourites": "Favourites",
|
"favourites": "Favourites",
|
||||||
"favourites_empty": "Drag here your favourite folder.",
|
"favourites_empty": "Drag here your favourite folder.",
|
||||||
"latest": "Last Uploads",
|
"folders_empty": "Create some new folder.",
|
||||||
"latest_empty": "You don't have any latest uploads."
|
"latest": "Recent Uploads",
|
||||||
|
"home": "Home",
|
||||||
|
"tools_title": "Tools",
|
||||||
|
"locations_title": "Base",
|
||||||
|
"navigator_title": "Navigator",
|
||||||
|
"my_shared": "My Shared Items",
|
||||||
|
"participant_uploads": "Participant Uploads"
|
||||||
},
|
},
|
||||||
"popup_rename": {
|
"popup_rename": {
|
||||||
"title": "Change your item name"
|
"title": "Change your item name"
|
||||||
@@ -191,7 +219,7 @@
|
|||||||
"confirm": "Confirm"
|
"confirm": "Confirm"
|
||||||
},
|
},
|
||||||
"shared": {
|
"shared": {
|
||||||
"empty_shared": "You Haven't Shared Anything Yet",
|
"empty_shared": "You haven't shared anything yet.",
|
||||||
"editor": "Can edit and upload files",
|
"editor": "Can edit and upload files",
|
||||||
"visitor": "Can only view and download",
|
"visitor": "Can only view and download",
|
||||||
"can_download": "Can download file"
|
"can_download": "Can download file"
|
||||||
@@ -208,7 +236,9 @@
|
|||||||
"create_folder": "Create folder",
|
"create_folder": "Create folder",
|
||||||
"preview": "Change preview",
|
"preview": "Change preview",
|
||||||
"upload": "Upload file",
|
"upload": "Upload file",
|
||||||
"delete": "Delete item"
|
"delete": "Delete item",
|
||||||
|
"move": "Move item",
|
||||||
|
"share": "Share item"
|
||||||
},
|
},
|
||||||
"types": {
|
"types": {
|
||||||
"folder": "Folder",
|
"folder": "Folder",
|
||||||
|
|||||||
@@ -2,8 +2,13 @@
|
|||||||
"routes": {
|
"routes": {
|
||||||
"create_new_password": "vytvorit-nove-heslo"
|
"create_new_password": "vytvorit-nove-heslo"
|
||||||
},
|
},
|
||||||
|
"routes_title": {
|
||||||
|
"profile": "Uživateľský profil",
|
||||||
|
"settings_password": "Zmeniť heslo",
|
||||||
|
"settings_storage": "Úložisko",
|
||||||
|
"settings_mobile": "Nastavenia"
|
||||||
|
},
|
||||||
"profile": {
|
"profile": {
|
||||||
"page_title": "Uživateľský profil",
|
|
||||||
"store_pass": "Uložiť nové heslo",
|
"store_pass": "Uložiť nové heslo",
|
||||||
"change_pass": "Zmeniť heslo",
|
"change_pass": "Zmeniť heslo",
|
||||||
"profile_info": "Profil",
|
"profile_info": "Profil",
|
||||||
@@ -78,8 +83,9 @@
|
|||||||
"placeholder_search_files": "Hľadajte súbory…"
|
"placeholder_search_files": "Hľadajte súbory…"
|
||||||
},
|
},
|
||||||
"messages": {
|
"messages": {
|
||||||
|
"nothing_from_participants": "Zatiaľ nemáš žiadné súbory od ostatných uživateľov",
|
||||||
"nothing_to_preview": "Tu nie je nič pre zobrazenie.",
|
"nothing_to_preview": "Tu nie je nič pre zobrazenie.",
|
||||||
"nothing_was_found": "Nič sa nenašlo"
|
"nothing_was_found": "Nič sa nenašlo."
|
||||||
},
|
},
|
||||||
"locations": {
|
"locations": {
|
||||||
"shared": "Zdieľané",
|
"shared": "Zdieľané",
|
||||||
@@ -111,8 +117,15 @@
|
|||||||
"of": "z"
|
"of": "z"
|
||||||
},
|
},
|
||||||
"storage": {
|
"storage": {
|
||||||
"used": "{used} z {capacity} Použité",
|
"sec_capacity": "Kapacita úložiska",
|
||||||
"title": "Úložisko"
|
"sec_details": "Detail využitej kapacity",
|
||||||
|
"total_used": "Používané {used}",
|
||||||
|
"total_capacity": "Tvoja kapacita disku {capacity}",
|
||||||
|
"images": "Obrázky",
|
||||||
|
"videos": "Videá",
|
||||||
|
"audios": "Audio",
|
||||||
|
"documents": "Dokumenty",
|
||||||
|
"others": "Ostatné"
|
||||||
},
|
},
|
||||||
"folder": {
|
"folder": {
|
||||||
"item_counts": "{count} Položka | {count} Položky",
|
"item_counts": "{count} Položka | {count} Položky",
|
||||||
@@ -144,13 +157,28 @@
|
|||||||
"share": "Zdieľať",
|
"share": "Zdieľať",
|
||||||
"move": "Presunúť"
|
"move": "Presunúť"
|
||||||
},
|
},
|
||||||
"sidebar": {
|
"menu": {
|
||||||
"shared": "Zdieľané",
|
"files": "Súbory",
|
||||||
"locations": "Umiestnenie",
|
|
||||||
"favourites": "Obľúbené",
|
|
||||||
"favourites_empty": "Presuňte sem svoj obľúbený priečinok.",
|
|
||||||
"latest": "Posledne nahrané",
|
"latest": "Posledne nahrané",
|
||||||
"latest_empty": "Nemáte žiadne nahrané súbory"
|
"shared": "Zdieľané súbory",
|
||||||
|
"trash": "Kôš",
|
||||||
|
"settings": "Nastavenia",
|
||||||
|
"logout": "Odhlásiť sa",
|
||||||
|
"profile": "Nastavenia profilu",
|
||||||
|
"password": "Heslo",
|
||||||
|
"storage": "Úložisko"
|
||||||
|
},
|
||||||
|
"sidebar": {
|
||||||
|
"favourites": "Obľúbené",
|
||||||
|
"favourites_empty": "Presuňte sem obľúbený priečinok",
|
||||||
|
"folders_empty": "Vytvorte svoj prvý priečinok",
|
||||||
|
"latest": "Posledne nahraté",
|
||||||
|
"home": "Domov",
|
||||||
|
"tools_title": "Nástroje",
|
||||||
|
"locations_title": "Menu",
|
||||||
|
"navigator_title": "Navigátor",
|
||||||
|
"my_shared": "Moje zdieľané položky",
|
||||||
|
"participant_uploads": "Nahrávania účastníkov"
|
||||||
},
|
},
|
||||||
"popup_rename": {
|
"popup_rename": {
|
||||||
"title": "Zmeňte názov položky"
|
"title": "Zmeňte názov položky"
|
||||||
@@ -208,7 +236,9 @@
|
|||||||
"create_folder": "Vytvoriť priečinok",
|
"create_folder": "Vytvoriť priečinok",
|
||||||
"preview": "Zmeniť náhľad",
|
"preview": "Zmeniť náhľad",
|
||||||
"upload": "Nahrať súbory",
|
"upload": "Nahrať súbory",
|
||||||
"delete": "Vymazať položku"
|
"delete": "Vymazať položku",
|
||||||
|
"move": "Presunúť položku",
|
||||||
|
"share": "Zdieľať položku"
|
||||||
},
|
},
|
||||||
"types": {
|
"types": {
|
||||||
"folder": "Priečinok",
|
"folder": "Priečinok",
|
||||||
|
|||||||
Vendored
+67
-5
@@ -1,5 +1,6 @@
|
|||||||
import Vue from 'vue'
|
import Vue from 'vue'
|
||||||
import Router from 'vue-router'
|
import Router from 'vue-router'
|
||||||
|
import i18n from '@/i18n/index'
|
||||||
|
|
||||||
import Index from './views/Auth/SignIn'
|
import Index from './views/Auth/SignIn'
|
||||||
import SignUp from './views/Auth/SignUp'
|
import SignUp from './views/Auth/SignUp'
|
||||||
@@ -8,8 +9,15 @@ import NotFoundShared from './views/Shared/NotFoundShared'
|
|||||||
import ForgottenPassword from './views/Auth/ForgottenPassword'
|
import ForgottenPassword from './views/Auth/ForgottenPassword'
|
||||||
import CreateNewPassword from './views/Auth/CreateNewPassword'
|
import CreateNewPassword from './views/Auth/CreateNewPassword'
|
||||||
|
|
||||||
import Files from './views/Files'
|
import Settings from './views/Settings'
|
||||||
import Profile from './views/Profile'
|
import Profile from './views/User/Profile'
|
||||||
|
import Storage from './views/User/Storage'
|
||||||
|
import Trash from './views/FilePages/Trash'
|
||||||
|
import Files from './views/FilePages/Files'
|
||||||
|
import Password from './views/User/Password'
|
||||||
|
import SharedFiles from './views/FilePages/SharedFiles'
|
||||||
|
|
||||||
|
import MobileSettings from './views/Mobile/MobileSettings'
|
||||||
|
|
||||||
Vue.use(Router)
|
Vue.use(Router)
|
||||||
|
|
||||||
@@ -73,13 +81,67 @@ const router = new Router({
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: 'Profile',
|
name: 'SharedFiles',
|
||||||
path: '/profile',
|
path: '/shared-files',
|
||||||
component: Profile,
|
component: SharedFiles,
|
||||||
meta: {
|
meta: {
|
||||||
requiresAuth: true
|
requiresAuth: true
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
name: 'Trash',
|
||||||
|
path: '/trash',
|
||||||
|
component: Trash,
|
||||||
|
meta: {
|
||||||
|
requiresAuth: true
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'Settings',
|
||||||
|
path: '/settings',
|
||||||
|
component: Settings,
|
||||||
|
meta: {
|
||||||
|
requiresAuth: true
|
||||||
|
},
|
||||||
|
children: [
|
||||||
|
{
|
||||||
|
name: 'Profile',
|
||||||
|
path: 'profile',
|
||||||
|
component: Profile,
|
||||||
|
meta: {
|
||||||
|
requiresAuth: true,
|
||||||
|
title: i18n.t('routes_title.profile')
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'Password',
|
||||||
|
path: '/settings/password',
|
||||||
|
component: Password,
|
||||||
|
meta: {
|
||||||
|
requiresAuth: true,
|
||||||
|
title: i18n.t('routes_title.settings_password')
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'Storage',
|
||||||
|
path: '/settings/storage',
|
||||||
|
component: Storage,
|
||||||
|
meta: {
|
||||||
|
requiresAuth: true,
|
||||||
|
title: i18n.t('routes_title.settings_storage')
|
||||||
|
},
|
||||||
|
},
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'MobileSettings',
|
||||||
|
path: '/settings-mobile',
|
||||||
|
component: MobileSettings,
|
||||||
|
meta: {
|
||||||
|
requiresAuth: true,
|
||||||
|
title: i18n.t('routes_title.settings_mobile')
|
||||||
|
},
|
||||||
|
}
|
||||||
],
|
],
|
||||||
scrollBehavior(to, from, savedPosition) {
|
scrollBehavior(to, from, savedPosition) {
|
||||||
|
|
||||||
|
|||||||
Vendored
+11
-16
@@ -3,6 +3,8 @@ const defaultState = {
|
|||||||
FilePreviewType: localStorage.getItem('preview_type') || 'list',
|
FilePreviewType: localStorage.getItem('preview_type') || 'list',
|
||||||
appSize: undefined,
|
appSize: undefined,
|
||||||
config: undefined,
|
config: undefined,
|
||||||
|
authorized: undefined,
|
||||||
|
homeDirectory: undefined,
|
||||||
}
|
}
|
||||||
const actions = {
|
const actions = {
|
||||||
changePreviewType: ({commit, dispatch, state, getters}) => {
|
changePreviewType: ({commit, dispatch, state, getters}) => {
|
||||||
@@ -14,18 +16,6 @@ const actions = {
|
|||||||
|
|
||||||
// Change preview
|
// Change preview
|
||||||
commit('CHANGE_PREVIEW', previewType)
|
commit('CHANGE_PREVIEW', previewType)
|
||||||
|
|
||||||
if (getters.currentFolder.location === 'trash-root') {
|
|
||||||
dispatch('getTrash')
|
|
||||||
|
|
||||||
} else {
|
|
||||||
|
|
||||||
if ( getters.currentFolder.location === 'public' ) {
|
|
||||||
dispatch('browseShared', [getters.currentFolder, false, true])
|
|
||||||
} else {
|
|
||||||
dispatch('getFolder', [getters.currentFolder, false, true])
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
fileInfoToggle: (context, visibility = undefined) => {
|
fileInfoToggle: (context, visibility = undefined) => {
|
||||||
if (!visibility) {
|
if (!visibility) {
|
||||||
@@ -40,6 +30,11 @@ const actions = {
|
|||||||
},
|
},
|
||||||
}
|
}
|
||||||
const mutations = {
|
const mutations = {
|
||||||
|
INIT(state, data) {
|
||||||
|
state.config = data.config
|
||||||
|
state.authorized = data.authCookie
|
||||||
|
state.homeDirectory = data.rootDirectory
|
||||||
|
},
|
||||||
FILE_INFO_TOGGLE(state, isVisible) {
|
FILE_INFO_TOGGLE(state, isVisible) {
|
||||||
state.fileInfoPanelVisible = isVisible
|
state.fileInfoPanelVisible = isVisible
|
||||||
|
|
||||||
@@ -48,13 +43,12 @@ const mutations = {
|
|||||||
SET_APP_WIDTH(state, scale) {
|
SET_APP_WIDTH(state, scale) {
|
||||||
state.appSize = scale
|
state.appSize = scale
|
||||||
},
|
},
|
||||||
|
SET_AUTHORIZED(state, data) {
|
||||||
|
state.authorized = data
|
||||||
|
},
|
||||||
CHANGE_PREVIEW(state, type) {
|
CHANGE_PREVIEW(state, type) {
|
||||||
state.FilePreviewType = type
|
state.FilePreviewType = type
|
||||||
},
|
},
|
||||||
SET_CONFIG(state, config) {
|
|
||||||
state.config = config
|
|
||||||
},
|
|
||||||
|
|
||||||
}
|
}
|
||||||
const getters = {
|
const getters = {
|
||||||
fileInfoVisible: state => state.fileInfoPanelVisible,
|
fileInfoVisible: state => state.fileInfoPanelVisible,
|
||||||
@@ -62,6 +56,7 @@ const getters = {
|
|||||||
appSize: state => state.appSize,
|
appSize: state => state.appSize,
|
||||||
api: state => state.config.api,
|
api: state => state.config.api,
|
||||||
config: state => state.config,
|
config: state => state.config,
|
||||||
|
homeDirectory: state => state.homeDirectory,
|
||||||
}
|
}
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
|
|||||||
+103
-133
@@ -1,16 +1,13 @@
|
|||||||
import axios from 'axios'
|
import axios from 'axios'
|
||||||
import {events} from '@/bus'
|
import {events} from '@/bus'
|
||||||
import router from '@/router'
|
import router from '@/router'
|
||||||
import {includes} from 'lodash'
|
|
||||||
import i18n from '@/i18n/index'
|
import i18n from '@/i18n/index'
|
||||||
|
|
||||||
const defaultState = {
|
const defaultState = {
|
||||||
uploadingFilesCount: undefined,
|
uploadingFilesCount: undefined,
|
||||||
fileInfoDetail: undefined,
|
fileInfoDetail: undefined,
|
||||||
currentFolder: undefined,
|
currentFolder: undefined,
|
||||||
homeDirectory: undefined,
|
|
||||||
uploadingFileProgress: 0,
|
uploadingFileProgress: 0,
|
||||||
filesViewWidth: undefined,
|
|
||||||
navigation: undefined,
|
navigation: undefined,
|
||||||
isSearching: false,
|
isSearching: false,
|
||||||
browseHistory: [],
|
browseHistory: [],
|
||||||
@@ -19,56 +16,45 @@ const defaultState = {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const actions = {
|
const actions = {
|
||||||
getFolder: (context, [folder, back = false, init = false]) => {
|
getFolder: ({commit, getters}, [payload]) => {
|
||||||
events.$emit('show:content')
|
commit('LOADING_STATE', {loading: true, data: []})
|
||||||
|
|
||||||
// Go to files view
|
if (payload.init)
|
||||||
if (!includes(['Files', 'SharedPage'], router.currentRoute.name)) {
|
commit('FLUSH_FOLDER_HISTORY')
|
||||||
router.push({name: 'Files'})
|
|
||||||
}
|
|
||||||
|
|
||||||
context.commit('LOADING_STATE', true)
|
|
||||||
context.commit('FLUSH_DATA')
|
|
||||||
|
|
||||||
// Clear search
|
// Clear search
|
||||||
if (context.state.isSearching) {
|
if (getters.isSearching) {
|
||||||
context.commit('CHANGE_SEARCHING_STATE', false)
|
commit('CHANGE_SEARCHING_STATE', false)
|
||||||
events.$emit('clear-query')
|
events.$emit('clear-query')
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create current folder for history
|
// Set folder location
|
||||||
let currentFolder = {
|
payload.folder.location = payload.folder.deleted_at || payload.folder.location === 'trash' ? 'trash' : 'base'
|
||||||
name: folder.name,
|
|
||||||
unique_id: folder.unique_id,
|
|
||||||
location: folder.deleted_at || folder.location === 'trash' ? 'trash' : 'base'
|
|
||||||
}
|
|
||||||
|
|
||||||
let url = currentFolder.location === 'trash'
|
if (! payload.back)
|
||||||
? '/folders/' + currentFolder.unique_id + '?trash=true'
|
commit('STORE_PREVIOUS_FOLDER', getters.currentFolder)
|
||||||
: '/folders/' + currentFolder.unique_id
|
|
||||||
|
let url = payload.folder.location === 'trash'
|
||||||
|
? '/folders/' + payload.folder.unique_id + '?trash=true'
|
||||||
|
: '/folders/' + payload.folder.unique_id
|
||||||
|
|
||||||
axios
|
axios
|
||||||
.get(context.getters.api + url)
|
.get(getters.api + url)
|
||||||
.then(response => {
|
.then(response => {
|
||||||
context.commit('LOADING_STATE', false)
|
commit('LOADING_STATE', {loading: false, data: response.data})
|
||||||
context.commit('GET_DATA', response.data)
|
commit('STORE_CURRENT_FOLDER', payload.folder)
|
||||||
context.commit('STORE_CURRENT_FOLDER', currentFolder)
|
|
||||||
|
if (payload.back)
|
||||||
|
commit('REMOVE_BROWSER_HISTORY')
|
||||||
|
|
||||||
events.$emit('scrollTop')
|
events.$emit('scrollTop')
|
||||||
|
|
||||||
if (back) {
|
|
||||||
context.commit('REMOVE_BROWSER_HISTORY')
|
|
||||||
|
|
||||||
} else {
|
|
||||||
if (!init) context.commit('ADD_BROWSER_HISTORY', currentFolder)
|
|
||||||
}
|
|
||||||
})
|
})
|
||||||
.catch(error => {
|
.catch(error => {
|
||||||
|
|
||||||
// Redirect if unauthenticated
|
// Redirect if unauthenticated
|
||||||
if ([401, 403].includes(error.response.status)) {
|
if ([401, 403].includes(error.response.status)) {
|
||||||
|
|
||||||
context.commit('SET_AUTHORIZED', false)
|
commit('SET_AUTHORIZED', false)
|
||||||
router.push({name: 'SignIn'})
|
router.push({name: 'SignIn'})
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
@@ -81,83 +67,89 @@ const actions = {
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
getShared: (context, back = false) => {
|
getLatest: ({commit, getters}) => {
|
||||||
events.$emit('show:content')
|
commit('LOADING_STATE', {loading: true, data: []})
|
||||||
|
|
||||||
// Go to files view
|
commit('STORE_PREVIOUS_FOLDER', getters.currentFolder)
|
||||||
if (router.currentRoute.name !== 'Files') {
|
commit('STORE_CURRENT_FOLDER', {
|
||||||
router.push({name: 'Files'})
|
name: i18n.t('sidebar.latest'),
|
||||||
}
|
|
||||||
|
|
||||||
if (!back) context.commit('FLUSH_BROWSER_HISTORY')
|
|
||||||
context.commit('FLUSH_DATA')
|
|
||||||
context.commit('LOADING_STATE', true)
|
|
||||||
|
|
||||||
// Create shared object for history
|
|
||||||
let trash = {
|
|
||||||
name: 'Shared',
|
|
||||||
unique_id: undefined,
|
unique_id: undefined,
|
||||||
location: 'shared',
|
location: 'latest',
|
||||||
}
|
})
|
||||||
|
|
||||||
axios
|
axios
|
||||||
.get(context.getters.api + '/shared-all')
|
.get(getters.api + '/latest')
|
||||||
.then(response => {
|
.then(response => {
|
||||||
context.commit('GET_DATA', response.data)
|
commit('LOADING_STATE', {loading: false, data: response.data})
|
||||||
context.commit('LOADING_STATE', false)
|
events.$emit('scrollTop')
|
||||||
context.commit('STORE_CURRENT_FOLDER', trash)
|
})
|
||||||
context.commit('ADD_BROWSER_HISTORY', trash)
|
.catch(() => isSomethingWrong())
|
||||||
|
},
|
||||||
|
getShared: ({commit, getters}) => {
|
||||||
|
commit('LOADING_STATE', {loading: true, data: []})
|
||||||
|
commit('FLUSH_FOLDER_HISTORY')
|
||||||
|
|
||||||
|
let currentFolder = {
|
||||||
|
name: i18n.t('sidebar.my_shared'),
|
||||||
|
location: 'shared',
|
||||||
|
unique_id: undefined,
|
||||||
|
}
|
||||||
|
|
||||||
|
commit('STORE_CURRENT_FOLDER', currentFolder)
|
||||||
|
|
||||||
|
axios
|
||||||
|
.get(getters.api + '/shared-all')
|
||||||
|
.then(response => {
|
||||||
|
commit('LOADING_STATE', {loading: false, data: response.data})
|
||||||
|
commit('STORE_PREVIOUS_FOLDER', currentFolder)
|
||||||
|
|
||||||
events.$emit('scrollTop')
|
events.$emit('scrollTop')
|
||||||
})
|
})
|
||||||
.catch(() => {
|
.catch(() => isSomethingWrong())
|
||||||
// Show error message
|
|
||||||
events.$emit('alert:open', {
|
|
||||||
title: i18n.t('popup_error.title'),
|
|
||||||
message: i18n.t('popup_error.message'),
|
|
||||||
})
|
|
||||||
})
|
|
||||||
},
|
},
|
||||||
getTrash: (context, back = false) => {
|
getParticipantUploads: ({commit, getters}) => {
|
||||||
events.$emit('show:content')
|
commit('LOADING_STATE', {loading: true, data: []})
|
||||||
|
|
||||||
// Go to files view
|
commit('STORE_PREVIOUS_FOLDER', getters.currentFolder)
|
||||||
if (router.currentRoute.name !== 'Files') {
|
commit('STORE_CURRENT_FOLDER', {
|
||||||
router.push({name: 'Files'})
|
name: i18n.t('sidebar.participant_uploads'),
|
||||||
}
|
unique_id: undefined,
|
||||||
|
location: 'participant_uploads',
|
||||||
|
})
|
||||||
|
|
||||||
if (!back) context.commit('FLUSH_BROWSER_HISTORY')
|
axios
|
||||||
context.commit('FLUSH_DATA')
|
.get(getters.api + '/participant-uploads')
|
||||||
context.commit('LOADING_STATE', true)
|
.then(response => {
|
||||||
|
commit('LOADING_STATE', {loading: false, data: response.data})
|
||||||
|
|
||||||
|
events.$emit('scrollTop')
|
||||||
|
})
|
||||||
|
.catch(() => isSomethingWrong())
|
||||||
|
},
|
||||||
|
getTrash: ({commit, getters}) => {
|
||||||
|
commit('LOADING_STATE', {loading: true, data: []})
|
||||||
|
commit('FLUSH_FOLDER_HISTORY')
|
||||||
|
|
||||||
// Create trash object for history
|
|
||||||
let trash = {
|
let trash = {
|
||||||
name: 'Trash',
|
name: i18n.t('locations.trash'),
|
||||||
unique_id: undefined,
|
unique_id: undefined,
|
||||||
location: 'trash-root',
|
location: 'trash-root',
|
||||||
}
|
}
|
||||||
|
|
||||||
|
commit('STORE_CURRENT_FOLDER', trash)
|
||||||
|
|
||||||
axios
|
axios
|
||||||
.get(context.getters.api + '/trash')
|
.get(getters.api + '/trash')
|
||||||
.then(response => {
|
.then(response => {
|
||||||
context.commit('GET_DATA', response.data)
|
commit('LOADING_STATE', {loading: false, data: response.data})
|
||||||
context.commit('LOADING_STATE', false)
|
commit('STORE_PREVIOUS_FOLDER', trash)
|
||||||
context.commit('STORE_CURRENT_FOLDER', trash)
|
|
||||||
context.commit('ADD_BROWSER_HISTORY', trash)
|
|
||||||
|
|
||||||
events.$emit('scrollTop')
|
events.$emit('scrollTop')
|
||||||
})
|
})
|
||||||
.catch(() => {
|
.catch(() => isSomethingWrong())
|
||||||
// Show error message
|
|
||||||
events.$emit('alert:open', {
|
|
||||||
title: i18n.t('popup_error.title'),
|
|
||||||
message: i18n.t('popup_error.message'),
|
|
||||||
})
|
|
||||||
})
|
|
||||||
},
|
},
|
||||||
getSearchResult: ({commit, getters}, query) => {
|
getSearchResult: ({commit, getters}, query) => {
|
||||||
commit('FLUSH_DATA')
|
commit('LOADING_STATE', {loading: true, data: []})
|
||||||
commit('LOADING_STATE', true)
|
|
||||||
commit('CHANGE_SEARCHING_STATE', true)
|
commit('CHANGE_SEARCHING_STATE', true)
|
||||||
|
|
||||||
// Get route
|
// Get route
|
||||||
@@ -175,30 +167,17 @@ const actions = {
|
|||||||
params: {query: query}
|
params: {query: query}
|
||||||
})
|
})
|
||||||
.then(response => {
|
.then(response => {
|
||||||
commit('LOADING_STATE', false)
|
commit('LOADING_STATE', {loading: false, data: response.data})
|
||||||
commit('GET_DATA', response.data)
|
|
||||||
})
|
|
||||||
.catch(() => {
|
|
||||||
// Show error message
|
|
||||||
events.$emit('alert:open', {
|
|
||||||
title: i18n.t('popup_error.title'),
|
|
||||||
message: i18n.t('popup_error.message'),
|
|
||||||
})
|
|
||||||
})
|
})
|
||||||
|
.catch(() => isSomethingWrong())
|
||||||
},
|
},
|
||||||
getFileDetail: (context, file) => {
|
getFileDetail: ({commit, getters}, file) => {
|
||||||
axios
|
axios
|
||||||
.get(context.getters.api + '/file-detail/' + file.unique_id)
|
.get(getters.api + '/file-detail/' + file.unique_id)
|
||||||
.then(response => {
|
.then(response => {
|
||||||
context.commit('LOAD_FILEINFO_DETAIL', response.data)
|
commit('LOAD_FILEINFO_DETAIL', response.data)
|
||||||
})
|
|
||||||
.catch(() => {
|
|
||||||
// Show error message
|
|
||||||
events.$emit('alert:open', {
|
|
||||||
title: i18n.t('popup_error.title'),
|
|
||||||
message: i18n.t('popup_error.message'),
|
|
||||||
})
|
|
||||||
})
|
})
|
||||||
|
.catch(() => isSomethingWrong())
|
||||||
},
|
},
|
||||||
getFolderTree: ({commit, getters}) => {
|
getFolderTree: ({commit, getters}) => {
|
||||||
|
|
||||||
@@ -224,11 +203,7 @@ const actions = {
|
|||||||
.catch((error) => {
|
.catch((error) => {
|
||||||
reject(error)
|
reject(error)
|
||||||
|
|
||||||
// Show error message
|
isSomethingWrong()
|
||||||
events.$emit('alert:open', {
|
|
||||||
title: i18n.t('popup_error.title'),
|
|
||||||
message: i18n.t('popup_error.message'),
|
|
||||||
})
|
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
@@ -238,13 +213,11 @@ const mutations = {
|
|||||||
UPDATE_FOLDER_TREE(state, tree) {
|
UPDATE_FOLDER_TREE(state, tree) {
|
||||||
state.navigation = tree
|
state.navigation = tree
|
||||||
},
|
},
|
||||||
LOADING_STATE(state, val) {
|
LOADING_STATE(state, payload) {
|
||||||
state.isLoading = val
|
state.data = payload.data
|
||||||
|
state.isLoading = payload.loading
|
||||||
},
|
},
|
||||||
SET_START_DIRECTORY(state, directory) {
|
FLUSH_FOLDER_HISTORY(state) {
|
||||||
state.homeDirectory = directory
|
|
||||||
},
|
|
||||||
FLUSH_BROWSER_HISTORY(state) {
|
|
||||||
state.browseHistory = []
|
state.browseHistory = []
|
||||||
},
|
},
|
||||||
FLUSH_SHARED(state, unique_id) {
|
FLUSH_SHARED(state, unique_id) {
|
||||||
@@ -252,7 +225,7 @@ const mutations = {
|
|||||||
if (item.unique_id == unique_id) item.shared = undefined
|
if (item.unique_id == unique_id) item.shared = undefined
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
ADD_BROWSER_HISTORY(state, folder) {
|
STORE_PREVIOUS_FOLDER(state, folder) {
|
||||||
state.browseHistory.push(folder)
|
state.browseHistory.push(folder)
|
||||||
},
|
},
|
||||||
REMOVE_BROWSER_HISTORY(state) {
|
REMOVE_BROWSER_HISTORY(state) {
|
||||||
@@ -277,9 +250,9 @@ const mutations = {
|
|||||||
state.fileInfoDetail = item
|
state.fileInfoDetail = item
|
||||||
},
|
},
|
||||||
GET_FILEINFO_DETAIL(state, item) {
|
GET_FILEINFO_DETAIL(state, item) {
|
||||||
state.fileInfoDetail = state.data.find(
|
let checkData = state.data.find(el => el.unique_id == item.unique_id)
|
||||||
el => el.unique_id == item.unique_id
|
|
||||||
)
|
state.fileInfoDetail = checkData ? checkData : state.currentFolder
|
||||||
},
|
},
|
||||||
CHANGE_SEARCHING_STATE(state, searchState) {
|
CHANGE_SEARCHING_STATE(state, searchState) {
|
||||||
state.isSearching = searchState
|
state.isSearching = searchState
|
||||||
@@ -295,12 +268,6 @@ const mutations = {
|
|||||||
if (item.unique_id == data.item_id) item.shared = data
|
if (item.unique_id == data.item_id) item.shared = data
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
FLUSH_DATA(state) {
|
|
||||||
state.data = []
|
|
||||||
},
|
|
||||||
GET_DATA(state, loaded_data) {
|
|
||||||
state.data = loaded_data
|
|
||||||
},
|
|
||||||
ADD_NEW_FOLDER(state, folder) {
|
ADD_NEW_FOLDER(state, folder) {
|
||||||
state.data.unshift(folder)
|
state.data.unshift(folder)
|
||||||
},
|
},
|
||||||
@@ -318,17 +285,12 @@ const mutations = {
|
|||||||
STORE_CURRENT_FOLDER(state, folder) {
|
STORE_CURRENT_FOLDER(state, folder) {
|
||||||
state.currentFolder = folder
|
state.currentFolder = folder
|
||||||
},
|
},
|
||||||
SET_FILES_VIEW_SIZE(state, type) {
|
|
||||||
state.filesViewWidth = type
|
|
||||||
},
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const getters = {
|
const getters = {
|
||||||
uploadingFileProgress: state => state.uploadingFileProgress,
|
uploadingFileProgress: state => state.uploadingFileProgress,
|
||||||
uploadingFilesCount: state => state.uploadingFilesCount,
|
uploadingFilesCount: state => state.uploadingFilesCount,
|
||||||
fileInfoDetail: state => state.fileInfoDetail,
|
fileInfoDetail: state => state.fileInfoDetail,
|
||||||
filesViewWidth: state => state.filesViewWidth,
|
|
||||||
homeDirectory: state => state.homeDirectory,
|
|
||||||
currentFolder: state => state.currentFolder,
|
currentFolder: state => state.currentFolder,
|
||||||
browseHistory: state => state.browseHistory,
|
browseHistory: state => state.browseHistory,
|
||||||
isSearching: state => state.isSearching,
|
isSearching: state => state.isSearching,
|
||||||
@@ -337,6 +299,14 @@ const getters = {
|
|||||||
data: state => state.data,
|
data: state => state.data,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Show error message
|
||||||
|
function isSomethingWrong() {
|
||||||
|
events.$emit('alert:open', {
|
||||||
|
title: i18n.t('popup_error.title'),
|
||||||
|
message: i18n.t('popup_error.message'),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
state: defaultState,
|
state: defaultState,
|
||||||
getters,
|
getters,
|
||||||
|
|||||||
+36
-12
@@ -1,10 +1,11 @@
|
|||||||
import i18n from '@/i18n/index'
|
import i18n from '@/i18n/index'
|
||||||
import router from '@/router'
|
import router from '@/router'
|
||||||
import {events} from '@/bus'
|
import {events} from '@/bus'
|
||||||
|
import {last} from 'lodash'
|
||||||
import axios from 'axios'
|
import axios from 'axios'
|
||||||
|
|
||||||
const actions = {
|
const actions = {
|
||||||
moveItem: ({commit, getters}, [item_from, to_item]) => {
|
moveItem: ({commit, getters, dispatch}, [item_from, to_item]) => {
|
||||||
|
|
||||||
// Get route
|
// Get route
|
||||||
let route = getters.sharedDetail && ! getters.sharedDetail.protected
|
let route = getters.sharedDetail && ! getters.sharedDetail.protected
|
||||||
@@ -19,10 +20,14 @@ const actions = {
|
|||||||
.then(() => {
|
.then(() => {
|
||||||
commit('REMOVE_ITEM', item_from.unique_id)
|
commit('REMOVE_ITEM', item_from.unique_id)
|
||||||
commit('INCREASE_FOLDER_ITEM', to_item.unique_id)
|
commit('INCREASE_FOLDER_ITEM', to_item.unique_id)
|
||||||
|
|
||||||
|
if (item_from.type === 'folder' && getters.currentFolder.location !== 'public')
|
||||||
|
dispatch('getAppData')
|
||||||
|
|
||||||
})
|
})
|
||||||
.catch(() => isSomethingWrong())
|
.catch(() => isSomethingWrong())
|
||||||
},
|
},
|
||||||
createFolder: ({commit, getters}, folderName) => {
|
createFolder: ({commit, getters, dispatch}, folderName) => {
|
||||||
|
|
||||||
// Get route
|
// Get route
|
||||||
let route = getters.sharedDetail && ! getters.sharedDetail.protected
|
let route = getters.sharedDetail && ! getters.sharedDetail.protected
|
||||||
@@ -36,10 +41,14 @@ const actions = {
|
|||||||
})
|
})
|
||||||
.then(response => {
|
.then(response => {
|
||||||
commit('ADD_NEW_FOLDER', response.data)
|
commit('ADD_NEW_FOLDER', response.data)
|
||||||
|
|
||||||
|
if ( getters.currentFolder.location !== 'public' ) {
|
||||||
|
dispatch('getAppData')
|
||||||
|
}
|
||||||
})
|
})
|
||||||
.catch(() => isSomethingWrong())
|
.catch(() => isSomethingWrong())
|
||||||
},
|
},
|
||||||
renameItem: ({commit, getters}, data) => {
|
renameItem: ({commit, getters, dispatch}, data) => {
|
||||||
|
|
||||||
// Updated name in favourites panel
|
// Updated name in favourites panel
|
||||||
if (getters.permission === 'master' && data.type === 'folder')
|
if (getters.permission === 'master' && data.type === 'folder')
|
||||||
@@ -57,6 +66,9 @@ const actions = {
|
|||||||
})
|
})
|
||||||
.then(response => {
|
.then(response => {
|
||||||
commit('CHANGE_ITEM_NAME', response.data)
|
commit('CHANGE_ITEM_NAME', response.data)
|
||||||
|
|
||||||
|
if (data.type === 'folder' && getters.currentFolder.location !== 'public')
|
||||||
|
dispatch('getAppData')
|
||||||
})
|
})
|
||||||
.catch(() => isSomethingWrong())
|
.catch(() => isSomethingWrong())
|
||||||
},
|
},
|
||||||
@@ -87,9 +99,6 @@ const actions = {
|
|||||||
|
|
||||||
commit('UPLOADING_FILE_PROGRESS', 0)
|
commit('UPLOADING_FILE_PROGRESS', 0)
|
||||||
|
|
||||||
if (getters.permission === 'master')
|
|
||||||
commit('UPDATE_RECENT_UPLOAD', response.data)
|
|
||||||
|
|
||||||
resolve(response)
|
resolve(response)
|
||||||
})
|
})
|
||||||
.catch(error => {
|
.catch(error => {
|
||||||
@@ -121,7 +130,7 @@ const actions = {
|
|||||||
})
|
})
|
||||||
.catch(() => isSomethingWrong())
|
.catch(() => isSomethingWrong())
|
||||||
},
|
},
|
||||||
deleteItem: ({commit, getters}, data) => {
|
deleteItem: ({commit, getters, dispatch}, data) => {
|
||||||
|
|
||||||
// Remove file
|
// Remove file
|
||||||
commit('REMOVE_ITEM', data.unique_id)
|
commit('REMOVE_ITEM', data.unique_id)
|
||||||
@@ -131,8 +140,6 @@ const actions = {
|
|||||||
|
|
||||||
if (data.type === 'folder')
|
if (data.type === 'folder')
|
||||||
commit('REMOVE_ITEM_FROM_FAVOURITES', data)
|
commit('REMOVE_ITEM_FROM_FAVOURITES', data)
|
||||||
else
|
|
||||||
commit('REMOVE_ITEM_FROM_RECENT_UPLOAD', data.unique_id)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Remove file preview
|
// Remove file preview
|
||||||
@@ -150,18 +157,35 @@ const actions = {
|
|||||||
force_delete: data.deleted_at ? true : false
|
force_delete: data.deleted_at ? true : false
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
.then(() => {
|
||||||
|
|
||||||
|
// If is folder, update app data
|
||||||
|
if (data.type === 'folder') {
|
||||||
|
|
||||||
|
if (data.unique_id === getters.currentFolder.unique_id) {
|
||||||
|
|
||||||
|
if ( getters.currentFolder.location === 'public' ) {
|
||||||
|
dispatch('browseShared', [{folder: last(getters.browseHistory), back: true, init: false}])
|
||||||
|
} else {
|
||||||
|
dispatch('getFolder', [{folder: last(getters.browseHistory), back: true, init: false}])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( getters.currentFolder.location !== 'public' )
|
||||||
|
dispatch('getAppData')
|
||||||
|
}
|
||||||
|
})
|
||||||
.catch(() => isSomethingWrong())
|
.catch(() => isSomethingWrong())
|
||||||
},
|
},
|
||||||
emptyTrash: ({commit, getters}) => {
|
emptyTrash: ({commit, getters}) => {
|
||||||
|
|
||||||
// Clear file browser
|
// Clear file browser
|
||||||
commit('FLUSH_DATA')
|
commit('LOADING_STATE', {loading: true, data: []})
|
||||||
commit('LOADING_STATE', true)
|
|
||||||
|
|
||||||
axios
|
axios
|
||||||
.delete(getters.api + '/empty-trash')
|
.delete(getters.api + '/empty-trash')
|
||||||
.then(() => {
|
.then(() => {
|
||||||
commit('LOADING_STATE', false)
|
commit('LOADING_STATE', {loading: false, data: []})
|
||||||
events.$emit('scrollTop')
|
events.$emit('scrollTop')
|
||||||
|
|
||||||
// Remove file preview
|
// Remove file preview
|
||||||
|
|||||||
+14
-21
@@ -20,9 +20,11 @@ const defaultState = {
|
|||||||
sharedFile: undefined,
|
sharedFile: undefined,
|
||||||
}
|
}
|
||||||
const actions = {
|
const actions = {
|
||||||
browseShared: ({commit, state, getters}, [folder, back = false, init = false]) => {
|
browseShared: ({commit, getters}, [payload]) => {
|
||||||
commit('LOADING_STATE', true)
|
commit('LOADING_STATE', {loading: true, data: []})
|
||||||
commit('FLUSH_DATA')
|
|
||||||
|
if (payload.init)
|
||||||
|
commit('FLUSH_FOLDER_HISTORY')
|
||||||
|
|
||||||
// Clear search
|
// Clear search
|
||||||
if (getters.isSearching) {
|
if (getters.isSearching) {
|
||||||
@@ -30,35 +32,26 @@ const actions = {
|
|||||||
events.$emit('clear-query')
|
events.$emit('clear-query')
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create current folder for history
|
if (! payload.back)
|
||||||
let currentFolder = {
|
commit('STORE_PREVIOUS_FOLDER', getters.currentFolder)
|
||||||
name: folder.name,
|
|
||||||
unique_id: folder.unique_id,
|
payload.folder.location = 'public'
|
||||||
location: 'public'
|
|
||||||
}
|
|
||||||
|
|
||||||
let route = getters.sharedDetail.protected
|
let route = getters.sharedDetail.protected
|
||||||
? '/api/folders/' + currentFolder.unique_id + '/private'
|
? '/api/folders/' + payload.folder.unique_id + '/private'
|
||||||
: '/api/folders/' + currentFolder.unique_id + '/public/' + router.currentRoute.params.token +'/'
|
: '/api/folders/' + payload.folder.unique_id + '/public/' + router.currentRoute.params.token +'/'
|
||||||
|
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
axios
|
axios
|
||||||
.get(route)
|
.get(route)
|
||||||
.then(response => {
|
.then(response => {
|
||||||
|
commit('LOADING_STATE', {loading: false, data: response.data})
|
||||||
commit('LOADING_STATE', false)
|
commit('STORE_CURRENT_FOLDER', payload.folder)
|
||||||
commit('GET_DATA', response.data)
|
|
||||||
commit('STORE_CURRENT_FOLDER', currentFolder)
|
|
||||||
events.$emit('scrollTop')
|
events.$emit('scrollTop')
|
||||||
|
|
||||||
if (back) {
|
if (payload.back)
|
||||||
commit('REMOVE_BROWSER_HISTORY')
|
commit('REMOVE_BROWSER_HISTORY')
|
||||||
|
|
||||||
} else {
|
|
||||||
if (!init)
|
|
||||||
commit('ADD_BROWSER_HISTORY', currentFolder)
|
|
||||||
}
|
|
||||||
|
|
||||||
resolve(response)
|
resolve(response)
|
||||||
})
|
})
|
||||||
.catch((error) => {
|
.catch((error) => {
|
||||||
|
|||||||
-7
@@ -80,9 +80,6 @@ const mutations = {
|
|||||||
SET_PERMISSION(state, role) {
|
SET_PERMISSION(state, role) {
|
||||||
state.permission = role
|
state.permission = role
|
||||||
},
|
},
|
||||||
SET_AUTHORIZED(state, data) {
|
|
||||||
state.authorized = data
|
|
||||||
},
|
|
||||||
DESTROY_DATA(state) {
|
DESTROY_DATA(state) {
|
||||||
state.authorized = false
|
state.authorized = false
|
||||||
state.app = undefined
|
state.app = undefined
|
||||||
@@ -101,16 +98,12 @@ const mutations = {
|
|||||||
state.app.user.avatar = avatar
|
state.app.user.avatar = avatar
|
||||||
},
|
},
|
||||||
UPDATE_RECENT_UPLOAD(state, file) {
|
UPDATE_RECENT_UPLOAD(state, file) {
|
||||||
|
|
||||||
// Remove last file from altest uploads
|
// Remove last file from altest uploads
|
||||||
if (state.app.latest_uploads.length === 7) state.app.latest_uploads.pop()
|
if (state.app.latest_uploads.length === 7) state.app.latest_uploads.pop()
|
||||||
|
|
||||||
// Add new file to latest uploads
|
// Add new file to latest uploads
|
||||||
state.app.latest_uploads.unshift(file)
|
state.app.latest_uploads.unshift(file)
|
||||||
},
|
},
|
||||||
REMOVE_ITEM_FROM_RECENT_UPLOAD(state, unique_id) {
|
|
||||||
state.app.latest_uploads = state.app.latest_uploads.filter(file => file.unique_id !== unique_id)
|
|
||||||
},
|
|
||||||
REMOVE_ITEM_FROM_FAVOURITES(state, item) {
|
REMOVE_ITEM_FROM_FAVOURITES(state, item) {
|
||||||
state.app.favourites = state.app.favourites.filter(folder => folder.unique_id !== item.unique_id)
|
state.app.favourites = state.app.favourites.filter(folder => folder.unique_id !== item.unique_id)
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -171,7 +171,6 @@
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped lang="scss">
|
<style scoped lang="scss">
|
||||||
@import "@assets/app.scss";
|
@import '@assets/vue-file-manager/_auth-form';
|
||||||
@import '@assets/vue-file-manager/_forms';
|
|
||||||
@import '@assets/vue-file-manager/_auth';
|
@import '@assets/vue-file-manager/_auth';
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
@@ -122,7 +122,6 @@
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped lang="scss">
|
<style scoped lang="scss">
|
||||||
@import "@assets/app.scss";
|
@import '@assets/vue-file-manager/_auth-form';
|
||||||
@import '@assets/vue-file-manager/_forms';
|
|
||||||
@import '@assets/vue-file-manager/_auth';
|
@import '@assets/vue-file-manager/_auth';
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
@@ -208,7 +208,6 @@
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped lang="scss">
|
<style scoped lang="scss">
|
||||||
@import "@assets/app.scss";
|
@import '@assets/vue-file-manager/_auth-form';
|
||||||
@import '@assets/vue-file-manager/_forms';
|
|
||||||
@import '@assets/vue-file-manager/_auth';
|
@import '@assets/vue-file-manager/_auth';
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
@@ -172,7 +172,6 @@
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped lang="scss">
|
<style scoped lang="scss">
|
||||||
@import "@assets/app.scss";
|
@import '@assets/vue-file-manager/_auth-form';
|
||||||
@import '@assets/vue-file-manager/_forms';
|
|
||||||
@import '@assets/vue-file-manager/_auth';
|
@import '@assets/vue-file-manager/_auth';
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
@@ -0,0 +1,206 @@
|
|||||||
|
<template>
|
||||||
|
<section id="viewport" v-if="app">
|
||||||
|
|
||||||
|
<ContentSidebar>
|
||||||
|
|
||||||
|
<!--Locations-->
|
||||||
|
<ContentGroup :title="$t('sidebar.locations_title')">
|
||||||
|
<div class="menu-list-wrapper">
|
||||||
|
<a class="menu-list-item link" :class="{'is-active': $isThisLocation(['base'])}" @click="goHome">
|
||||||
|
<div class="icon">
|
||||||
|
<home-icon size="17"></home-icon>
|
||||||
|
</div>
|
||||||
|
<div class="label">
|
||||||
|
{{ $t('sidebar.home') }}
|
||||||
|
</div>
|
||||||
|
</a>
|
||||||
|
<a class="menu-list-item link" :class="{'is-active': $isThisLocation(['latest'])}"
|
||||||
|
@click="getLatest">
|
||||||
|
<div class="icon">
|
||||||
|
<upload-cloud-icon size="17"></upload-cloud-icon>
|
||||||
|
</div>
|
||||||
|
<div class="label">
|
||||||
|
{{ $t('sidebar.latest') }}
|
||||||
|
</div>
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
</ContentGroup>
|
||||||
|
|
||||||
|
<!--Navigator-->
|
||||||
|
<ContentGroup :title="$t('sidebar.navigator_title')" class="navigator">
|
||||||
|
<span class="empty-note navigator" v-if="app.tree.length == 0">
|
||||||
|
{{ $t('sidebar.folders_empty') }}
|
||||||
|
</span>
|
||||||
|
<TreeMenuNavigator class="folder-tree" :depth="0" :nodes="items" v-for="items in app.tree"
|
||||||
|
:key="items.unique_id"/>
|
||||||
|
</ContentGroup>
|
||||||
|
|
||||||
|
<!--Favourites-->
|
||||||
|
<ContentGroup :title="$t('sidebar.favourites')">
|
||||||
|
|
||||||
|
<div class="menu-list-wrapper favourites"
|
||||||
|
:class="{ 'is-dragenter': area }"
|
||||||
|
@dragover.prevent="dragEnter"
|
||||||
|
@dragleave="dragLeave"
|
||||||
|
@drop="dragFinish($event)"
|
||||||
|
>
|
||||||
|
<transition-group tag="div" class="menu-list" name="folder-item">
|
||||||
|
<span class="empty-note favourites" v-if="app.favourites.length == 0" :key="0">
|
||||||
|
{{ $t('sidebar.favourites_empty') }}
|
||||||
|
</span>
|
||||||
|
|
||||||
|
<a @click.stop="openFolder(folder)"
|
||||||
|
class="menu-list-item"
|
||||||
|
:class="{'is-current': (folder && currentFolder) && (currentFolder.unique_id === folder.unique_id)}"
|
||||||
|
v-for="folder in app.favourites"
|
||||||
|
:key="folder.unique_id">
|
||||||
|
<div>
|
||||||
|
<folder-icon size="17" class="folder-icon"></folder-icon>
|
||||||
|
<span class="label">{{ folder.name }}</span>
|
||||||
|
</div>
|
||||||
|
<x-icon size="17" @click.stop="removeFavourite(folder)" class="delete-icon"></x-icon>
|
||||||
|
</a>
|
||||||
|
</transition-group>
|
||||||
|
</div>
|
||||||
|
</ContentGroup>
|
||||||
|
</ContentSidebar>
|
||||||
|
|
||||||
|
<ContentFileView/>
|
||||||
|
</section>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import TreeMenuNavigator from '@/components/Others/TreeMenuNavigator'
|
||||||
|
import ContentFileView from '@/components/Others/ContentFileView'
|
||||||
|
import ContentSidebar from '@/components/Sidebar/ContentSidebar'
|
||||||
|
import ContentGroup from '@/components/Sidebar/ContentGroup'
|
||||||
|
import {mapGetters} from 'vuex'
|
||||||
|
import {events} from '@/bus'
|
||||||
|
import {
|
||||||
|
UploadCloudIcon,
|
||||||
|
FolderIcon,
|
||||||
|
HomeIcon,
|
||||||
|
XIcon,
|
||||||
|
} from 'vue-feather-icons'
|
||||||
|
|
||||||
|
export default {
|
||||||
|
name: 'FilesView',
|
||||||
|
components: {
|
||||||
|
TreeMenuNavigator,
|
||||||
|
ContentFileView,
|
||||||
|
ContentSidebar,
|
||||||
|
UploadCloudIcon,
|
||||||
|
ContentGroup,
|
||||||
|
FolderIcon,
|
||||||
|
HomeIcon,
|
||||||
|
XIcon,
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
...mapGetters(['app', 'homeDirectory', 'currentFolder']),
|
||||||
|
},
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
area: false,
|
||||||
|
draggedItem: undefined,
|
||||||
|
}
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
getLatest() {
|
||||||
|
this.$store.dispatch('getLatest')
|
||||||
|
},
|
||||||
|
goHome() {
|
||||||
|
this.$store.dispatch('getFolder', [{folder: this.homeDirectory, back: false, init: true}])
|
||||||
|
},
|
||||||
|
openFolder(folder) {
|
||||||
|
this.$store.dispatch('getFolder', [{folder: folder, back: false, init: false}])
|
||||||
|
},
|
||||||
|
dragEnter() {
|
||||||
|
if (this.draggedItem && this.draggedItem.type !== 'folder') return
|
||||||
|
|
||||||
|
this.area = true
|
||||||
|
},
|
||||||
|
dragLeave() {
|
||||||
|
this.area = false
|
||||||
|
},
|
||||||
|
dragFinish() {
|
||||||
|
this.area = false
|
||||||
|
|
||||||
|
// Check if draged item is folder
|
||||||
|
if (this.draggedItem && this.draggedItem.type !== 'folder') return
|
||||||
|
|
||||||
|
// Check if folder exist in favourites
|
||||||
|
if (this.app.favourites.find(folder => folder.unique_id == this.draggedItem.unique_id)) return
|
||||||
|
|
||||||
|
// Store favourites folder
|
||||||
|
this.$store.dispatch('addToFavourites', this.draggedItem)
|
||||||
|
|
||||||
|
},
|
||||||
|
removeFavourite(folder) {
|
||||||
|
this.$store.dispatch('removeFromFavourites', folder)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
created() {
|
||||||
|
this.goHome()
|
||||||
|
|
||||||
|
// Listen for dragstart folder items
|
||||||
|
events.$on('dragstart', (item) => this.draggedItem = item)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
|
||||||
|
.empty-note {
|
||||||
|
|
||||||
|
&.navigator {
|
||||||
|
padding: 5px 25px 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
&.favourites {
|
||||||
|
padding: 5px 23px 10px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.navigator {
|
||||||
|
width: 100%;
|
||||||
|
overflow-x: auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
@media only screen and (max-width: 1024px) {
|
||||||
|
|
||||||
|
.empty-note {
|
||||||
|
|
||||||
|
&.navigator {
|
||||||
|
padding: 5px 20px 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
&.favourites {
|
||||||
|
padding: 5px 18px 10px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Transition
|
||||||
|
.folder-item-move {
|
||||||
|
transition: transform 300s ease;
|
||||||
|
}
|
||||||
|
|
||||||
|
.folder-item-enter-active {
|
||||||
|
transition: all 300ms ease;
|
||||||
|
}
|
||||||
|
|
||||||
|
.folder-item-leave-active {
|
||||||
|
transition: all 300ms;
|
||||||
|
}
|
||||||
|
|
||||||
|
.folder-item-enter, .folder-item-leave-to /* .list-leave-active below version 2.1.8 */
|
||||||
|
{
|
||||||
|
opacity: 0;
|
||||||
|
transform: translateX(30px);
|
||||||
|
}
|
||||||
|
|
||||||
|
.folder-item-leave-active {
|
||||||
|
position: absolute;
|
||||||
|
}
|
||||||
|
|
||||||
|
</style>
|
||||||
@@ -0,0 +1,67 @@
|
|||||||
|
<template>
|
||||||
|
<section id="viewport">
|
||||||
|
|
||||||
|
<ContentSidebar>
|
||||||
|
|
||||||
|
<!--Navigator-->
|
||||||
|
<ContentGroup :title="$t('sidebar.locations_title')">
|
||||||
|
<div class="menu-list-wrapper">
|
||||||
|
<li class="menu-list-item link" :class="{'is-active': $isThisLocation(['shared'])}" @click="getShared()">
|
||||||
|
<div class="icon">
|
||||||
|
<link-icon size="17"></link-icon>
|
||||||
|
</div>
|
||||||
|
<div class="label">
|
||||||
|
{{ $t('sidebar.my_shared') }}
|
||||||
|
</div>
|
||||||
|
</li>
|
||||||
|
<li class="menu-list-item link" :class="{'is-active': $isThisLocation(['participant_uploads'])}" @click="getParticipantUploads()">
|
||||||
|
<div class="icon">
|
||||||
|
<users-icon size="17"></users-icon>
|
||||||
|
</div>
|
||||||
|
<div class="label">
|
||||||
|
{{ $t('sidebar.participant_uploads') }}
|
||||||
|
</div>
|
||||||
|
</li>
|
||||||
|
</div>
|
||||||
|
</ContentGroup>
|
||||||
|
|
||||||
|
</ContentSidebar>
|
||||||
|
|
||||||
|
<ContentFileView />
|
||||||
|
</section>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import ContentFileView from '@/components/Others/ContentFileView'
|
||||||
|
import ContentSidebar from '@/components/Sidebar/ContentSidebar'
|
||||||
|
import ContentGroup from '@/components/Sidebar/ContentGroup'
|
||||||
|
import {
|
||||||
|
LinkIcon,
|
||||||
|
UsersIcon,
|
||||||
|
} from 'vue-feather-icons'
|
||||||
|
|
||||||
|
export default {
|
||||||
|
name: 'FilesView',
|
||||||
|
components: {
|
||||||
|
ContentFileView,
|
||||||
|
ContentSidebar,
|
||||||
|
ContentGroup,
|
||||||
|
LinkIcon,
|
||||||
|
UsersIcon,
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
getShared() {
|
||||||
|
this.$store.dispatch('getShared', [{back: false, init: false}])
|
||||||
|
},
|
||||||
|
getParticipantUploads() {
|
||||||
|
this.$store.dispatch('getParticipantUploads')
|
||||||
|
},
|
||||||
|
},
|
||||||
|
mounted() {
|
||||||
|
this.getShared()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
</style>
|
||||||
@@ -0,0 +1,51 @@
|
|||||||
|
<template>
|
||||||
|
<section id="viewport">
|
||||||
|
<ContentSidebar>
|
||||||
|
|
||||||
|
<!--Tools-->
|
||||||
|
<ContentGroup :title="$t('sidebar.tools_title')" class="navigator">
|
||||||
|
<div class="menu-list-wrapper">
|
||||||
|
<div class="menu-list-item link" @click="emptyTrash()">
|
||||||
|
<div class="icon">
|
||||||
|
<trash-icon size="17"></trash-icon>
|
||||||
|
</div>
|
||||||
|
<div class="label">
|
||||||
|
{{ $t('context_menu.empty_trash') }}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</ContentGroup>
|
||||||
|
</ContentSidebar>
|
||||||
|
<ContentFileView/>
|
||||||
|
</section>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import ContentFileView from '@/components/Others/ContentFileView'
|
||||||
|
import ContentSidebar from '@/components/Sidebar/ContentSidebar'
|
||||||
|
import ContentGroup from '@/components/Sidebar/ContentGroup'
|
||||||
|
import {
|
||||||
|
TrashIcon,
|
||||||
|
} from 'vue-feather-icons'
|
||||||
|
|
||||||
|
export default {
|
||||||
|
name: 'FilesView',
|
||||||
|
components: {
|
||||||
|
ContentFileView,
|
||||||
|
ContentSidebar,
|
||||||
|
ContentGroup,
|
||||||
|
TrashIcon,
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
emptyTrash() {
|
||||||
|
this.$store.dispatch('emptyTrash')
|
||||||
|
},
|
||||||
|
},
|
||||||
|
created() {
|
||||||
|
this.$store.dispatch('getTrash')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
</style>
|
||||||
@@ -1,253 +0,0 @@
|
|||||||
<template>
|
|
||||||
<div @click="fileViewClick" @contextmenu.prevent.capture="contextMenu($event, undefined)" id="files-view" :class="filesViewWidth">
|
|
||||||
<ContextMenu />
|
|
||||||
<DesktopToolbar />
|
|
||||||
<FileBrowser />
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script>
|
|
||||||
import DesktopToolbar from '@/components/FilesView/DesktopToolbar'
|
|
||||||
import FileBrowser from '@/components/FilesView/FileBrowser'
|
|
||||||
import ContextMenu from '@/components/FilesView/ContextMenu'
|
|
||||||
import {ResizeSensor} from 'css-element-queries'
|
|
||||||
import {mapGetters} from 'vuex'
|
|
||||||
import {events} from '@/bus'
|
|
||||||
|
|
||||||
export default {
|
|
||||||
name: 'FilesView',
|
|
||||||
components: {
|
|
||||||
DesktopToolbar,
|
|
||||||
FileBrowser,
|
|
||||||
ContextMenu,
|
|
||||||
},
|
|
||||||
computed: {
|
|
||||||
...mapGetters(['config', 'filesViewWidth']),
|
|
||||||
},
|
|
||||||
methods: {
|
|
||||||
fileViewClick() {
|
|
||||||
events.$emit('contextMenu:hide')
|
|
||||||
},
|
|
||||||
contextMenu(event, item) {
|
|
||||||
events.$emit('contextMenu:show', event, item)
|
|
||||||
},
|
|
||||||
handleContentResize() {
|
|
||||||
let filesView = document.getElementById('files-view')
|
|
||||||
.clientWidth
|
|
||||||
|
|
||||||
if (filesView >= 0 && filesView <= 690)
|
|
||||||
this.$store.commit('SET_FILES_VIEW_SIZE', 'minimal-scale')
|
|
||||||
|
|
||||||
else if (filesView >= 690 && filesView <= 960)
|
|
||||||
this.$store.commit('SET_FILES_VIEW_SIZE', 'compact-scale')
|
|
||||||
|
|
||||||
else if (filesView >= 960)
|
|
||||||
this.$store.commit('SET_FILES_VIEW_SIZE', 'full-scale')
|
|
||||||
},
|
|
||||||
},
|
|
||||||
mounted() {
|
|
||||||
|
|
||||||
let homeDirectory = {
|
|
||||||
name: this.$t('locations.home'),
|
|
||||||
location: 'base',
|
|
||||||
unique_id: 0,
|
|
||||||
}
|
|
||||||
|
|
||||||
// Set start directory
|
|
||||||
this.$store.commit('SET_START_DIRECTORY', homeDirectory)
|
|
||||||
|
|
||||||
// Load folder
|
|
||||||
this.$store.dispatch('getFolder', [homeDirectory, false, true])
|
|
||||||
|
|
||||||
var filesView = document.getElementById('files-view');
|
|
||||||
new ResizeSensor(filesView, this.handleContentResize);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<style lang="scss">
|
|
||||||
@import "@assets/app.scss";
|
|
||||||
|
|
||||||
#files-view {
|
|
||||||
font-family: 'Nunito', sans-serif;
|
|
||||||
font-size: 16px;
|
|
||||||
//overflow: hidden;
|
|
||||||
width: 100%;
|
|
||||||
height: 100%;
|
|
||||||
position: relative;
|
|
||||||
min-width: 320px;
|
|
||||||
overflow-x: hidden;
|
|
||||||
|
|
||||||
&.minimal-scale {
|
|
||||||
padding: 0;
|
|
||||||
|
|
||||||
.mobile-toolbar {
|
|
||||||
padding: 10px 0 5px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.popup-wrapper {
|
|
||||||
left: 15px;
|
|
||||||
right: 15px;
|
|
||||||
padding: 25px 15px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.toolbar {
|
|
||||||
display: block;
|
|
||||||
position: sticky;
|
|
||||||
top: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.toolbar-go-back {
|
|
||||||
padding-top: 15px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.toolbar-tools {
|
|
||||||
text-align: left;
|
|
||||||
display: flex;
|
|
||||||
|
|
||||||
.toolbar-button-wrapper {
|
|
||||||
width: 100%;
|
|
||||||
|
|
||||||
&:last-child {
|
|
||||||
text-align: right;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.files-container {
|
|
||||||
padding-left: 15px;
|
|
||||||
padding-right: 15px;
|
|
||||||
top: 0;
|
|
||||||
left: 0;
|
|
||||||
right: 0;
|
|
||||||
bottom: 0;
|
|
||||||
position: absolute;
|
|
||||||
overflow-y: auto;
|
|
||||||
|
|
||||||
.file-list {
|
|
||||||
//height: 100%;
|
|
||||||
|
|
||||||
&.grid {
|
|
||||||
grid-template-columns: repeat(auto-fill, 120px);
|
|
||||||
|
|
||||||
.file-wrapper {
|
|
||||||
|
|
||||||
.file-item {
|
|
||||||
width: 120px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.icon-item {
|
|
||||||
margin-bottom: 10px;
|
|
||||||
height: 90px;
|
|
||||||
|
|
||||||
.file-icon {
|
|
||||||
@include font-size(75);
|
|
||||||
}
|
|
||||||
|
|
||||||
.file-icon-text {
|
|
||||||
@include font-size(12);
|
|
||||||
}
|
|
||||||
|
|
||||||
.folder-icon {
|
|
||||||
@include font-size(75);
|
|
||||||
margin-top: 0;
|
|
||||||
margin-bottom: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.image {
|
|
||||||
width: 90px;
|
|
||||||
height: 90px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.item-name .name {
|
|
||||||
@include font-size(13);
|
|
||||||
line-height: 1.2;
|
|
||||||
max-height: 30px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.file-wrapper {
|
|
||||||
.item-name .name {
|
|
||||||
max-width: 220px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.search-bar {
|
|
||||||
|
|
||||||
input {
|
|
||||||
min-width: initial;
|
|
||||||
width: 100%;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.item-shared {
|
|
||||||
.label {
|
|
||||||
display: none;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
&.compact-scale {
|
|
||||||
padding-left: 15px;
|
|
||||||
padding-right: 15px;
|
|
||||||
|
|
||||||
.file-content {
|
|
||||||
position: absolute;
|
|
||||||
top: 72px;
|
|
||||||
left: 15px;
|
|
||||||
right: 15px;
|
|
||||||
bottom: 0;
|
|
||||||
@include transition;
|
|
||||||
|
|
||||||
&.is-offset {
|
|
||||||
margin-top: 50px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.toolbar-tools {
|
|
||||||
|
|
||||||
.toolbar-button-wrapper {
|
|
||||||
margin-left: 35px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.search-bar input {
|
|
||||||
min-width: 190px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.toolbar-go-back span {
|
|
||||||
max-width: 120px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.grid .file-wrapper {
|
|
||||||
|
|
||||||
.icon-item {
|
|
||||||
margin-bottom: 15px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
&.full-scale {
|
|
||||||
padding-left: 15px;
|
|
||||||
padding-right: 15px;
|
|
||||||
|
|
||||||
.file-content {
|
|
||||||
position: absolute;
|
|
||||||
top: 72px;
|
|
||||||
left: 15px;
|
|
||||||
right: 15px;
|
|
||||||
bottom: 0;
|
|
||||||
@include transition;
|
|
||||||
|
|
||||||
&.is-offset {
|
|
||||||
margin-top: 50px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
</style>
|
|
||||||
@@ -0,0 +1,110 @@
|
|||||||
|
<template>
|
||||||
|
<div class="page">
|
||||||
|
|
||||||
|
<MobileHeader />
|
||||||
|
|
||||||
|
<nav class="mobile-navigation">
|
||||||
|
|
||||||
|
<!--Navigation-->
|
||||||
|
<MenuItemList :navigation="navigation" />
|
||||||
|
</nav>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import MenuItemList from '@/components/Mobile/MenuItemList'
|
||||||
|
import MobileHeader from '@/components/Mobile/MobileHeader'
|
||||||
|
import { mapGetters } from 'vuex'
|
||||||
|
|
||||||
|
export default {
|
||||||
|
name: 'MobileSettings',
|
||||||
|
components: {
|
||||||
|
MenuItemList,
|
||||||
|
MobileHeader,
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
...mapGetters(['config']),
|
||||||
|
},
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
navigation: undefined
|
||||||
|
}
|
||||||
|
},
|
||||||
|
created() {
|
||||||
|
|
||||||
|
this.navigation = [
|
||||||
|
{
|
||||||
|
icon: 'user',
|
||||||
|
title: this.$t('menu.profile'),
|
||||||
|
routeName: 'Profile',
|
||||||
|
isVisible: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
icon: 'lock',
|
||||||
|
title: this.$t('menu.password'),
|
||||||
|
routeName: 'Password',
|
||||||
|
isVisible: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
icon: 'hard-drive',
|
||||||
|
title: this.$t('menu.storage'),
|
||||||
|
routeName: 'Storage',
|
||||||
|
isVisible: this.config.storageLimit,
|
||||||
|
},
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped lang="scss">
|
||||||
|
@import '@assets/vue-file-manager/_variables';
|
||||||
|
@import '@assets/vue-file-manager/_mixins';
|
||||||
|
|
||||||
|
.page {
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.mobile-navigation {
|
||||||
|
padding: 0 20px;
|
||||||
|
width: 100%;
|
||||||
|
bottom: 0;
|
||||||
|
left: 0;
|
||||||
|
right: 0;
|
||||||
|
z-index: 99;
|
||||||
|
}
|
||||||
|
|
||||||
|
@media only screen and (max-width: 690px) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (prefers-color-scheme: dark) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// Transition
|
||||||
|
.context-menu-enter-active,
|
||||||
|
.fade-enter-active {
|
||||||
|
transition: all 200ms;
|
||||||
|
}
|
||||||
|
|
||||||
|
.context-menu-leave-active,
|
||||||
|
.fade-leave-active {
|
||||||
|
transition: all 200ms;
|
||||||
|
}
|
||||||
|
|
||||||
|
.fade-enter,
|
||||||
|
.fade-leave-to {
|
||||||
|
opacity: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.context-menu-enter,
|
||||||
|
.context-menu-leave-to {
|
||||||
|
opacity: 0;
|
||||||
|
transform: translateY(100%);
|
||||||
|
}
|
||||||
|
|
||||||
|
.context-menu-leave-active {
|
||||||
|
position: absolute;
|
||||||
|
}
|
||||||
|
|
||||||
|
</style>
|
||||||
@@ -0,0 +1,76 @@
|
|||||||
|
<template>
|
||||||
|
<section id="viewport">
|
||||||
|
|
||||||
|
<ContentSidebar>
|
||||||
|
|
||||||
|
<!--User Headline-->
|
||||||
|
<UserHeadline class="user-headline"/>
|
||||||
|
|
||||||
|
<!--Locations-->
|
||||||
|
<ContentGroup title="Menu" class="navigator">
|
||||||
|
<div class="menu-list-wrapper">
|
||||||
|
<router-link :to="{name: 'Profile'}" class="menu-list-item link">
|
||||||
|
<div class="icon">
|
||||||
|
<user-icon size="17"></user-icon>
|
||||||
|
</div>
|
||||||
|
<div class="label">
|
||||||
|
{{ $t('menu.profile') }}
|
||||||
|
</div>
|
||||||
|
</router-link>
|
||||||
|
<router-link :to="{name: 'Password'}" class="menu-list-item link">
|
||||||
|
<div class="icon">
|
||||||
|
<lock-icon size="17"></lock-icon>
|
||||||
|
</div>
|
||||||
|
<div class="label">
|
||||||
|
{{ $t('menu.password') }}
|
||||||
|
</div>
|
||||||
|
</router-link>
|
||||||
|
<router-link v-if="config.storageLimit" :to="{name: 'Storage'}" class="menu-list-item link">
|
||||||
|
<div class="icon">
|
||||||
|
<hard-drive-icon size="17"></hard-drive-icon>
|
||||||
|
</div>
|
||||||
|
<div class="label">
|
||||||
|
{{ $t('menu.storage') }}
|
||||||
|
</div>
|
||||||
|
</router-link>
|
||||||
|
</div>
|
||||||
|
</ContentGroup>
|
||||||
|
</ContentSidebar>
|
||||||
|
|
||||||
|
<router-view/>
|
||||||
|
</section>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import ContentSidebar from '@/components/Sidebar/ContentSidebar'
|
||||||
|
import ContentGroup from '@/components/Sidebar/ContentGroup'
|
||||||
|
import UserHeadline from '@/components/Sidebar/UserHeadline'
|
||||||
|
import { mapGetters } from 'vuex'
|
||||||
|
import {
|
||||||
|
HardDriveIcon,
|
||||||
|
UserIcon,
|
||||||
|
LockIcon,
|
||||||
|
} from 'vue-feather-icons'
|
||||||
|
|
||||||
|
export default {
|
||||||
|
name: 'Settings',
|
||||||
|
computed: {
|
||||||
|
...mapGetters(['config']),
|
||||||
|
},
|
||||||
|
components: {
|
||||||
|
ContentSidebar,
|
||||||
|
HardDriveIcon,
|
||||||
|
UserHeadline,
|
||||||
|
ContentGroup,
|
||||||
|
UserIcon,
|
||||||
|
LockIcon,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
|
||||||
|
.user-headline {
|
||||||
|
margin-bottom: 38px;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
@@ -47,7 +47,5 @@
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped lang="scss">
|
<style scoped lang="scss">
|
||||||
@import "@assets/app.scss";
|
|
||||||
@import '@assets/vue-file-manager/_forms';
|
|
||||||
@import '@assets/vue-file-manager/_auth';
|
@import '@assets/vue-file-manager/_auth';
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user