]> BookStack Code Mirror - bookstack/commitdiff
Added ability to set a page to view on the homepage.
authorDan Brown <redacted>
Mon, 28 Aug 2017 12:38:32 +0000 (13:38 +0100)
committerDan Brown <redacted>
Mon, 28 Aug 2017 12:38:32 +0000 (13:38 +0100)
Relates to #372 and #126

14 files changed:
app/Http/Controllers/HomeController.php
app/Http/Controllers/PageController.php
app/Repos/EntityRepo.php
app/Services/ExportService.php
app/Services/ViewService.php
resources/assets/js/components/entity-selector.js
resources/assets/js/components/index.js
resources/assets/js/components/page-picker.js [new file with mode: 0644]
resources/assets/sass/_forms.scss
resources/lang/en/settings.php
resources/views/components/page-picker.blade.php [new file with mode: 0644]
resources/views/home-custom.blade.php [new file with mode: 0644]
resources/views/pages/page-display.blade.php
resources/views/settings/index.blade.php

index ad3b416555d76ebf818d8470673030432f8150b8..e9cd72fe219a0f64b04157e27c3048c11f96375d 100644 (file)
@@ -31,11 +31,23 @@ class HomeController extends Controller
         $recentFactor = count($draftPages) > 0 ? 0.5 : 1;
         $recents = $this->signedIn ? Views::getUserRecentlyViewed(12*$recentFactor, 0) : $this->entityRepo->getRecentlyCreated('book', 12*$recentFactor);
         $recentlyUpdatedPages = $this->entityRepo->getRecentlyUpdated('page', 12);
-        return view('home', [
+
+        // Custom homepage
+        $customHomepage = false;
+        $homepageSetting = setting('app-homepage');
+        if ($homepageSetting) {
+            $id = intval(explode(':', $homepageSetting)[0]);
+            $customHomepage = $this->entityRepo->getById('page', $id);
+            $this->entityRepo->renderPage($customHomepage);
+        }
+
+        $view = $customHomepage ? 'home-custom' : 'home';
+        return view($view, [
             'activity' => $activity,
             'recents' => $recents,
             'recentlyUpdatedPages' => $recentlyUpdatedPages,
-            'draftPages' => $draftPages
+            'draftPages' => $draftPages,
+            'customHomepage' => $customHomepage
         ]);
     }
 
index 573907e560e017965617d8bd7567b3128320ebce..21572db29ddb2cf65ac2f4a72b72e834bbb2244b 100644 (file)
@@ -167,7 +167,7 @@ class PageController extends Controller
         return view('pages/show', [
             'page' => $page,'book' => $page->book,
             'current' => $page, 'sidebarTree' => $sidebarTree,
-            'pageNav' => $pageNav, 'pageContent' => $pageContent]);
+            'pageNav' => $pageNav]);
     }
 
     /**
index d87c40f9b12cca06c74fbe81b5133e84c6a7c517..b2067ad7b75a1f6c661cf0c26ef8f086c5c38feb 100644 (file)
@@ -710,6 +710,7 @@ class EntityRepo
             $content = str_replace($matches[0][$index], trim($innerContent), $content);
         }
 
+        $page->renderedHTML = $content;
         return $content;
     }
 
index 78cef41a4d333270c0af29b7b5e7fba07ec03514..40402dbce461e73b3c0b81e7bb7b3a5b515c9805 100644 (file)
@@ -27,9 +27,9 @@ class ExportService
      */
     public function pageToContainedHtml(Page $page)
     {
+        $this->entityRepo->renderPage($page);
         $pageHtml = view('pages/export', [
-            'page' => $page,
-            'pageContent' => $this->entityRepo->renderPage($page)
+            'page' => $page
         ])->render();
         return $this->containHtml($pageHtml);
     }
@@ -74,9 +74,9 @@ class ExportService
      */
     public function pageToPdf(Page $page)
     {
+        $this->entityRepo->renderPage($page);
         $html = view('pages/pdf', [
-            'page' => $page,
-            'pageContent' => $this->entityRepo->renderPage($page)
+            'page' => $page
         ])->render();
         return $this->htmlToPdf($html);
     }
index 3285745ce4d8c5a3b1a9acc4adfa58ac77b50e29..770a9e39ffef3387ba10efc975b8749e662e5a5c 100644 (file)
@@ -62,7 +62,7 @@ class ViewService
             $query->whereIn('viewable_type', $filterModel);
         } else if ($filterModel) {
             $query->where('viewable_type', '=', get_class($filterModel));
-        };
+        }
 
         return $query->with('viewable')->skip($skipCount)->take($count)->get()->pluck('viewable');
     }
