Addded sorting logic to pages
This commit is contained in:
		
							parent
							
								
									da2ba4d9f3
								
							
						
					
					
						commit
						941b4496c2
					
				| 
						 | 
					@ -135,12 +135,23 @@ class PageController extends Controller
 | 
				
			||||||
        return redirect($page->getUrl());
 | 
					        return redirect($page->getUrl());
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * Redirect from a special link url which
 | 
				
			||||||
 | 
					     * uses the page id rather than the name.
 | 
				
			||||||
 | 
					     * @param $pageId
 | 
				
			||||||
 | 
					     * @return \Illuminate\Http\RedirectResponse|\Illuminate\Routing\Redirector
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
    public function redirectFromLink($pageId)
 | 
					    public function redirectFromLink($pageId)
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        $page = $this->pageRepo->getById($pageId);
 | 
					        $page = $this->pageRepo->getById($pageId);
 | 
				
			||||||
        return redirect($page->getUrl());
 | 
					        return redirect($page->getUrl());
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * Search all available pages, Across all books.
 | 
				
			||||||
 | 
					     * @param Request $request
 | 
				
			||||||
 | 
					     * @return \Illuminate\Http\RedirectResponse|\Illuminate\View\View
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
    public function searchAll(Request $request)
 | 
					    public function searchAll(Request $request)
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        $searchTerm = $request->get('term');
 | 
					        $searchTerm = $request->get('term');
 | 
				
			||||||
