mirror of
https://github.com/BookStackApp/BookStack.git
synced 2025-05-06 01:00:11 +00:00
Finished off UI for search system
This commit is contained in:
parent
ad125327c0
commit
0e0945ef84
14 changed files with 225 additions and 120 deletions
app
resources
assets
lang
views/search
|
@ -34,14 +34,20 @@ class SearchController extends Controller
|
||||||
public function search(Request $request)
|
public function search(Request $request)
|
||||||
{
|
{
|
||||||
$searchTerm = $request->get('term');
|
$searchTerm = $request->get('term');
|
||||||
// $paginationAppends = $request->only('term'); TODO - Check pagination
|
|
||||||
$this->setPageTitle(trans('entities.search_for_term', ['term' => $searchTerm]));
|
$this->setPageTitle(trans('entities.search_for_term', ['term' => $searchTerm]));
|
||||||
|
|
||||||
$entities = $this->searchService->searchEntities($searchTerm);
|
$page = $request->has('page') && is_int(intval($request->get('page'))) ? intval($request->get('page')) : 1;
|
||||||
|
$nextPageLink = baseUrl('/search?term=' . urlencode($searchTerm) . '&page=' . ($page+1));
|
||||||
|
|
||||||
|
$results = $this->searchService->searchEntities($searchTerm, 'all', $page, 20);
|
||||||
|
$hasNextPage = $this->searchService->searchEntities($searchTerm, 'all', $page+1, 20)['count'] > 0;
|
||||||
|
|
||||||
return view('search/all', [
|
return view('search/all', [
|
||||||
'entities' => $entities,
|
'entities' => $results['results'],
|
||||||
'searchTerm' => $searchTerm
|
'totalResults' => $results['total'],
|
||||||
|
'searchTerm' => $searchTerm,
|
||||||
|
'hasNextPage' => $hasNextPage,
|
||||||
|
'nextPageLink' => $nextPageLink
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -8,7 +8,6 @@ use BookStack\SearchTerm;
|
||||||
use Illuminate\Database\Connection;
|
use Illuminate\Database\Connection;
|
||||||
use Illuminate\Database\Query\Builder;
|
use Illuminate\Database\Query\Builder;
|
||||||
use Illuminate\Database\Query\JoinClause;
|
use Illuminate\Database\Query\JoinClause;
|
||||||
use Illuminate\Support\Collection;
|
|
||||||
|
|
||||||
class SearchService
|
class SearchService
|
||||||
{
|
{
|
||||||
|
@ -56,9 +55,9 @@ class SearchService
|
||||||
* @param string $entityType
|
* @param string $entityType
|
||||||
* @param int $page
|
* @param int $page
|
||||||
* @param int $count
|
* @param int $count
|
||||||
* @return Collection
|
* @return array[int, Collection];
|
||||||
*/
|
*/
|
||||||
public function searchEntities($searchString, $entityType = 'all', $page = 0, $count = 20)
|
public function searchEntities($searchString, $entityType = 'all', $page = 1, $count = 20)
|
||||||
{
|
{
|
||||||
$terms = $this->parseSearchString($searchString);
|
$terms = $this->parseSearchString($searchString);
|
||||||
$entityTypes = array_keys($this->entities);
|
$entityTypes = array_keys($this->entities);
|
||||||
|
@ -71,14 +70,20 @@ class SearchService
|
||||||
$entityTypesToSearch = explode('|', $terms['filters']['type']);
|
$entityTypesToSearch = explode('|', $terms['filters']['type']);
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO - Check drafts don't show up in results
|
$total = 0;
|
||||||
|
|
||||||
foreach ($entityTypesToSearch as $entityType) {
|
foreach ($entityTypesToSearch as $entityType) {
|
||||||
if (!in_array($entityType, $entityTypes)) continue;
|
if (!in_array($entityType, $entityTypes)) continue;
|
||||||
$search = $this->searchEntityTable($terms, $entityType, $page, $count);
|
$search = $this->searchEntityTable($terms, $entityType, $page, $count);
|
||||||
|
$total += $this->searchEntityTable($terms, $entityType, $page, $count, true);
|
||||||
$results = $results->merge($search);
|
$results = $results->merge($search);
|
||||||
}
|
}
|
||||||
|
|
||||||
return $results->sortByDesc('score');
|
return [
|
||||||
|
'total' => $total,
|
||||||
|
'count' => count($results),
|
||||||
|
'results' => $results->sortByDesc('score')
|
||||||
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -87,9 +92,10 @@ class SearchService
|
||||||
* @param string $entityType
|
* @param string $entityType
|
||||||
* @param int $page
|
* @param int $page
|
||||||
* @param int $count
|
* @param int $count
|
||||||
* @return \Illuminate\Database\Eloquent\Collection|static[]
|
* @param bool $getCount Return the total count of the search
|
||||||
|
* @return \Illuminate\Database\Eloquent\Collection|int|static[]
|
||||||
*/
|
*/
|
||||||
public function searchEntityTable($terms, $entityType = 'page', $page = 0, $count = 20)
|
public function searchEntityTable($terms, $entityType = 'page', $page = 1, $count = 20, $getCount = false)
|
||||||
{
|
{
|
||||||
$entity = $this->getEntity($entityType);
|
$entity = $this->getEntity($entityType);
|
||||||
$entitySelect = $entity->newQuery();
|
$entitySelect = $entity->newQuery();
|
||||||
|
@ -131,8 +137,10 @@ class SearchService
|
||||||
if (method_exists($this, $functionName)) $this->$functionName($entitySelect, $entity, $filterValue);
|
if (method_exists($this, $functionName)) $this->$functionName($entitySelect, $entity, $filterValue);
|
||||||
}
|
}
|
||||||
|
|
||||||
$entitySelect->skip($page * $count)->take($count);
|
|
||||||
$query = $this->permissionService->enforceEntityRestrictions($entityType, $entitySelect, 'view');
|
$query = $this->permissionService->enforceEntityRestrictions($entityType, $entitySelect, 'view');
|
||||||
|
if ($getCount) return $query->count();
|
||||||
|
|
||||||
|
$query = $query->skip(($page-1) * $count)->take($count);
|
||||||
return $query->get();
|
return $query->get();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -371,13 +379,15 @@ class SearchService
|
||||||
|
|
||||||
protected function filterCreatedBy(\Illuminate\Database\Eloquent\Builder $query, Entity $model, $input)
|
protected function filterCreatedBy(\Illuminate\Database\Eloquent\Builder $query, Entity $model, $input)
|
||||||
{
|
{
|
||||||
if (!is_numeric($input)) return;
|
if (!is_numeric($input) && $input !== 'me') return;
|
||||||
|
if ($input === 'me') $input = user()->id;
|
||||||
$query->where('created_by', '=', $input);
|
$query->where('created_by', '=', $input);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected function filterUpdatedBy(\Illuminate\Database\Eloquent\Builder $query, Entity $model, $input)
|
protected function filterUpdatedBy(\Illuminate\Database\Eloquent\Builder $query, Entity $model, $input)
|
||||||
{
|
{
|
||||||
if (!is_numeric($input)) return;
|
if (!is_numeric($input) && $input !== 'me') return;
|
||||||
|
if ($input === 'me') $input = user()->id;
|
||||||
$query->where('updated_by', '=', $input);
|
$query->where('updated_by', '=', $input);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -12,7 +12,12 @@ let data = {
|
||||||
exactTerms: [],
|
exactTerms: [],
|
||||||
tagTerms: [],
|
tagTerms: [],
|
||||||
option: {},
|
option: {},
|
||||||
dates: {}
|
dates: {
|
||||||
|
updated_after: false,
|
||||||
|
updated_before: false,
|
||||||
|
created_after: false,
|
||||||
|
created_before: false,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -126,7 +131,7 @@ let methods = {
|
||||||
},
|
},
|
||||||
|
|
||||||
optionParse(searchString) {
|
optionParse(searchString) {
|
||||||
let optionFilter = /{([a-z_-]+?)}/gi;
|
let optionFilter = /{([a-z_\-:]+?)}/gi;
|
||||||
let matches;
|
let matches;
|
||||||
while ((matches = optionFilter.exec(searchString)) !== null) {
|
while ((matches = optionFilter.exec(searchString)) !== null) {
|
||||||
this.search.option[matches[1].toLowerCase()] = true;
|
this.search.option[matches[1].toLowerCase()] = true;
|
||||||
|
@ -148,7 +153,30 @@ let methods = {
|
||||||
},
|
},
|
||||||
|
|
||||||
enableDate(optionName) {
|
enableDate(optionName) {
|
||||||
this.search.dates[optionName] = moment().format('YYYY-MM-DD');
|
this.search.dates[optionName.toLowerCase()] = moment().format('YYYY-MM-DD');
|
||||||
|
this.dateChange(optionName);
|
||||||
|
},
|
||||||
|
|
||||||
|
dateParse(searchString) {
|
||||||
|
let dateFilter = /{([a-z_\-]+?):([a-z_\-0-9]+?)}/gi;
|
||||||
|
let dateTags = Object.keys(this.search.dates);
|
||||||
|
let matches;
|
||||||
|
while ((matches = dateFilter.exec(searchString)) !== null) {
|
||||||
|
if (dateTags.indexOf(matches[1]) === -1) continue;
|
||||||
|
this.search.dates[matches[1].toLowerCase()] = matches[2];
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
dateChange(optionName) {
|
||||||
|
let dateFilter = new RegExp('{\\s?'+optionName+'\\s?:([a-z_\\-0-9]+?)}', 'gi');
|
||||||
|
this.termString = this.termString.replace(dateFilter, '');
|
||||||
|
if (!this.search.dates[optionName]) return;
|
||||||
|
this.appendTerm(`{${optionName}:${this.search.dates[optionName]}}`);
|
||||||
|
},
|
||||||
|
|
||||||
|
dateRemove(optionName) {
|
||||||
|
this.search.dates[optionName] = false;
|
||||||
|
this.dateChange(optionName);
|
||||||
}
|
}
|
||||||
|
|
||||||
};
|
};
|
||||||
|
@ -159,6 +187,7 @@ function created() {
|
||||||
this.exactParse(this.termString);
|
this.exactParse(this.termString);
|
||||||
this.tagParse(this.termString);
|
this.tagParse(this.termString);
|
||||||
this.optionParse(this.termString);
|
this.optionParse(this.termString);
|
||||||
|
this.dateParse(this.termString);
|
||||||
}
|
}
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
.anim.fadeIn {
|
.anim.fadeIn {
|
||||||
opacity: 0;
|
opacity: 0;
|
||||||
animation-name: fadeIn;
|
animation-name: fadeIn;
|
||||||
animation-duration: 160ms;
|
animation-duration: 180ms;
|
||||||
animation-timing-function: ease-in-out;
|
animation-timing-function: ease-in-out;
|
||||||
animation-fill-mode: forwards;
|
animation-fill-mode: forwards;
|
||||||
}
|
}
|
||||||
|
|
|
@ -98,19 +98,36 @@ label {
|
||||||
|
|
||||||
label.radio, label.checkbox {
|
label.radio, label.checkbox {
|
||||||
font-weight: 400;
|
font-weight: 400;
|
||||||
|
user-select: none;
|
||||||
input[type="radio"], input[type="checkbox"] {
|
input[type="radio"], input[type="checkbox"] {
|
||||||
margin-right: $-xs;
|
margin-right: $-xs;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
label.inline.checkbox {
|
||||||
|
margin-right: $-m;
|
||||||
|
}
|
||||||
|
|
||||||
label + p.small {
|
label + p.small {
|
||||||
margin-bottom: 0.8em;
|
margin-bottom: 0.8em;
|
||||||
}
|
}
|
||||||
|
|
||||||
input[type="text"], input[type="number"], input[type="email"], input[type="search"], input[type="url"], input[type="password"], select, textarea {
|
table.form-table {
|
||||||
|
max-width: 100%;
|
||||||
|
td {
|
||||||
|
overflow: hidden;
|
||||||
|
padding: $-xxs/2 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
input[type="text"], input[type="number"], input[type="email"], input[type="date"], input[type="search"], input[type="url"], input[type="password"], select, textarea {
|
||||||
@extend .input-base;
|
@extend .input-base;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
input[type=date] {
|
||||||
|
width: 190px;
|
||||||
|
}
|
||||||
|
|
||||||
.toggle-switch {
|
.toggle-switch {
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
background-color: #BBB;
|
background-color: #BBB;
|
||||||
|
|
|
@ -7,8 +7,8 @@
|
||||||
@import "grid";
|
@import "grid";
|
||||||
@import "blocks";
|
@import "blocks";
|
||||||
@import "buttons";
|
@import "buttons";
|
||||||
@import "forms";
|
|
||||||
@import "tables";
|
@import "tables";
|
||||||
|
@import "forms";
|
||||||
@import "animations";
|
@import "animations";
|
||||||
@import "tinymce";
|
@import "tinymce";
|
||||||
@import "highlightjs";
|
@import "highlightjs";
|
||||||
|
@ -17,7 +17,11 @@
|
||||||
@import "lists";
|
@import "lists";
|
||||||
@import "pages";
|
@import "pages";
|
||||||
|
|
||||||
[v-cloak], [v-show] {display: none;}
|
[v-cloak], [v-show] {
|
||||||
|
display: none; opacity: 0;
|
||||||
|
animation-name: none !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
[ng\:cloak], [ng-cloak], .ng-cloak {
|
[ng\:cloak], [ng-cloak], .ng-cloak {
|
||||||
display: none !important;
|
display: none !important;
|
||||||
|
@ -272,8 +276,3 @@ $btt-size: 40px;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -43,18 +43,9 @@ return [
|
||||||
* Search
|
* Search
|
||||||
*/
|
*/
|
||||||
'search_results' => 'Suchergebnisse',
|
'search_results' => 'Suchergebnisse',
|
||||||
'search_results_page' => 'Seiten-Suchergebnisse',
|
|
||||||
'search_results_chapter' => 'Kapitel-Suchergebnisse',
|
|
||||||
'search_results_book' => 'Buch-Suchergebnisse',
|
|
||||||
'search_clear' => 'Suche zurücksetzen',
|
'search_clear' => 'Suche zurücksetzen',
|
||||||
'search_view_pages' => 'Zeige alle passenden Seiten',
|
|
||||||
'search_view_chapters' => 'Zeige alle passenden Kapitel',
|
|
||||||
'search_view_books' => 'Zeige alle passenden Bücher',
|
|
||||||
'search_no_pages' => 'Es wurden keine passenden Suchergebnisse gefunden',
|
'search_no_pages' => 'Es wurden keine passenden Suchergebnisse gefunden',
|
||||||
'search_for_term' => 'Suche nach :term',
|
'search_for_term' => 'Suche nach :term',
|
||||||
'search_page_for_term' => 'Suche nach :term in Seiten',
|
|
||||||
'search_chapter_for_term' => 'Suche nach :term in Kapiteln',
|
|
||||||
'search_book_for_term' => 'Suche nach :term in Büchern',
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Books
|
* Books
|
||||||
|
|
|
@ -33,6 +33,7 @@ return [
|
||||||
'search_clear' => 'Clear Search',
|
'search_clear' => 'Clear Search',
|
||||||
'reset' => 'Reset',
|
'reset' => 'Reset',
|
||||||
'remove' => 'Remove',
|
'remove' => 'Remove',
|
||||||
|
'add' => 'Add',
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -43,18 +43,26 @@ return [
|
||||||
* Search
|
* Search
|
||||||
*/
|
*/
|
||||||
'search_results' => 'Search Results',
|
'search_results' => 'Search Results',
|
||||||
'search_results_page' => 'Page Search Results',
|
'search_total_results_found' => ':count result found|:count total results found',
|
||||||
'search_results_chapter' => 'Chapter Search Results',
|
|
||||||
'search_results_book' => 'Book Search Results',
|
|
||||||
'search_clear' => 'Clear Search',
|
'search_clear' => 'Clear Search',
|
||||||
'search_view_pages' => 'View all matches pages',
|
|
||||||
'search_view_chapters' => 'View all matches chapters',
|
|
||||||
'search_view_books' => 'View all matches books',
|
|
||||||
'search_no_pages' => 'No pages matched this search',
|
'search_no_pages' => 'No pages matched this search',
|
||||||
'search_for_term' => 'Search for :term',
|
'search_for_term' => 'Search for :term',
|
||||||
'search_page_for_term' => 'Page search for :term',
|
'search_more' => 'More Results',
|
||||||
'search_chapter_for_term' => 'Chapter search for :term',
|
'search_filters' => 'Search Filters',
|
||||||
'search_book_for_term' => 'Books search for :term',
|
'search_content_type' => 'Content Type',
|
||||||
|
'search_exact_matches' => 'Exact Matches',
|
||||||
|
'search_tags' => 'Tag Searches',
|
||||||
|
'search_viewed_by_me' => 'Viewed by me',
|
||||||
|
'search_not_viewed_by_me' => 'Not viewed by me',
|
||||||
|
'search_permissions_set' => 'Permissions set',
|
||||||
|
'search_created_by_me' => 'Created by me',
|
||||||
|
'search_updated_by_me' => 'Updated by me',
|
||||||
|
'search_updated_before' => 'Updated before',
|
||||||
|
'search_updated_after' => 'Updated after',
|
||||||
|
'search_created_before' => 'Created before',
|
||||||
|
'search_created_after' => 'Created after',
|
||||||
|
'search_set_date' => 'Set Date',
|
||||||
|
'search_update' => 'Update Search',
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Books
|
* Books
|
||||||
|
|
|
@ -43,18 +43,9 @@ return [
|
||||||
* Search
|
* Search
|
||||||
*/
|
*/
|
||||||
'search_results' => 'Buscar resultados',
|
'search_results' => 'Buscar resultados',
|
||||||
'search_results_page' => 'resultados de búsqueda en página',
|
|
||||||
'search_results_chapter' => 'Resultados de búsqueda en capítulo ',
|
|
||||||
'search_results_book' => 'Resultados de búsqueda en libro',
|
|
||||||
'search_clear' => 'Limpiar resultados',
|
'search_clear' => 'Limpiar resultados',
|
||||||
'search_view_pages' => 'Ver todas las páginas que concuerdan',
|
|
||||||
'search_view_chapters' => 'Ver todos los capítulos que concuerdan',
|
|
||||||
'search_view_books' => 'Ver todos los libros que concuerdan',
|
|
||||||
'search_no_pages' => 'Ninguna página encontrada para la búsqueda',
|
'search_no_pages' => 'Ninguna página encontrada para la búsqueda',
|
||||||
'search_for_term' => 'Busqueda por :term',
|
'search_for_term' => 'Busqueda por :term',
|
||||||
'search_page_for_term' => 'Búsqueda de página por :term',
|
|
||||||
'search_chapter_for_term' => 'Búsqueda por capítulo de :term',
|
|
||||||
'search_book_for_term' => 'Búsqueda en libro de :term',
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Books
|
* Books
|
||||||
|
|
|
@ -43,18 +43,9 @@ return [
|
||||||
* Search
|
* Search
|
||||||
*/
|
*/
|
||||||
'search_results' => 'Résultats de recherche',
|
'search_results' => 'Résultats de recherche',
|
||||||
'search_results_page' => 'Résultats de recherche des pages',
|
|
||||||
'search_results_chapter' => 'Résultats de recherche des chapitres',
|
|
||||||
'search_results_book' => 'Résultats de recherche des livres',
|
|
||||||
'search_clear' => 'Réinitialiser la recherche',
|
'search_clear' => 'Réinitialiser la recherche',
|
||||||
'search_view_pages' => 'Voir toutes les pages correspondantes',
|
|
||||||
'search_view_chapters' => 'Voir tous les chapitres correspondants',
|
|
||||||
'search_view_books' => 'Voir tous les livres correspondants',
|
|
||||||
'search_no_pages' => 'Aucune page correspondant à cette recherche',
|
'search_no_pages' => 'Aucune page correspondant à cette recherche',
|
||||||
'search_for_term' => 'recherche pour :term',
|
'search_for_term' => 'recherche pour :term',
|
||||||
'search_page_for_term' => 'Recherche de page pour :term',
|
|
||||||
'search_chapter_for_term' => 'Recherche de chapitre pour :term',
|
|
||||||
'search_book_for_term' => 'Recherche de livres pour :term',
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Books
|
* Books
|
||||||
|
|
|
@ -43,18 +43,9 @@ return [
|
||||||
* Search
|
* Search
|
||||||
*/
|
*/
|
||||||
'search_results' => 'Zoekresultaten',
|
'search_results' => 'Zoekresultaten',
|
||||||
'search_results_page' => 'Pagina Zoekresultaten',
|
|
||||||
'search_results_chapter' => 'Hoofdstuk Zoekresultaten',
|
|
||||||
'search_results_book' => 'Boek Zoekresultaten',
|
|
||||||
'search_clear' => 'Zoekopdracht wissen',
|
'search_clear' => 'Zoekopdracht wissen',
|
||||||
'search_view_pages' => 'Bekijk alle gevonden pagina\'s',
|
|
||||||
'search_view_chapters' => 'Bekijk alle gevonden hoofdstukken',
|
|
||||||
'search_view_books' => 'Bekijk alle gevonden boeken',
|
|
||||||
'search_no_pages' => 'Er zijn geen pagina\'s gevonden',
|
'search_no_pages' => 'Er zijn geen pagina\'s gevonden',
|
||||||
'search_for_term' => 'Zoeken op :term',
|
'search_for_term' => 'Zoeken op :term',
|
||||||
'search_page_for_term' => 'Pagina doorzoeken op :term',
|
|
||||||
'search_chapter_for_term' => 'Hoofdstuk doorzoeken op :term',
|
|
||||||
'search_book_for_term' => 'Boeken doorzoeken op :term',
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Books
|
* Books
|
||||||
|
|
|
@ -43,18 +43,9 @@ return [
|
||||||
* Search
|
* Search
|
||||||
*/
|
*/
|
||||||
'search_results' => 'Resultado(s) da Pesquisa',
|
'search_results' => 'Resultado(s) da Pesquisa',
|
||||||
'search_results_page' => 'Resultado(s) de Pesquisa de Página',
|
|
||||||
'search_results_chapter' => 'Resultado(s) de Pesquisa de Capítulo',
|
|
||||||
'search_results_book' => 'Resultado(s) de Pesquisa de Livro',
|
|
||||||
'search_clear' => 'Limpar Pesquisa',
|
'search_clear' => 'Limpar Pesquisa',
|
||||||
'search_view_pages' => 'Visualizar todas as páginas correspondentes',
|
|
||||||
'search_view_chapters' => 'Visualizar todos os capítulos correspondentes',
|
|
||||||
'search_view_books' => 'Visualizar todos os livros correspondentes',
|
|
||||||
'search_no_pages' => 'Nenhuma página corresponde à pesquisa',
|
'search_no_pages' => 'Nenhuma página corresponde à pesquisa',
|
||||||
'search_for_term' => 'Pesquisar por :term',
|
'search_for_term' => 'Pesquisar por :term',
|
||||||
'search_page_for_term' => 'Pesquisar Página por :term',
|
|
||||||
'search_chapter_for_term' => 'Pesquisar Capítulo por :term',
|
|
||||||
'search_book_for_term' => 'Pesquisar Livros por :term',
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Books
|
* Books
|
||||||
|
|
|
@ -5,123 +5,203 @@
|
||||||
<input type="hidden" name="searchTerm" value="{{$searchTerm}}">
|
<input type="hidden" name="searchTerm" value="{{$searchTerm}}">
|
||||||
|
|
||||||
<div id="search-system">
|
<div id="search-system">
|
||||||
|
|
||||||
<div class="faded-small toolbar">
|
<div class="faded-small toolbar">
|
||||||
<div class="container">
|
<div class="container">
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="col-sm-12 faded">
|
<div class="col-sm-12 faded">
|
||||||
<div class="breadcrumbs">
|
<div class="breadcrumbs">
|
||||||
<a href="{{ baseUrl("/search/all?term={$searchTerm}") }}" class="text-button"><i class="zmdi zmdi-search"></i>{{ $searchTerm }}</a>
|
<a href="{{ baseUrl("/search?term=" . urlencode($searchTerm)) }}" class="text-button"><i class="zmdi zmdi-search"></i>{{ trans('entities.search_for_term', ['term' => $searchTerm]) }}</a>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
||||||
<div class="container" ng-non-bindable id="searchSystem">
|
<div class="container" ng-non-bindable id="searchSystem">
|
||||||
|
|
||||||
<h1>{{ trans('entities.search_results') }}</h1>
|
|
||||||
|
|
||||||
<input type="text" v-model="termString">
|
|
||||||
|
|
||||||
<div class="row">
|
<div class="row">
|
||||||
|
|
||||||
<div class="col-md-6">
|
<div class="col-md-6">
|
||||||
|
<h1>{{ trans('entities.search_results') }}</h1>
|
||||||
|
<h6 class="text-muted">{{ trans_choice('entities.search_total_results_found', $totalResults, ['count' => $totalResults]) }}</h6>
|
||||||
@include('partials/entity-list', ['entities' => $entities])
|
@include('partials/entity-list', ['entities' => $entities])
|
||||||
|
@if ($hasNextPage)
|
||||||
|
<a href="{{ $nextPageLink }}" class="button">{{ trans('entities.search_more') }}</a>
|
||||||
|
@endif
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="col-md-5 col-md-offset-1">
|
<div class="col-md-5 col-md-offset-1">
|
||||||
<h3>Search Filters</h3>
|
<h3>{{ trans('entities.search_filters') }}</h3>
|
||||||
|
|
||||||
<form v-on:submit="updateSearch" v-cloak>
|
<form v-on:submit="updateSearch" v-cloak class="v-cloak anim fadeIn">
|
||||||
<p><strong>Content Type</strong></p>
|
<h6 class="text-muted">{{ trans('entities.search_content_type') }}</h6>
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<label><input type="checkbox" v-on:change="typeChange" v-model="search.type.page" value="page"> Page</label>
|
<label class="inline checkbox text-page"><input type="checkbox" v-on:change="typeChange" v-model="search.type.page" value="page">{{ trans('entities.page') }}</label>
|
||||||
<label><input type="checkbox" v-on:change="typeChange" v-model="search.type.chapter" value="chapter"> Chapter</label>
|
<label class="inline checkbox text-chapter"><input type="checkbox" v-on:change="typeChange" v-model="search.type.chapter" value="chapter">{{ trans('entities.chapter') }}</label>
|
||||||
<label><input type="checkbox" v-on:change="typeChange" v-model="search.type.book" value="book"> Book</label>
|
<label class="inline checkbox text-book"><input type="checkbox" v-on:change="typeChange" v-model="search.type.book" value="book">{{ trans('entities.book') }}</label>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<p><strong>Exact Matches</strong></p>
|
<h6 class="text-muted">{{ trans('entities.search_exact_matches') }}</h6>
|
||||||
<table cellpadding="0" cellspacing="0" border="0" class="no-style">
|
<table cellpadding="0" cellspacing="0" border="0" class="no-style">
|
||||||
<tr v-for="(term, i) in search.exactTerms">
|
<tr v-for="(term, i) in search.exactTerms">
|
||||||
<td style="padding: 0 12px 6px 0;">
|
<td style="padding: 0 12px 6px 0;">
|
||||||
<input class="exact-input" v-on:input="exactChange" type="text" v-model="search.exactTerms[i]"></td>
|
<input class="exact-input outline" v-on:input="exactChange" type="text" v-model="search.exactTerms[i]"></td>
|
||||||
<td>
|
<td>
|
||||||
<button type="button" class="text-button" v-on:click="removeExact(i)">
|
<button type="button" class="text-neg text-button" v-on:click="removeExact(i)">
|
||||||
<i class="zmdi zmdi-close-circle-o"></i>
|
<i class="zmdi zmdi-close"></i>
|
||||||
</button>
|
</button>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<td colspan="2">
|
<td colspan="2">
|
||||||
<button type="button" class="text-button" v-on:click="addExact">
|
<button type="button" class="text-button" v-on:click="addExact">
|
||||||
<i class="zmdi zmdi-plus-circle-o"></i>Add exact match term
|
<i class="zmdi zmdi-plus-circle-o"></i>{{ trans('common.add') }}
|
||||||
</button>
|
</button>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
</table>
|
</table>
|
||||||
|
|
||||||
<p><strong>Tag Searches</strong></p>
|
<h6 class="text-muted">{{ trans('entities.search_tags') }}</h6>
|
||||||
<table cellpadding="0" cellspacing="0" border="0" class="no-style">
|
<table cellpadding="0" cellspacing="0" border="0" class="no-style">
|
||||||
<tr v-for="(term, i) in search.tagTerms">
|
<tr v-for="(term, i) in search.tagTerms">
|
||||||
<td style="padding: 0 12px 6px 0;">
|
<td style="padding: 0 12px 6px 0;">
|
||||||
<input class="tag-input" v-on:input="tagChange" type="text" v-model="search.tagTerms[i]"></td>
|
<input class="tag-input outline" v-on:input="tagChange" type="text" v-model="search.tagTerms[i]"></td>
|
||||||
<td>
|
<td>
|
||||||
<button type="button" class="text-button" v-on:click="removeTag(i)">
|
<button type="button" class="text-neg text-button" v-on:click="removeTag(i)">
|
||||||
<i class="zmdi zmdi-close-circle-o"></i>
|
<i class="zmdi zmdi-close"></i>
|
||||||
</button>
|
</button>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<td colspan="2">
|
<td colspan="2">
|
||||||
<button type="button" class="text-button" v-on:click="addTag">
|
<button type="button" class="text-button" v-on:click="addTag">
|
||||||
<i class="zmdi zmdi-plus-circle-o"></i>Add tag search
|
<i class="zmdi zmdi-plus-circle-o"></i>{{ trans('common.add') }}
|
||||||
</button>
|
</button>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
</table>
|
</table>
|
||||||
|
|
||||||
<p><strong>Options</strong></p>
|
<h6 class="text-muted">Options</h6>
|
||||||
<label>
|
<label class="checkbox">
|
||||||
<input type="checkbox" v-on:change="optionChange('viewed_by_me')"
|
<input type="checkbox" v-on:change="optionChange('viewed_by_me')"
|
||||||
v-model="search.option.viewed_by_me" value="page">
|
v-model="search.option.viewed_by_me" value="page">
|
||||||
Viewed by me
|
{{ trans('entities.search_viewed_by_me') }}
|
||||||
</label>
|
</label>
|
||||||
<label>
|
<label class="checkbox">
|
||||||
<input type="checkbox" v-on:change="optionChange('not_viewed_by_me')"
|
<input type="checkbox" v-on:change="optionChange('not_viewed_by_me')"
|
||||||
v-model="search.option.not_viewed_by_me" value="page">
|
v-model="search.option.not_viewed_by_me" value="page">
|
||||||
Not viewed by me
|
{{ trans('entities.search_not_viewed_by_me') }}
|
||||||
|
</label>
|
||||||
|
<label class="checkbox">
|
||||||
|
<input type="checkbox" v-on:change="optionChange('is_restricted')"
|
||||||
|
v-model="search.option.is_restricted" value="page">
|
||||||
|
{{ trans('entities.search_permissions_set') }}
|
||||||
|
</label>
|
||||||
|
<label class="checkbox">
|
||||||
|
<input type="checkbox" v-on:change="optionChange('created_by:me')"
|
||||||
|
v-model="search.option['created_by:me']" value="page">
|
||||||
|
{{ trans('entities.search_created_by_me') }}
|
||||||
|
</label>
|
||||||
|
<label class="checkbox">
|
||||||
|
<input type="checkbox" v-on:change="optionChange('updated_by:me')"
|
||||||
|
v-model="search.option['updated_by:me']" value="page">
|
||||||
|
{{ trans('entities.search_updated_by_me') }}
|
||||||
</label>
|
</label>
|
||||||
|
|
||||||
<p><strong>Date Options</strong></p>
|
<h6 class="text-muted">Date Options</h6>
|
||||||
<table cellpadding="0" cellspacing="0" border="0" class="no-style">
|
<table cellpadding="0" cellspacing="0" border="0" class="no-style form-table">
|
||||||
<tr>
|
<tr>
|
||||||
<td>Updated After</td>
|
<td width="200">{{ trans('entities.search_updated_after') }}</td>
|
||||||
<td style="padding: 0 12px 6px 0;">
|
<td width="80">
|
||||||
<input v-if="search.dates.updated_after" class="tag-input" v-on:input="tagChange" type="date" v-model="search.dates.updated_after" pattern="[0-9]{4}-[0-9]{2}-[0-9]{2}">
|
<button type="button" class="text-button" v-if="!search.dates.updated_after"
|
||||||
<button type="button" class="text-button" v-if="!search.dates.updated_after" v-on:click="enableDate('updated_at')">Set Date</button>
|
v-on:click="enableDate('updated_after')">{{ trans('entities.search_set_date') }}</button>
|
||||||
|
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr v-if="search.dates.updated_after">
|
||||||
|
<td>
|
||||||
|
<input v-if="search.dates.updated_after" class="tag-input"
|
||||||
|
v-on:input="dateChange('updated_after')" type="date" v-model="search.dates.updated_after"
|
||||||
|
pattern="[0-9]{4}-[0-9]{2}-[0-9]{2}">
|
||||||
</td>
|
</td>
|
||||||
<td>
|
<td>
|
||||||
<button v-if="search.dates.updated_after" type="button" class="text-button" v-on:click="search.dates.updated_after = false">
|
<button v-if="search.dates.updated_after" type="button" class="text-neg text-button"
|
||||||
<i class="zmdi zmdi-close-circle-o"></i>
|
v-on:click="dateRemove('updated_after')">
|
||||||
|
<i class="zmdi zmdi-close"></i>
|
||||||
</button>
|
</button>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<td colspan="2">
|
<td>{{ trans('entities.search_updated_before') }}</td>
|
||||||
<button type="button" class="text-button" v-on:click="addTag">
|
<td>
|
||||||
<i class="zmdi zmdi-plus-circle-o"></i>Add tag search
|
<button type="button" class="text-button" v-if="!search.dates.updated_before"
|
||||||
|
v-on:click="enableDate('updated_before')">{{ trans('entities.search_set_date') }}</button>
|
||||||
|
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr v-if="search.dates.updated_before">
|
||||||
|
<td>
|
||||||
|
<input v-if="search.dates.updated_before" class="tag-input"
|
||||||
|
v-on:input="dateChange('updated_before')" type="date" v-model="search.dates.updated_before"
|
||||||
|
pattern="[0-9]{4}-[0-9]{2}-[0-9]{2}">
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<button v-if="search.dates.updated_before" type="button" class="text-neg text-button"
|
||||||
|
v-on:click="dateRemove('updated_before')">
|
||||||
|
<i class="zmdi zmdi-close"></i>
|
||||||
|
</button>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>{{ trans('entities.search_created_after') }}</td>
|
||||||
|
<td>
|
||||||
|
<button type="button" class="text-button" v-if="!search.dates.created_after"
|
||||||
|
v-on:click="enableDate('created_after')">{{ trans('entities.search_set_date') }}</button>
|
||||||
|
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr v-if="search.dates.created_after">
|
||||||
|
<td>
|
||||||
|
<input v-if="search.dates.created_after" class="tag-input"
|
||||||
|
v-on:input="dateChange('created_after')" type="date" v-model="search.dates.created_after"
|
||||||
|
pattern="[0-9]{4}-[0-9]{2}-[0-9]{2}">
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<button v-if="search.dates.created_after" type="button" class="text-neg text-button"
|
||||||
|
v-on:click="dateRemove('created_after')">
|
||||||
|
<i class="zmdi zmdi-close"></i>
|
||||||
|
</button>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>{{ trans('entities.search_created_before') }}</td>
|
||||||
|
<td>
|
||||||
|
<button type="button" class="text-button" v-if="!search.dates.created_before"
|
||||||
|
v-on:click="enableDate('created_before')">{{ trans('entities.search_set_date') }}</button>
|
||||||
|
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr v-if="search.dates.created_before">
|
||||||
|
<td>
|
||||||
|
<input v-if="search.dates.created_before" class="tag-input"
|
||||||
|
v-on:input="dateChange('created_before')" type="date" v-model="search.dates.created_before"
|
||||||
|
pattern="[0-9]{4}-[0-9]{2}-[0-9]{2}">
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<button v-if="search.dates.created_before" type="button" class="text-neg text-button"
|
||||||
|
v-on:click="dateRemove('created_before')">
|
||||||
|
<i class="zmdi zmdi-close"></i>
|
||||||
</button>
|
</button>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
</table>
|
</table>
|
||||||
|
|
||||||
|
|
||||||
<button type="submit" class="button pos">Update Search</button>
|
<button type="submit" class="button primary">{{ trans('entities.search_update') }}</button>
|
||||||
</form>
|
</form>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue