]> BookStack Code Mirror - bookstack/commitdiff
Merge branch 'BookStackApp-master' of git://github.com/OsmosysSoftware/BookStack...
authorDan Brown <redacted>
Wed, 6 Dec 2017 15:52:54 +0000 (15:52 +0000)
committerDan Brown <redacted>
Wed, 6 Dec 2017 15:52:54 +0000 (15:52 +0000)
31 files changed:
app/Book.php
app/Http/Controllers/BookController.php
app/User.php
database/migrations/2017_08_29_102650_add_cover_image_display.php [new file with mode: 0644]
public/book_default_cover.png [new file with mode: 0644]
resources/assets/js/global.js
resources/assets/sass/styles.scss
resources/lang/de/common.php
resources/lang/de/settings.php
resources/lang/en/common.php
resources/lang/en/settings.php
resources/lang/es/common.php
resources/lang/es/settings.php
resources/lang/fr/common.php
resources/lang/fr/settings.php
resources/lang/ja/common.php
resources/lang/nl/common.php
resources/lang/nl/settings.php
resources/lang/pl/common.php
resources/lang/pt_BR/common.php
resources/lang/pt_BR/settings.php
resources/lang/sk/common.php
resources/lang/sk/settings.php
resources/views/books/create.blade.php
resources/views/books/edit.blade.php
resources/views/books/form.blade.php
resources/views/books/grid-item.blade.php [new file with mode: 0644]
resources/views/books/index.blade.php
resources/views/components/image-picker.blade.php
resources/views/users/edit.blade.php
tests/UserProfileTest.php

index 06c00945d43c4dbdea946c21769ffef7a626888f..fed602332bb18c41489f0008793bf3b1228eb24d 100644 (file)
@@ -3,7 +3,7 @@
 class Book extends Entity
 {
 
-    protected $fillable = ['name', 'description'];
+    protected $fillable = ['name', 'description', 'image_id'];
 
     /**
      * Get the url for this book.
@@ -17,7 +17,46 @@ class Book extends Entity
         }
         return baseUrl('/books/' . urlencode($this->slug));
     }
-
+    
+    /**
+     * Returns book cover image, if book cover not exists return default cover image.
+     * @param int $height - Height of the image
+     * @param type $width - Width of the image
+     * @return type string
+     */
+    public function getBookCover($height = 170, $width = 300)
+    {
+        $default = baseUrl('/book_default_cover.png');
+        $image = $this->image_id;
+        if ($image === 0 || $image === '0' || $image === null) 
+            return $default;
+        try {
+            $cover = $this->cover ? baseUrl($this->cover->getThumb($width, $height, false)) : $default;
+        } catch (\Exception $err) {
+            $cover = $default;
+        }
+        return $cover;
+    }
+    
+    /**
+     * Get an excerpt of this book's name to the specified length or less.
+     * @param int $length
+     * @return string
+     */
+    public function getHeadingExcerpt($length = 35)
+    {
+        $bookHeading = $this->name;
+        return strlen($bookHeading) > $length ? substr($bookHeading, 0, $length-3) . '...' : $bookHeading;
+    }
+    
+    /**
+     * Get the cover image of the book
+     * @return \Illuminate\Database\Eloquent\Relations\BelongsTo
+     */
+    public function cover()
+    {
+        return $this->belongsTo(Image::class, 'image_id');
+    }
     /*
      * Get the edit url for this book.
      * @return string
@@ -64,5 +103,14 @@ class Book extends Entity
     {
         return "'BookStack\\\\Book' as entity_type, id, id as entity_id, slug, name, {$this->textField} as text,'' as html, '0' as book_id, '0' as priority, '0' as chapter_id, '0' as draft, created_by, updated_by, updated_at, created_at";
     }
+    
+    /**
+     * Get the user that created the page revision
+     * @return \Illuminate\Database\Eloquent\Relations\BelongsTo
+     */
+    public function createdBy()
+    {   
+        return $this->belongsTo(User::class, 'created_by');
+    }
 
 }
index 7e4b3fd81f80f4a001c368c3f061e972f0e6f5dc..2d961355be84f1ea740fb1e16db09c6358a21436 100644 (file)
@@ -40,12 +40,14 @@ class BookController extends Controller
         $recents = $this->signedIn ? $this->entityRepo->getRecentlyViewed('book', 4, 0) : false;
         $popular = $this->entityRepo->getPopular('book', 4, 0);
         $new = $this->entityRepo->getRecentlyCreated('book', 4, 0);
