1
0
mirror of https://github.com/BookStackApp/BookStack.git synced 2025-07-28 17:02:04 +03:00

Added chapter search

Migrated book search to vue-based system.
Updated old tag seached.
Made chapter page layout widths same as book page.
Closes #344
This commit is contained in:
Dan Brown
2017-04-15 19:16:07 +01:00
parent 0e0945ef84
commit dcde599709
12 changed files with 179 additions and 99 deletions

View File

@ -259,39 +259,6 @@ module.exports = function (ngApp, events) {
}]);
ngApp.controller('BookShowController', ['$scope', '$http', '$attrs', '$sce', function ($scope, $http, $attrs, $sce) {
$scope.searching = false;
$scope.searchTerm = '';
$scope.searchResults = '';
$scope.searchBook = function (e) {
e.preventDefault();
let term = $scope.searchTerm;
if (term.length == 0) return;
$scope.searching = true;
$scope.searchResults = '';
let searchUrl = window.baseUrl('/search/book/' + $attrs.bookId);
searchUrl += '?term=' + encodeURIComponent(term);
$http.get(searchUrl).then((response) => {
$scope.searchResults = $sce.trustAsHtml(response.data);
});
};
$scope.checkSearchForm = function () {
if ($scope.searchTerm.length < 1) {
$scope.searching = false;
}
};
$scope.clearSearch = function () {
$scope.searching = false;
$scope.searchTerm = '';
};
}]);
ngApp.controller('PageEditController', ['$scope', '$http', '$attrs', '$interval', '$timeout', '$sce',
function ($scope, $http, $attrs, $interval, $timeout, $sce) {

View File

@ -0,0 +1,44 @@
let data = {
id: null,
type: '',
searching: false,
searchTerm: '',
searchResults: '',
};
let computed = {
};
let methods = {
searchBook() {
if (this.searchTerm.trim().length === 0) return;
this.searching = true;
this.searchResults = '';
let url = window.baseUrl(`/search/${this.type}/${this.id}`);
url += `?term=${encodeURIComponent(this.searchTerm)}`;
this.$http.get(url).then(resp => {
this.searchResults = resp.data;
});
},
checkSearchForm() {
this.searching = this.searchTerm > 0;
},
clearSearch() {
this.searching = false;
this.searchTerm = '';
}
};
function mounted() {
this.id = Number(this.$el.getAttribute('entity-id'));
this.type = this.$el.getAttribute('entity-type');
}
module.exports = {
data, computed, methods, mounted
};

View File

@ -5,7 +5,8 @@ function exists(id) {
}
let vueMapping = {
'search-system': require('./search')
'search-system': require('./search'),
'entity-dashboard': require('./entity-search'),
};
Object.keys(vueMapping).forEach(id => {

View File

@ -109,6 +109,7 @@
transition-property: right, border;
border-left: 0px solid #FFF;
background-color: #FFF;
max-width: 320px;
&.fixed {
background-color: #FFF;
z-index: 5;

View File

@ -120,6 +120,7 @@ return [
'chapters_empty' => 'No pages are currently in this chapter.',
'chapters_permissions_active' => 'Chapter Permissions Active',
'chapters_permissions_success' => 'Chapter Permissions Updated',
'chapters_search_this' => 'Search this chapter',
/**
* Pages

View File

@ -50,15 +50,15 @@
</div>
<div class="container" id="book-dashboard" ng-controller="BookShowController" book-id="{{ $book->id }}">
<div class="container" id="entity-dashboard" entity-id="{{ $book->id }}" entity-type="book">
<div class="row">
<div class="col-md-7">
<h1>{{$book->name}}</h1>
<div class="book-content" ng-show="!searching">
<p class="text-muted" ng-non-bindable>{{$book->description}}</p>
<div class="book-content" v-if="!searching">
<p class="text-muted" v-pre>{{$book->description}}</p>
<div class="page-list" ng-non-bindable>
<div class="page-list" v-pre>
<hr>
@if(count($bookChildren) > 0)
@foreach($bookChildren as $childElement)
@ -81,12 +81,12 @@
@include('partials.entity-meta', ['entity' => $book])
</div>
</div>
<div class="search-results" ng-cloak ng-show="searching">
<h3 class="text-muted">{{ trans('entities.search_results') }} <a ng-if="searching" ng-click="clearSearch()" class="text-small"><i class="zmdi zmdi-close"></i>{{ trans('entities.search_clear') }}</a></h3>
<div ng-if="!searchResults">
<div class="search-results" v-cloak v-if="searching">
<h3 class="text-muted">{{ trans('entities.search_results') }} <a v-if="searching" v-on:click="clearSearch()" class="text-small"><i class="zmdi zmdi-close"></i>{{ trans('entities.search_clear') }}</a></h3>
<div v-if="!searchResults">
@include('partials/loading-icon')
</div>
<div ng-bind-html="searchResults"></div>
<div v-html="searchResults"></div>
</div>
@ -94,6 +94,7 @@
<div class="col-md-4 col-md-offset-1">
<div class="margin-top large"></div>
@if($book->restricted)
<p class="text-muted">
@if(userCan('restrictions-manage', $book))
@ -103,14 +104,16 @@
@endif
</p>
@endif
<div class="search-box">
<form ng-submit="searchBook($event)">
<input ng-model="searchTerm" ng-change="checkSearchForm()" type="text" name="term" placeholder="{{ trans('entities.books_search_this') }}">
<form v-on:submit="searchBook">
<input v-model="searchTerm" v-on:change="checkSearchForm()" type="text" name="term" placeholder="{{ trans('entities.books_search_this') }}">
<button type="submit"><i class="zmdi zmdi-search"></i></button>
<button ng-if="searching" ng-click="clearSearch()" type="button"><i class="zmdi zmdi-close"></i></button>
<button v-if="searching" v-cloak class="text-neg" v-on:click="clearSearch()" type="button"><i class="zmdi zmdi-close"></i></button>
</form>
</div>
<div class="activity anim fadeIn">
<div class="activity">
<h3>{{ trans('entities.recent_activity') }}</h3>
@include('partials/activity-list', ['activity' => Activity::entityActivity($book, 20, 0)])
</div>

View File

@ -47,40 +47,50 @@
</div>
<div class="container" ng-non-bindable>
<div class="container" id="entity-dashboard" entity-id="{{ $chapter->id }}" entity-type="chapter">
<div class="row">
<div class="col-md-8">
<div class="col-md-7">
<h1>{{ $chapter->name }}</h1>
<p class="text-muted">{{ $chapter->description }}</p>
<div class="chapter-content" v-if="!searching">
<p class="text-muted">{{ $chapter->description }}</p>
@if(count($pages) > 0)
<div class="page-list">
<hr>
@foreach($pages as $page)
@include('pages/list-item', ['page' => $page])
@if(count($pages) > 0)
<div class="page-list">
<hr>
@endforeach
</div>
@else
<hr>
<p class="text-muted">{{ trans('entities.chapters_empty') }}</p>
<p>
@if(userCan('page-create', $chapter))
<a href="{{ $chapter->getUrl('/create-page') }}" class="text-page"><i class="zmdi zmdi-file-text"></i>{{ trans('entities.books_empty_create_page') }}</a>
@endif
@if(userCan('page-create', $chapter) && userCan('book-update', $book))
&nbsp;&nbsp;<em class="text-muted">-{{ trans('entities.books_empty_or') }}-</em>&nbsp;&nbsp;&nbsp;
@endif
@if(userCan('book-update', $book))
<a href="{{ $book->getUrl('/sort') }}" class="text-book"><i class="zmdi zmdi-book"></i>{{ trans('entities.books_empty_sort_current_book') }}</a>
@endif
</p>
<hr>
@endif
@foreach($pages as $page)
@include('pages/list-item', ['page' => $page])
<hr>
@endforeach
</div>
@else
<hr>
<p class="text-muted">{{ trans('entities.chapters_empty') }}</p>
<p>
@if(userCan('page-create', $chapter))
<a href="{{ $chapter->getUrl('/create-page') }}" class="text-page"><i class="zmdi zmdi-file-text"></i>{{ trans('entities.books_empty_create_page') }}</a>
@endif
@if(userCan('page-create', $chapter) && userCan('book-update', $book))
&nbsp;&nbsp;<em class="text-muted">-{{ trans('entities.books_empty_or') }}-</em>&nbsp;&nbsp;&nbsp;
@endif
@if(userCan('book-update', $book))
<a href="{{ $book->getUrl('/sort') }}" class="text-book"><i class="zmdi zmdi-book"></i>{{ trans('entities.books_empty_sort_current_book') }}</a>
@endif
</p>
<hr>
@endif
@include('partials.entity-meta', ['entity' => $chapter])
@include('partials.entity-meta', ['entity' => $chapter])
</div>
<div class="search-results" v-cloak v-if="searching">
<h3 class="text-muted">{{ trans('entities.search_results') }} <a v-if="searching" v-on:click="clearSearch()" class="text-small"><i class="zmdi zmdi-close"></i>{{ trans('entities.search_clear') }}</a></h3>
<div v-if="!searchResults">
@include('partials/loading-icon')
</div>
<div v-html="searchResults"></div>
</div>
</div>
<div class="col-md-3 col-md-offset-1">
<div class="col-md-4 col-md-offset-1">
<div class="margin-top large"></div>
@if($book->restricted || $chapter->restricted)
<div class="text-muted">
@ -105,7 +115,16 @@
</div>
@endif
<div class="search-box">
<form v-on:submit="searchBook">
<input v-model="searchTerm" v-on:change="checkSearchForm()" type="text" name="term" placeholder="{{ trans('entities.chapters_search_this') }}">
<button type="submit"><i class="zmdi zmdi-search"></i></button>
<button v-if="searching" v-cloak class="text-neg" v-on:click="clearSearch()" type="button"><i class="zmdi zmdi-close"></i></button>
</form>
</div>
@include('pages/sidebar-tree-list', ['book' => $book, 'sidebarTree' => $sidebarTree])
</div>
</div>
</div>

View File

@ -3,13 +3,13 @@
@if(isset($page) && $page->tags->count() > 0)
<div class="tag-display">
<h6 class="text-muted">Page Tags</h6>
<h6 class="text-muted">{{ trans('entities.page_tags') }}</h6>
<table>
<tbody>
@foreach($page->tags as $tag)
<tr class="tag">
<td @if(!$tag->value) colspan="2" @endif><a href="{{ baseUrl('/search/all?term=%5B' . urlencode($tag->name) .'%5D') }}">{{ $tag->name }}</a></td>
@if($tag->value) <td class="tag-value"><a href="{{ baseUrl('/search/all?term=%5B' . urlencode($tag->name) .'%3D' . urlencode($tag->value) . '%5D') }}">{{$tag->value}}</a></td> @endif
<td @if(!$tag->value) colspan="2" @endif><a href="{{ baseUrl('/search?term=%5B' . urlencode($tag->name) .'%5D') }}">{{ $tag->name }}</a></td>
@if($tag->value) <td class="tag-value"><a href="{{ baseUrl('/search?term=%5B' . urlencode($tag->name) .'%3D' . urlencode($tag->value) . '%5D') }}">{{$tag->value}}</a></td> @endif
</tr>
@endforeach
</tbody>