first upload all files

This commit is contained in:
NW
2023-06-11 13:14:03 +01:00
parent f14dbc52b5
commit c08b36d1b6
1705 changed files with 106852 additions and 0 deletions

View File

@@ -0,0 +1,79 @@
import MediaPicker from './MediaPicker';
export default class {
constructor() {
$('.image-picker').on('click', (e) => {
this.pickImage(e);
});
this.sortable();
this.removeImageEventListener();
}
pickImage(e) {
let inputName = e.currentTarget.dataset.inputName;
let multiple = e.currentTarget.hasAttribute('data-multiple');
let picker = new MediaPicker({ type: 'image', multiple });
picker.on('select', (file) => {
this.addImage(inputName, file, multiple, e.currentTarget);
});
}
addImage(inputName, file, multiple, target) {
let html = this.getTemplate(inputName, file);
if (multiple) {
let multipleImagesWrapper = $(target).next('.multiple-images');
multipleImagesWrapper.find('.image-holder.placeholder').remove();
multipleImagesWrapper.find('.image-list').append(html);
} else {
$(target).siblings('.single-image').html(html);
}
}
getTemplate(inputName, file) {
return $(`
<div class="image-holder">
<img src="${file.path}">
<button type="button" class="btn remove-image"></button>
<input type="hidden" name="${inputName}" value="${file.id}">
</div>
`);
}
sortable() {
let imageList = $('.image-list');
if (imageList.length > 0) {
Sortable.create(imageList[0], { animation: 150 });
}
}
removeImageEventListener() {
$('.image-holder-wrapper').on('click', '.remove-image', (e) => {
e.preventDefault();
let imageHolderWrapper = $(e.currentTarget).closest('.image-holder-wrapper');
if (imageHolderWrapper.find('.image-holder').length === 1) {
imageHolderWrapper.html(
this.getImagePlaceholder(e.currentTarget.dataset.inputName)
);
}
$(e.currentTarget).parent().remove();
});
}
getImagePlaceholder(inputName) {
return `
<div class="image-holder placeholder cursor-auto">
<i class="fa fa-picture-o"></i>
<input type="hidden" name="${inputName}">
</div>
`;
}
}

View File

@@ -0,0 +1,120 @@
import '../sass/media-picker.scss';
export default class {
constructor(options) {
this.options = _.merge({
type: null,
multiple: false,
route: 'admin.file_manager.index',
title: trans('media::media.file_manager.title'),
message: trans('media::messages.image_has_been_added'),
}, options);
this.events = {};
this.frame = this.getFrame();
this.appendModalToBody();
this.openFrame();
}
on(event, handler) {
this.events[event] = handler;
}
getFrame() {
let src = route(this.options.route, {
type: this.options.type,
multiple: this.options.multiple,
});
return $(`<iframe class="file-manager-iframe" frameborder="0" src="${src}"></iframe>`);
}
appendModalToBody() {
if ($('.media-picker-modal').length === 1) {
return;
}
$('body').append(this.getModal());
}
openFrame() {
this.showModal();
this.frame.on('load', () => {
this.selectMedia();
});
}
showModal() {
let modal = $('.media-picker-modal').modal('show');
this.setFrameHeight();
this.setModalTitle(modal);
this.setModalBody(modal);
this.closeModalOnEsc(modal);
}
setFrameHeight() {
this.frame.css('height', window.innerHeight * 0.8);
}
setModalTitle(modal) {
modal.find('.modal-title').text(this.options.title);
}
setModalBody(modal) {
modal.find('.modal-body').html(this.frame);
}
closeModalOnEsc(modal) {
$(document).on('keydown', (e) => {
if (e.keyCode === 27) {
modal.modal('hide');
}
});
this.frame.on('load keydown', () => {
this.frame.contents().on('keydown', (e) => {
if (e.keyCode === 27) {
modal.modal('hide');
}
});
});
}
selectMedia() {
this.frame.contents().find('.table').on('click', '.select-media', (e) => {
e.preventDefault();
this.events['select'](e.currentTarget.dataset);
if (this.options.multiple) {
if (this.options.message) {
notify('success', this.options.message, { context: this.frame.contents() });
}
} else {
$('.media-picker-modal').modal('hide');
}
});
}
getModal() {
return `
<div class="media-picker-modal modal fade" role="dialog">
<div class="modal-dialog clearfix">
<div class="modal-content col-md-10 col-sm-11 clearfix">
<div class="row">
<div class="modal-header">
<a type="button" class="close" data-dismiss="modal">&times;</a>
<h4 class="modal-title"></h4>
</div>
<div class="modal-body"></div>
</div>
</div>
</div>
</div>
`;
}
}