+        $booksViewType = $this->currentUser->books_view_type;
         $this->setPageTitle('Books');
         return view('books/index', [
             'books' => $books,
             'recents' => $recents,
             'popular' => $popular,
-            'new' => $new
+            'new' => $new, 
+            'booksViewType' => $booksViewType
         ]);
     }
 
@@ -125,9 +127,9 @@ class BookController extends Controller
             'name' => 'required|string|max:255',
             'description' => 'string|max:1000'
         ]);
-        $book = $this->entityRepo->updateFromInput('book', $book, $request->all());
-        Activity::add($book, 'book_update', $book->id);
-        return redirect($book->getUrl());
+         $book = $this->entityRepo->updateFromInput('book', $book, $request->all());
+         Activity::add($book, 'book_update', $book->id);
+         return redirect($book->getUrl());
     }
 
     /**
index 8033557e4cb9a0a048c1d7112c90f84dc4e4bf70..264723be9c615a8477ea47fd1be670c3756cf405 100644 (file)
@@ -22,7 +22,7 @@ class User extends Model implements AuthenticatableContract, CanResetPasswordCon
      * The attributes that are mass assignable.
      * @var array
      */
-    protected $fillable = ['name', 'email', 'image_id'];
+    protected $fillable = ['name', 'email', 'image_id', 'books_view_type' ];
 
     /**
      * The attributes excluded from the model's JSON form.
diff --git a/database/migrations/2017_08_29_102650_add_cover_image_display.php b/database/migrations/2017_08_29_102650_add_cover_image_display.php
new file mode 100644 (file)
index 0000000..a8bba51
--- /dev/null
@@ -0,0 +1,40 @@
+<?php
+
+use Illuminate\Support\Facades\Schema;
+use Illuminate\Database\Schema\Blueprint;
+use Illuminate\Database\Migrations\Migration;
+
+class AddCoverImageDisplay extends Migration
+{
+    /**
+     * Run the migrations.
+     *
+     * @return void
+     */
+    public function up()
+    {
+        Schema::table('users', function (Blueprint $table) {
+            $table->string('books_view_type',10)->default('grid');
+        });
+
+        Schema::table('books', function (Blueprint $table) {
+            $table->integer('image_id');
+        });
+    }
+
+    /**
+     * Reverse the migrations.
+     *
+     * @return void
+     */
+    public function down()
+    {
+        Schema::table('users', function (Blueprint $table) {
+            $table->dropColumn('books_view_type');
+        });
+
+        Schema::table('books', function (Blueprint $table) {
+            $table->dropColumn('image_id');
+        });
+    }
+}
diff --git a/public/book_default_cover.png b/public/book_default_cover.png
new file mode 100644 (file)
index 0000000..7b6c995
Binary files /dev/null and b/public/book_default_cover.png differ
index 352616c5a2e00c73a7b88e521f84e9eca414b76c..f746b28612dff39befb3f6b53b0f07e5bebc7549 100644 (file)
@@ -119,6 +119,19 @@ jQuery.expr[":"].contains = $.expr.createPseudo(function (arg) {
     };
 });
 
+// Common jQuery actions
+$('[data-action="expand-entity-list-details"]').click(function() {
+    $('.entity-list.compact').find('p').not('.empty-text').slideToggle(240);
+});
+
+// Toggle thumbnail::hide image and reduce grid size
+$(document).ready(function(){
+   $('[data-action="expand-thumbnail"]').click(function(){
+     $('.gallery-item').toggleClass("collapse").find('img').slideToggle(50);
+   });
+});
+
+
 // Detect IE for css
 if(navigator.userAgent.indexOf('MSIE')!==-1
     || navigator.appVersion.indexOf('Trident/') > 0
index e8d87d520260dadee1693d7c7e6b5930c7f42d06..730cc8a65b989729573fbf5e65854434ef220083 100644 (file)
@@ -233,5 +233,73 @@ $btt-size: 40px;
   }
 }
 
