]> 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)
1  2 
app/Http/Controllers/BookController.php
resources/assets/js/global.js
resources/assets/sass/styles.scss
resources/lang/en/common.php
resources/lang/en/settings.php
resources/lang/nl/common.php
resources/lang/pt_BR/common.php
resources/lang/pt_BR/settings.php
tests/UserProfileTest.php

index 7e4b3fd81f80f4a001c368c3f061e972f0e6f5dc,b6175d8591e5ec6ee1a586c21b2e2517f9c19755..2d961355be84f1ea740fb1e16db09c6358a21436
@@@ -40,12 -40,14 +40,14 @@@ class BookController extends Controlle
          $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
          ]);
      }
  
              '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());
      }
  
      /**
          $this->checkOwnablePermission('book-update', $book);
  
          // Return if no map sent
 -        if (!$request->has('sort-tree')) {
 +        if (!$request->filled('sort-tree')) {
              return redirect($book->getUrl());
          }
  
index 352616c5a2e00c73a7b88e521f84e9eca414b76c,26dbf9a5eaab58859b777b1ddc892a55963ceb6a..f746b28612dff39befb3f6b53b0f07e5bebc7549
@@@ -58,57 -58,40 +58,57 @@@ window.$http = axiosInstance
  Vue.prototype.$http = axiosInstance;
  Vue.prototype.$events = window.$events;
  
 -
 -// AngularJS - Create application and load components
 -const angular = require("angular");
 -require("angular-resource");
 -require("angular-animate");
 -require("angular-sanitize");
 -require("angular-ui-sortable");
 -
 -let ngApp = angular.module('bookStack', ['ngResource', 'ngAnimate', 'ngSanitize', 'ui.sortable']);
 -
  // Translation setup
  // Creates a global function with name 'trans' to be used in the same way as Laravel's translation system
  const Translations = require("./translations");
  let translator = new Translations(window.translations);
  window.trans = translator.get.bind(translator);
 +window.trans_choice = translator.getPlural.bind(translator);
  
  
  require("./vues/vues");
  require("./components");
  
 -// Load in angular specific items
 -const Directives = require('./directives');
 -const Controllers = require('./controllers');
 -Directives(ngApp, window.$events);
 -Controllers(ngApp, window.$events);
  
  //Global jQuery Config & Extensions
  
 +/**
 + * Scroll the view to a specific element.
 + * @param {HTMLElement} element
 + */
 +window.scrollToElement = function(element) {
 +    if (!element) return;
 +    let offset = window.pageYOffset || document.documentElement.scrollTop || document.body.scrollTop;
 +    let top = element.getBoundingClientRect().top + offset;
 +    $('html, body').animate({
 +        scrollTop: top - 60 // Adjust to change final scroll position top margin
 +    }, 300);
 +};
 +
 +/**
 + * Scroll and highlight an element.
 + * @param {HTMLElement} element
 + */
 +window.scrollAndHighlight = function(element) {
 +    if (!element) return;
 +    window.scrollToElement(element);
 +    let color = document.getElementById('custom-styles').getAttribute('data-color-light');
 +    let initColor = window.getComputedStyle(element).getPropertyValue('background-color');
 +    element.style.backgroundColor = color;
 +    setTimeout(() => {
 +        element.classList.add('selectFade');
 +        element.style.backgroundColor = initColor;
 +    }, 10);
 +    setTimeout(() => {
 +        element.classList.remove('selectFade');
 +        element.style.backgroundColor = '';
 +    }, 3000);
 +};
 +
  // Smooth scrolling
  jQuery.fn.smoothScrollTo = function () {
      if (this.length === 0) return;
 -    $('html, body').animate({
 -        scrollTop: this.offset().top - 60 // Adjust to change final scroll position top margin
 -    }, 300); // Adjust to change animations speed (ms)
 +    window.scrollToElement(this[0]);
      return this;
  };
  
@@@ -119,6 -102,19 +119,19 @@@ jQuery.expr[":"].contains = $.expr.crea
      };
  });
  