View File

@@ -0,0 +1,34 @@
import Dropzone from 'dropzone';
export default class {
constructor() {
Dropzone.autoDiscover = false;
this.dropzone = new Dropzone('.dropzone', {
url: route('admin.media.store'),
autoProcessQueue: true,
maxFilesize: FleetCart.maxFileSize,
});
this.dropzone.on('sending', this.sending);
this.dropzone.on('success', this.success);
this.dropzone.on('error', this.error);
}
sending(file, xhr) {
xhr.timeout = 3600000;
$('.alert-danger').remove();
}
success() {
if (this.getUploadingFiles().length === 0 && this.getQueuedFiles().length === 0) {
setTimeout(DataTable.reload, 1000, '#media-table .table');
}
}
error(file, response) {
$('.dz-progress').css('z-index', 1);
$(file.previewElement).find('.dz-error-message').text(response.message);
}
}

View File

@@ -0,0 +1,13 @@
import ImagePicker from './ImagePicker';
import MediaPicker from './MediaPicker';
import Uploader from './Uploader';
window.MediaPicker = MediaPicker;
if ($('.image-picker').length !== 0) {
new ImagePicker();
}
if ($('.dropzone').length !== 0) {
new Uploader();
}

View File

@@ -0,0 +1,161 @@
@import '~dropzone/dist/dropzone';
.dropzone {
border: 1px dashed #d2d6de;
min-height: 232px;
margin-bottom: 20px;
&.dz-clickable {
border-radius: 3px;
}
.dz-message {
color: #646C7F;
font-size: 20px;
margin-top: 82px;
}
.dz-preview .dz-progress .dz-upload {
background: #0068e1;
}
}
.file-icon {
font-size: 20px;
}
.main-file {
width: 100%;
}
.file-thumbnail {
float: left;
margin-right: 10px;
> .thumbnail-name {
text-align: center;
}
}
.media-picker-divider {
border-bottom: 1px solid #e9e9e9;
margin-bottom: 20px;
}
.single-image-wrapper {
padding-bottom: 20px;
h4 {
font-weight: 500;
margin-bottom: 10px;
}
}
.single-image {
padding: 10px;
background: #f1f1f1;
margin-top: 15px;
display: inline-block;
border-radius: 3px;
vertical-align: bottom;
> .image-holder {
cursor: default;
margin: 0;
border-radius: 3px;
}
}
.multiple-images-wrapper {
margin-top: 15px;
h4 {
font-weight: 500;
margin-bottom: 10px;
}
}
.multiple-images {
overflow: hidden;
padding: 10px 10px 0 10px;
background: #f1f1f1;
margin-top: 15px;
border-radius: 3px;
}
.image-holder {
position: relative;
float: left;
height: 125px;
width: 125px;
overflow: hidden;
background: #fff;
margin: 0 10px 10px 0;
border: 1px solid #d2d6de;
border-radius: 3px;
cursor: move;
z-index: 0;
> i {
position: absolute;
font-size: 60px;
color: #d9d9d9;
top: 50%;
left: 50%;
transform: translate(-50%,-50%);
z-index: -1;
}
> img {
position: absolute;
left: 50%;
top: 50%;
max-height: 100%;
max-width: 100%;
transform: translate(-50%, -50%);
z-index: 1;
}
> .remove-image {
position: absolute;
top: -2px;
right: 4px;
color: #ffffff;
padding: 0;
background: transparent;
transition: 200ms;
visibility: hidden;
opacity: 0;
font-size: 18px;
font-family: 'FontAwesome';
-webkit-text-stroke: 1px #737881;
-moz-text-stroke: 1px #737881;
-ms-text-stroke: 1px #737881;
-o-text-stroke: 1px #737881;
z-index: 2;
&:focus {
border-color: transparent;
-webkit-box-shadow: none;
box-shadow: none;
}
&:active {
-webkit-box-shadow: none;
box-shadow: none;
}
&::after {
content: "\f00d";
}
}
&:hover > .remove-image {
visibility: visible;
opacity: 1;
}
}
.image-picker > i {
color: #737881;
}