+// styles for Books grid view
+.cover {
+    width: 290px;
+    border-radius: 3px;
+  }
+
+.featured-image-container {
+    position: relative;
+    overflow: hidden;
+    background: #F2F2F2;
+    border: 1px solid #ddd;
+    border-bottom: 0px;
+}
+
+.featured-image-container img {
+    display: block;
+    max-width: 100%;
+    height: auto;
+    -webkit-transition: all .5s ease;
+    -moz-transition: all .5s ease;
+    -ms-transition: all .5s ease;
+    -o-transition: all .5s ease;
+    transition: all .5s ease;
+}
+
+.book-content {
+    padding: 30px;
+    border: 1px solid #ddd;
+    border-top: 0px;
+    border-bottom-width: 2px;
+}
+.book-content h2 {
+    font-size: 1.5em;
+    line-height: 1.2;
+    margin: 0 0 10px;
+}
+
+.book-content  h2 a {
+    display: block;
+    color: #009688;;
+    text-decoration: none;
+}
+
+.book-content p {
+    font-size: .85em;
+    margin: 0 0 10px;
+    line-height: 1.6em;
+}
 
+.featured-image-container img:hover {
+    -webkit-transform: scale(1.15);
+    -moz-transform: scale(1.15);
+    -ms-transform: scale(1.15);
+    -o-transform: scale(1.15);
+    transform: scale(1.15);
+    opacity: .5;
+}
+.books-grid-div {
+    margin-bottom : 20px;
+}
 