+ // 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,04aa0d968886b6e81ba048f9890673fd1d47c0a4..730cc8a65b989729573fbf5e65854434ef220083
@@@ -15,6 -15,7 +15,6 @@@
  @import "header";
  @import "lists";
  @import "pages";
 -@import "comments";
  
  [v-cloak] {
    display: none; opacity: 0;
@@@ -68,6 -69,7 +68,6 @@@ $loadingSize: 10px
  .loading-container {
    position: relative;
    display: block;
 -  height: $loadingSize;
    margin: $-xl auto;
    > div {
      width: $loadingSize;
@@@ -75,8 -77,7 +75,8 @@@
      border-radius: $loadingSize;
      display: inline-block;
      vertical-align: top;
 -    transform: translate3d(0, 0, 0);
 +    transform: translate3d(-10px, 0, 0);
 +    margin-top: $-xs;
      animation-name: loadingBob;
      animation-duration: 1.4s;
      animation-iteration-count: infinite;
        background-color: $color-book;
        animation-delay: 0s;
    }
 -  > div:last-child {
 +  > div:last-of-type {
      left: $loadingSize+$-xs;
      background-color: $color-chapter;
      animation-delay: 0.6s;
    }
 +  > span {
 +    margin-left: $-s;
 +    font-style: italic;
 +    color: #888;
 +    vertical-align: top;
 +  }
  }
  
  
@@@ -233,5 -228,73 +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;}
+ }
index 269905a59c7f181430f47565b8828fdc16b49b50,1b05a229db25630b5e3944261b1d495b444f9c7b..70cfc5701bd3d379d32650d6f9412df399463b40
@@@ -18,7 -18,9 +18,9 @@@ return 
      'name' => 'Name',
      'description' => 'Description',
      'role' => 'Role',
+     'cover_image' => 'Cover image',
+     'cover_image_description' => 'This image should be approx 300x170px.',
+     
      /**
       * Actions
       */
@@@ -29,7 -31,6 +31,7 @@@
      'edit' => 'Edit',
      'sort' => 'Sort',
      'move' => 'Move',
 +    'reply' => 'Reply',
      'delete' => 'Delete',
      'search' => 'Search',
      'search_clear' => 'Clear Search',
@@@ -45,8 -46,8 +47,8 @@@
      'no_items' => 'No items available',
      'back_to_top' => 'Back to top',
      'toggle_details' => 'Toggle Details',
+     'toggle_thumbnails' => 'Toggle Thumbnails',
      'details' => 'Details',
      /**
       * Header
       */
index 468c5981f9641178e8d0dc8f1c1d23904761d690,644ca3a31497491fd20e4906a96ceaddb6221fda..4153055eb39443d3f427426d95ebd3b5dde86f63
mode 100755,100644..100755
@@@ -94,6 -94,7 +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.',
          'en' => 'English',
          'de' => 'Deutsch',
          'es' => 'Español',
 +        'es_AR' => 'Español Argentina',
          'fr' => 'Français',
          'nl' => 'Nederlands',
          'pt_BR' => 'Português do Brasil',
          'sk' => 'Slovensky',
          'ja' => '日本語',
          'pl' => 'Polski',
 +        'it' => 'Italian',
 +        'ru' => 'Русский'
      ]
      ///////////////////////////////////
  ];
index 1ae0ade7caa082ac39a50a668da8fd77db66c511,096676130eccfebae74dd8d159bab704c58efa12..fdfb90fb250704d074fa36a84c303ea13a110117
@@@ -10,7 -10,6 +10,7 @@@ return 
      'save' => 'Opslaan',
      'continue' => 'Doorgaan',
      'select' => 'Kies',
 +    'more' => 'Meer',
  
      /**
       * Form Labels
@@@ -18,7 -17,8 +18,8 @@@
      'name' => 'Naam',
      'description' => 'Beschrijving',
      'role' => 'Rol',
+     'cover_image' => 'Omslagfoto',
+     'cover_image_description' => 'Deze afbeelding moet ongeveer 300x170px zijn.',
      /**
       * Actions
       */
