diff --git a/app/Http/Controllers/SearchController.php b/app/Http/Controllers/SearchController.php index 6d29ab17b..b65bca51e 100644 --- a/app/Http/Controllers/SearchController.php +++ b/app/Http/Controllers/SearchController.php @@ -34,14 +34,20 @@ class SearchController extends Controller public function search(Request $request) { $searchTerm = $request->get('term'); -// $paginationAppends = $request->only('term'); TODO - Check pagination $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', [ - 'entities' => $entities, - 'searchTerm' => $searchTerm + 'entities' => $results['results'], + 'totalResults' => $results['total'], + 'searchTerm' => $searchTerm, + 'hasNextPage' => $hasNextPage, + 'nextPageLink' => $nextPageLink ]); } diff --git a/app/Services/SearchService.php b/app/Services/SearchService.php index a2844c593..7ecfb95c7 100644 --- a/app/Services/SearchService.php +++ b/app/Services/SearchService.php @@ -8,7 +8,6 @@ use BookStack\SearchTerm; use Illuminate\Database\Connection; use Illuminate\Database\Query\Builder; use Illuminate\Database\Query\JoinClause; -use Illuminate\Support\Collection; class SearchService { @@ -56,9 +55,9 @@ class SearchService * @param string $entityType * @param int $page * @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); $entityTypes = array_keys($this->entities); @@ -71,14 +70,20 @@ class SearchService $entityTypesToSearch = explode('|', $terms['filters']['type']); } - // TODO - Check drafts don't show up in results + $total = 0; + foreach ($entityTypesToSearch as $entityType) { if (!in_array($entityType, $entityTypes)) continue; $search = $this->searchEntityTable($terms, $entityType, $page, $count); + $total += $this->searchEntityTable($terms, $entityType, $page, $count, true); $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 int $page * @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); $entitySelect = $entity->newQuery(); @@ -131,8 +137,10 @@ class SearchService if (method_exists($this, $functionName)) $this->$functionName($entitySelect, $entity, $filterValue); } - $entitySelect->skip($page * $count)->take($count); $query = $this->permissionService->enforceEntityRestrictions($entityType, $entitySelect, 'view'); + if ($getCount) return $query->count(); + + $query = $query->skip(($page-1) * $count)->take($count); return $query->get(); } @@ -371,13 +379,15 @@ class SearchService 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); } 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); } diff --git a/resources/assets/js/vues/search.js b/resources/assets/js/vues/search.js index 710f4b214..515ca3bc9 100644 --- a/resources/assets/js/vues/search.js +++ b/resources/assets/js/vues/search.js @@ -12,7 +12,12 @@ let data = { exactTerms: [], tagTerms: [], option: {}, - dates: {} + dates: { + updated_after: false, + updated_before: false, + created_after: false, + created_before: false, + } } }; @@ -126,7 +131,7 @@ let methods = { }, optionParse(searchString) { - let optionFilter = /{([a-z_-]+?)}/gi; + let optionFilter = /{([a-z_\-:]+?)}/gi; let matches; while ((matches = optionFilter.exec(searchString)) !== null) { this.search.option[matches[1].toLowerCase()] = true; @@ -148,7 +153,30 @@ let methods = { }, 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.tagParse(this.termString); this.optionParse(this.termString); + this.dateParse(this.termString); } module.exports = { diff --git a/resources/assets/sass/_animations.scss b/resources/assets/sass/_animations.scss index 582d718c8..afcf01cff 100644 --- a/resources/assets/sass/_animations.scss +++ b/resources/assets/sass/_animations.scss @@ -2,7 +2,7 @@ .anim.fadeIn { opacity: 0; animation-name: fadeIn; - animation-duration: 160ms; + animation-duration: 180ms; animation-timing-function: ease-in-out; animation-fill-mode: forwards; } diff --git a/resources/assets/sass/_forms.scss b/resources/assets/sass/_forms.scss index 7e6b800d2..1fc812896 100644 --- a/resources/assets/sass/_forms.scss +++ b/resources/assets/sass/_forms.scss @@ -98,19 +98,36 @@ label { label.radio, label.checkbox { font-weight: 400; + user-select: none; input[type="radio"], input[type="checkbox"] { margin-right: $-xs; } } +label.inline.checkbox { + margin-right: $-m; +} + label + p.small { 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; } +input[type=date] { + width: 190px; +} + .toggle-switch { display: inline-block; background-color: #BBB; diff --git a/resources/assets/sass/styles.scss b/resources/assets/sass/styles.scss index 967aba76b..50c3a50b2 100644 --- a/resources/assets/sass/styles.scss +++ b/resources/assets/sass/styles.scss @@ -7,8 +7,8 @@ @import "grid"; @import "blocks"; @import "buttons"; -@import "forms"; @import "tables"; +@import "forms"; @import "animations"; @import "tinymce"; @import "highlightjs"; @@ -17,7 +17,11 @@ @import "lists"; @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 { display: none !important; @@ -272,8 +276,3 @@ $btt-size: 40px; - - - - - diff --git a/resources/lang/de/entities.php b/resources/lang/de/entities.php index 2859e4ec5..c9feb8497 100644 --- a/resources/lang/de/entities.php +++ b/resources/lang/de/entities.php @@ -43,18 +43,9 @@ return [ * Search */ 'search_results' => 'Suchergebnisse', - 'search_results_page' => 'Seiten-Suchergebnisse', - 'search_results_chapter' => 'Kapitel-Suchergebnisse', - 'search_results_book' => 'Buch-Suchergebnisse', '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_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 diff --git a/resources/lang/en/common.php b/resources/lang/en/common.php index 31ef42e97..e1d74c95e 100644 --- a/resources/lang/en/common.php +++ b/resources/lang/en/common.php @@ -33,6 +33,7 @@ return [ 'search_clear' => 'Clear Search', 'reset' => 'Reset', 'remove' => 'Remove', + 'add' => 'Add', /** diff --git a/resources/lang/en/entities.php b/resources/lang/en/entities.php index f54134718..66c2e8042 100644 --- a/resources/lang/en/entities.php +++ b/resources/lang/en/entities.php @@ -43,18 +43,26 @@ return [ * Search */ 'search_results' => 'Search Results', - 'search_results_page' => 'Page Search Results', - 'search_results_chapter' => 'Chapter Search Results', - 'search_results_book' => 'Book Search Results', + 'search_total_results_found' => ':count result found|:count total results found', '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_for_term' => 'Search for :term', - 'search_page_for_term' => 'Page search for :term', - 'search_chapter_for_term' => 'Chapter search for :term', - 'search_book_for_term' => 'Books search for :term', + 'search_more' => 'More Results', + 'search_filters' => 'Search Filters', + '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 diff --git a/resources/lang/es/entities.php b/resources/lang/es/entities.php index 14e952f1a..b03366da6 100644 --- a/resources/lang/es/entities.php +++ b/resources/lang/es/entities.php @@ -43,18 +43,9 @@ return [ * Search */ '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_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_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 diff --git a/resources/lang/fr/entities.php b/resources/lang/fr/entities.php index cfd206b91..5562fb0fd 100644 --- a/resources/lang/fr/entities.php +++ b/resources/lang/fr/entities.php @@ -43,18 +43,9 @@ return [ * Search */ '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_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_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 diff --git a/resources/lang/nl/entities.php b/resources/lang/nl/entities.php index 610116c8b..d6975e130 100644 --- a/resources/lang/nl/entities.php +++ b/resources/lang/nl/entities.php @@ -43,18 +43,9 @@ return [ * Search */ 'search_results' => 'Zoekresultaten', - 'search_results_page' => 'Pagina Zoekresultaten', - 'search_results_chapter' => 'Hoofdstuk Zoekresultaten', - 'search_results_book' => 'Boek Zoekresultaten', '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_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 diff --git a/resources/lang/pt_BR/entities.php b/resources/lang/pt_BR/entities.php index 922342424..5a965fe62 100644 --- a/resources/lang/pt_BR/entities.php +++ b/resources/lang/pt_BR/entities.php @@ -43,18 +43,9 @@ return [ * Search */ '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_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_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 diff --git a/resources/views/search/all.blade.php b/resources/views/search/all.blade.php index d1f928912..1029b65fa 100644 --- a/resources/views/search/all.blade.php +++ b/resources/views/search/all.blade.php @@ -5,123 +5,203 @@ <input type="hidden" name="searchTerm" value="{{$searchTerm}}"> <div id="search-system"> + <div class="faded-small toolbar"> <div class="container"> <div class="row"> <div class="col-sm-12 faded"> <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 class="container" ng-non-bindable id="searchSystem"> - <h1>{{ trans('entities.search_results') }}</h1> - - <input type="text" v-model="termString"> - <div class="row"> <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]) + @if ($hasNextPage) + <a href="{{ $nextPageLink }}" class="button">{{ trans('entities.search_more') }}</a> + @endif </div> <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> - <p><strong>Content Type</strong></p> + <form v-on:submit="updateSearch" v-cloak class="v-cloak anim fadeIn"> + <h6 class="text-muted">{{ trans('entities.search_content_type') }}</h6> <div class="form-group"> - <label><input type="checkbox" v-on:change="typeChange" v-model="search.type.page" value="page"> Page</label> - <label><input type="checkbox" v-on:change="typeChange" v-model="search.type.chapter" value="chapter"> Chapter</label> - <label><input type="checkbox" v-on:change="typeChange" v-model="search.type.book" value="book"> Book</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 class="inline checkbox text-chapter"><input type="checkbox" v-on:change="typeChange" v-model="search.type.chapter" value="chapter">{{ trans('entities.chapter') }}</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> - <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"> <tr v-for="(term, i) in search.exactTerms"> <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> - <button type="button" class="text-button" v-on:click="removeExact(i)"> - <i class="zmdi zmdi-close-circle-o"></i> + <button type="button" class="text-neg text-button" v-on:click="removeExact(i)"> + <i class="zmdi zmdi-close"></i> </button> </td> </tr> <tr> <td colspan="2"> <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> </td> </tr> </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"> <tr v-for="(term, i) in search.tagTerms"> <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> - <button type="button" class="text-button" v-on:click="removeTag(i)"> - <i class="zmdi zmdi-close-circle-o"></i> + <button type="button" class="text-neg text-button" v-on:click="removeTag(i)"> + <i class="zmdi zmdi-close"></i> </button> </td> </tr> <tr> <td colspan="2"> <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> </td> </tr> </table> - <p><strong>Options</strong></p> - <label> + <h6 class="text-muted">Options</h6> + <label class="checkbox"> <input type="checkbox" v-on:change="optionChange('viewed_by_me')" v-model="search.option.viewed_by_me" value="page"> - Viewed by me + {{ trans('entities.search_viewed_by_me') }} </label> - <label> + <label class="checkbox"> <input type="checkbox" v-on:change="optionChange('not_viewed_by_me')" 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> - <p><strong>Date Options</strong></p> - <table cellpadding="0" cellspacing="0" border="0" class="no-style"> + <h6 class="text-muted">Date Options</h6> + <table cellpadding="0" cellspacing="0" border="0" class="no-style form-table"> <tr> - <td>Updated After</td> - <td style="padding: 0 12px 6px 0;"> - <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" v-on:click="enableDate('updated_at')">Set Date</button> + <td width="200">{{ trans('entities.search_updated_after') }}</td> + <td width="80"> + <button type="button" class="text-button" v-if="!search.dates.updated_after" + 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> - <button v-if="search.dates.updated_after" type="button" class="text-button" v-on:click="search.dates.updated_after = false"> - <i class="zmdi zmdi-close-circle-o"></i> + <button v-if="search.dates.updated_after" type="button" class="text-neg text-button" + v-on:click="dateRemove('updated_after')"> + <i class="zmdi zmdi-close"></i> </button> </td> </tr> <tr> - <td colspan="2"> - <button type="button" class="text-button" v-on:click="addTag"> - <i class="zmdi zmdi-plus-circle-o"></i>Add tag search + <td>{{ trans('entities.search_updated_before') }}</td> + <td> + <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> </td> </tr> </table> - <button type="submit" class="button pos">Update Search</button> + <button type="submit" class="button primary">{{ trans('entities.search_update') }}</button> </form> - </div> </div>