index 57b2499cc5bd48284375d7d613980498e551b3e5..53358378a31aa5dc6303e995f48a429be8d88724 100644 (file)
@@ -68,8 +68,9 @@ class EntitySelector {
 
     onClick(event) {
         let t = event.target;
+        console.log('click', t);
 
-        if (t.matches('.entity-list a')) {
+        if (t.matches('.entity-list-item  *')) {
             event.preventDefault();
             event.stopPropagation();
             let item = t.closest('[data-entity-type]');
@@ -84,12 +85,16 @@ class EntitySelector {
         let isDblClick = this.isDoubleClick();
         let type = item.getAttribute('data-entity-type');
         let id = item.getAttribute('data-entity-id');
-        let isSelected = item.classList.contains('selected') || isDblClick;
+        let isSelected = !item.classList.contains('selected') || isDblClick;
 
         this.unselectAll();
         this.input.value = isSelected ? `${type}:${id}` : '';
 
         if (!isSelected) window.$events.emit('entity-select-change', null);
+        if (isSelected) {
+            item.classList.add('selected');
+            item.classList.add('primary-background');
+        }
         if (!isDblClick && !isSelected) return;
 
         let link = item.querySelector('.entity-list-item-link').getAttribute('href');
index f8025ac3d97ecb60e56ed4eab47b7ce66fb80cde..988409fbca08b8c30c8051c1f63c1fffb19f2fcd 100644 (file)
@@ -9,6 +9,7 @@ let componentMapping = {
     'entity-selector-popup': require('./entity-selector-popup'),
     'entity-selector': require('./entity-selector'),
     'sidebar': require('./sidebar'),
+    'page-picker': require('./page-picker'),
 };
 
 window.components = {};
diff --git a/resources/assets/js/components/page-picker.js b/resources/assets/js/components/page-picker.js
new file mode 100644 (file)
index 0000000..e697d5f
--- /dev/null
@@ -0,0 +1,60 @@
+
+class PagePicker {
+
+    constructor(elem) {
+        this.elem = elem;
+        this.input = elem.querySelector('input');
+        this.resetButton = elem.querySelector('[page-picker-reset]');
+        this.selectButton = elem.querySelector('[page-picker-select]');
+        this.display = elem.querySelector('[page-picker-display]');
+        this.defaultDisplay = elem.querySelector('[page-picker-default]');
+        this.buttonSep = elem.querySelector('span.sep');
+
+        this.value = this.input.value;
+        this.setupListeners();
+    }
+
+    setupListeners() {
+        // Select click
+        this.selectButton.addEventListener('click', event => {
+            window.EntitySelectorPopup.show(entity => {
+                this.setValue(entity.id, entity.name);
+            });
+        });
+
+        this.resetButton.addEventListener('click', event => {
+            this.setValue('', '');
+        });
+    }
+
+    setValue(value, name) {
+        this.value = value;
+        this.input.value = value;
+        this.controlView(name);
+    }
+
+    controlView(name) {
+        let hasValue = this.value && this.value !== 0;
+        toggleElem(this.resetButton, hasValue);
+        toggleElem(this.buttonSep, hasValue);
+        toggleElem(this.defaultDisplay, !hasValue);
+        toggleElem(this.display, hasValue);
+        if (hasValue) {
+            let id = this.getAssetIdFromVal();
+            this.display.textContent = `#${id}, ${name}`;
+            this.display.href = window.baseUrl(`/link/${id}`);
+        }
+    }
+
+    getAssetIdFromVal() {
+        return Number(this.value);
+    }
+
+}
+
+function toggleElem(elem, show) {
+    let display = (elem.tagName === 'BUTTON' || elem.tagName === 'SPAN') ? 'inline-block' : 'block';
+    elem.style.display = show ? display : 'none';
+}
+
+module.exports = PagePicker;
\ No newline at end of file
index 657bbed17fe85490e93ff5dfdebe272d5bd93b0a..700c15336ff1d49677d8f20ebc9e8a4ccc17b01a 100644 (file)
   }
 }
 
+.fake-input {
+  @extend .input-base;
+  overflow: auto;
+}
+
 #html-editor {
   display: none;
 }
index 3eec7737f913c493b8cf60b45e08b4a4cb64fd8c..c4c8bfc785463833ab3a447bcf70491918fef51f 100644 (file)
@@ -31,6 +31,9 @@ return [
     'app_logo_desc' => 'This image should be 43px in height. <br>Large images will be scaled down.',
     'app_primary_color' => 'Application primary color',
     'app_primary_color_desc' => 'This should be a hex value. <br>Leave empty to reset to the default color.',
+    'app_homepage' => 'Application Homepage',
+    'app_homepage_desc' => 'Select a page to show on the homepage instead of the default view. Page permissions are ignored for selected pages.',
+    'app_homepage_default' => 'Default homepage view chosen',
 
     /**
      * Registration settings
diff --git a/resources/views/components/page-picker.blade.php b/resources/views/components/page-picker.blade.php
new file mode 100644 (file)
index 0000000..91d8eb6
--- /dev/null
@@ -0,0 +1,13 @@
+
+{{--Depends on entity selector popup--}}
+<div page-picker>
+    <div class="input-base">
+        <span @if($value) style="display: none" @endif page-picker-default class="text-muted italic">{{ $placeholder }}</span>
+        <a @if(!$value) style="display: none" @endif href="{{ baseUrl('/link/' . $value) }}" target="_blank" class="text-page" page-picker-display>#{{$value}}, {{$value ? \BookStack\Page::find($value)->name : '' }}</a>
+    </div>
+    <br>
+    <input type="hidden" value="{{$value}}" name="{{$name}}" id="{{$name}}">
+    <button @if(!$value) style="display: none" @endif type="button" page-picker-reset class="text-button">{{ trans('common.reset') }}</button>
+    <span @if(!$value) style="display: none" @endif class="sep">|</span>
+    <button type="button" page-picker-select class="text-button">{{ trans('common.select') }}</button>
+</div>
\ No newline at end of file
diff --git a/resources/views/home-custom.blade.php b/resources/views/home-custom.blade.php
new file mode 100644 (file)
index 0000000..3d4616c
--- /dev/null
@@ -0,0 +1,56 @@
+@extends('sidebar-layout')
+
+@section('toolbar')
+    <div class="col-sm-6 faded">
+        <div class="action-buttons text-left">
+            <a expand-toggle=".entity-list.compact .entity-item-snippet" class="text-primary text-button"><i class="zmdi zmdi-wrap-text"></i>{{ trans('common.toggle_details') }}</a>
+        </div>
+    </div>
+@stop
+
+@section('sidebar')
+    @if(count($draftPages) > 0)
+        <div id="recent-drafts" class="card">
+            <h3><i class="zmdi zmdi-edit"></i> {{ trans('entities.my_recent_drafts') }}</h3>
+            @include('partials/entity-list', ['entities' => $draftPages, 'style' => 'compact'])
+        </div>
+    @endif
+
+    <div class="card">
+        <h3><i class="zmdi zmdi-{{ $signedIn ? 'eye' : 'star-circle' }}"></i> {{ trans('entities.' . ($signedIn ? 'my_recently_viewed' : 'books_recent')) }}</h3>
+        @include('partials/entity-list', [
+            'entities' => $recents,
+            'style' => 'compact',
+            'emptyText' => $signedIn ? trans('entities.no_pages_viewed') : trans('entities.books_empty')
+            ])
+    </div>
+
+    <div class="card">
+        <h3><i class="zmdi zmdi-file"></i> <a class="no-color" href="{{ baseUrl("/pages/recently-updated") }}">{{ trans('entities.recently_updated_pages') }}</a></h3>
+        <div id="recently-updated-pages">
+            @include('partials/entity-list', [
+            'entities' => $recentlyUpdatedPages,
+            'style' => 'compact',
+            'emptyText' => trans('entities.no_pages_recently_updated')
+            ])
+        </div>
+    </div>
+
+    <div id="recent-activity" class="card">
+        <h3><i class="zmdi zmdi-time"></i> {{ trans('entities.recent_activity') }}</h3>
+        @include('partials/activity-list', ['activity' => $activity])
+    </div>
+@stop
+
+@section('body')
+    <div class="page-content" ng-non-bindable>
+        @include('pages/page-display', ['page' => $customHomepage])
+    </div>
+@stop
+
+@section('scripts')
+    <script>
+        setupPageShow({{$customHomepage->id}});
+    </script>
+@stop
+
index cb7cae445bcafbe2b38b134bdc98c00607d23df7..2f70c747d490d37f25883b61d187c52c98eac0fc 100644 (file)
@@ -7,6 +7,6 @@
     @if (isset($diff) && $diff)
         {!! $diff !!}
     @else
-        {!! isset($pageContent) ? $pageContent : $page->html !!}
+        {!! isset($page->renderedHTML) ? $page->renderedHTML : $page->html !!}
     @endif
 </div>
\ No newline at end of file
index cd6a25493105a6508fda83e4dc9e118cb9734eca..09e480b4381701b477ac98f689866ce04b0f8c09 100644 (file)
                             <input type="text" value="{{ setting('app-color') }}" name="setting-app-color" id="setting-app-color" placeholder="#0288D1">
                             <input type="hidden" value="{{ setting('app-color-light') }}" name="setting-app-color-light" id="setting-app-color-light">
                         </div>
+                        <div class="form-group" id="homepage-control">
+                            <label for="setting-app-homepage">{{ trans('settings.app_homepage') }}</label>
+                            <p class="small">{{ trans('settings.app_homepage_desc') }}</p>
+                            @include('components.page-picker', ['name' => 'setting-app-homepage', 'placeholder' => trans('settings.app_homepage_default'), 'value' => setting('app-homepage')])
+                        </div>
                     </div>
 
                 </div>
 </div>
 
 @include('components.image-manager', ['imageType' => 'system'])
+@include('components.entity-selector-popup', ['entityTypes' => 'page'])
 
 @stop