@@@ -34,7 -34,7 +35,7 @@@
      'search_clear' => 'Zoekopdracht wissen',
      'reset' => 'Reset',
      'remove' => 'Verwijderen',
 -
 +    'add' => 'Toevoegen',
  
      /**
       * Misc
@@@ -44,6 -44,7 +45,7 @@@
      'no_items' => 'Geen items beschikbaar',
      'back_to_top' => 'Terug naar boven',
      'toggle_details' => 'Details Weergeven',
+     'toggle_thumbnails' => 'Thumbnails Weergeven',
  
      /**
       * Header
index 632a1a078bc99bbdd2affbcb99517e0b73df4b36,97b6a93c4f273036d0bc836084dfe39c0292eabd..991cb0b7e4fbfde96fe75a270cd2176125f5a8c6
@@@ -10,7 -10,6 +10,7 @@@ return 
      'save' => 'Salvar',
      'continue' => 'Continuar',
      'select' => 'Selecionar',
 +    'more' => 'Mais',
  
      /**
       * Form Labels
@@@ -18,7 -17,8 +18,8 @@@
      'name' => 'Nome',
      'description' => 'Descrição',
      'role' => 'Regra',
+     'cover_image' => 'Imagem de capa',
+     'cover_image_description' => 'Esta imagem deve ser aproximadamente 300x170px.',
      /**
       * Actions
       */
      'edit' => 'Editar',
      'sort' => 'Ordenar',
      'move' => 'Mover',
 +    'reply' => 'Responder',
      'delete' => 'Excluir',
      'search' => 'Pesquisar',
      'search_clear' => 'Limpar Pesquisa',
      'reset' => 'Resetar',
      'remove' => 'Remover',
 -
 +    'add' => 'Adicionar',
  
      /**
       * Misc
@@@ -45,7 -44,7 +46,8 @@@
      'no_items' => 'Nenhum item disponível',
      'back_to_top' => 'Voltar ao topo',
      'toggle_details' => 'Alternar Detalhes',
+     'toggle_thumbnails' => 'Alternar Miniaturas',
 +    'details' => 'Detalhes',
  
      /**
       * Header
index 5513c217f7f7326f21630f5d29bdb6afbfa4e643,8ebd2b728e6a91c88b85e49d895618e42e11a758..0da7985577301c66bddcc8111b9ca185b5606e7a
@@@ -1,13 -1,13 +1,13 @@@
  <?php
  
  return [
 -    
 +
      /**
       * Settings text strings
       * Contains all text strings used in the general settings sections of BookStack
       * including users and roles.
       */
 -    
 +
      'settings' => 'Configurações',
      'settings_save' => 'Salvar Configurações',
      'settings_save_success' => 'Configurações Salvas',
@@@ -31,9 -31,6 +31,9 @@@
      'app_logo_desc' => 'A imagem deve ter 43px de altura. <br>Imagens mais largas devem ser reduzidas.',
      'app_primary_color' => 'Cor primária da Aplicação',
      'app_primary_color_desc' => 'Esse valor deverá ser Hexadecimal. <br>Deixe em branco para que o Bookstack assuma a cor padrão.',
 +    'app_homepage' => 'Página incial',
 +    'app_homepage_desc' => 'Selecione a página para ser usada como página inicial em vez da padrão. Permissões da página serão ignoradas.',
 +    'app_homepage_default' => 'Escolhida página inicial padrão',
  
      /**
       * Registration settings
@@@ -94,6 -91,7 +94,7 @@@
      '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.',
      'users_edit_success' => 'Usuário atualizado com sucesso',
      'users_avatar' => 'Imagem de Usuário',
      'users_avatar_desc' => 'Essa imagem deve ser um quadrado com aproximadamente 256px de altura e largura.',
 +    'users_preferred_language' => 'Linguagem de Preferência',
      'users_social_accounts' => 'Contas Sociais',
      'users_social_accounts_info' => 'Aqui você pode conectar outras contas para acesso mais rápido. Desconectar uma conta não retira a possibilidade de acesso usando-a. Para revogar o acesso ao perfil através da conta social, você deverá fazê-lo na sua conta social.',
      'users_social_connect' => 'Contas conectadas',
index 54671bbf6257cdc64c561241aa8ee2bc108c0433,eabfce00409ea5c569c44634a5989d8fa94e395d..4636fc76cf5b3747fed6a0ae45a6357896c9a7f6
@@@ -33,7 -33,7 +33,7 @@@ class UserProfileTest extends BrowserKi
  
      public function test_profile_page_shows_created_content_counts()
      {
 -        $newUser = $this->getEditor();
 +        $newUser = $this->getNewBlankUser();
  
          $this->asAdmin()->visit('/user/' . $newUser->id)
              ->see($newUser->name)
@@@ -52,7 -52,7 +52,7 @@@
  
      public function test_profile_page_shows_recent_activity()
      {
 -        $newUser = $this->getEditor();
 +        $newUser = $this->getNewBlankUser();
          $this->actingAs($newUser);
          $entities = $this->createEntityChainBelongingToUser($newUser, $newUser);
          \Activity::add($entities['book'], 'book_update', $entities['book']->id);
@@@ -66,7 -66,7 +66,7 @@@
  
      public function test_clicking_user_name_in_activity_leads_to_profile_page()
      {
 -        $newUser = $this->getEditor();
 +        $newUser = $this->getNewBlankUser();
          $this->actingAs($newUser);
          $entities = $this->createEntityChainBelongingToUser($newUser, $newUser);
          \Activity::add($entities['book'], 'book_update', $entities['book']->id);
              ->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');
+     }
  }