Finished off UI for search system

This commit is contained in:
Dan Brown 2017-04-15 15:04:30 +01:00
parent ad125327c0
commit 0e0945ef84
No known key found for this signature in database
GPG Key ID: 46D9F943C24A2EF9
14 changed files with 225 additions and 120 deletions

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -33,6 +33,7 @@ return [
'search_clear' => 'Clear Search', 'search_clear' => 'Clear Search',
'reset' => 'Reset', 'reset' => 'Reset',
'remove' => 'Remove', 'remove' => 'Remove',
'add' => 'Add',
/** /**

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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