#9: Started updating the "show album" page (easily the most complex in the application!) to use Bootstrap 4 and VueJS.
This commit is contained in:
parent
00328c7ba2
commit
8201f1df8b
@ -22961,3 +22961,131 @@ var Popover = function ($) {
|
||||
}(jQuery);
|
||||
|
||||
}();
|
||||
|
||||
/**
|
||||
* This model is used by admin/show_album.blade.php to handle photo uploads.
|
||||
* @param album_id ID of the album the photos are being uploaded to
|
||||
* @param queue_token Unique token of the upload queue to save the photos to
|
||||
* @param language Array containing language strings
|
||||
* @param urls Array containing URLs
|
||||
* @constructor
|
||||
*/
|
||||
function UploadPhotosViewModel(album_id, queue_token, language, urls) {
|
||||
this.el = '#upload-tab';
|
||||
this.data = {
|
||||
currentStatus: '',
|
||||
imagesFailed: 0,
|
||||
imagesTotal: 0,
|
||||
isBulkUploadInProgress: false,
|
||||
isUploadInProgress: false,
|
||||
statusMessages: []
|
||||
};
|
||||
this.computed = {
|
||||
// a computed getter
|
||||
failedPercentage: function () {
|
||||
return ((this.imagesFailed() / this.imagesTotal()) * 100).toFixed(2) + '%';
|
||||
},
|
||||
successfulPercentage: function () {
|
||||
return ((self.imagesUploaded() / self.imagesTotal()) * 100).toFixed(2) + '%';
|
||||
}
|
||||
};
|
||||
this.methods = {
|
||||
// This method is called when an image is uploaded - regardless if it fails or not
|
||||
onUploadCompleted: function () {
|
||||
this.currentStatus = language.upload_status
|
||||
.replace(':current', (self.imagesUploaded + self.imagesFailed))
|
||||
.replace(':total', self.imagesTotal);
|
||||
|
||||
if ((this.imagesFailed + this.imagesUploaded) >= this.imagesTotal) {
|
||||
this.isUploadInProgress = false;
|
||||
|
||||
if (this.imagesFailed == 0 && this.imagesUploaded > 0) {
|
||||
window.location = urls.analyse;
|
||||
}
|
||||
}
|
||||
},
|
||||
// This method is called when an uploaded image fails
|
||||
onUploadFailed: function (data, file_name) {
|
||||
this.imagesFailed++;
|
||||
this.statusMessages.push({
|
||||
'message_class': 'text-danger',
|
||||
'message_text': language.image_failed.replace(':file_name', file_name)
|
||||
});
|
||||
this.onUploadCompleted();
|
||||
},
|
||||
// This method is called when an uploaded image succeeds
|
||||
onUploadSuccessful: function (data, file_name) {
|
||||
if (data.is_successful) {
|
||||
self.imagesUploaded++;
|
||||
// Don't add to statusMessages() array so user only sees errors
|
||||
/*self.statusMessages.push({
|
||||
'message_class': 'text-success',
|
||||
'message_text': language.image_uploaded.replace(':file_name', file_name)
|
||||
});*/
|
||||
self.onUploadCompleted();
|
||||
}
|
||||
else {
|
||||
self.onUploadFailed(data, file_name);
|
||||
}
|
||||
},
|
||||
uploadFile: function uploadImageFile(formObject, imageFile) {
|
||||
var self = this;
|
||||
var formData = new FormData();
|
||||
formData.append('album_id', album_id);
|
||||
formData.append('queue_token', queue_token);
|
||||
formData.append('photo[]', imageFile, imageFile.name);
|
||||
|
||||
$.ajax(
|
||||
{
|
||||
contentType: false,
|
||||
data: formData,
|
||||
error: function (data) {
|
||||
self.onUploadFailed(data, imageFile.name);
|
||||
},
|
||||
method: $(formObject).attr('method'),
|
||||
processData: false,
|
||||
success: function (data) {
|
||||
self.onUploadSuccessful(data, imageFile.name);
|
||||
},
|
||||
url: $(formObject).attr('action')
|
||||
}
|
||||
);
|
||||
this.isUploadInProgress = true;
|
||||
},
|
||||
uploadIndividualFiles: function(event) {
|
||||
var fileSelect = $('input[type=file]', event.target);
|
||||
|
||||
// Get the selected files
|
||||
var files = fileSelect[0].files;
|
||||
|
||||
// Reset statistics
|
||||
this.currentStatus = '';
|
||||
this.statusMessages = [];
|
||||
this.imagesUploaded = 0;
|
||||
this.imagesFailed = 0;
|
||||
this.imagesTotal = files.length;
|
||||
this.isUploadInProgress = true;
|
||||
|
||||
// Loop through each of the selected files and upload them individually
|
||||
for (var i = 0; i < files.length; i++)
|
||||
{
|
||||
var file = files[i];
|
||||
|
||||
// We're only interested in image files
|
||||
if (!file.type.match('image.*'))
|
||||
{
|
||||
alert(language.not_an_image_file.replace(':file_name', file.name));
|
||||
this.onUploadFailed(null, file.name);
|
||||
continue;
|
||||
}
|
||||
|
||||
// Upload the file
|
||||
this.uploadFile($(this), file);
|
||||
}
|
||||
|
||||
// Prevent standard form upload
|
||||
event.preventDefault();
|
||||
return false;
|
||||
}
|
||||
};
|
||||
}
|
127
resources/assets/js/albums.js
Normal file
127
resources/assets/js/albums.js
Normal file
@ -0,0 +1,127 @@
|
||||
/**
|
||||
* This model is used by admin/show_album.blade.php to handle photo uploads.
|
||||
* @param album_id ID of the album the photos are being uploaded to
|
||||
* @param queue_token Unique token of the upload queue to save the photos to
|
||||
* @param language Array containing language strings
|
||||
* @param urls Array containing URLs
|
||||
* @constructor
|
||||
*/
|
||||
function UploadPhotosViewModel(album_id, queue_token, language, urls) {
|
||||
this.el = '#upload-tab';
|
||||
this.data = {
|
||||
currentStatus: '',
|
||||
imagesFailed: 0,
|
||||
imagesTotal: 0,
|
||||
isBulkUploadInProgress: false,
|
||||
isUploadInProgress: false,
|
||||
statusMessages: []
|
||||
};
|
||||
this.computed = {
|
||||
// a computed getter
|
||||
failedPercentage: function () {
|
||||
return ((this.imagesFailed() / this.imagesTotal()) * 100).toFixed(2) + '%';
|
||||
},
|
||||
successfulPercentage: function () {
|
||||
return ((self.imagesUploaded() / self.imagesTotal()) * 100).toFixed(2) + '%';
|
||||
}
|
||||
};
|
||||
this.methods = {
|
||||
// This method is called when an image is uploaded - regardless if it fails or not
|
||||
onUploadCompleted: function () {
|
||||
this.currentStatus = language.upload_status
|
||||
.replace(':current', (self.imagesUploaded + self.imagesFailed))
|
||||
.replace(':total', self.imagesTotal);
|
||||
|
||||
if ((this.imagesFailed + this.imagesUploaded) >= this.imagesTotal) {
|
||||
this.isUploadInProgress = false;
|
||||
|
||||
if (this.imagesFailed == 0 && this.imagesUploaded > 0) {
|
||||
window.location = urls.analyse;
|
||||
}
|
||||
}
|
||||
},
|
||||
// This method is called when an uploaded image fails
|
||||
onUploadFailed: function (data, file_name) {
|
||||
this.imagesFailed++;
|
||||
this.statusMessages.push({
|
||||
'message_class': 'text-danger',
|
||||
'message_text': language.image_failed.replace(':file_name', file_name)
|
||||
});
|
||||
this.onUploadCompleted();
|
||||
},
|
||||
// This method is called when an uploaded image succeeds
|
||||
onUploadSuccessful: function (data, file_name) {
|
||||
if (data.is_successful) {
|
||||
self.imagesUploaded++;
|
||||
// Don't add to statusMessages() array so user only sees errors
|
||||
/*self.statusMessages.push({
|
||||
'message_class': 'text-success',
|
||||
'message_text': language.image_uploaded.replace(':file_name', file_name)
|
||||
});*/
|
||||
self.onUploadCompleted();
|
||||
}
|
||||
else {
|
||||
self.onUploadFailed(data, file_name);
|
||||
}
|
||||
},
|
||||
uploadFile: function uploadImageFile(formObject, imageFile) {
|
||||
var self = this;
|
||||
var formData = new FormData();
|
||||
formData.append('album_id', album_id);
|
||||
formData.append('queue_token', queue_token);
|
||||
formData.append('photo[]', imageFile, imageFile.name);
|
||||
|
||||
$.ajax(
|
||||
{
|
||||
contentType: false,
|
||||
data: formData,
|
||||
error: function (data) {
|
||||
self.onUploadFailed(data, imageFile.name);
|
||||
},
|
||||
method: $(formObject).attr('method'),
|
||||
processData: false,
|
||||
success: function (data) {
|
||||
self.onUploadSuccessful(data, imageFile.name);
|
||||
},
|
||||
url: $(formObject).attr('action')
|
||||
}
|
||||
);
|
||||
this.isUploadInProgress = true;
|
||||
},
|
||||
uploadIndividualFiles: function(event) {
|
||||
var fileSelect = $('input[type=file]', event.target);
|
||||
|
||||
// Get the selected files
|
||||
var files = fileSelect[0].files;
|
||||
|
||||
// Reset statistics
|
||||
this.currentStatus = '';
|
||||
this.statusMessages = [];
|
||||
this.imagesUploaded = 0;
|
||||
this.imagesFailed = 0;
|
||||
this.imagesTotal = files.length;
|
||||
this.isUploadInProgress = true;
|
||||
|
||||
// Loop through each of the selected files and upload them individually
|
||||
for (var i = 0; i < files.length; i++)
|
||||
{
|
||||
var file = files[i];
|
||||
|
||||
// We're only interested in image files
|
||||
if (!file.type.match('image.*'))
|
||||
{
|
||||
alert(language.not_an_image_file.replace(':file_name', file.name));
|
||||
this.onUploadFailed(null, file.name);
|
||||
continue;
|
||||
}
|
||||
|
||||
// Upload the file
|
||||
this.uploadFile($(this), file);
|
||||
}
|
||||
|
||||
// Prevent standard form upload
|
||||
event.preventDefault();
|
||||
return false;
|
||||
}
|
||||
};
|
||||
}
|
@ -2,61 +2,60 @@
|
||||
@section('title', 'Gallery Admin')
|
||||
|
||||
@section('breadcrumb')
|
||||
<div class="breadcrumb">
|
||||
<div class="container">
|
||||
<ol class="breadcrumb">
|
||||
<li><a href="{{ route('home') }}"><i class="fa fa-fw fa-home"></i></a></li>
|
||||
<li><a href="{{ route('admin') }}">@lang('navigation.breadcrumb.admin')</a></li>
|
||||
<li><a href="{{ route('albums.index') }}">@lang('navigation.breadcrumb.albums')</a></li>
|
||||
<li class="active">@lang('navigation.breadcrumb.create_album')</li>
|
||||
</ol>
|
||||
</div>
|
||||
</div>
|
||||
<li class="breadcrumb-item"><a href="{{ route('home') }}"><i class="fa fa-fw fa-home"></i></a></li>
|
||||
<li class="breadcrumb-item"><a href="{{ route('admin') }}">@lang('navigation.breadcrumb.admin')</a></li>
|
||||
<li class="breadcrumb-item"><a href="{{ route('albums.index') }}">@lang('navigation.breadcrumb.albums')</a></li>
|
||||
<li class="breadcrumb-item active">@lang('navigation.breadcrumb.create_album')</li>
|
||||
@endsection
|
||||
|
||||
@section('content')
|
||||
<div class="container">
|
||||
<div class="row">
|
||||
<div class="col-xs-12">
|
||||
<div class="col">
|
||||
<h1>@lang('admin.create_album')</h1>
|
||||
<p>@lang('admin.create_album_intro')</p>
|
||||
<p>@lang('admin.create_album_intro2')</p>
|
||||
<hr/>
|
||||
|
||||
{!! Form::open(['route' => 'albums.store', 'method' => 'POST']) !!}
|
||||
<div class="form-group{{ $errors->has('name') ? ' has-error' : '' }}">
|
||||
{!! Form::label('name', trans('forms.name_label'), ['class' => 'control-label']) !!}
|
||||
{!! Form::text('name', old('name'), ['class' => 'form-control']) !!}
|
||||
<form action="{{ route('albums.store') }}" method="POST">
|
||||
{{ csrf_field() }}
|
||||
<div class="form-group{{ $errors->has('name') ? ' has-danger' : '' }}">
|
||||
<label class="form-control-label" for="album-name">@lang('forms.name_label')</label>
|
||||
<input type="text" class="form-control" id="album-name" name="name" value="{{ old('name') }}">
|
||||
|
||||
@if ($errors->has('name'))
|
||||
<span class="help-block">
|
||||
<strong>{{ $errors->first('name') }}</strong>
|
||||
</span>
|
||||
@endif
|
||||
</div>
|
||||
@if ($errors->has('name'))
|
||||
<div class="form-control-feedback">
|
||||
<strong>{{ $errors->first('name') }}</strong>
|
||||
</div>
|
||||
@endif
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
{!! Form::label('description', trans('forms.description_label'), ['class' => 'control-label']) !!}
|
||||
{!! Form::textarea('description', old('description'), ['class' => 'form-control']) !!}
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label class="form-control-label" for="album-description">@lang('forms.description_label')</label>
|
||||
<textarea class="form-control" id="album-description" name="description">{{ old('description') }}</textarea>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
{!! Form::label('storage_id', trans('forms.album_source_label'), ['class' => 'control-label']) !!}
|
||||
{!! Form::select('storage_id', $album_sources, old('storage_id', $default_storage_id), ['class' => 'form-control']) !!}
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label class="form-control-label" for="album-source">@lang('forms.album_source_label')</label>
|
||||
<select class="form-control" name="storage_id">
|
||||
@foreach ($album_sources as $key => $value)
|
||||
<option value="{{ $key }}"{{ $key == old('storage_id') ? ' selected="selected"' : '' }}>{{ $value }}</option>
|
||||
@endforeach
|
||||
</select>
|
||||
</div>
|
||||
|
||||
<div class="checkbox">
|
||||
<label>
|
||||
<input type="checkbox" name="is_private">
|
||||
<strong>@lang('forms.private_album_label')</strong>
|
||||
</label>
|
||||
</div>
|
||||
<div class="form-check">
|
||||
<label class="form-check-label">
|
||||
<input class="form-check-inline" type="checkbox" name="is_private">
|
||||
<i class="fa fa-fw fa-lock"></i> @lang('forms.private_album_label')
|
||||
</label>
|
||||
</div>
|
||||
|
||||
<div class="form-actions">
|
||||
<a href="{{ route('albums.index') }}" class="btn btn-default">@lang('forms.cancel_action')</a>
|
||||
<button class="btn btn-success" type="submit"><i class="fa fa-fw fa-check"></i> @lang('forms.create_action')</button>
|
||||
</div>
|
||||
{!! Form::close() !!}
|
||||
<div class="text-right">
|
||||
<a href="{{ route('albums.index') }}" class="btn btn-link">@lang('forms.cancel_action')</a>
|
||||
<button class="btn btn-success" type="submit"><i class="fa fa-fw fa-check"></i> @lang('forms.create_action')</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -2,24 +2,18 @@
|
||||
@section('title', 'Gallery Admin')
|
||||
|
||||
@section('breadcrumb')
|
||||
<div class="breadcrumb">
|
||||
<div class="container">
|
||||
<ol class="breadcrumb">
|
||||
<li><a href="{{ route('home') }}"><i class="fa fa-fw fa-home"></i></a></li>
|
||||
<li><a href="{{ route('admin') }}">@lang('navigation.breadcrumb.admin')</a></li>
|
||||
<li class="active">@lang('navigation.breadcrumb.albums')</li>
|
||||
</ol>
|
||||
</div>
|
||||
</div>
|
||||
<li class="breadcrumb-item"><a href="{{ route('home') }}"><i class="fa fa-fw fa-home"></i></a></li>
|
||||
<li class="breadcrumb-item"><a href="{{ route('admin') }}">@lang('navigation.breadcrumb.admin')</a></li>
|
||||
<li class="breadcrumb-item active">@lang('navigation.breadcrumb.albums')</li>
|
||||
@endsection
|
||||
|
||||
@section('content')
|
||||
<div class="container">
|
||||
<div class="row">
|
||||
<div class="col-xs-12">
|
||||
<div class="col">
|
||||
<h1>@lang('admin.list_albums_title')</h1>
|
||||
<div class="alert alert-info" style="margin-bottom: 30px;">
|
||||
<p><i class="fa fa-fw fa-info"></i> @lang('admin.list_albums_intro')</p>
|
||||
<i class="fa fa-fw fa-info"></i> @lang('admin.list_albums_intro')
|
||||
</div>
|
||||
|
||||
@if (count($albums) == 0)
|
||||
@ -48,9 +42,6 @@
|
||||
<p style="margin-bottom: 0;"><b>{{ $album->photos_count }}</b> {{ trans_choice('admin.stats_widget.photos', $album->photos_count) }}</p>
|
||||
</td>
|
||||
<td class="text-right">
|
||||
@can('edit', $album)
|
||||
<a href="{{ route('albums.edit', ['id' => $album->id]) }}" class="btn btn-default">@lang('forms.edit_action')</a>
|
||||
@endcan
|
||||
@can('delete', $album)
|
||||
<a href="{{ route('albums.delete', ['id' => $album->id]) }}" class="btn btn-danger">@lang('forms.delete_action')</a>
|
||||
@endcan
|
||||
|
@ -13,7 +13,7 @@
|
||||
<div class="col">
|
||||
<h1>@yield('title')</h1>
|
||||
<div class="alert alert-info" style="margin-bottom: 30px;">
|
||||
<p><i class="fa fa-fw fa-info"></i> @lang('admin.list_groups_intro')</p>
|
||||
<i class="fa fa-fw fa-info"></i> @lang('admin.list_groups_intro')
|
||||
</div>
|
||||
|
||||
@if (count($groups) == 0)
|
||||
|
@ -13,7 +13,7 @@
|
||||
<div class="col">
|
||||
<h1>@lang('admin.list_users_title')</h1>
|
||||
<div class="alert alert-info" style="margin-bottom: 30px;">
|
||||
<p><i class="fa fa-fw fa-info"></i> @lang('admin.list_users_intro')</p>
|
||||
<i class="fa fa-fw fa-info"></i> @lang('admin.list_users_intro')
|
||||
</div>
|
||||
|
||||
<table class="table table-hover table-striped">
|
||||
|
@ -2,22 +2,16 @@
|
||||
@section('title', $album->name)
|
||||
|
||||
@section('breadcrumb')
|
||||
<div class="breadcrumb">
|
||||
<div class="container">
|
||||
<ol class="breadcrumb">
|
||||
<li><a href="{{ route('home') }}"><i class="fa fa-fw fa-home"></i></a></li>
|
||||
<li><a href="{{ route('admin') }}">@lang('navigation.breadcrumb.admin')</a></li>
|
||||
<li><a href="{{ route('albums.index') }}">@lang('navigation.breadcrumb.albums')</a></li>
|
||||
<li class="active">{{ $album->name }}</li>
|
||||
</ol>
|
||||
</div>
|
||||
</div>
|
||||
<li class="breadcrumb-item"><a href="{{ route('home') }}"><i class="fa fa-fw fa-home"></i></a></li>
|
||||
<li class="breadcrumb-item"><a href="{{ route('admin') }}">@lang('navigation.breadcrumb.admin')</a></li>
|
||||
<li class="breadcrumb-item"><a href="{{ route('albums.index') }}">@lang('navigation.breadcrumb.albums')</a></li>
|
||||
<li class="breadcrumb-item active">{{ $album->name }}</li>
|
||||
@endsection
|
||||
|
||||
@section('content')
|
||||
<div class="container">
|
||||
<div class="row">
|
||||
<div class="col-xs-12">
|
||||
<div class="col">
|
||||
<a class="pull-right btn btn-default" href="{{ $album->url() }}" target="_blank"><i class="fa fa-fw fa-eye"></i> @lang('admin.open_album')</a>
|
||||
|
||||
<h1 class="page-title">{{ $album->name }}</h1>
|
||||
@ -42,34 +36,39 @@
|
||||
<p style="margin-top: 30px;"><button id="upload-button" class="btn btn-lg btn-success"><i class="fa fa-fw fa-upload"></i> @lang('admin.album_no_photos_button')</button></p>
|
||||
</div>
|
||||
@else
|
||||
{!! Form::open(['route' => ['photos.updateBulk', $album->id], 'method' => 'PUT', 'id' => 'bulk-modify-form']) !!}
|
||||
<form action="{{ route('photos.updateBulk', [$album->id]) }}" method="POST">
|
||||
{{ csrf_field() }}
|
||||
{{ method_field('PUT') }}
|
||||
|
||||
@foreach ($photos as $photo)
|
||||
@include (Theme::viewName('partials.single_photo_admin'))
|
||||
@endforeach
|
||||
@foreach ($photos as $photo)
|
||||
@include (Theme::viewName('partials.single_photo_admin'))
|
||||
@endforeach
|
||||
|
||||
<div class="pull-left" style="margin-bottom: 15px;">
|
||||
<p style="margin-bottom: 15px;">
|
||||
<button data-bind="click: selectAll" type="button" class="btn btn-default">@lang('admin.select_all_action')</button>
|
||||
<button data-bind="click: selectNone" type="button" class="btn btn-default">@lang('admin.select_none_action')</button>
|
||||
</p>
|
||||
<input data-bind="value: selectAllInAlbum" type="hidden" name="select-all-album"/>
|
||||
<div class="pull-left" style="margin-bottom: 15px;">
|
||||
<p style="margin-bottom: 15px;">
|
||||
<button data-bind="click: selectAll" type="button" class="btn btn-default">@lang('admin.select_all_action')</button>
|
||||
<button data-bind="click: selectNone" type="button" class="btn btn-default">@lang('admin.select_none_action')</button>
|
||||
</p>
|
||||
<input data-bind="value: selectAllInAlbum" type="hidden" name="select-all-album"/>
|
||||
|
||||
<div data-bind="visible: selectAllInAlbum" class="alert alert-warning">
|
||||
<p>@lang('admin.select_all_album_active')</p>
|
||||
<div data-bind="visible: selectAllInAlbum" class="alert alert-warning">
|
||||
<p>@lang('admin.select_all_album_active')</p>
|
||||
</div>
|
||||
|
||||
<p><label class="control-label" for="bulk-action">@lang('forms.bulk_edit_photos_label')</label></p>
|
||||
<input type="hidden" name="new-album-id" value="{{ $album->id }}"/>
|
||||
<select name="bulk-action" data-bind="value: bulkModifyMethod, enable: photoIDs().length > 0">
|
||||
<option>@lang('forms.bulk_edit_photos_placeholder')</option>
|
||||
@foreach ($bulk_actions as $key => $value)
|
||||
<option value="{{ $key }}"{{ $key == old('bulk-action') ? ' selected="selected"' : '' }}>{{ $value }}</option>
|
||||
@endforeach
|
||||
</select>
|
||||
<button type="submit" class="btn btn-sm btn-primary" name="bulk-apply" value="clicked" data-bind="click: bulkModifySelected, enable: photoIDs().length > 0">@lang('forms.apply_action')</button>
|
||||
</div>
|
||||
|
||||
<p>{!! Form::label('bulk-action', trans('forms.bulk_edit_photos_label'), ['class' => 'control-label']) !!}</p>
|
||||
{!! Form::hidden('new-album-id', $album->id) !!}
|
||||
{!! Form::select('bulk-action', $bulk_actions, null, ['placeholder' => trans('forms.bulk_edit_photos_placeholder'), 'id' => 'bulk-action-apply', 'data-bind' => 'value: bulkModifyMethod, enable: photoIDs().length > 0']) !!}
|
||||
<button type="submit" class="btn btn-sm btn-primary" name="bulk-apply" value="clicked" data-bind="click: bulkModifySelected, enable: photoIDs().length > 0">@lang('forms.apply_action')</button>
|
||||
</div>
|
||||
<div class="pull-right">
|
||||
<button type="submit" class="btn btn-success">@lang('forms.save_action')</button>
|
||||
</div>
|
||||
<div class="clearfix"></div>
|
||||
|
||||
{!! Form::close() !!}
|
||||
<div class="text-right">
|
||||
<button type="submit" class="btn btn-success">@lang('forms.save_action')</button>
|
||||
</div>
|
||||
</form>
|
||||
|
||||
<div class="text-center">
|
||||
{{ $photos->links() }}
|
||||
@ -78,93 +77,7 @@
|
||||
</div>
|
||||
|
||||
{{-- Upload --}}
|
||||
<div role="tabpanel" class="tab-pane{{ $active_tab == 'upload' ? ' active' : '' }}" id="upload-tab">
|
||||
@if (!$is_upload_enabled)
|
||||
<div class="row">
|
||||
<div class="col-xs-12">
|
||||
<p class="text-danger" style="font-weight: bold">@lang('admin.upload_disabled_heading')</p>
|
||||
<p>@lang('admin.upload_disabled_text')</p>
|
||||
</div>
|
||||
</div>
|
||||
@else
|
||||
<h4>@lang('admin.upload_single_file_heading')</h4>
|
||||
<p>@lang('admin.upload_single_file_text')</p>
|
||||
<div class="alert alert-info">
|
||||
<p>@lang('admin.upload_single_file_text2', [
|
||||
'file_size' => sprintf('<b>%s%s</b>', round($file_upload_limit, 2), trans('global.units.megabytes')),
|
||||
'max_upload_size' => sprintf('<b>%s%s</b>', round($max_post_limit, 2), trans('global.units.megabytes'))
|
||||
])</p>
|
||||
</div>
|
||||
|
||||
<div class="row">
|
||||
<div class="col-sm-5" style="margin-bottom: 20px;">
|
||||
{!! Form::open(['route' => 'photos.store', 'method' => 'POST', 'files' => true, 'id' => 'single-upload-form']) !!}
|
||||
{!! Form::hidden('album_id', $album->id) !!}
|
||||
{!! Form::hidden('queue_token', $queue_token) !!}
|
||||
|
||||
<div class="form-group">
|
||||
{!! Form::file('photo[]', ['class' => 'control-label', 'multiple' => 'multiple', 'id' => 'single-upload-files']) !!}
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<button type="submit" class="btn btn-success" data-bind="disable: (isUploadInProgress() || isBulkUploadInProgress()), text: isUploadInProgress() ? '@lang('admin.is_uploading')' : '@lang('forms.upload_action')'"><i class="fa fa-fw fa-upload"></i> @lang('forms.upload_action')</button>
|
||||
</div>
|
||||
{!! Form::close() !!}
|
||||
</div>
|
||||
|
||||
<div class="col-sm-5">
|
||||
<div class="text-center" data-bind="visible: isUploadInProgress">
|
||||
<p><b>@lang('admin.is_uploading')</b></p>
|
||||
<div class="progress">
|
||||
<div class="progress-bar progress-bar-success" data-bind="style: { width: successfulPercentage() }">
|
||||
<span class="sr-only"><span class="percentage-success" data-bind="text: successfulPercentage"></span></span>
|
||||
</div>
|
||||
<div class="progress-bar progress-bar-danger" data-bind="style: { width: failedPercentage() }">
|
||||
<span class="sr-only"><span class="percentage-danger" data-bind="text: failedPercentage"></span></span>
|
||||
</div>
|
||||
</div>
|
||||
<p data-bind="text: currentStatus"></p>
|
||||
</div>
|
||||
|
||||
<div data-bind="visible: statusMessages().length > 0">
|
||||
<p data-bind="visible: !isUploadInProgress()" class="text-danger" style="font-weight: bold">
|
||||
<span data-bind="text: imagesFailed"></span> @lang('admin.upload_file_number_failed')
|
||||
</p>
|
||||
<p data-bind="visible: imagesUploaded() > 0">
|
||||
@lang('admin.upload_file_failed_continue')<br /><br/>
|
||||
<a href="{{ route('albums.analyse', ['id' => $album->id, 'queue_token' => $queue_token]) }}" class="btn btn-primary">@lang('forms.continue_action')</a>
|
||||
</p>
|
||||
|
||||
<ul data-bind="foreach: statusMessages">
|
||||
<li data-bind="css: message_class, text: message_text"></li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<hr/>
|
||||
<h4>@lang('admin.upload_bulk_heading')</h4>
|
||||
<p>@lang('admin.upload_bulk_text')</p>
|
||||
<div class="alert alert-info">
|
||||
<p>@lang('admin.upload_bulk_text2', [
|
||||
'max_upload_size' => sprintf('<b>%s%s</b>', round($max_post_limit_bulk, 2), trans('global.units.megabytes'))
|
||||
])</p>
|
||||
</div>
|
||||
|
||||
{!! Form::open(['route' => 'photos.storeBulk', 'method' => 'POST', 'files' => true, 'id' => 'bulk-upload-form']) !!}
|
||||
{!! Form::hidden('album_id', $album->id) !!}
|
||||
{!! Form::hidden('queue_token', $queue_token) !!}
|
||||
|
||||
<div class="form-group">
|
||||
{!! Form::file('archive', ['class' => 'control-label']) !!}
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<button type="submit" class="btn btn-success" data-bind="disable: (isUploadInProgress() || isBulkUploadInProgress()), text: isBulkUploadInProgress() ? '@lang('admin.is_uploading')' : '@lang('forms.upload_action')'"><i class="fa fa-fw fa-upload"></i> @lang('forms.upload_action')</button>
|
||||
</div>
|
||||
{!! Form::close() !!}
|
||||
@endif
|
||||
</div>
|
||||
@include(Theme::viewName('partials.album_upload_tab'))
|
||||
|
||||
{{-- Permissions --}}
|
||||
<div role="tabpanel" class="tab-pane{{ $active_tab == 'permissions' ? ' active' : '' }}" id="permissions-tab">
|
||||
@ -259,64 +172,71 @@
|
||||
|
||||
{{-- Settings --}}
|
||||
<div role="tabpanel" class="tab-pane{{ $active_tab == 'settings' ? ' active' : '' }}" id="settings-tab">
|
||||
{!! Form::model($album, ['route' => ['albums.update', $album->id], 'method' => 'PUT']) !!}
|
||||
<h4><i class="fa fa-fw fa-info"></i> @lang('admin.album_basic_info_heading')</h4>
|
||||
<p>@lang('admin.album_basic_info_intro')</p>
|
||||
<form action="{{ route('albums.update', [$album->id]) }}" method="POST">
|
||||
{{ csrf_field() }}
|
||||
{{ method_field('PUT') }}
|
||||
|
||||
<div class="form-group{{ $errors->has('name') ? ' has-error' : '' }}" style="margin-top: 20px;">
|
||||
{!! Form::label('name', trans('forms.name_label'), ['class' => 'control-label']) !!}
|
||||
{!! Form::text('name', old('name'), ['class' => 'form-control']) !!}
|
||||
<h4><i class="fa fa-fw fa-info"></i> @lang('admin.album_basic_info_heading')</h4>
|
||||
<p>@lang('admin.album_basic_info_intro')</p>
|
||||
|
||||
@if ($errors->has('name'))
|
||||
<span class="help-block">
|
||||
<strong>{{ $errors->first('name') }}</strong>
|
||||
</span>
|
||||
@endif
|
||||
</div>
|
||||
<div class="form-group{{ $errors->has('name') ? ' has-danger' : '' }}" style="margin-top: 20px;">
|
||||
<label class="form-control-label" for="album-name">@lang('forms.name_label')</label>
|
||||
<input type="text" class="form-control" id="album-name" name="name" value="{{ old('name') }}">
|
||||
|
||||
<div class="form-group">
|
||||
{!! Form::label('description', trans('forms.description_label'), ['class' => 'control-label']) !!}
|
||||
{!! Form::textarea('description', old('description'), ['class' => 'form-control']) !!}
|
||||
</div>
|
||||
@if ($errors->has('name'))
|
||||
<div class="form-control-feedback">
|
||||
<strong>{{ $errors->first('name') }}</strong>
|
||||
</div>
|
||||
@endif
|
||||
</div>
|
||||
|
||||
<hr/>
|
||||
<div class="form-group">
|
||||
<label class="form-control-label" for="album-description">@lang('forms.description_label')</label>
|
||||
<textarea class="form-control" id="album-description" name="description">{{ old('description') }}</textarea>
|
||||
</div>
|
||||
|
||||
<h4><i class="fa fa-fw fa-paint-brush"></i> @lang('admin.album_appearance_heading')</h4>
|
||||
<p>@lang('admin.album_appearance_intro')</p>
|
||||
<hr/>
|
||||
|
||||
<div class="form-group" style="margin-top: 20px;">
|
||||
<label class="control-label">@lang('forms.default_album_view_label')</label>
|
||||
{!! Form::select('default_view', $allowed_views, old('default_view'), ['class' => 'form-control']) !!}
|
||||
</div>
|
||||
<h4><i class="fa fa-fw fa-paint-brush"></i> @lang('admin.album_appearance_heading')</h4>
|
||||
<p>@lang('admin.album_appearance_intro')</p>
|
||||
|
||||
<hr/>
|
||||
<div class="form-group" style="margin-top: 20px;">
|
||||
<label class="control-label" for="album-view">@lang('forms.default_album_view_label')</label>
|
||||
<select class="form-control" name="default_view">
|
||||
@foreach ($allowed_views as $view)
|
||||
<option value="{{ $view }}"{{ $view == old('default_view') ? ' selected="selected"' : '' }}>{{ $view }}</option>
|
||||
@endforeach
|
||||
</select>
|
||||
</div>
|
||||
|
||||
<div class="row">
|
||||
<div class="col-sm-6 col-sm-push-6">
|
||||
<div class="panel panel-default">
|
||||
<div class="panel-heading">@lang('admin.save_changes_heading')</div>
|
||||
<div class="panel-body">
|
||||
<p>@lang('admin.save_changes_intro')</p>
|
||||
<p class="text-right">
|
||||
<button type="submit" class="btn btn-success"><i class="fa fa-fw fa-floppy-o"></i> @lang('forms.save_action')</button>
|
||||
</p>
|
||||
<hr/>
|
||||
|
||||
<div class="row">
|
||||
<div class="col-sm-6 push-sm-6">
|
||||
<div class="card">
|
||||
<div class="card-header">@lang('admin.save_changes_heading')</div>
|
||||
<div class="card-block">
|
||||
<p>@lang('admin.save_changes_intro')</p>
|
||||
<div class="text-right">
|
||||
<button type="submit" class="btn btn-success"><i class="fa fa-fw fa-floppy-o"></i> @lang('forms.save_action')</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-sm-6 pull-sm-6">
|
||||
<div class="card card-outline-danger">
|
||||
<div class="card-header card-danger">@lang('admin.danger_zone_heading')</div>
|
||||
<div class="card-block">
|
||||
<p class="text-danger">@lang('admin.danger_zone_intro')</p>
|
||||
<div>
|
||||
<a href="{{ route('albums.delete', ['id' => $album->id]) }}" class="btn btn-danger">@lang('forms.delete_action')</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-sm-6 col-sm-pull-6">
|
||||
<div class="panel panel-danger">
|
||||
<div class="panel-heading">@lang('admin.danger_zone_heading')</div>
|
||||
<div class="panel-body">
|
||||
<p class="text-danger">@lang('admin.danger_zone_intro')</p>
|
||||
<p>
|
||||
<a href="{{ route('albums.delete', ['id' => $album->id]) }}" class="btn btn-danger">@lang('forms.delete_action')</a>
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{!! Form::close() !!}
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@ -337,6 +257,7 @@
|
||||
language.delete_bulk_confirm_title = '{!! addslashes(trans('admin.delete_bulk_photos_title')) !!}';
|
||||
language.delete_confirm_message = '{!! addslashes(trans('admin.delete_photo_message')) !!}';
|
||||
language.delete_confirm_title = '{!! addslashes(trans('admin.delete_photo_title')) !!}';
|
||||
language.not_an_image_file = '{!! addslashes(trans('admin.upload_file_not_image_messages')) !!}';
|
||||
language.select_all_choice_all_action = '{!! addslashes(trans('admin.select_all_choice.all_action')) !!}';
|
||||
language.select_all_choice_message = '{!! addslashes(trans('admin.select_all_choice.message')) !!}';
|
||||
language.select_all_choice_title = '{!! addslashes(trans('admin.select_all_choice.title')) !!}';
|
||||
@ -354,7 +275,7 @@
|
||||
urls.rotate_photo = '{{ route('photos.rotate', ['id' => 0, 'angle' => 1]) }}';
|
||||
|
||||
var viewModel = new UploadPhotosViewModel('{{ $album->id }}', '{{ $queue_token }}', language, urls);
|
||||
var editViewModel = new EditPhotosViewModel('{{ $album->id }}', language, urls);
|
||||
/*var editViewModel = new EditPhotosViewModel('{{ $album->id }}', language, urls);
|
||||
|
||||
@foreach ($photos as $photo)
|
||||
editViewModel.photoIDsAvailable.push('{{ $photo->id }}');
|
||||
@ -366,7 +287,7 @@
|
||||
'id': '{{ $album->id }}',
|
||||
'name': '{!! addslashes($album->name) !!}'
|
||||
});
|
||||
@endforeach
|
||||
@endforeach*/
|
||||
|
||||
$(document).ready(function() {
|
||||
$('#upload-button').click(function() {
|
||||
@ -374,51 +295,18 @@
|
||||
});
|
||||
|
||||
{{-- Photo editing tasks - the buttons beneath the photos in partials/single_photo_admin --}}
|
||||
$('a.change-album').click(editViewModel.changeAlbum);
|
||||
/*$('a.change-album').click(editViewModel.changeAlbum);
|
||||
$('a.delete-photo').click(editViewModel.delete);
|
||||
$('a.flip-photo-both').click(editViewModel.flipBoth);
|
||||
$('a.flip-photo-horizontal').click(editViewModel.flipHorizontal);
|
||||
$('a.flip-photo-vertical').click(editViewModel.flipVertical);
|
||||
$('a.regenerate-thumbnails').click(editViewModel.regenerateThumbnails);
|
||||
$('a.rotate-photo-left').click(editViewModel.rotateLeft);
|
||||
$('a.rotate-photo-right').click(editViewModel.rotateRight);
|
||||
$('a.rotate-photo-right').click(editViewModel.rotateRight);*/
|
||||
|
||||
{{-- Photo uploads using AJAX --}}
|
||||
if (window.FormData)
|
||||
{
|
||||
$('#single-upload-form').submit(function(event) {
|
||||
var fileSelect = $('#single-upload-files', this);
|
||||
var uploadButton = $('button[type=submit]', this);
|
||||
|
||||
// Get the selected files
|
||||
var notImageString = '{!! addslashes(trans('admin.upload_file_not_image_messages')) !!}';
|
||||
var files = fileSelect[0].files;
|
||||
|
||||
// Reset statistics
|
||||
viewModel.startUpload(files.length);
|
||||
|
||||
// Loop through each of the selected files and upload them individually
|
||||
for (var i = 0; i < files.length; i++)
|
||||
{
|
||||
var file = files[i];
|
||||
|
||||
// We're only interested in image files
|
||||
if (!file.type.match('image.*'))
|
||||
{
|
||||
alert(notImageString.replace(':file_name', file.name));
|
||||
viewModel.onUploadFailed(null, file.name);
|
||||
continue;
|
||||
}
|
||||
|
||||
// Upload the file
|
||||
viewModel.uploadFile($(this), file);
|
||||
}
|
||||
|
||||
// Prevent standard form upload
|
||||
event.preventDefault();
|
||||
return false;
|
||||
});
|
||||
|
||||
$('#bulk-upload-form').submit(function(event) {
|
||||
// Set the in progress flag - no need to unset it as this is a synchronous process so the browser
|
||||
// will reload the page in some way after completion
|
||||
@ -450,7 +338,7 @@
|
||||
});
|
||||
|
||||
{{-- Type-ahead support for users textbox on the permissions tab --}}
|
||||
var userDataSource = new Bloodhound({
|
||||
/*var userDataSource = new Bloodhound({
|
||||
datumTokenizer: Bloodhound.tokenizers.obj.whitespace('value'),
|
||||
queryTokenizer: Bloodhound.tokenizers.whitespace,
|
||||
//prefetch: '../data/films/post_1960.json',
|
||||
@ -467,11 +355,12 @@
|
||||
});
|
||||
$('#user-search-textbox').bind('typeahead:select', function(ev, suggestion) {
|
||||
$('#user-id-field').val(suggestion.id);
|
||||
});
|
||||
});*/
|
||||
|
||||
// Bind the view models to the relevant tab
|
||||
ko.applyBindings(editViewModel, document.getElementById('photos-tab'));
|
||||
ko.applyBindings(viewModel, document.getElementById('upload-tab'));
|
||||
//ko.applyBindings(editViewModel, document.getElementById('photos-tab'));
|
||||
//ko.applyBindings(viewModel, document.getElementById('upload-tab'));
|
||||
var appUpload = new Vue(viewModel);
|
||||
})
|
||||
</script>
|
||||
@endpush
|
@ -0,0 +1,95 @@
|
||||
<div role="tabpanel" class="tab-pane{{ $active_tab == 'upload' ? ' active' : '' }}" id="upload-tab">
|
||||
@if (!$is_upload_enabled)
|
||||
<div class="row">
|
||||
<div class="col-xs-12">
|
||||
<p class="text-danger" style="font-weight: bold">@lang('admin.upload_disabled_heading')</p>
|
||||
<p>@lang('admin.upload_disabled_text')</p>
|
||||
</div>
|
||||
</div>
|
||||
@else
|
||||
<h4>@lang('admin.upload_single_file_heading')</h4>
|
||||
<p>@lang('admin.upload_single_file_text')</p>
|
||||
<div class="alert alert-info">
|
||||
@lang('admin.upload_single_file_text2', [
|
||||
'file_size' => sprintf('<b>%s%s</b>', round($file_upload_limit, 2), trans('global.units.megabytes')),
|
||||
'max_upload_size' => sprintf('<b>%s%s</b>', round($max_post_limit, 2), trans('global.units.megabytes'))
|
||||
])
|
||||
</div>
|
||||
|
||||
<div class="row">
|
||||
<div class="col-sm-5" style="margin-bottom: 20px;">
|
||||
<form action="{{ route('photos.store') }}" method="POST" enctype="multipart/form-data" v-on:submit="uploadIndividualFiles">
|
||||
{{ csrf_field() }}
|
||||
<input type="hidden" name="album_id" value="{{ $album->id }}"/>
|
||||
<input type="hidden" name="queue_token" value="{{ $queue_token }}"/>
|
||||
|
||||
<div class="form-group">
|
||||
<label class="custom-file">
|
||||
<input type="file" name="photo[]" id="single-upload-files" class="custom-file-input" multiple="multiple">
|
||||
<span class="custom-file-control"></span>
|
||||
</label>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<button type="submit" class="btn btn-success" v-bind:disabled="isUploadInProgress || isBulkUploadInProgress" v-html="isUploadInProgress ? '@lang('admin.is_uploading')' : '@lang('forms.upload_action')'"><i class="fa fa-fw fa-upload"></i> @lang('forms.upload_action')</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
|
||||
<div class="col-sm-5">
|
||||
<div class="text-center" data-bind="visible: isUploadInProgress">
|
||||
<p><b>@lang('admin.is_uploading')</b></p>
|
||||
<div class="progress">
|
||||
<div class="progress-bar progress-bar-success" data-bind="style: { width: successfulPercentage() }">
|
||||
<span class="sr-only"><span class="percentage-success" data-bind="text: successfulPercentage"></span></span>
|
||||
</div>
|
||||
<div class="progress-bar progress-bar-danger" data-bind="style: { width: failedPercentage() }">
|
||||
<span class="sr-only"><span class="percentage-danger" data-bind="text: failedPercentage"></span></span>
|
||||
</div>
|
||||
</div>
|
||||
<p data-bind="text: currentStatus"></p>
|
||||
</div>
|
||||
|
||||
<div data-bind="visible: statusMessages().length > 0">
|
||||
<p data-bind="visible: !isUploadInProgress()" class="text-danger" style="font-weight: bold">
|
||||
<span data-bind="text: imagesFailed"></span> @lang('admin.upload_file_number_failed')
|
||||
</p>
|
||||
<p data-bind="visible: imagesUploaded() > 0">
|
||||
@lang('admin.upload_file_failed_continue')<br /><br/>
|
||||
<a href="{{ route('albums.analyse', ['id' => $album->id, 'queue_token' => $queue_token]) }}" class="btn btn-primary">@lang('forms.continue_action')</a>
|
||||
</p>
|
||||
|
||||
<ul data-bind="foreach: statusMessages">
|
||||
<li data-bind="css: message_class, text: message_text"></li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<hr/>
|
||||
<h4>@lang('admin.upload_bulk_heading')</h4>
|
||||
<p>@lang('admin.upload_bulk_text')</p>
|
||||
<div class="alert alert-info">
|
||||
@lang('admin.upload_bulk_text2', [
|
||||
'max_upload_size' => sprintf('<b>%s%s</b>', round($max_post_limit_bulk, 2), trans('global.units.megabytes'))
|
||||
])
|
||||
</div>
|
||||
|
||||
<form action="{{ route('photos.storeBulk') }}" method="POST" enctype="multipart/form-data">
|
||||
{{ csrf_field() }}
|
||||
<input type="hidden" name="album_id" value="{{ $album->id }}"/>
|
||||
<input type="hidden" name="queue_token" value="{{ $queue_token }}"/>
|
||||
|
||||
<div class="form-group">
|
||||
<label class="custom-file">
|
||||
<input type="file" id="single-upload-files" class="custom-file-input" multiple="multiple" name="archive">
|
||||
<span class="custom-file-control"></span>
|
||||
</label>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<button type="submit" class="btn btn-success" data-bind="disable: (isUploadInProgress() || isBulkUploadInProgress()), text: isBulkUploadInProgress() ? '@lang('admin.is_uploading')' : '@lang('forms.upload_action')'"><i class="fa fa-fw fa-upload"></i> @lang('forms.upload_action')</button>
|
||||
</div>
|
||||
</form>
|
||||
@endif
|
||||
</div>
|
Loading…
Reference in New Issue
Block a user