#4: Nested albums are now supported in the admin panel
This commit is contained in:
parent
e93e4d2413
commit
7ea1dc5c83
@ -19,7 +19,7 @@ class Album extends Model
|
|||||||
* @var array
|
* @var array
|
||||||
*/
|
*/
|
||||||
protected $fillable = [
|
protected $fillable = [
|
||||||
'name', 'description', 'url_alias', 'is_private', 'user_id', 'storage_id', 'default_view'
|
'name', 'description', 'url_alias', 'is_private', 'user_id', 'storage_id', 'default_view', 'parent_album_id'
|
||||||
];
|
];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -35,6 +35,11 @@ class Album extends Model
|
|||||||
return $this->belongsToMany(Permission::class, 'album_anonymous_permissions');
|
return $this->belongsToMany(Permission::class, 'album_anonymous_permissions');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function children()
|
||||||
|
{
|
||||||
|
return $this->hasMany(Album::class, 'parent_album_id');
|
||||||
|
}
|
||||||
|
|
||||||
public function doesGroupHavePermission(Group $group, Permission $permission)
|
public function doesGroupHavePermission(Group $group, Permission $permission)
|
||||||
{
|
{
|
||||||
return $this->groupPermissions()->where([
|
return $this->groupPermissions()->where([
|
||||||
@ -84,6 +89,31 @@ class Album extends Model
|
|||||||
return $this->belongsToMany(Permission::class, 'album_group_permissions');
|
return $this->belongsToMany(Permission::class, 'album_group_permissions');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns true if this album is a descendant of the given album.
|
||||||
|
* @param Album $album
|
||||||
|
*/
|
||||||
|
public function isChildOf(Album $album)
|
||||||
|
{
|
||||||
|
$currentAlbum = $this;
|
||||||
|
while (!is_null($currentAlbum))
|
||||||
|
{
|
||||||
|
if ($currentAlbum->parent_album_id == $album->id)
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
$currentAlbum = Album::where('id', $currentAlbum->parent_album_id)->first();
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function parent()
|
||||||
|
{
|
||||||
|
return $this->belongsTo(Album::class, 'parent_album_id');
|
||||||
|
}
|
||||||
|
|
||||||
public function photos()
|
public function photos()
|
||||||
{
|
{
|
||||||
return $this->hasMany(Photo::class);
|
return $this->hasMany(Photo::class);
|
||||||
|
@ -9,10 +9,16 @@ use Illuminate\Support\Facades\Auth;
|
|||||||
|
|
||||||
class DbHelper
|
class DbHelper
|
||||||
{
|
{
|
||||||
public static function getAlbumsForCurrentUser()
|
public static function getAlbumsForCurrentUser($parentID = -1)
|
||||||
{
|
{
|
||||||
return self::getAlbumsForCurrentUser_NonPaged()
|
$query = self::getAlbumsForCurrentUser_NonPaged();
|
||||||
->paginate(UserConfig::get('items_per_page'));
|
|
||||||
|
if ($parentID == 0)
|
||||||
|
{
|
||||||
|
$query = $query->where('albums.parent_album_id', null);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $query->paginate(UserConfig::get('items_per_page'));
|
||||||
}
|
}
|
||||||
|
|
||||||
public static function getAlbumsForCurrentUser_NonPaged()
|
public static function getAlbumsForCurrentUser_NonPaged()
|
||||||
|
@ -14,6 +14,7 @@ use App\Http\Controllers\Controller;
|
|||||||
use App\Http\Requests;
|
use App\Http\Requests;
|
||||||
use App\Permission;
|
use App\Permission;
|
||||||
use App\Photo;
|
use App\Photo;
|
||||||
|
use App\Services\AlbumService;
|
||||||
use App\Services\PhotoService;
|
use App\Services\PhotoService;
|
||||||
use App\Storage;
|
use App\Storage;
|
||||||
use App\Upload;
|
use App\Upload;
|
||||||
@ -71,11 +72,13 @@ class AlbumController extends Controller
|
|||||||
return redirect(route('storage.create'));
|
return redirect(route('storage.create'));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$albumService = new AlbumService();
|
||||||
$defaultSource = Storage::where('is_default', true)->limit(1)->first();
|
$defaultSource = Storage::where('is_default', true)->limit(1)->first();
|
||||||
|
|
||||||
return Theme::render('admin.create_album', [
|
return Theme::render('admin.create_album', [
|
||||||
'album_sources' => $albumSources,
|
'album_sources' => $albumSources,
|
||||||
'default_storage_id' => (!is_null($defaultSource) ? $defaultSource->id : 0)
|
'default_storage_id' => (!is_null($defaultSource) ? $defaultSource->id : 0),
|
||||||
|
'parent_albums' => $albumService->getFlattenedAlbumTree()
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -133,7 +136,12 @@ class AlbumController extends Controller
|
|||||||
$request->session()->flash('_old_input', $album->toArray());
|
$request->session()->flash('_old_input', $album->toArray());
|
||||||
}
|
}
|
||||||
|
|
||||||
return Theme::render('admin.edit_album', ['album' => $album]);
|
$albumService = new AlbumService();
|
||||||
|
|
||||||
|
return Theme::render('admin.edit_album', [
|
||||||
|
'album' => $album,
|
||||||
|
'parent_albums' => $albumService->getFlattenedAlbumTree()
|
||||||
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -145,7 +153,8 @@ class AlbumController extends Controller
|
|||||||
{
|
{
|
||||||
$this->authorizeAccessToAdminPanel('admin:manage-albums');
|
$this->authorizeAccessToAdminPanel('admin:manage-albums');
|
||||||
|
|
||||||
$albums = DbHelper::getAlbumsForCurrentUser();
|
// Only get top-level albums
|
||||||
|
$albums = DbHelper::getAlbumsForCurrentUser(0);
|
||||||
|
|
||||||
return Theme::render('admin.list_albums', [
|
return Theme::render('admin.list_albums', [
|
||||||
'albums' => $albums,
|
'albums' => $albums,
|
||||||
@ -384,7 +393,12 @@ class AlbumController extends Controller
|
|||||||
$this->authorizeAccessToAdminPanel('admin:manage-albums');
|
$this->authorizeAccessToAdminPanel('admin:manage-albums');
|
||||||
|
|
||||||
$album = new Album();
|
$album = new Album();
|
||||||
$album->fill($request->only(['name', 'description', 'storage_id']));
|
$album->fill($request->only(['name', 'description', 'storage_id', 'parent_album_id']));
|
||||||
|
|
||||||
|
if (strlen($album->parent_album_id) == 0)
|
||||||
|
{
|
||||||
|
$album->parent_album_id = null;
|
||||||
|
}
|
||||||
|
|
||||||
$album->default_view = UserConfig::get('default_album_view');
|
$album->default_view = UserConfig::get('default_album_view');
|
||||||
$album->is_private = (strtolower($request->get('is_private')) == 'on');
|
$album->is_private = (strtolower($request->get('is_private')) == 'on');
|
||||||
@ -408,9 +422,14 @@ class AlbumController extends Controller
|
|||||||
$this->authorizeAccessToAdminPanel('admin:manage-albums');
|
$this->authorizeAccessToAdminPanel('admin:manage-albums');
|
||||||
|
|
||||||
$album = $this->loadAlbum($id);
|
$album = $this->loadAlbum($id);
|
||||||
$album->fill($request->only(['name', 'description']));
|
$album->fill($request->only(['name', 'description', 'parent_album_id']));
|
||||||
$album->is_private = (strtolower($request->get('is_private')) == 'on');
|
$album->is_private = (strtolower($request->get('is_private')) == 'on');
|
||||||
|
|
||||||
|
if (strlen($album->parent_album_id) == 0)
|
||||||
|
{
|
||||||
|
$album->parent_album_id = null;
|
||||||
|
}
|
||||||
|
|
||||||
// These keys are optional and may or may not be in the request, depending on the page requesting it
|
// These keys are optional and may or may not be in the request, depending on the page requesting it
|
||||||
foreach (['storage_id', 'default_view'] as $key)
|
foreach (['storage_id', 'default_view'] as $key)
|
||||||
{
|
{
|
||||||
|
42
app/Services/AlbumService.php
Normal file
42
app/Services/AlbumService.php
Normal file
@ -0,0 +1,42 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Services;
|
||||||
|
|
||||||
|
use App\Album;
|
||||||
|
use App\Helpers\DbHelper;
|
||||||
|
|
||||||
|
class AlbumService
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Get a list of all albums in a flattened tree-structure.
|
||||||
|
* @return mixed
|
||||||
|
*/
|
||||||
|
public function getFlattenedAlbumTree()
|
||||||
|
{
|
||||||
|
$allAlbums = DbHelper::getAlbumsForCurrentUser_NonPaged()->get();
|
||||||
|
$result = [];
|
||||||
|
|
||||||
|
$this->buildAlbumTree($result, $allAlbums);
|
||||||
|
|
||||||
|
return $result;
|
||||||
|
}
|
||||||
|
|
||||||
|
private function buildAlbumTree(array &$result, $allAlbums, Album $parent = null, $level = 0)
|
||||||
|
{
|
||||||
|
$parentAlbums = [];
|
||||||
|
foreach ($allAlbums as $album)
|
||||||
|
{
|
||||||
|
if ((is_null($parent) && is_null($album->parent_album_id)) || (!is_null($parent) && $album->parent_album_id == $parent->id))
|
||||||
|
{
|
||||||
|
$parentAlbums[] = $album;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach ($parentAlbums as $album)
|
||||||
|
{
|
||||||
|
$album->display_name = trim(sprintf('%s %s', str_repeat('-', $level), $album->name));
|
||||||
|
$result[$album->id] = $album;
|
||||||
|
$this->buildAlbumTree($result, $allAlbums, $album, $level + 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -27,13 +27,13 @@ class CreateVisitorHitsTable extends Migration
|
|||||||
|
|
||||||
$table->foreign('album_id')
|
$table->foreign('album_id')
|
||||||
->references('id')->on('albums')
|
->references('id')->on('albums')
|
||||||
->onDelete('no action');
|
->onDelete('cascade');
|
||||||
$table->foreign('photo_id')
|
$table->foreign('photo_id')
|
||||||
->references('id')->on('photos')
|
->references('id')->on('photos')
|
||||||
->onDelete('no action');
|
->onDelete('cascade');
|
||||||
$table->foreign('user_id')
|
$table->foreign('user_id')
|
||||||
->references('id')->on('users')
|
->references('id')->on('users')
|
||||||
->onDelete('no action');
|
->onDelete('cascade');
|
||||||
|
|
||||||
$table->timestamps();
|
$table->timestamps();
|
||||||
});
|
});
|
||||||
|
@ -14,12 +14,12 @@ class AttachHitColumns extends Migration
|
|||||||
public function up()
|
public function up()
|
||||||
{
|
{
|
||||||
Schema::table('albums', function (Blueprint $table) {
|
Schema::table('albums', function (Blueprint $table) {
|
||||||
$table->bigInteger('hits');
|
$table->bigInteger('hits')->default(0);
|
||||||
});
|
});
|
||||||
|
|
||||||
Schema::table('photos', function (Blueprint $table) {
|
Schema::table('photos', function (Blueprint $table) {
|
||||||
$table->bigInteger('hits');
|
$table->bigInteger('hits')->default(0);
|
||||||
$table->bigInteger('hits_download');
|
$table->bigInteger('hits_download')->default(0);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -0,0 +1,39 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
use Illuminate\Support\Facades\Schema;
|
||||||
|
use Illuminate\Database\Schema\Blueprint;
|
||||||
|
use Illuminate\Database\Migrations\Migration;
|
||||||
|
|
||||||
|
class AddParentAlbumColumn extends Migration
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Run the migrations.
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function up()
|
||||||
|
{
|
||||||
|
Schema::table('albums', function (Blueprint $table)
|
||||||
|
{
|
||||||
|
$table->unsignedInteger('parent_album_id')->nullable();
|
||||||
|
|
||||||
|
$table->foreign('parent_album_id')
|
||||||
|
->references('id')->on('albums')
|
||||||
|
->onDelete('set null');
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reverse the migrations.
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function down()
|
||||||
|
{
|
||||||
|
Schema::table('albums', function (Blueprint $table)
|
||||||
|
{
|
||||||
|
$table->dropForeign('albums_parent_album_id_foreign');
|
||||||
|
$table->dropColumn('parent_album_id');
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
5
resources/assets/css/admin.css
vendored
5
resources/assets/css/admin.css
vendored
@ -2,6 +2,11 @@
|
|||||||
margin-bottom: 15px;
|
margin-bottom: 15px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.album-expand-handle {
|
||||||
|
cursor: pointer;
|
||||||
|
margin-top: 5px;
|
||||||
|
}
|
||||||
|
|
||||||
.card-header.card-danger {
|
.card-header.card-danger {
|
||||||
color: #fff;
|
color: #fff;
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
|
4
resources/assets/css/global.css
vendored
4
resources/assets/css/global.css
vendored
@ -19,6 +19,10 @@ textarea {
|
|||||||
margin-top: 20px;
|
margin-top: 20px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.hidden {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
.tab-content {
|
.tab-content {
|
||||||
border: solid 1px rgb(221, 221, 221);
|
border: solid 1px rgb(221, 221, 221);
|
||||||
border-top: 0;
|
border-top: 0;
|
||||||
|
@ -19,6 +19,8 @@ return [
|
|||||||
'email_label' => 'E-mail address:',
|
'email_label' => 'E-mail address:',
|
||||||
'login_action' => 'Login',
|
'login_action' => 'Login',
|
||||||
'name_label' => 'Name:',
|
'name_label' => 'Name:',
|
||||||
|
'parent_album_label' => 'Parent album:',
|
||||||
|
'parent_album_placeholder' => 'None (top-level album)',
|
||||||
'password_label' => 'Password:',
|
'password_label' => 'Password:',
|
||||||
'password_confirm_label' => 'Confirm password:',
|
'password_confirm_label' => 'Confirm password:',
|
||||||
'private_album_label' => 'Private album (only visible to me)',
|
'private_album_label' => 'Private album (only visible to me)',
|
||||||
@ -27,6 +29,7 @@ return [
|
|||||||
'remember_me_label' => 'Remember me',
|
'remember_me_label' => 'Remember me',
|
||||||
'remove_action' => 'Remove',
|
'remove_action' => 'Remove',
|
||||||
'select' => 'Select',
|
'select' => 'Select',
|
||||||
|
'select_current_text' => '(current)',
|
||||||
'settings_hotlink_protection' => 'Prevent hot-linking to images',
|
'settings_hotlink_protection' => 'Prevent hot-linking to images',
|
||||||
'settings_hotlink_protection_help' => 'With this option enabled, direct linking to images is not allowed. Photos can only be viewed through Blue Twilight.',
|
'settings_hotlink_protection_help' => 'With this option enabled, direct linking to images is not allowed. Photos can only be viewed through Blue Twilight.',
|
||||||
'settings_restrict_originals_download' => 'Restrict access to original images',
|
'settings_restrict_originals_download' => 'Restrict access to original images',
|
||||||
|
@ -35,9 +35,19 @@
|
|||||||
<textarea class="form-control" id="album-description" name="description" rows="5">{{ old('description') }}</textarea>
|
<textarea class="form-control" id="album-description" name="description" rows="5">{{ old('description') }}</textarea>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<div class="form-group">
|
||||||
|
<label class="form-control-label" for="parent-album">@lang('forms.parent_album_label')</label>
|
||||||
|
<select class="form-control" name="parent_album_id" id="parent-album">
|
||||||
|
<option value="">@lang('forms.parent_album_placeholder')</option>
|
||||||
|
@foreach ($parent_albums as $key => $value)
|
||||||
|
<option value="{{ $key }}"{{ $key == old('parent_album_id') ? ' selected="selected"' : '' }}>{{ $value->display_name }}</option>
|
||||||
|
@endforeach
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<label class="form-control-label" for="album-source">@lang('forms.album_source_label')</label>
|
<label class="form-control-label" for="album-source">@lang('forms.album_source_label')</label>
|
||||||
<select class="form-control" name="storage_id">
|
<select class="form-control" name="storage_id" id="album-source">
|
||||||
@foreach ($album_sources as $key => $value)
|
@foreach ($album_sources as $key => $value)
|
||||||
<option value="{{ $key }}"{{ $key == old('storage_id') ? ' selected="selected"' : '' }}>{{ $value }}</option>
|
<option value="{{ $key }}"{{ $key == old('storage_id') ? ' selected="selected"' : '' }}>{{ $value }}</option>
|
||||||
@endforeach
|
@endforeach
|
||||||
|
@ -44,6 +44,16 @@
|
|||||||
@endif
|
@endif
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<div class="form-group">
|
||||||
|
<label class="form-control-label" for="parent-album">@lang('forms.parent_album_label')</label>
|
||||||
|
<select class="form-control" name="parent_album_id" id="parent-album">
|
||||||
|
<option value="">@lang('forms.parent_album_placeholder')</option>
|
||||||
|
@foreach ($parent_albums as $key => $value)
|
||||||
|
<option value="{{ $key }}"{{ $key == $album->id || $value->isChildOf($album) ? ' disabled="disabled"' : '' }}{{ $key == old('parent_album_id') ? ' selected="selected"' : '' }}>{{ $value->display_name }}{{ $key == old('parent_album_id') ? ' ' . trans('forms.select_current_text') : '' }}</option>
|
||||||
|
@endforeach
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
|
||||||
<div class="text-right">
|
<div class="text-right">
|
||||||
<a href="{{ route('albums.show', ['id' => $album->id]) }}" class="btn btn-link">@lang('forms.cancel_action')</a>
|
<a href="{{ route('albums.show', ['id' => $album->id]) }}" class="btn btn-link">@lang('forms.cancel_action')</a>
|
||||||
<button type="submit" class="btn btn-success"><i class="fa fa-fw fa-check"></i> @lang('forms.save_action')</button>
|
<button type="submit" class="btn btn-success"><i class="fa fa-fw fa-check"></i> @lang('forms.save_action')</button>
|
||||||
|
@ -28,30 +28,7 @@
|
|||||||
<table class="table table-hover table-striped">
|
<table class="table table-hover table-striped">
|
||||||
<tbody>
|
<tbody>
|
||||||
@foreach ($albums as $album)
|
@foreach ($albums as $album)
|
||||||
<tr>
|
@include (Theme::viewName('partials.single_album_admin'), ['is_child' => false])
|
||||||
<td>
|
|
||||||
<span style="font-size: 1.3em;">
|
|
||||||
@can('edit', $album)
|
|
||||||
<a href="{{ route('albums.show', ['id' => $album->id]) }}">{{ $album->name }}</a>
|
|
||||||
@endcan
|
|
||||||
@cannot('edit', $album)
|
|
||||||
{{ $album->name }} <i class="fa fa-fw fa-lock"></i>
|
|
||||||
@endcannot
|
|
||||||
</span><br/>
|
|
||||||
<p>{{ $album->description }}</p>
|
|
||||||
<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">
|
|
||||||
<div class="btn-group">
|
|
||||||
@can('edit', $album)
|
|
||||||
<a href="{{ route('albums.edit', ['id' => $album->id]) }}" class="btn btn-secondary">@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
|
|
||||||
</div>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
@endforeach
|
@endforeach
|
||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
@ -68,3 +45,38 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@endsection
|
@endsection
|
||||||
|
|
||||||
|
@push('scripts')
|
||||||
|
<script type="text/javascript">
|
||||||
|
$(document).ready(function() {
|
||||||
|
$('.album-expand-handle').click(function() {
|
||||||
|
var parent = $(this).closest('tr');
|
||||||
|
|
||||||
|
var handle = $('.album-expand-handle', parent);
|
||||||
|
var albumID = parent.data('album-id');
|
||||||
|
$('tr[data-parent-album-id=' + albumID + ']').toggle();
|
||||||
|
|
||||||
|
if (handle.hasClass('fa-plus'))
|
||||||
|
{
|
||||||
|
handle.addClass('fa-minus');
|
||||||
|
handle.removeClass('fa-plus');
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Toggle all children
|
||||||
|
$('tr[data-parent-album-id=' + albumID + ']').each(function(index, element)
|
||||||
|
{
|
||||||
|
var childHandle = $('.album-expand-handle', element);
|
||||||
|
if (childHandle.hasClass('fa-minus'))
|
||||||
|
{
|
||||||
|
childHandle.click();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
handle.addClass('fa-plus');
|
||||||
|
handle.removeClass('fa-minus');
|
||||||
|
}
|
||||||
|
})
|
||||||
|
})
|
||||||
|
</script>
|
||||||
|
@endpush
|
@ -0,0 +1,32 @@
|
|||||||
|
<tr data-album-id="{{ $album->id }}" class="{{ $is_child ? 'hidden' : '' }}" @if (!is_null($album->parent_album_id)) data-parent-album-id="{{ $album->parent_album_id }}" @endif>
|
||||||
|
<td style="width: 20px;">
|
||||||
|
@if ($album->children()->count() > 0)
|
||||||
|
<i class="album-expand-handle fa fa-fw fa-plus mt-2"></i>
|
||||||
|
@endif
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<span style="font-size: 1.3em;">
|
||||||
|
@can('edit', $album)
|
||||||
|
<a href="{{ route('albums.show', ['id' => $album->id]) }}">{{ $album->name }}</a>
|
||||||
|
@endcan
|
||||||
|
@cannot('edit', $album)
|
||||||
|
{{ $album->name }} <i class="fa fa-fw fa-lock"></i>
|
||||||
|
@endcannot
|
||||||
|
</span><br/>
|
||||||
|
<p>{{ $album->description }}</p>
|
||||||
|
<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">
|
||||||
|
<div class="btn-group">
|
||||||
|
@can('edit', $album)
|
||||||
|
<a href="{{ route('albums.edit', ['id' => $album->id]) }}" class="btn btn-secondary">@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
|
||||||
|
</div>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
@foreach ($album->children as $album)
|
||||||
|
@include (Theme::viewName('partials.single_album_admin'), ['is_child' => true])
|
||||||
|
@endforeach
|
Loading…
Reference in New Issue
Block a user