Added ability to set a page to view on the homepage.

Relates to #372 and #126
This commit is contained in:
Dan Brown 2017-08-28 13:38:32 +01:00
parent d8e1f52ddd
commit 55759bd22a
No known key found for this signature in database
GPG Key ID: 46D9F943C24A2EF9
14 changed files with 173 additions and 11 deletions

View 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
]);
}

View 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]);
}
/**

View File

@ -710,6 +710,7 @@ class EntityRepo
$content = str_replace($matches[0][$index], trim($innerContent), $content);
}
$page->renderedHTML = $content;
return $content;
}

View 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);
}

View 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');
}

View 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');

View 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 = {};

View File

@ -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;

View File

@ -23,6 +23,11 @@
}
}
.fake-input {
@extend .input-base;
overflow: auto;
}
#html-editor {
display: none;
}

View 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

View File

@ -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>

View File

@ -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

View 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>

View File

@ -71,6 +71,11 @@
<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>
@ -140,6 +145,7 @@
</div>
@include('components.image-manager', ['imageType' => 'system'])
@include('components.entity-selector-popup', ['entityTypes' => 'page'])
@stop