+@media (min-width:992px){
+    .row.auto-clear .col-md-4:nth-child(3n+1){clear:left;}
+}
+@media (min-width:992px){
+    .row.auto-clear .col-md-4:nth-child(3n+1){clear:left;}
+}
+@media (max-width:991px){
+    .row.auto-clear .col-xs-6:nth-child(2n+1){clear:left;}
+}
\ No newline at end of file
index 3c21a9d0802bab681efb927e572df83f6f9ae77c..2cc98084611a2d02abbb92811e2b9343ee7eeda4 100644 (file)
@@ -17,6 +17,8 @@ return [
     'name' => 'Name',
     'description' => 'Beschreibung',
     'role' => 'Rolle',
+    'cover_image' => 'Titelbild',
+    'cover_image_description' => 'Das Bild sollte eine Auflösung von 300x170px haben.',
 
     /**
      * Actions
@@ -43,7 +45,7 @@ return [
     'no_items' => 'Keine Einträge gefunden.',
     'back_to_top' => 'nach oben',
     'toggle_details' => 'Details zeigen/verstecken',
-
+    'toggle_thumbnails' => 'Thumbnails zeigen/verstecken',
     /**
      * Header
      */
index 9435ec80853ecea267fdc04126acbe268f50181f..2da517292289452e706a5330b3b955adecda90df 100644 (file)
@@ -96,6 +96,7 @@ return [
     'users_delete_warning' => 'Der Benutzer ":userName" wird aus dem System gelöscht.',
     'users_delete_confirm' => 'Sind Sie sicher, dass Sie diesen Benutzer löschen möchten?',
     'users_delete_success' => 'Benutzer erfolgreich gelöscht.',
+    'users_books_view_type' => 'Bevorzugtes Display-Layout für Bücher',
     'users_edit' => 'Benutzer bearbeiten',
     'users_edit_profile' => 'Profil bearbeiten',
     'users_edit_success' => 'Benutzer erfolgreich aktualisisert',
index 269905a59c7f181430f47565b8828fdc16b49b50..70cfc5701bd3d379d32650d6f9412df399463b40 100644 (file)
@@ -18,7 +18,9 @@ return [
     'name' => 'Name',
     'description' => 'Description',
     'role' => 'Role',
-
+    'cover_image' => 'Cover image',
+    'cover_image_description' => 'This image should be approx 300x170px.',
+    
     /**
      * Actions
      */
@@ -45,8 +47,8 @@ return [
     'no_items' => 'No items available',
     'back_to_top' => 'Back to top',
     'toggle_details' => 'Toggle Details',
+    'toggle_thumbnails' => 'Toggle Thumbnails',
     'details' => 'Details',
-
     /**
      * Header
      */
index 468c5981f9641178e8d0dc8f1c1d23904761d690..4153055eb39443d3f427426d95ebd3b5dde86f63 100755 (executable)
@@ -94,6 +94,7 @@ return [
     'users_external_auth_id' => 'External Authentication ID',
     'users_password_warning' => 'Only fill the below if you would like to change your password:',
     'users_system_public' => 'This user represents any guest users that visit your instance. It cannot be used to log in but is assigned automatically.',
+    'users_books_view_type' => 'Preferred layout for books viewing',
     'users_delete' => 'Delete User',
     'users_delete_named' => 'Delete user :userName',
     'users_delete_warning' => 'This will fully delete this user with the name \':userName\' from the system.',
index 3a62a21776fcc09817ad3d3990c7c68951bdc720..a173f286e3985653d6fa374c19041c282de2cb7d 100644 (file)
@@ -17,7 +17,8 @@ return [
     'name' => 'Nombre',
     'description' => 'Descripción',
     'role' => 'Rol',
-
+    'cover_image' => 'Imagen de portada',
+    'cover_image_description' => 'Esta imagen debe ser aproximadamente 300x170px.',
     /**
      * Actions
      */
@@ -43,6 +44,7 @@ return [
     'no_items' => 'No hay items disponibles',
     'back_to_top' => 'Volver arriba',
     'toggle_details' => 'Alternar detalles',
+    'toggle_thumbnails' => 'Alternar miniaturas',
 
     /**
      * Header
index cd6a8b8d9b56eac1852dafbf88dcf620f4291445..9535d3f455146d520e5b060685857217ef912a0b 100644 (file)
@@ -91,6 +91,7 @@ return [
     'users_external_auth_id' => 'ID externo de autenticación',
     'users_password_warning' => 'Solo rellene a continuación si desea cambiar su password:',
     'users_system_public' => 'Este usuario representa cualquier usuario invitado que visita la aplicación. No puede utilizarse para hacer login sio que es asignado automáticamente.',
+    'users_books_view_type' => 'Diseño de pantalla preferido para libros',
     'users_delete' => 'Borrar usuario',
     'users_delete_named' => 'Borrar usuario :userName',
     'users_delete_warning' => 'Se borrará completamente el usuario con el nombre \':userName\' del sistema.',
index 7a8ec55b605d90f53bc27559b6988b535b6231dd..2553d14822c3ac3ba5b7829a1ef1ed0017c20a6c 100644 (file)
@@ -17,7 +17,8 @@ return [
     'name' => 'Nom',
     'description' => 'Description',
     'role' => 'Rôle',
-
+    'cover_image' => 'Image de couverture',
+    'cover_image_description' => 'Cette image doit être environ 300x170px.',
     /**
      * Actions
      */
@@ -43,6 +44,7 @@ return [
     'no_items' => 'Aucun élément',
     'back_to_top' => 'Retour en haut',
     'toggle_details' => 'Afficher les détails',
+    'toggle_thumbnails' => 'Afficher les vignettes',
 
     /**
      * Header
index 92e623795dcbc851cbf006e993859d135b2b624f..399afdc9ab3b907bab6f464ccf3c5650aff1dfae 100644 (file)
@@ -91,6 +91,7 @@ return [
     'users_external_auth_id' => 'Identifiant d\'authentification externe',
     'users_password_warning' => 'Remplissez ce fomulaire uniquement si vous souhaitez changer de mot de passe:',
     'users_system_public' => 'Cet utilisateur représente les invités visitant votre instance. Il est assigné automatiquement aux invités.',
+    'users_books_view_type' => 'Disposition d\'affichage préférée pour les livres',
     'users_delete' => 'Supprimer un utilisateur',
     'users_delete_named' => 'Supprimer l\'utilisateur :userName',
     'users_delete_warning' => 'Ceci va supprimer \':userName\' du système.',
index 383294880b5d94d31748c7be61b5d5c7b8db3614..185e6116cf463d7115f3c46c6e3f9d24c741eabb 100644 (file)
@@ -17,7 +17,7 @@ return [
     'name' => '名称',
     'description' => '概要',
     'role' => '権限',
-
+    'cover_image_description' => 'この画像は約 300x170px をする必要があります。',
     /**
      * Actions
      */
index 1ae0ade7caa082ac39a50a668da8fd77db66c511..fdfb90fb250704d074fa36a84c303ea13a110117 100644 (file)
@@ -18,7 +18,8 @@ return [
     'name' => 'Naam',
     'description' => 'Beschrijving',
     'role' => 'Rol',
-
+    'cover_image' => 'Omslagfoto',
+    'cover_image_description' => 'Deze afbeelding moet ongeveer 300x170px zijn.',
     /**
      * Actions
      */
@@ -44,6 +45,7 @@ return [
     'no_items' => 'Geen items beschikbaar',
     'back_to_top' => 'Terug naar boven',
     'toggle_details' => 'Details Weergeven',
+    'toggle_thumbnails' => 'Thumbnails Weergeven',
 
     /**
      * Header
index 7408a2dc32c53ca5a6f62018bf1acf49d2576dd9..7b8adf602e7ad0c00176ff9028a882ad45fcf506 100644 (file)
@@ -91,6 +91,7 @@ return [
     'users_external_auth_id' => 'External Authentication ID',
     'users_password_warning' => 'Vul onderstaande formulier alleen in als je het wachtwoord wilt aanpassen:',
     'users_system_public' => 'De eigenschappen van deze gebruiker worden voor elke gastbezoeker gebruikt. Er kan niet mee ingelogd worden en wordt automatisch toegewezen.',
+    'users_books_view_type' => 'Voorkeursuitleg voor het weergeven van boeken',
     'users_delete' => 'Verwijder gebruiker',
     'users_delete_named' => 'Verwijder gebruiker :userName',
     'users_delete_warning' => 'Dit zal de gebruiker \':userName\' volledig uit het systeem verwijderen.',
index 1c8963653e15743f5f47d0f111fa0e29ab679888..f7741ba6f4b5ac886ee6cba2a8689a082bbb259a 100644 (file)
@@ -17,7 +17,9 @@ return [
     'name' => 'Nazwa',
     'description' => 'Opis',
     'role' => 'Rola',
-
+    'cover_image' => 'Zdjęcie z okładki',
+    'cover_image_description' => 'Ten obraz powinien wynosić około 300 x 170 piksli.',
+    
     /**
      * Actions
      */
index 632a1a078bc99bbdd2affbcb99517e0b73df4b36..991cb0b7e4fbfde96fe75a270cd2176125f5a8c6 100644 (file)
@@ -18,7 +18,8 @@ return [
     'name' => 'Nome',
     'description' => 'Descrição',
     'role' => 'Regra',
-
+    'cover_image' => 'Imagem de capa',
+    'cover_image_description' => 'Esta imagem deve ser aproximadamente 300x170px.',
     /**
      * Actions
      */
@@ -45,6 +46,7 @@ return [
     'no_items' => 'Nenhum item disponível',
     'back_to_top' => 'Voltar ao topo',
     'toggle_details' => 'Alternar Detalhes',
+    'toggle_thumbnails' => 'Alternar Miniaturas',
     'details' => 'Detalhes',
 
     /**
index 5513c217f7f7326f21630f5d29bdb6afbfa4e643..0da7985577301c66bddcc8111b9ca185b5606e7a 100644 (file)
@@ -94,6 +94,7 @@ return [
     'users_external_auth_id' => 'ID de Autenticação Externa',
     'users_password_warning' => 'Preencha os dados abaixo caso queira modificar a sua senha:',
     'users_system_public' => 'Esse usuário representa quaisquer convidados que visitam o aplicativo. Ele não pode ser usado para login.',
+    'users_books_view_type' => 'Layout preferido para mostrar livros',
     'users_delete' => 'Excluir Usuário',
     'users_delete_named' => 'Excluir :userName',
     'users_delete_warning' => 'A ação vai excluir completamente o usuário de nome \':userName\' do sistema.',
index 100981597374d714f49c4b284677772e7f16a7f1..a823fb37915c9d0f62bfe26e091833300184aa57 100644 (file)
@@ -17,7 +17,8 @@ return [
     'name' => 'Meno',
     'description' => 'Popis',
     'role' => 'Rola',
-
+    'cover_image' => 'Obal knihy',
+    'cover_image_description' => 'Tento obrázok by mal byť približne 300 x 170 pixelov.',
     /**
      * Actions
      */
@@ -43,6 +44,7 @@ return [
     'no_items' => 'Žiadne položky nie sú dostupné',
     'back_to_top' => 'Späť nahor',
     'toggle_details' => 'Prepnúť detaily',
+    'toggle_thumbnails' => 'Prepnúť náhľady',
 
     /**
      * Header
index 643b4b8ffbde1d2d9e122080544a0711dcb7a6ee..4438f8038750fd9b7895eb62eae81db3c054279f 100644 (file)
@@ -91,6 +91,7 @@ return [
     'users_external_auth_id' => 'Externé autentifikačné ID',
     'users_password_warning' => 'Pole nižšie vyplňte iba ak chcete zmeniť heslo:',
     'users_system_public' => 'Tento účet reprezentuje každého hosťovského používateľa, ktorý navštívi Vašu inštanciu. Nedá sa pomocou neho prihlásiť a je priradený automaticky.',
+    'users_books_view_type' => 'Preferované rozloženie pre prezeranie kníh',
     'users_delete' => 'Zmazať používateľa',
     'users_delete_named' => 'Zmazať používateľa :userName',
     'users_delete_warning' => ' Toto úplne odstráni používateľa menom \':userName\' zo systému.',
index 385e6b9d7a4e868f4a5b42acf4585c287068c8cd..4798459c21672b2068ecb1d2bb63c5ac932da595 100644 (file)
     <div class="card">
         <h3><i class="zmdi zmdi-plus"></i> {{ trans('entities.books_create') }}</h3>
         <div class="body">
-            <form action="{{ baseUrl("/books") }}" method="POST">
+            <form action="{{ baseUrl("/books") }}" method="POST" enctype="multipart/form-data">
                 @include('books/form')
             </form>
         </div>
     </div>
 </div>
-
+<p class="margin-top large"><br></p>
+    @include('components.image-manager', ['imageType' => 'cover'])
 @stop
\ No newline at end of file
index 9d9c54fec6e521e909c6e5ce159c640c975dc3e5..6bf285f95f2f8fcbe2c76499370eec2e860f046f 100644 (file)
@@ -20,5 +20,5 @@
             </div>
         </div>
     </div>
-
+@include('components.image-manager', ['imageType' => 'cover'])
 @stop
\ No newline at end of file
index 84a30e7e9982a40e7e0c5ecfe9c1bf752c9693b3..4a443466bbd88a70910f8a9362320496182f3b9a 100644 (file)
@@ -9,6 +9,21 @@
     <label for="description">{{ trans('common.description') }}</label>
     @include('form/textarea', ['name' => 'description'])
 </div>
+<div class="form-group" id="logo-control">
+        <label for="user-avatar">{{ trans('common.cover_image') }}</label>
+        <p class="small">{{ trans('common.cover_image_description') }}</p>
+
+        @include('components.image-picker', [
+            'resizeHeight' => '512',
+            'resizeWidth' => '512',
+            'showRemove' => true,
+            'defaultImage' => baseUrl('/book_default_cover.png'),
+            'currentImage' => @isset($model) ? $model->getBookCover() : baseUrl('/book_default_cover.png') ,
+            'currentId' => @isset($model) ? $model->image_id : 0,
+            'name' => 'image_id',
+            'imageClass' => 'cover'
+        ])
+</div>
 
 <div class="form-group text-right">
     <a href="{{ isset($book) ? $book->getUrl() : baseUrl('/books') }}" class="button outline">{{ trans('common.cancel') }}</a>
diff --git a/resources/views/books/grid-item.blade.php b/resources/views/books/grid-item.blade.php
new file mode 100644 (file)
index 0000000..74801ec
--- /dev/null
@@ -0,0 +1,18 @@
+<div class="col-xs-12 col-sm-4 col-md-4 col-lg-4 books-grid-div"  data-entity-type="book" data-entity-id="{{$book->id}}">
+    <div class="featured-image-container">
+        <a href="{{$book->getUrl()}}" title="{{$book->name}}">
+            <img width="1600" height="900" src="{{$book->getBookCover()}}" alt="{{$book->name}}">
+        </a>
+    </div>
+    <div class="book-content">
+        <h2><a href="{{$book->getUrl()}}" title="{{$book->name}}" > {{$book->getHeadingExcerpt()}} </a></h2>
+        @if(isset($book->searchSnippet))
+            <p >{{!! $book->searchSnippet !!}}</p>
+        @else
+            <p >{{ $book->getExcerpt(130) }}</p>
+        @endif
+        <div >
+            <span>@include('partials.entity-meta', ['entity' => $book])</span>
+        </div>
+    </div>
+</div>
\ No newline at end of file
index c22b4591f01c43f3efc126cf30dc40a8acc4e1d7..d392af045aab36ee3a99e03a21a8a2a9200517d5 100644 (file)
 @stop
 
 @section('body')
-
-    <div class="container small" ng-non-bindable>
+    @if($booksViewType === 'list')
+        <div class="container small" ng-non-bindable>
+    @else
+        <div class="container" ng-non-bindable>
+    @endif
         <h1>{{ trans('entities.books') }}</h1>
         @if(count($books) > 0)
-            @foreach($books as $book)
-                @include('books/list-item', ['book' => $book])
-                <hr>
-            @endforeach
-            {!! $books->render() !!}
+            @if($booksViewType === 'list')
+                @foreach($books as $book)
+                    @include('books/list-item', ['book' => $book])
+                    <hr>
+                @endforeach
+                {!! $books->render() !!}
+            @else 
+             <div class="row auto-clear">
+                    @foreach($books as $key => $book)
+                            @include('books/grid-item', ['book' => $book])
+                    @endforeach
+                <div class="col-xs-12">
+                    {!! $books->render() !!}
+                </div>
+             </div>
+            @endif
         @else
             <p class="text-muted">{{ trans('entities.books_empty') }}</p>
             @if(userCan('books-create-all'))
@@ -55,5 +69,4 @@
             @endif
         @endif
     </div>
-
 @stop
\ No newline at end of file
index 228e8d230c6663009ed3431758d1007ab4a4ec38..2aa39d3d2639e18ed9150f5f811e12fbc235855c 100644 (file)
@@ -13,7 +13,7 @@
         <button class="text-button neg" data-action="remove-image" type="button">{{ trans('common.remove') }}</button>
     @endif
 
-    <input type="hidden" name="{{$name}}" id="{{$name}}" value="{{ isset($currentId) && ($currentId !== '' && $currentId !== false) ? $currentId : $currentImage}}">
+    <input type="hidden" name="{{$name}}" id="{{$name}}" value="{{ isset($currentId) && ($currentId !== 0 && $currentId !== false) ? $currentId : $currentImage}}">
 </div>
 
 <script>
index f860d12fd96a27dbb110f1a6705b9966f99a6e98..00db029070f32657f626b4679e0778db83b70070 100644 (file)
                                     @endforeach
                                 </select>
                             </div>
+                            <div class="form-group">
+                                <label for="books-view-type">{{ trans('settings.users_books_view_type') }}</label>
+                                <select name="books_view_type" id="books-view-type">
+                                    <option @if($user->books_view_type === 'grid') selected @endif value="grid">Grid</option>
+                                    <option @if($user->books_view_type === 'list') selected @endif value="list">List</option>
+                                </select>
+                            </div>
                         </div>
                     </div>
                     <div class="form-group text-right">
@@ -87,4 +94,4 @@
 
     <p class="margin-top large"><br></p>
     @include('components.image-manager', ['imageType' => 'user'])
-@stop
+@stop
\ No newline at end of file
index 54671bbf6257cdc64c561241aa8ee2bc108c0433..4636fc76cf5b3747fed6a0ae45a6357896c9a7f6 100644 (file)
@@ -94,5 +94,27 @@ class UserProfileTest extends BrowserKitTest
             ->seePageIs('/settings/users/' . $guestUser->id)
             ->see('cannot delete the guest user');
     }
-    
+
+    public function test_books_view_is_list()
+    {
+        $editor = $this->getEditor([
+          'books_view_type' => 'list'
+        ]);
+
+        $this->actingAs($editor)
+            ->visit('/books')
+            ->pageNotHasElement('.featured-image-container')
+            ->pageHasElement('.entity-list-item');
+    }
+
+    public function test_books_view_is_grid()
+    {
+        $editor = $this->getEditor([
+          'books_view_type' => 'grid'
+        ]);
+
+        $this->actingAs($editor)
+            ->visit('/books')
+            ->pageHasElement('.featured-image-container');
+    }
 }