| 
						 | 
					@ -150,6 +161,30 @@ class PageController extends Controller
 | 
				
			||||||
        return view('pages/search-results', ['pages' => $pages, 'searchTerm' => $searchTerm]);
 | 
					        return view('pages/search-results', ['pages' => $pages, 'searchTerm' => $searchTerm]);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * Shows the view which allows pages to be re-ordered and sorted.
 | 
				
			||||||
 | 
					     * @param $bookSlug
 | 
				
			||||||
 | 
					     * @return \Illuminate\View\View
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    public function sortPages($bookSlug)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        $book = $this->bookRepo->getBySlug($bookSlug);
 | 
				
			||||||
 | 
					        $tree = $this->bookRepo->getTree($book);
 | 
				
			||||||
 | 
					        return view('pages/sort', ['book' => $book, 'tree' => $tree]);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    public function savePageSort($bookSlug, Request $request)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        $book = $this->bookRepo->getBySlug($bookSlug);
 | 
				
			||||||
 | 
					        if(!$request->has('sort-tree')) {
 | 
				
			||||||
 | 
					            return redirect($book->getUrl());
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        $sortMap = json_decode($request->get('sort-tree'));
 | 
				
			||||||
 | 
					        $this->pageRepo->applySortMap($sortMap, $book->id);
 | 
				
			||||||
 | 
					        return redirect($book->getUrl());
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /**
 | 
					    /**
 | 
				
			||||||
     * Remove the specified resource from storage.
 | 
					     * Remove the specified resource from storage.
 | 
				
			||||||
     *
 | 
					     *
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -24,6 +24,8 @@ Route::group(['prefix' => 'books'], function() {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    Route::get('/{bookSlug}/page/create', 'PageController@create');
 | 
					    Route::get('/{bookSlug}/page/create', 'PageController@create');
 | 
				
			||||||
    Route::post('/{bookSlug}/page', 'PageController@store');
 | 
					    Route::post('/{bookSlug}/page', 'PageController@store');
 | 
				
			||||||
 | 
					    Route::get('/{bookSlug}/sort', 'PageController@sortPages');
 | 
				
			||||||
 | 
					    Route::put('/{bookSlug}/sort', 'PageController@savePageSort');
 | 
				
			||||||
    Route::get('/{bookSlug}/{pageSlug}', 'PageController@show');
 | 
					    Route::get('/{bookSlug}/{pageSlug}', 'PageController@show');
 | 
				
			||||||
    Route::get('/{bookSlug}/{pageSlug}/create', 'PageController@create');
 | 
					    Route::get('/{bookSlug}/{pageSlug}/create', 'PageController@create');
 | 
				
			||||||
    Route::get('/{bookSlug}/{pageSlug}/edit', 'PageController@edit');
 | 
					    Route::get('/{bookSlug}/{pageSlug}/edit', 'PageController@edit');
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -24,7 +24,7 @@ class Page extends Model
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    public function children()
 | 
					    public function children()
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        return $this->hasMany('Oxbow\Page');
 | 
					        return $this->hasMany('Oxbow\Page')->orderBy('priority', 'ASC');
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    public function parent()
 | 
					    public function parent()
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -57,6 +57,7 @@ class BookRepo
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        $tree = $book->toArray();
 | 
					        $tree = $book->toArray();
 | 
				
			||||||
        $tree['pages'] = $this->pageRepo->getTreeByBookId($book->id);
 | 
					        $tree['pages'] = $this->pageRepo->getTreeByBookId($book->id);
 | 
				
			||||||
 | 
					        $tree['hasChildren'] = count($tree['pages']) > 0;
 | 
				
			||||||
        return $tree;
 | 
					        return $tree;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -114,7 +114,24 @@ class PageRepo
 | 
				
			||||||
     */
 | 
					     */
 | 
				
			||||||
    private function getTopLevelPages($bookId)
 | 
					    private function getTopLevelPages($bookId)
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        return $this->page->where('book_id', '=', $bookId)->where('page_id', '=', 0)->get();
 | 
					        return $this->page->where('book_id', '=', $bookId)->where('page_id', '=', 0)->orderBy('priority')->get();
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * Applies a sort map to all applicable pages.
 | 
				
			||||||
 | 
					     * @param $sortMap
 | 
				
			||||||
 | 
					     * @param $bookId
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    public function applySortMap($sortMap, $bookId)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        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();
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -94,6 +94,9 @@ header .menu {
 | 
				
			||||||
  &:hover {
 | 
					  &:hover {
 | 
				
			||||||
    opacity: 1;
 | 
					    opacity: 1;
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					  .buttons a {
 | 
				
			||||||
 | 
					    display: block;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
.page-nav-list {
 | 
					.page-nav-list {
 | 
				
			||||||
| 
						 | 
					@ -269,3 +272,43 @@ h1, h2, h3, h4, h5, h6 {
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.sortable-page-list, .sortable-page-list ul {
 | 
				
			||||||
 | 
					  list-style: none;
 | 
				
			||||||
 | 
					  //background-color: rgba(0, 0, 0, 0.04);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					.sortable-page-list {
 | 
				
			||||||
 | 
					  margin-left: 0;
 | 
				
			||||||
 | 
					  ul {
 | 
				
			||||||
 | 
					    margin-bottom: 0;
 | 
				
			||||||
 | 
					    margin-top: 0;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					  li {
 | 
				
			||||||
 | 
					    border-bottom: 1px solid #BBB;
 | 
				
			||||||
 | 
					    border-left: 1px solid #BBB;
 | 
				
			||||||
 | 
					    border-right: 1px solid #BBB;
 | 
				
			||||||
 | 
					    padding: $-xs $-s;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					  li:first-child {
 | 
				
			||||||
 | 
					    margin-top: $-xs;
 | 
				
			||||||
 | 
					    border-top: 1px solid #BBB;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Jquery Sortable Styles
 | 
				
			||||||
 | 
					.dragged {
 | 
				
			||||||
 | 
					  position: absolute;
 | 
				
			||||||
 | 
					  opacity: 0.5;
 | 
				
			||||||
 | 
					  z-index: 2000;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					body.dragging, body.dragging * {
 | 
				
			||||||
 | 
					  cursor: move !important;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.sortable-page-list li.placeholder {
 | 
				
			||||||
 | 
					  position: relative;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					.sortable-page-list li.placeholder:before {
 | 
				
			||||||
 | 
					  position: absolute;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -8,6 +8,7 @@
 | 
				
			||||||
    <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">
 | 
				
			||||||
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.4/jquery.min.js"></script>
 | 
					    <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/bootstrap/dist/js/bootstrap.js"></script>
 | 
				
			||||||
 | 
					    <script src="/bower/jquery-sortable/source/js/jquery-sortable.js"></script>
 | 
				
			||||||
    <script>
 | 
					    <script>
 | 
				
			||||||
        $.fn.smoothScrollTo = function() {
 | 
					        $.fn.smoothScrollTo = function() {
 | 
				
			||||||
            if(this.length === 0) return;
 | 
					            if(this.length === 0) return;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -9,6 +9,7 @@
 | 
				
			||||||
            <h4>Book Actions</h4>
 | 
					            <h4>Book Actions</h4>
 | 
				
			||||||
            <div class="buttons">
 | 
					            <div class="buttons">
 | 
				
			||||||
                <a href="{{$book->getEditUrl()}}"><i class="fa fa-pencil"></i>Edit Book</a>
 | 
					                <a href="{{$book->getEditUrl()}}"><i class="fa fa-pencil"></i>Edit Book</a>
 | 
				
			||||||
 | 
					                <a href="{{ $book->getUrl() }}/sort"><i class="fa fa-sort"></i>Sort Pages</a>
 | 
				
			||||||
            </div>
 | 
					            </div>
 | 
				
			||||||
        </div>
 | 
					        </div>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -0,0 +1,10 @@
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					<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>
 | 
				
			||||||
| 
						 | 
					@ -28,10 +28,10 @@
 | 
				
			||||||
                @endif
 | 
					                @endif
 | 
				
			||||||
            </div>
 | 
					            </div>
 | 
				
			||||||
            <h1>{{$page->name}}</h1>
 | 
					            <h1>{{$page->name}}</h1>
 | 
				
			||||||
            @if(count($page->pages) > 0)
 | 
					            @if(count($page->children) > 0)
 | 
				
			||||||
                <h4 class="text-muted">Sub-pages</h4>
 | 
					                <h4 class="text-muted">Sub-pages</h4>
 | 
				
			||||||
                <div class="page-list">
 | 
					                <div class="page-list">
 | 
				
			||||||
                    @foreach($page->pages as $childPage)
 | 
					                    @foreach($page->children as $childPage)
 | 
				
			||||||
                        <a href="{{ $childPage->getUrl() }}">{{ $childPage->name }}</a>
 | 
					                        <a href="{{ $childPage->getUrl() }}">{{ $childPage->name }}</a>
 | 
				
			||||||
                    @endforeach
 | 
					                    @endforeach
 | 
				
			||||||
                </div>
 | 
					                </div>
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -0,0 +1,61 @@
 | 
				
			||||||
 | 
					@extends('base')
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					@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 right col-md-9">
 | 
				
			||||||
 | 
					            <h1>{{ $book->name }} <span class="subheader">Sort Pages</span></h1>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            <ul class="sortable-page-list" id="sort-list">
 | 
				
			||||||
 | 
					                @foreach($tree['pages'] as $treePage)
 | 
				
			||||||
 | 
					                    @include('pages/page-tree-sort', ['page' => $treePage])
 | 
				
			||||||
 | 
					                @endforeach
 | 
				
			||||||
 | 
					            </ul>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        </div>
 | 
				
			||||||
 | 
					    </div>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    <script>
 | 
				
			||||||
 | 
					        $(document).ready(function() {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            var group = $('#sort-list').sortable({
 | 
				
			||||||
 | 
					                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]);
 | 
				
			||||||
 | 
					                    $('#sort-tree-input').val(JSON.stringify(pageMap));
 | 
				
			||||||
 | 
					                    _super($item, container);
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					            });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            function buildPageMap(pageMap, parent, data) {
 | 
				
			||||||
 | 
					                for(var i = 0; i < data.length; i++) {
 | 
				
			||||||
 | 
					                    var page = data[i];
 | 
				
			||||||
 | 
					                    pageMap.push({
 | 
				
			||||||
 | 
					                        id: page.id,
 | 
				
			||||||
 | 
					                        parent: parent
 | 
				
			||||||
 | 
					                    });
 | 
				
			||||||
 | 
					                    buildPageMap(pageMap, page.id, page.children[0]);
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        });
 | 
				
			||||||
 | 
					    </script>
 | 
				
			||||||
 | 
					@stop
 | 
				
			||||||
		Loading…
	
		Reference in New Issue