public function children()
{
- $pages = $this->pages()->get();
+ $pages = $this->pages()->where('chapter_id', '=', 0)->get();
$chapters = $this->chapters()->get();
$children = $pages->merge($chapters);
return $children->sortBy('priority');
return $this->belongsTo('Oxbow\Book');
}
- public function children()
+ public function pages()
{
return $this->hasMany('Oxbow\Page')->orderBy('priority', 'ASC');
}
return '/books/' . $this->book->slug . '/chapter/' . $this->slug;
}
+ public function getExcerpt($length = 100)
+ {
+ return strlen($this->description) > $length ? substr($this->description, 0, $length-3) . '...' : $this->description;
+ }
+
}
use Illuminate\Support\Str;
use Oxbow\Http\Requests;
use Oxbow\Repos\BookRepo;
+use Oxbow\Repos\ChapterRepo;
use Oxbow\Repos\PageRepo;
class PageController extends Controller
protected $pageRepo;
protected $bookRepo;
+ protected $chapterRepo;
/**
* PageController constructor.
- * @param $pageRepo
- * @param $bookRepo
+ * @param PageRepo $pageRepo
+ * @param BookRepo $bookRepo
+ * @param ChapterRepo $chapterRepo
*/
- public function __construct(PageRepo $pageRepo, BookRepo $bookRepo)
+ public function __construct(PageRepo $pageRepo, BookRepo $bookRepo, ChapterRepo $chapterRepo)
{
$this->pageRepo = $pageRepo;
$this->bookRepo = $bookRepo;
+ $this->chapterRepo = $chapterRepo;
}
* Show the form for creating a new resource.
*
* @param $bookSlug
- * @param bool $pageSlug
+ * @param bool $chapterSlug
* @return Response
+ * @internal param bool $pageSlug
*/
- public function create($bookSlug, $pageSlug = false)
+ public function create($bookSlug, $chapterSlug = false)
{
$book = $this->bookRepo->getBySlug($bookSlug);
- $page = $pageSlug ? $this->pageRepo->getBySlug($pageSlug, $book->id) : false;
- return view('pages/create', ['book' => $book, 'parentPage' => $page]);
+ $chapter = $chapterSlug ? $this->chapterRepo->getBySlug($chapterSlug, $book->id) : false;
+ return view('pages/create', ['book' => $book, 'chapter' => $chapter]);
}
/**
]);
$book = $this->bookRepo->getBySlug($bookSlug);
$page = $this->pageRepo->newFromInput($request->all());
- $slug = Str::slug($page->name);
- while($this->pageRepo->countBySlug($slug, $book->id) > 0) {
- $slug .= '1';
- }
- $page->slug = $slug;
+
+ $page->slug = $this->pageRepo->findSuitableSlug($page->name, $book->id);
$page->priority = $this->bookRepo->getNewPriority($book);
- if($request->has('parent')) {
- $page->page_id = $request->get('parent');
+ if($request->has('chapter') && $this->chapterRepo->idExists($request->get('chapter'))) {
+ $page->chapter_id = $request->get('chapter');
}
$page->book_id = $book->id;
{
$book = $this->bookRepo->getBySlug($bookSlug);
$page = $this->pageRepo->getBySlug($pageSlug, $book->id);
- $breadCrumbs = $this->pageRepo->getBreadCrumbs($page);
//dd($sidebarBookTree);
- return view('pages/show', ['page' => $page, 'breadCrumbs' => $breadCrumbs, 'book' => $book]);
+ return view('pages/show', ['page' => $page, 'book' => $book]);
}
/**
{
$book = $this->bookRepo->getBySlug($bookSlug);
$page = $this->pageRepo->getBySlug($pageSlug, $book->id);
- return view('pages/edit', ['page' => $page]);
+ return view('pages/edit', ['page' => $page, 'book' => $book]);
}
/**
$book = $this->bookRepo->getBySlug($bookSlug);
$page = $this->pageRepo->getBySlug($pageSlug, $book->id);
$page->fill($request->all());
- $slug = Str::slug($page->name);
- while($this->pageRepo->countBySlug($slug, $book->id) > 0 && $slug != $pageSlug) {
- $slug .= '1';
- }
+ $page->slug = $this->pageRepo->findSuitableSlug($page->name, $book->id, $page->id);
$page->text = strip_tags($page->html);
$page->save();
return redirect($page->getUrl());
public function sortPages($bookSlug)
{
$book = $this->bookRepo->getBySlug($bookSlug);
- $tree = $this->bookRepo->getTree($book);
- return view('pages/sort', ['book' => $book, 'tree' => $tree]);
+ return view('pages/sort', ['book' => $book]);
}
+ /**
+ * Saves an array of sort mapping to pages and chapters.
+ *
+ * @param $bookSlug
+ * @param Request $request
+ * @return \Illuminate\Http\RedirectResponse|\Illuminate\Routing\Redirector
+ */
public function savePageSort($bookSlug, Request $request)
{
$book = $this->bookRepo->getBySlug($bookSlug);
+ // Return if no map sent
if(!$request->has('sort-tree')) {
return redirect($book->getUrl());
}
+ // Sort pages and chapters
$sortMap = json_decode($request->get('sort-tree'));
- $this->pageRepo->applySortMap($sortMap, $book->id);
+ foreach($sortMap as $index => $bookChild) {
+ $id = $bookChild->id;
+ $isPage = $bookChild->type == 'page';
+ $model = $isPage ? $this->pageRepo->getById($id) : $this->chapterRepo->getById($id);
+ $model->priority = $index;
+ if($isPage) {
+ $model->chapter_id = ($bookChild->parentChapter === false) ? 0 : $bookChild->parentChapter;
+ }
+ $model->save();
+ }
return redirect($book->getUrl());
}
Route::get('/{bookSlug}/sort', 'PageController@sortPages');
Route::put('/{bookSlug}/sort', 'PageController@savePageSort');
Route::get('/{bookSlug}/page/{pageSlug}', 'PageController@show');
- Route::get('/{bookSlug}/page/{pageSlug}/create', 'PageController@create');
Route::get('/{bookSlug}/page/{pageSlug}/edit', 'PageController@edit');
Route::get('/{bookSlug}/page/{pageSlug}/delete', 'PageController@showDelete');
Route::put('/{bookSlug}/page/{pageSlug}', 'PageController@update');
Route::delete('/{bookSlug}/page/{pageSlug}', 'PageController@destroy');
+ Route::get('/{bookSlug}/chapter/{chapterSlug}/create-page', 'PageController@create');
Route::get('/{bookSlug}/chapter/create', 'ChapterController@create');
Route::post('/{bookSlug}/chapter/create', 'ChapterController@store');
Route::get('/{bookSlug}/chapter/{chapterSlug}', 'ChapterController@show');
return $this->belongsTo('Oxbow\Book');
}
+ public function chapter()
+ {
+ return $this->belongsTo('Oxbow\Chapter');
+ }
+
+ public function hasChapter()
+ {
+ return $this->chapter()->count() > 0;
+ }
+
public function parent()
{
return $this->belongsTo('Oxbow\Page', 'page_id');
return '/books/' . $this->book->slug . '/page/' . $this->slug;
}
+ public function getExcerpt($length = 100)
+ {
+ return strlen($this->text) > $length ? substr($this->text, 0, $length-3) . '...' : $this->text;
+ }
+
}
$this->chapter = $chapter;
}
+ public function idExists($id)
+ {
+ return $this->chapter->where('id', '=', $id)->count() > 0;
+ }
+
public function getById($id)
{
return $this->chapter->findOrFail($id);
$this->page = $page;
}
+ public function idExists($id)
+ {
+ return $this->page->where('page_id', '=', $id)->count() > 0;
+ }
+
public function getById($id)
{
return $this->page->findOrFail($id);
return $query->get();
}
- public function getBreadCrumbs($page)
- {
- $tree = [];
- $cPage = $page;
- while($cPage->parent && $cPage->parent->id !== 0) {
- $cPage = $cPage->parent;
- $tree[] = $cPage;
- }
- return count($tree) > 0 ? array_reverse($tree) : false;
- }
-
/**
- * Gets the pages at the top of the page hierarchy.
+ * Checks if a slug exists within a book already.
+ * @param $slug
* @param $bookId
+ * @param bool|false $currentId
+ * @return bool
*/
- private function getTopLevelPages($bookId)
+ public function doesSlugExist($slug, $bookId, $currentId = false)
{
- return $this->page->where('book_id', '=', $bookId)->where('chapter_id', '=', 0)->orderBy('priority')->get();
+ $query = $this->page->where('slug', '=', $slug)->where('book_id', '=', $bookId);
+ if($currentId) {
+ $query = $query->where('id', '!=', $currentId);
+ }
+ return $query->count() > 0;
}
/**
- * Applies a sort map to all applicable pages.
- * @param $sortMap
+ * Gets a suitable slug for the resource
+ *
+ * @param $name
* @param $bookId
+ * @param bool|false $currentId
+ * @return string
*/
- public function applySortMap($sortMap, $bookId)
+ public function findSuitableSlug($name, $bookId, $currentId = false)
{
- foreach($sortMap as $index => $map) {
- $page = $this->getById($map->id);
- if($page->book_id === $bookId) {
- $page->page_id = $map->parent;
- $page->priority = $index;
- $page->save();
- }
+ $slug = Str::slug($name);
+ while($this->doesSlugExist($slug, $bookId, $currentId)) {
+ $slug .= '-' . substr(md5(rand(1, 500)), 0, 3);
}
+ return $slug;
}
+
}
\ No newline at end of file
"dropzone": "~4.0.1",
"tinymce-dist": "~4.2.1",
"bootstrap": "~3.3.5",
- "jquery-sortable": "~0.9.13"
+ "jquery-sortable": "~0.9.13",
+ "material-design-iconic-font": "~2.1.1"
}
}
}
}
}
+
+// Floating action button
+//.fab {
+// $size: 70px;
+// button.button {
+// border-radius: 100%;
+// width: $size;
+// height: $size;
+// font-size: 48px;
+// text-align: center;
+// margin: 0;
+// padding: 0;
+// border: 0;
+// box-shadow: 0 0 2px 2px #DDD;
+// transition: all ease-in-out 160ms;
+// i {
+// transform: rotate(0deg);
+// transition: all ease-in-out 160ms;
+// }
+// &:hover {
+// box-shadow: 0 2px 4px 2px #CCC;
+// i {
+// transform: rotate(180deg);
+// }
+// }
+// }
+//}
line-height: 1.22222222em;
margin-top: 0.48888889em;
margin-bottom: 0.48888889em;
- padding-bottom: 0.3333em;
- border-bottom: 1px solid #EAEAEA;
+ //padding-bottom: 0.3333em;
+ //border-bottom: 1px solid #EAEAEA;
//margin-left: -$-xxl;
//margin-right: -$-xxl;
}
border: 0;
height: 1px;
border: 0;
- background: #e3e0e0;
+ background: #EAEAEA;
margin-bottom: $-l;
&.faded {
background-image: linear-gradient(to right, #FFF, #e3e0e0 20%, #e3e0e0 80%, #FFF);
* Text colors
*/
p.pos, p .pos, span.pos, .text-pos {
- color: $positive;
+ color: $positive;
+ &:hover {
+ color: $positive;
+ }
}
p.neg, p .neg, span.neg, .text-neg {
- color: $negative;
+ color: $negative;
+ &:hover {
+ color: $negative;
+ }
}
p.muted, p .muted, span.muted, .text-muted {
p.primary, p .primary, span.primary, .text-primary {
color: $primary;
+ &:hover {
+ color: $primary;
+ }
}
p.secondary, p .secondary, span.secondary, .text-secondary {
color: $secondary;
+ &:hover {
+ color: $secondary;
+ }
}
/*
li a {
padding: $-m;
display: block;
- border-bottom: 1px solid #333;
+ border-bottom: 1px solid #3A3939;
}
}
}
.page-list {
- a {
+ h3 {
+ margin: $-l 0;
+ }
+ .inset-list {
display: block;
- padding: $-s 0;
- border-bottom: 2px dotted #CCC;
- &:first-child {
- border-top: 2px dotted #CCC;
- }
+ overflow: hidden;
+ padding-left: $-l*2;
+ border-top: 3px dotted #EEE;
+ }
+ h4 {
+ display: block;
+ margin: $-m 0;
+ }
+ hr {
+ margin-top: 0;
}
}
padding-right: 4px;
}
span.sep {
- color: #888;
+ color: #aaa;
padding: 0 $-xs;
}
}
.faded {
- opacity: 0.5;
- transition: opacity ease-in-out 120ms;
- &:hover {
- opacity: 1;
+ a {
+ color: #666;
+ opacity: 0.5;
+ transition: all ease-in-out 120ms;
+ &:hover {
+ opacity: 1;
+ text-decoration: none;
+ }
}
}
}
-.nested-page-list {
- list-style: none;
- margin-left: 0;
- li {
- border-top: 3px dotted #BBB;
- padding: $-s 0;
- user-select: none;
- }
- li:last-child {
- border-bottom: 3px dotted #BBB;
- }
- .nested-page-list {
- margin-top: $-xs;
- display: none;
- margin: $-xs 0 $-xs 9px;
- font-size: $fs-m * 0.9;
- border-left: 2px solid #EEE;
- }
- .nested-page-list li {
- border: none;
- padding-right: $-m;
- padding-left: $-m;
- &.expanded.has-children {
- padding-bottom: 0;
- }
- }
- i.arrow {
- font-size: 0.8em;
- padding: $-xs;
- margin-top: -$-xs;
- margin-bottom: -$-xs;
- transform-origin: 50% 50%;
- transition: transform ease-in-out 180ms;
- cursor: pointer;
- }
- li.expanded {
- > i.arrow {
- transform: rotate(90deg);
- }
- >.nested-page-list {
- display: block;
- }
- }
-}
-
.book-tree h4 {
padding: $-m $-s 0 $-s;
i {
padding-right: $-s;
}
}
+// Sidebar list
.book-tree .sidebar-page-list {
list-style: none;
margin: 0;
li a {
display: block;
- padding: $-s $-m;
- border-bottom: 2px dotted #333;
+ border-bottom: 1px solid #3A3939;
}
a.bold {
color: #EEE !important;
}
+ ul {
+ list-style: none;
+ margin: 0;
+ }
+ ul li a {
+ padding-left: $-xl;
+ }
+ .book {
+ color: #7BD06E !important;
+ }
+ .chapter {
+ color: #D2A64B !important;
+ }
+ .page {
+ color: #4599DC !important;
+ }
}
.sortable-page-list, .sortable-page-list ul {
}
.sortable-page-list li.placeholder:before {
position: absolute;
-}
-
-.material-icons {
- font-size: 1em;
- line-height: 1.4em;
}
\ No newline at end of file
<meta name="viewport" content="width=device-width">
<link rel="stylesheet" href="/css/app.css">
<link href='//fonts.googleapis.com/css?family=Roboto:400,400italic,500,500italic,700,700italic,300italic,100,300' rel='stylesheet' type='text/css'>
- <link rel="stylesheet" href="//maxcdn.bootstrapcdn.com/font-awesome/4.3.0/css/font-awesome.min.css">
+ {{--<link rel="stylesheet" href="//maxcdn.bootstrapcdn.com/font-awesome/4.3.0/css/font-awesome.min.css">--}}
+ <link rel="stylesheet" href="/bower/material-design-iconic-font/dist/css/material-design-iconic-font.min.css">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.4/jquery.min.js"></script>
<script src="/bower/bootstrap/dist/js/bootstrap.js"></script>
<script src="/bower/jquery-sortable/source/js/jquery-sortable.js"></script>
</form>
</div>
<ul class="menu">
- <li><a href="/books"><i class="fa fa-book"></i>Books</a></li>
+ <li><a href="/books"><i class="zmdi zmdi-book"></i>Books</a></li>
</ul>
+ @if(isset($book) && !isset($books))
+ <div class="book-tree">
+ @include('pages/sidebar-tree-list', ['book' => $book])
+ </div>
+ @endif
@yield('sidebar')
</section>
<div class="col-md-6"></div>
<div class="col-md-6 faded">
<div class="action-buttons">
- <a href="/books/create">+ Add new book</a>
+ <a href="/books/create" class="text-pos"><i class="zmdi zmdi-plus"></i>Add new book</a>
</div>
</div>
</div>
<div class="col-md-6"></div>
<div class="col-md-6">
<div class="action-buttons faded">
- <a href="{{$book->getEditUrl()}}"><i class="fa fa-pencil"></i>Edit</a>
- <a href="{{ $book->getUrl() }}/sort"><i class="fa fa-sort"></i>Sort</a>
- <a href="{{ $book->getUrl() }}/delete"><i class="fa fa-trash"></i>Delete</a>
+ <a href="{{$book->getUrl() . '/page/create'}}" class="text-pos"><i class="zmdi zmdi-plus"></i> New Page</a>
+ <a href="{{$book->getUrl() . '/chapter/create'}}" class="text-pos"><i class="zmdi zmdi-plus"></i> New Chapter</a>
+ <a href="{{$book->getEditUrl()}}" class="text-primary"><i class="zmdi zmdi-edit"></i>Edit</a>
+ <a href="{{ $book->getUrl() }}/sort" class="text-primary"><i class="zmdi zmdi-sort"></i>Sort</a>
+ <a href="{{ $book->getUrl() }}/delete" class="text-neg"><i class="zmdi zmdi-delete"></i>Delete</a>
</div>
</div>
</div>
<h1>{{$book->name}}</h1>
<p class="text-muted">{{$book->description}}</p>
- <div class="clearfix header-group">
- <h4 class="float">Contents</h4>
- <div class="float right">
- <a href="{{$book->getUrl() . '/page/create'}}" class="text-pos">+ New Page</a>
- <a href="{{$book->getUrl() . '/chapter/create'}}" class="text-pos">+ New Chapter</a>
- </div>
- </div>
-
- <div>
+ <div class="page-list">
+ <hr>
@foreach($book->children() as $childElement)
- <div >
+ <div class="book-child">
<h3>
<a href="{{ $childElement->getUrl() }}">
@if(is_a($childElement, 'Oxbow\Chapter'))
- <i class="fa fa-archive"></i>
+ <i class="zmdi zmdi-collection-bookmark chapter-toggle"></i>
@else
- <i class="fa fa-file"></i>
+ <i class="zmdi zmdi-file-text"></i>
@endif
{{ $childElement->name }}
</a>
</h3>
+ <p class="text-muted">
+ {{$childElement->getExcerpt()}}
+ </p>
+
+ @if(is_a($childElement, 'Oxbow\Chapter'))
+ <div class="inset-list">
+ @foreach($childElement->pages as $page)
+ <h4><a href="{{$page->getUrl()}}"><i class="zmdi zmdi-file-text"></i> {{$page->name}}</a></h4>
+ @endforeach
+ </div>
+ @endif
</div>
<hr>
@endforeach
</div>
- {{--@include('pages/page-tree-list', ['pageTree' => $pageTree])--}}
-
</div>
<script>
$(function() {
- $('.nested-page-list i.arrow').click(function() {
- var list = $(this).closest('.nested-page-list');
- var listItem = $(this).closest('li');
- listItem.toggleClass('expanded');
+ $('.chapter-toggle').click(function(e) {
+ e.preventDefault();
+ $(this).closest('.book-child').find('.inset-list').slideToggle(180);
});
});
@section('content')
<div class="row faded-small">
- <div class="col-md-6"></div>
+ <div class="col-md-6 faded">
+ <div class="breadcrumbs padded-horizontal">
+ <a href="{{$book->getUrl()}}"><i class="zmdi zmdi-book"></i>{{ $book->name }}</a>
+ </div>
+ </div>
<div class="col-md-6 faded">
<div class="action-buttons">
- <a href="{{$chapter->getUrl() . '/edit'}}" ><i class="fa fa-pencil"></i>Edit</a>
- <a href="{{$chapter->getUrl() . '/delete'}}"><i class="fa fa-trash"></i>Delete</a>
+ <a href="{{$chapter->getUrl() . '/create-page'}}" class="text-pos"><i class="zmdi zmdi-plus"></i>New Page</a>
+ <a href="{{$chapter->getUrl() . '/edit'}}" class="text-primary"><i class="zmdi zmdi-edit"></i>Edit</a>
+ <a href="{{$chapter->getUrl() . '/delete'}}" class="text-neg"><i class="zmdi zmdi-delete"></i>Delete</a>
</div>
</div>
</div>
<div class="page-content">
<h1>{{ $chapter->name }}</h1>
<p class="text-muted">{{ $chapter->description }}</p>
+
@if(count($chapter->pages) > 0)
- <h4 class="text-muted">Pages</h4>
<div class="page-list">
+ <hr>
@foreach($chapter->pages as $page)
<div >
<h3>
<a href="{{ $page->getUrl() }}">
- <i class="fa fa-file"></i>
- {{ $page->name }}
+ <i class="zmdi zmdi-file-text"></i>{{ $page->name }}
</a>
</h3>
+ <p class="text-muted">
+ {{$page->getExcerpt()}}
+ </p>
</div>
<hr>
@endforeach
</div>
+ @else
+ <p class="text-muted">No pages are in this chapter</p>
@endif
</div>
@section('content')
<form action="{{$book->getUrl() . '/page'}}" method="POST">
@include('pages/form')
- @if($parentPage)
- <input type="hidden" name="parent" value="{{$parentPage->id}}">
+ @if($chapter)
+ <input type="hidden" name="chapter" value="{{$chapter->id}}">
@endif
</form>
@stop
+++ /dev/null
-{{--Requires an array of pages to be passed as $pageTree--}}
-
-<ul class="nested-page-list">
- @foreach($pageTree as $subPage)
- <li @if($subPage['hasChildren'])class="has-children"@endif>
- @if($subPage['hasChildren'])
- <i class="fa fa-chevron-right arrow"></i>
- @endif
- <a href="{{$subPage['url']}}">{{$subPage['name']}}</a>
- @if($subPage['hasChildren'])
- @include('pages/page-tree-list', ['pageTree' => $subPage['pages']])
- @endif
- </li>
- @endforeach
-</ul>
\ No newline at end of file
+++ /dev/null
-
-<li data-id="{{$page['id']}}">{{ $page['name'] }}
- <ul>
- @if($page['hasChildren'])
- @foreach($page['pages'] as $childPage)
- @include('pages/page-tree-sort', ['page'=>$childPage])
- @endforeach
- @endif
- </ul>
-</li>
@extends('base')
-@section('sidebar')
- <div class="book-tree">
- <h4><a href="{{$book->getUrl()}}"><i class="fa fa-book"></i>{{$book->name}}</a></h4>
- @include('pages/sidebar-tree-list', ['book' => $book])
- </div>
-@stop
-
@section('content')
<div class="row faded-small">
<div class="col-md-6 faded">
<div class="breadcrumbs padded-horizontal">
- <a href="{{$book->getUrl()}}"><i class="fa fa-book"></i>{{ $book->name }}</a>
- @if($breadCrumbs)
- @foreach($breadCrumbs as $parentPage)
- <span class="sep">></span>
- <a href="{{$parentPage->getUrl()}}">{{ $parentPage->name }}</a>
- @endforeach
+ <a href="{{$book->getUrl()}}"><i class="zmdi zmdi-book"></i>{{ $book->name }}</a>
+ @if($page->hasChapter())
+ <span class="sep">»</span>
+ <a href="{{ $page->chapter->getUrl() }}">
+ <i class="zmdi zmdi-collection-bookmark"></i>
+ {{$page->chapter->name}}
+ </a>
@endif
</div>
</div>
<div class="col-md-6 faded">
<div class="action-buttons">
- <a href="{{$page->getUrl() . '/edit'}}" ><i class="fa fa-pencil"></i>Edit</a>
- <a href="{{$page->getUrl() . '/delete'}}"><i class="fa fa-trash"></i>Delete</a>
+ <a href="{{$page->getUrl() . '/edit'}}" class="text-primary" ><i class="zmdi zmdi-edit"></i>Edit</a>
+ <a href="{{$page->getUrl() . '/delete'}}" class="text-neg"><i class="zmdi zmdi-delete"></i>Delete</a>
</div>
</div>
</div>
var pageNav = $('.page-nav-list');
var pageContent = $('.page-content');
var headers = pageContent.find('h1, h2, h3, h4, h5, h6');
- headers.each(function() {
- var header = $(this);
- var tag = header.prop('tagName');
- var listElem = $('<li></li>').addClass('nav-'+tag);
- var link = $('<a></a>').text(header.text().trim()).attr('href', '#');
- listElem.append(link);
- pageNav.append(listElem);
- link.click(function(e) {
- e.preventDefault();
- header.smoothScrollTo();
- })
- });
+ if(headers.length > 5) {
+ headers.each(function() {
+ var header = $(this);
+ var tag = header.prop('tagName');
+ var listElem = $('<li></li>').addClass('nav-'+tag);
+ var link = $('<a></a>').text(header.text().trim()).attr('href', '#');
+ listElem.append(link);
+ pageNav.append(listElem);
+ link.click(function(e) {
+ e.preventDefault();
+ header.smoothScrollTo();
+ })
+ });
+ } else {
+ $('.side-nav').hide();
+ }
+
// Set up link hooks
var pageId = {{$page->id}};
-{{--Requires an array of pages to be passed as $pageTree--}}
-<ul class="sidebar-page-list">
+<ul class="sidebar-page-list menu">
+ <li class="book-header"><a href="{{$book->getUrl()}}" class="book"><i class="zmdi zmdi-book"></i>{{$book->name}}</a></li>
@foreach($book->children() as $bookChild)
<li>
- {{ $bookChild->name }}
+ <a href="{{$bookChild->getUrl()}}" class="@if(is_a($bookChild, 'Oxbow\Chapter')) chapter @else page @endif">
+ @if(is_a($bookChild, 'Oxbow\Chapter'))
+ <i class="zmdi zmdi-collection-bookmark chapter-toggle"></i>
+ @else
+ <i class="zmdi zmdi-file-text"></i>
+ @endif
+ {{ $bookChild->name }}
+ </a>
+
@if(is_a($bookChild, 'Oxbow\Chapter') && count($bookChild->pages) > 0)
- <ul>
- @foreach($pages as $page)
- <li>{{ $page->name }}</li>
+ <ul class="menu">
+ @foreach($bookChild->pages as $page)
+ <li>
+ <a href="{{$page->getUrl()}}" class="@if(is_a($page, 'Oxbow\Chapter')) chapter @else page @endif">
+ @if(is_a($page, 'Oxbow\Chapter'))
+ <i class="zmdi zmdi-collection-bookmark chapter-toggle"></i>
+ @else
+ <i class="zmdi zmdi-file-text"></i>
+ @endif
+ {{ $page->name }}
+ </a>
+ </li>
@endforeach
</ul>
@endif
@section('content')
- <div class="row">
- <div class="page-menu col-md-3">
- <div class="page-actions">
- <form action="{{$book->getUrl()}}/sort" method="POST">
- {!! csrf_field() !!}
- <input type="hidden" name="_method" value="PUT">
- <input type="hidden" id="sort-tree-input" name="sort-tree">
- <h4>Actions</h4>
- <div class="list">
- <button class="button pos" type="submit">Save Ordering</button>
- </div>
- </form>
- </div>
- </div>
+ <div class="page-content">
+ <h1>{{ $book->name }} <span class="subheader">Sort Pages</span></h1>
- <div class="page-content right col-md-9">
- <h1>{{ $book->name }} <span class="subheader">Sort Pages</span></h1>
+ <ul class="sortable-page-list" id="sort-list">
+ @foreach($book->children() as $bookChild)
+ <li data-id="{{$bookChild->id}}" data-type="{{ is_a($bookChild, 'Oxbow\Chapter') ? 'chapter' : 'page' }}">
+ {{ $bookChild->name }}
+ @if(is_a($bookChild, 'Oxbow\Chapter'))
+ <ul>
+ @foreach($bookChild->pages as $page)
+ <li data-id="{{$page->id}}" data-type="page">
+ {{ $page->name }}
+ </li>
+ @endforeach
+ </ul>
+ @endif
+ </li>
+ @endforeach
+ </ul>
- <ul class="sortable-page-list" id="sort-list">
- @foreach($tree['pages'] as $treePage)
- @include('pages/page-tree-sort', ['page' => $treePage])
- @endforeach
- </ul>
+ <form action="{{$book->getUrl()}}/sort" method="POST">
+ {!! csrf_field() !!}
+ <input type="hidden" name="_method" value="PUT">
+ <input type="hidden" id="sort-tree-input" name="sort-tree">
+ <div class="list">
+ <button class="button pos" type="submit">Save Ordering</button>
+ </div>
+ </form>
- </div>
</div>
<script>
group: 'serialization',
onDrop: function($item, container, _super) {
var data = group.sortable('serialize').get();
- console.log(data);
- var pageMap = [];
- var parent = 0;
- buildPageMap(pageMap, parent, data[0]);
+ var pageMap = buildPageMap(data[0]);
$('#sort-tree-input').val(JSON.stringify(pageMap));
_super($item, container);
}
});
- function buildPageMap(pageMap, parent, data) {
+ function buildPageMap(data) {
+ var pageMap = [];
for(var i = 0; i < data.length; i++) {
- var page = data[i];
+ var bookChild = data[i];
pageMap.push({
- id: page.id,
- parent: parent
+ id: bookChild.id,
+ parentChapter: false,
+ type: bookChild.type
});
- buildPageMap(pageMap, page.id, page.children[0]);
+ if(bookChild.type == 'chapter' && bookChild.children) {
+ var chapterId = bookChild.id;
+ var chapterChildren = bookChild.children[0];
+ for(var j = 0; j < chapterChildren.length; j++) {
+ var page = chapterChildren[j];
+ pageMap.push({
+ id: page.id,
+ parentChapter: chapterId,
+ type: 'page'
+ });
+ }
+ }
}
+ return pageMap;
}
});