View File

@@ -0,0 +1,78 @@
.file-manager-iframe {
width: 100%;
vertical-align: bottom;
}
.file-manager {
background: #f9f9f9;
margin-top: 20px;
overflow-x: auto;
#notification-toast {
bottom: 0;
}
.dataTable {
.btn {
padding: 10px 16px 8px;
> i {
margin-top: 5px;
}
}
}
}
.media-picker-modal {
padding-right: 0 !important;
z-index: 1050;
> i {
margin-right: 5px;
}
.modal-dialog {
width: auto;
margin: 25px auto;
}
.modal-content {
margin: auto;
float: none;
border: 1px solid #d2d6de;
border-radius: 3px;
}
.modal-header {
padding: 6px 15px;
background: #f1f1f1;
> .close {
margin-top: 5px;
-webkit-text-stroke: 0;
transition: 200ms;
}
}
.modal-body {
background: #f9f9f9;
padding: 15px 0;
}
.modal.fade .modal-dialog {
transform: scale(0.8);
opacity: 0;
transition: 200ms ease-in-out;
&.in .modal-dialog {
transform: scale(1);
opacity: 1;
}
}
}
@media screen and (max-width: 767px) {
.media-picker-modal .modal-dialog {
margin: 10px;
}
}

View File

@@ -0,0 +1,19 @@
<?php
return [
'media' => 'Media',
'drop_files_here' => 'Drop files here or click to upload',
'upload_new_file' => 'Upload New File',
'browse' => 'Browse',
'thumbnails' => 'Thumbnails',
'table' => [
'thumbnail' => 'Thumbnail',
'filename' => 'Filename',
'width' => 'Width',
'height' => 'Height',
],
'file_manager' => [
'title' => 'File Manager',
'select_this_file' => 'Select this file',
],
];

View File

@@ -0,0 +1,5 @@
<?php
return [
'image_has_been_added' => 'Image has been added.',
];

View File

@@ -0,0 +1,7 @@
<?php
return [
'index' => 'Index Media',
'create' => 'Create Media',
'destroy' => 'Delete Media',
];

View File

@@ -0,0 +1,61 @@
<!DOCTYPE html>
<html lang="{{ locale() }}">
<head>
<meta charset="UTF-8">
<title>{{ trans('media::media.file_manager.title') }}</title>
<meta content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no" name="viewport">
<link href="https://fonts.googleapis.com/css?family=Open+Sans:600|Roboto" rel="stylesheet">
@foreach ($assets->allCss() as $css)
<link media="all" type="text/css" rel="stylesheet" href="{{ v($css) }}">
@endforeach
@include('admin::partials.globals')
</head>
<body class="file-manager">
<div class="container">
@include('media::admin.media.partials.uploader')
<div class="row">
<div class="col-md-12">
<div class="box box-primary">
@include('media::admin.media.partials.table')
</div>
</div>
</div>
</div>
<div id="notification-toast"></div>
@include('admin::partials.confirmation_modal')
@foreach ($assets->allJs() as $js)
<script src="{{ v($js) }}"></script>
@endforeach
<script>
DataTable.setRoutes('.file-manager .table', {
index: {
name: 'admin.media.index',
params: { type: '{{ $type }}' }
},
destroy: 'admin.media.destroy',
});
new DataTable('.file-manager .table', {
columns: [
{ data: 'checkbox', orderable: false, searchable: false, width: '3%' },
{ data: 'id', width: '5%' },
{ data: 'thumbnail', orderable: false, searchable: false, width: '10%' },
{ data: 'filename', name: 'filename' },
{ data: 'created', name: 'created_at' },
{ data: 'action', orderable: false, searchable: false },
],
});
</script>
</body>
</html>

View File

@@ -0,0 +1,29 @@
<div class="multiple-images-wrapper">
<h4>{{ $title }}</h4>
<button type="button" class="image-picker btn btn-default" data-input-name="{{ $inputName }}" data-multiple>
<i class="fa fa-folder-open m-r-5"></i>{{ trans('media::media.browse') }}
</button>
<div class="multiple-images">
<div class="col-md-12">
<div class="row">
<div class="image-list image-holder-wrapper clearfix">
@if ($files->isEmpty())
<div class="image-holder placeholder cursor-auto">
<i class="fa fa-picture-o"></i>
</div>
@else
@foreach ($files as $file)
<div class="image-holder">
<img src="{{ $file->path }}">
<button type="button" class="btn remove-image" data-input-name="{{ $inputName }}"></button>
<input type="hidden" name="{{ $inputName }}" value="{{ $file->id }}">
</div>
@endforeach
@endif
</div>
</div>
</div>
</div>
</div>

View File

@@ -0,0 +1,25 @@
@hasAccess('admin.media.index')
<div class="single-image-wrapper">
<h4>{{ $title }}</h4>
<button type="button" class="image-picker btn btn-default" data-input-name="{{ $inputName }}">
<i class="fa fa-folder-open m-r-5"></i>{{ trans('media::media.browse') }}
</button>
<div class="clearfix"></div>
<div class="single-image image-holder-wrapper clearfix">
@if (! $file->exists)
<div class="image-holder placeholder">
<i class="fa fa-picture-o"></i>
</div>
@else
<div class="image-holder">
<img src="{{ $file->path }}">
<button type="button" class="btn remove-image" data-input-name="{{ $inputName }}"></button>
<input type="hidden" name="{{ $inputName }}" value="{{ $file->id }}">
</div>
@endif
</div>
</div>
@endHasAccess

View File

@@ -0,0 +1,51 @@
@extends('admin::layout')
@component('admin::components.page.header')
@slot('title', trans('media::media.media'))
<li class="active">{{ trans('media::media.media') }}</li>
@endcomponent
@section('content')
@include('media::admin.media.partials.uploader')
<div class="box box-primary">
<div class="box-header"></div>
@include('media::admin.media.partials.table')
</div>
@endsection
@push('shortcuts')
<dl class="dl-horizontal">
<dt><code>u</code></dt>
<dd>{{ trans('media::media.upload_new_file') }}</dd>
</dl>
@endpush
@push('scripts')
<script>
Mousetrap.bind('u', function() {
$('.dropzone').trigger('click');
});
Mousetrap.bind('del', function () {
$('.btn-delete').trigger('click');
});
DataTable.setRoutes('#media-table .table', {
index: 'admin.media.index',
destroy: 'admin.media.destroy',
});
new DataTable('#media-table .table', {
columns: [
{ data: 'checkbox', orderable: false, searchable: false, width: '3%' },
{ data: 'id', width: '5%' },
{ data: 'thumbnail', orderable: false, searchable: false, width: '10%' },
{ data: 'filename' },
{ data: 'created', name: 'created_at' },
],
});
</script>
@endpush

View File

@@ -0,0 +1,18 @@
<div class="box-body index-table" id="media-table">
@component('admin::components.table')
@slot('thead')
<tr>
@include('admin::partials.table.select_all')
<th data-sort>{{ trans('admin::admin.table.id') }}</th>
<th>{{ trans('media::media.table.thumbnail') }}</th>
<th>{{ trans('media::media.table.filename') }}</th>
<th data-sort>{{ trans('admin::admin.table.created') }}</th>
@unless (request()->routeIs('admin.media.index'))
<th class="min-tablet"></th>
@endif
</tr>
@endslot
@endcomponent
</div>

View File

@@ -0,0 +1,11 @@
<button type="button" class="btn btn-default select-media"
data-id="{{ $file->id }}"
data-path="{{ $file->path }}"
data-filename="{{ $file->filename }}"
data-type="{{ strtok($file->mime, '/') }}"
data-icon="{{ $file->icon() }}"
data-toggle="tooltip"
title="{{ trans('media::media.file_manager.select_this_file') }}"
>
<i class="fa fa-check-square-o"></i>
</button>

View File

@@ -0,0 +1,7 @@
<div class="thumbnail-holder">
@if ($file->isImage())
<img src="{{ $file->path }}" alt="thumbnail">
@else
<i class="file-icon fa {{ $file->icon() }}"></i>
@endif
</div>

View File

@@ -0,0 +1,17 @@
@push('globals')
<script>
FleetCart.maxFileSize = {{ (int) ini_get('upload_max_filesize') }}
</script>
@endpush
<div class="row">
<div class="col-md-12">
<form method="POST" class="dropzone">
{{ csrf_field() }}
<div class="dz-message needsclick">
{{ trans('media::media.drop_files_here') }}
</div>
</form>
</div>
</div>