Showing
36 changed files
with
234 additions
and
153 deletions
| ... | @@ -31,11 +31,8 @@ class SearchController extends Controller | ... | @@ -31,11 +31,8 @@ class SearchController extends Controller |
| 31 | * @return \Illuminate\View\View | 31 | * @return \Illuminate\View\View |
| 32 | * @internal param string $searchTerm | 32 | * @internal param string $searchTerm |
| 33 | */ | 33 | */ |
| 34 | - public function searchAll(Request $request) | 34 | + public function search(Request $request) |
| 35 | { | 35 | { |
| 36 | - if (!$request->has('term')) { | ||
| 37 | - return redirect()->back(); | ||
| 38 | - } | ||
| 39 | $searchTerm = $request->get('term'); | 36 | $searchTerm = $request->get('term'); |
| 40 | // $paginationAppends = $request->only('term'); TODO - Check pagination | 37 | // $paginationAppends = $request->only('term'); TODO - Check pagination |
| 41 | $this->setPageTitle(trans('entities.search_for_term', ['term' => $searchTerm])); | 38 | $this->setPageTitle(trans('entities.search_for_term', ['term' => $searchTerm])); |
| ... | @@ -48,65 +45,6 @@ class SearchController extends Controller | ... | @@ -48,65 +45,6 @@ class SearchController extends Controller |
| 48 | ]); | 45 | ]); |
| 49 | } | 46 | } |
| 50 | 47 | ||
| 51 | - /** | ||
| 52 | - * Search only the pages in the system. | ||
| 53 | - * @param Request $request | ||
| 54 | - * @return \Illuminate\Http\RedirectResponse|\Illuminate\View\View | ||
| 55 | - */ | ||
| 56 | - public function searchPages(Request $request) | ||
| 57 | - { | ||
| 58 | - if (!$request->has('term')) return redirect()->back(); | ||
| 59 | - | ||
| 60 | - $searchTerm = $request->get('term'); | ||
| 61 | - $paginationAppends = $request->only('term'); | ||
| 62 | - $pages = $this->entityRepo->getBySearch('page', $searchTerm, [], 20, $paginationAppends); | ||
| 63 | - $this->setPageTitle(trans('entities.search_page_for_term', ['term' => $searchTerm])); | ||
| 64 | - return view('search/entity-search-list', [ | ||
| 65 | - 'entities' => $pages, | ||
| 66 | - 'title' => trans('entities.search_results_page'), | ||
| 67 | - 'searchTerm' => $searchTerm | ||
| 68 | - ]); | ||
| 69 | - } | ||
| 70 | - | ||
| 71 | - /** | ||
| 72 | - * Search only the chapters in the system. | ||
| 73 | - * @param Request $request | ||
| 74 | - * @return \Illuminate\Http\RedirectResponse|\Illuminate\View\View | ||
| 75 | - */ | ||
| 76 | - public function searchChapters(Request $request) | ||
| 77 | - { | ||
| 78 | - if (!$request->has('term')) return redirect()->back(); | ||
| 79 | - | ||
| 80 | - $searchTerm = $request->get('term'); | ||
| 81 | - $paginationAppends = $request->only('term'); | ||
| 82 | - $chapters = $this->entityRepo->getBySearch('chapter', $searchTerm, [], 20, $paginationAppends); | ||
| 83 | - $this->setPageTitle(trans('entities.search_chapter_for_term', ['term' => $searchTerm])); | ||
| 84 | - return view('search/entity-search-list', [ | ||
| 85 | - 'entities' => $chapters, | ||
| 86 | - 'title' => trans('entities.search_results_chapter'), | ||
| 87 | - 'searchTerm' => $searchTerm | ||
| 88 | - ]); | ||
| 89 | - } | ||
| 90 | - | ||
| 91 | - /** | ||
| 92 | - * Search only the books in the system. | ||
| 93 | - * @param Request $request | ||
| 94 | - * @return \Illuminate\Http\RedirectResponse|\Illuminate\View\View | ||
| 95 | - */ | ||
| 96 | - public function searchBooks(Request $request) | ||
| 97 | - { | ||
| 98 | - if (!$request->has('term')) return redirect()->back(); | ||
| 99 | - | ||
| 100 | - $searchTerm = $request->get('term'); | ||
| 101 | - $paginationAppends = $request->only('term'); | ||
| 102 | - $books = $this->entityRepo->getBySearch('book', $searchTerm, [], 20, $paginationAppends); | ||
| 103 | - $this->setPageTitle(trans('entities.search_book_for_term', ['term' => $searchTerm])); | ||
| 104 | - return view('search/entity-search-list', [ | ||
| 105 | - 'entities' => $books, | ||
| 106 | - 'title' => trans('entities.search_results_book'), | ||
| 107 | - 'searchTerm' => $searchTerm | ||
| 108 | - ]); | ||
| 109 | - } | ||
| 110 | 48 | ||
| 111 | /** | 49 | /** |
| 112 | * Searches all entities within a book. | 50 | * Searches all entities within a book. |
| ... | @@ -144,6 +82,7 @@ class SearchController extends Controller | ... | @@ -144,6 +82,7 @@ class SearchController extends Controller |
| 144 | if ($searchTerm !== false) { | 82 | if ($searchTerm !== false) { |
| 145 | foreach (['page', 'chapter', 'book'] as $entityType) { | 83 | foreach (['page', 'chapter', 'book'] as $entityType) { |
| 146 | if ($entityTypes->contains($entityType)) { | 84 | if ($entityTypes->contains($entityType)) { |
| 85 | + // TODO - Update to new system | ||
| 147 | $entities = $entities->merge($this->entityRepo->getBySearch($entityType, $searchTerm)->items()); | 86 | $entities = $entities->merge($this->entityRepo->getBySearch($entityType, $searchTerm)->items()); |
| 148 | } | 87 | } |
| 149 | } | 88 | } | ... | ... |
| ... | @@ -52,7 +52,7 @@ class SearchService | ... | @@ -52,7 +52,7 @@ class SearchService |
| 52 | 52 | ||
| 53 | /** | 53 | /** |
| 54 | * Search all entities in the system. | 54 | * Search all entities in the system. |
| 55 | - * @param $searchString | 55 | + * @param string $searchString |
| 56 | * @param string $entityType | 56 | * @param string $entityType |
| 57 | * @param int $page | 57 | * @param int $page |
| 58 | * @param int $count | 58 | * @param int $count |
| ... | @@ -60,35 +60,45 @@ class SearchService | ... | @@ -60,35 +60,45 @@ class SearchService |
| 60 | */ | 60 | */ |
| 61 | public function searchEntities($searchString, $entityType = 'all', $page = 0, $count = 20) | 61 | public function searchEntities($searchString, $entityType = 'all', $page = 0, $count = 20) |
| 62 | { | 62 | { |
| 63 | + $terms = $this->parseSearchString($searchString); | ||
| 64 | + $entityTypes = array_keys($this->entities); | ||
| 65 | + $entityTypesToSearch = $entityTypes; | ||
| 66 | + $results = collect(); | ||
| 67 | + | ||
| 68 | + if ($entityType !== 'all') { | ||
| 69 | + $entityTypesToSearch = $entityType; | ||
| 70 | + } else if (isset($terms['filters']['type'])) { | ||
| 71 | + $entityTypesToSearch = explode('|', $terms['filters']['type']); | ||
| 72 | + } | ||
| 73 | + | ||
| 63 | // TODO - Check drafts don't show up in results | 74 | // TODO - Check drafts don't show up in results |
| 64 | - if ($entityType !== 'all') return $this->searchEntityTable($searchString, $entityType, $page, $count); | 75 | + foreach ($entityTypesToSearch as $entityType) { |
| 76 | + if (!in_array($entityType, $entityTypes)) continue; | ||
| 77 | + $search = $this->searchEntityTable($terms, $entityType, $page, $count); | ||
| 78 | + $results = $results->merge($search); | ||
| 79 | + } | ||
| 65 | 80 | ||
| 66 | - $bookSearch = $this->searchEntityTable($searchString, 'book', $page, $count); | 81 | + return $results->sortByDesc('score'); |
| 67 | - $chapterSearch = $this->searchEntityTable($searchString, 'chapter', $page, $count); | ||
| 68 | - $pageSearch = $this->searchEntityTable($searchString, 'page', $page, $count); | ||
| 69 | - return collect($bookSearch)->merge($chapterSearch)->merge($pageSearch)->sortByDesc('score'); | ||
| 70 | } | 82 | } |
| 71 | 83 | ||
| 72 | /** | 84 | /** |
| 73 | * Search across a particular entity type. | 85 | * Search across a particular entity type. |
| 74 | - * @param string $searchString | 86 | + * @param array $terms |
| 75 | * @param string $entityType | 87 | * @param string $entityType |
| 76 | * @param int $page | 88 | * @param int $page |
| 77 | * @param int $count | 89 | * @param int $count |
| 78 | * @return \Illuminate\Database\Eloquent\Collection|static[] | 90 | * @return \Illuminate\Database\Eloquent\Collection|static[] |
| 79 | */ | 91 | */ |
| 80 | - public function searchEntityTable($searchString, $entityType = 'page', $page = 0, $count = 20) | 92 | + public function searchEntityTable($terms, $entityType = 'page', $page = 0, $count = 20) |
| 81 | { | 93 | { |
| 82 | - $searchTerms = $this->parseSearchString($searchString); | ||
| 83 | - | ||
| 84 | $entity = $this->getEntity($entityType); | 94 | $entity = $this->getEntity($entityType); |
| 85 | $entitySelect = $entity->newQuery(); | 95 | $entitySelect = $entity->newQuery(); |
| 86 | 96 | ||
| 87 | // Handle normal search terms | 97 | // Handle normal search terms |
| 88 | - if (count($searchTerms['search']) > 0) { | 98 | + if (count($terms['search']) > 0) { |
| 89 | $subQuery = $this->db->table('search_terms')->select('entity_id', 'entity_type', \DB::raw('SUM(score) as score')); | 99 | $subQuery = $this->db->table('search_terms')->select('entity_id', 'entity_type', \DB::raw('SUM(score) as score')); |
| 90 | - $subQuery->where(function(Builder $query) use ($searchTerms) { | 100 | + $subQuery->where(function(Builder $query) use ($terms) { |
| 91 | - foreach ($searchTerms['search'] as $inputTerm) { | 101 | + foreach ($terms['search'] as $inputTerm) { |
| 92 | $query->orWhere('term', 'like', $inputTerm .'%'); | 102 | $query->orWhere('term', 'like', $inputTerm .'%'); |
| 93 | } | 103 | } |
| 94 | })->groupBy('entity_type', 'entity_id'); | 104 | })->groupBy('entity_type', 'entity_id'); |
| ... | @@ -99,9 +109,9 @@ class SearchService | ... | @@ -99,9 +109,9 @@ class SearchService |
| 99 | } | 109 | } |
| 100 | 110 | ||
| 101 | // Handle exact term matching | 111 | // Handle exact term matching |
| 102 | - if (count($searchTerms['exact']) > 0) { | 112 | + if (count($terms['exact']) > 0) { |
| 103 | - $entitySelect->where(function(\Illuminate\Database\Eloquent\Builder $query) use ($searchTerms, $entity) { | 113 | + $entitySelect->where(function(\Illuminate\Database\Eloquent\Builder $query) use ($terms, $entity) { |
| 104 | - foreach ($searchTerms['exact'] as $inputTerm) { | 114 | + foreach ($terms['exact'] as $inputTerm) { |
| 105 | $query->where(function (\Illuminate\Database\Eloquent\Builder $query) use ($inputTerm, $entity) { | 115 | $query->where(function (\Illuminate\Database\Eloquent\Builder $query) use ($inputTerm, $entity) { |
| 106 | $query->where('name', 'like', '%'.$inputTerm .'%') | 116 | $query->where('name', 'like', '%'.$inputTerm .'%') |
| 107 | ->orWhere($entity->textField, 'like', '%'.$inputTerm .'%'); | 117 | ->orWhere($entity->textField, 'like', '%'.$inputTerm .'%'); |
| ... | @@ -111,16 +121,14 @@ class SearchService | ... | @@ -111,16 +121,14 @@ class SearchService |
| 111 | } | 121 | } |
| 112 | 122 | ||
| 113 | // Handle tag searches | 123 | // Handle tag searches |
| 114 | - foreach ($searchTerms['tags'] as $inputTerm) { | 124 | + foreach ($terms['tags'] as $inputTerm) { |
| 115 | $this->applyTagSearch($entitySelect, $inputTerm); | 125 | $this->applyTagSearch($entitySelect, $inputTerm); |
| 116 | } | 126 | } |
| 117 | 127 | ||
| 118 | // Handle filters | 128 | // Handle filters |
| 119 | - foreach ($searchTerms['filters'] as $filterTerm) { | 129 | + foreach ($terms['filters'] as $filterTerm => $filterValue) { |
| 120 | - $splitTerm = explode(':', $filterTerm); | 130 | + $functionName = camel_case('filter_' . $filterTerm); |
| 121 | - $functionName = camel_case('filter_' . $splitTerm[0]); | 131 | + if (method_exists($this, $functionName)) $this->$functionName($entitySelect, $entity, $filterValue); |
| 122 | - $param = count($splitTerm) > 1 ? $splitTerm[1] : ''; | ||
| 123 | - if (method_exists($this, $functionName)) $this->$functionName($entitySelect, $entity, $param); | ||
| 124 | } | 132 | } |
| 125 | 133 | ||
| 126 | $entitySelect->skip($page * $count)->take($count); | 134 | $entitySelect->skip($page * $count)->take($count); |
| ... | @@ -149,6 +157,7 @@ class SearchService | ... | @@ -149,6 +157,7 @@ class SearchService |
| 149 | 'filters' => '/\{(.*?)\}/' | 157 | 'filters' => '/\{(.*?)\}/' |
| 150 | ]; | 158 | ]; |
| 151 | 159 | ||
| 160 | + // Parse special terms | ||
| 152 | foreach ($patterns as $termType => $pattern) { | 161 | foreach ($patterns as $termType => $pattern) { |
| 153 | $matches = []; | 162 | $matches = []; |
| 154 | preg_match_all($pattern, $searchString, $matches); | 163 | preg_match_all($pattern, $searchString, $matches); |
| ... | @@ -158,10 +167,19 @@ class SearchService | ... | @@ -158,10 +167,19 @@ class SearchService |
| 158 | } | 167 | } |
| 159 | } | 168 | } |
| 160 | 169 | ||
| 170 | + // Parse standard terms | ||
| 161 | foreach (explode(' ', trim($searchString)) as $searchTerm) { | 171 | foreach (explode(' ', trim($searchString)) as $searchTerm) { |
| 162 | if ($searchTerm !== '') $terms['search'][] = $searchTerm; | 172 | if ($searchTerm !== '') $terms['search'][] = $searchTerm; |
| 163 | } | 173 | } |
| 164 | 174 | ||
| 175 | + // Split filter values out | ||
| 176 | + $splitFilters = []; | ||
| 177 | + foreach ($terms['filters'] as $filter) { | ||
| 178 | + $explodedFilter = explode(':', $filter, 1); | ||
| 179 | + $splitFilters[$explodedFilter[0]] = (count($explodedFilter) > 1) ? $explodedFilter[1] : ''; | ||
| 180 | + } | ||
| 181 | + $terms['filters'] = $splitFilters; | ||
| 182 | + | ||
| 165 | return $terms; | 183 | return $terms; |
| 166 | } | 184 | } |
| 167 | 185 | ... | ... |
gulpfile.js
deleted
100644 → 0
| 1 | { | 1 | { |
| 2 | "private": true, | 2 | "private": true, |
| 3 | "scripts": { | 3 | "scripts": { |
| 4 | - "build": "gulp --production", | 4 | + "dev": "npm run development", |
| 5 | - "dev": "gulp watch", | 5 | + "development": "cross-env NODE_ENV=development node_modules/webpack/bin/webpack.js --progress --hide-modules --config=node_modules/laravel-mix/setup/webpack.config.js", |
| 6 | - "watch": "gulp watch" | 6 | + "watch": "cross-env NODE_ENV=development node_modules/webpack/bin/webpack.js --watch --progress --hide-modules --config=node_modules/laravel-mix/setup/webpack.config.js", |
| 7 | + "watch-poll": "npm run watch -- --watch-poll", | ||
| 8 | + "hot": "cross-env NODE_ENV=development node_modules/webpack-dev-server/bin/webpack-dev-server.js --inline --hot --config=node_modules/laravel-mix/setup/webpack.config.js", | ||
| 9 | + "prod": "npm run production", | ||
| 10 | + "production": "cross-env NODE_ENV=production node_modules/webpack/bin/webpack.js --progress --hide-modules --config=node_modules/laravel-mix/setup/webpack.config.js" | ||
| 7 | }, | 11 | }, |
| 8 | "devDependencies": { | 12 | "devDependencies": { |
| 9 | "angular": "^1.5.5", | 13 | "angular": "^1.5.5", |
| ... | @@ -11,14 +15,16 @@ | ... | @@ -11,14 +15,16 @@ |
| 11 | "angular-resource": "^1.5.5", | 15 | "angular-resource": "^1.5.5", |
| 12 | "angular-sanitize": "^1.5.5", | 16 | "angular-sanitize": "^1.5.5", |
| 13 | "angular-ui-sortable": "^0.15.0", | 17 | "angular-ui-sortable": "^0.15.0", |
| 18 | + "cross-env": "^3.2.3", | ||
| 14 | "dropzone": "^4.0.1", | 19 | "dropzone": "^4.0.1", |
| 15 | "gulp": "^3.9.0", | 20 | "gulp": "^3.9.0", |
| 16 | - "laravel-elixir": "^6.0.0-11", | 21 | + "laravel-mix": "0.*", |
| 17 | - "laravel-elixir-browserify-official": "^0.1.3", | ||
| 18 | "marked": "^0.3.5", | 22 | "marked": "^0.3.5", |
| 19 | "moment": "^2.12.0" | 23 | "moment": "^2.12.0" |
| 20 | }, | 24 | }, |
| 21 | "dependencies": { | 25 | "dependencies": { |
| 22 | - "clipboard": "^1.5.16" | 26 | + "axios": "^0.16.1", |
| 27 | + "clipboard": "^1.5.16", | ||
| 28 | + "vue": "^2.2.6" | ||
| 23 | } | 29 | } |
| 24 | } | 30 | } | ... | ... |
public/mix-manifest.json
0 → 100644
No preview for this file type
No preview for this file type
No preview for this file type
No preview for this file type
No preview for this file type
No preview for this file type
No preview for this file type
No preview for this file type
No preview for this file type
No preview for this file type
No preview for this file type
No preview for this file type
No preview for this file type
No preview for this file type
No preview for this file type
No preview for this file type
No preview for this file type
No preview for this file type
No preview for this file type
No preview for this file type
No preview for this file type
No preview for this file type
| 1 | "use strict"; | 1 | "use strict"; |
| 2 | 2 | ||
| 3 | -// AngularJS - Create application and load components | ||
| 4 | -import angular from "angular"; | ||
| 5 | -import "angular-resource"; | ||
| 6 | -import "angular-animate"; | ||
| 7 | -import "angular-sanitize"; | ||
| 8 | -import "angular-ui-sortable"; | ||
| 9 | - | ||
| 10 | // Url retrieval function | 3 | // Url retrieval function |
| 11 | window.baseUrl = function(path) { | 4 | window.baseUrl = function(path) { |
| 12 | let basePath = document.querySelector('meta[name="base-url"]').getAttribute('content'); | 5 | let basePath = document.querySelector('meta[name="base-url"]').getAttribute('content'); |
| ... | @@ -15,6 +8,28 @@ window.baseUrl = function(path) { | ... | @@ -15,6 +8,28 @@ window.baseUrl = function(path) { |
| 15 | return basePath + '/' + path; | 8 | return basePath + '/' + path; |
| 16 | }; | 9 | }; |
| 17 | 10 | ||
| 11 | +// Vue and axios setup | ||
| 12 | +import vue from "vue/dist/vue.common"; | ||
| 13 | +import axios from "axios"; | ||
| 14 | + | ||
| 15 | +let axiosInstance = axios.create({ | ||
| 16 | + headers: { | ||
| 17 | + 'X-CSRF-TOKEN': document.querySelector('meta[name=token]').getAttribute('content'), | ||
| 18 | + 'baseURL': baseUrl('') | ||
| 19 | + } | ||
| 20 | +}); | ||
| 21 | + | ||
| 22 | +window.Vue = vue; | ||
| 23 | +window.axios = axiosInstance; | ||
| 24 | +Vue.prototype.$http = axiosInstance; | ||
| 25 | + | ||
| 26 | +// AngularJS - Create application and load components | ||
| 27 | +import angular from "angular"; | ||
| 28 | +import "angular-resource"; | ||
| 29 | +import "angular-animate"; | ||
| 30 | +import "angular-sanitize"; | ||
| 31 | +import "angular-ui-sortable"; | ||
| 32 | + | ||
| 18 | let ngApp = angular.module('bookStack', ['ngResource', 'ngAnimate', 'ngSanitize', 'ui.sortable']); | 33 | let ngApp = angular.module('bookStack', ['ngResource', 'ngAnimate', 'ngSanitize', 'ui.sortable']); |
| 19 | 34 | ||
| 20 | // Translation setup | 35 | // Translation setup |
| ... | @@ -47,6 +62,7 @@ class EventManager { | ... | @@ -47,6 +62,7 @@ class EventManager { |
| 47 | } | 62 | } |
| 48 | 63 | ||
| 49 | window.Events = new EventManager(); | 64 | window.Events = new EventManager(); |
| 65 | +Vue.prototype.$events = window.Events; | ||
| 50 | 66 | ||
| 51 | // Load in angular specific items | 67 | // Load in angular specific items |
| 52 | import Services from './services'; | 68 | import Services from './services'; | ... | ... |
resources/assets/js/vues/search.js
0 → 100644
| 1 | + | ||
| 2 | +let termString = document.querySelector('[name=searchTerm]').value; | ||
| 3 | +let terms = termString.split(' '); | ||
| 4 | + | ||
| 5 | +let data = { | ||
| 6 | + terms: terms, | ||
| 7 | + termString : termString, | ||
| 8 | + search: { | ||
| 9 | + type: { | ||
| 10 | + page: true, | ||
| 11 | + chapter: true, | ||
| 12 | + book: true | ||
| 13 | + } | ||
| 14 | + } | ||
| 15 | +}; | ||
| 16 | + | ||
| 17 | +let computed = { | ||
| 18 | + | ||
| 19 | +}; | ||
| 20 | + | ||
| 21 | +let methods = { | ||
| 22 | + | ||
| 23 | + appendTerm(term) { | ||
| 24 | + if (this.termString.slice(-1) !== " ") this.termString += ' '; | ||
| 25 | + this.termString += term; | ||
| 26 | + }, | ||
| 27 | + | ||
| 28 | + typeParse(searchString) { | ||
| 29 | + let typeFilter = /{\s?type:\s?(.*?)\s?}/; | ||
| 30 | + let match = searchString.match(typeFilter); | ||
| 31 | + let type = this.search.type; | ||
| 32 | + if (!match) { | ||
| 33 | + type.page = type.book = type.chapter = true; | ||
| 34 | + return; | ||
| 35 | + } | ||
| 36 | + let splitTypes = match[1].replace(/ /g, '').split('|'); | ||
| 37 | + type.page = (splitTypes.indexOf('page') !== -1); | ||
| 38 | + type.chapter = (splitTypes.indexOf('chapter') !== -1); | ||
| 39 | + type.book = (splitTypes.indexOf('book') !== -1); | ||
| 40 | + }, | ||
| 41 | + | ||
| 42 | + typeChange() { | ||
| 43 | + let typeFilter = /{\s?type:\s?(.*?)\s?}/; | ||
| 44 | + let type = this.search.type; | ||
| 45 | + if (type.page === type.chapter && type.page === type.book) { | ||
| 46 | + this.termString = this.termString.replace(typeFilter, ''); | ||
| 47 | + return; | ||
| 48 | + } | ||
| 49 | + let selectedTypes = Object.keys(type).filter(type => {return this.search.type[type];}).join('|'); | ||
| 50 | + let typeTerm = '{type:'+selectedTypes+'}'; | ||
| 51 | + if (this.termString.match(typeFilter)) { | ||
| 52 | + this.termString = this.termString.replace(typeFilter, typeTerm); | ||
| 53 | + return; | ||
| 54 | + } | ||
| 55 | + this.appendTerm(typeTerm); | ||
| 56 | + } | ||
| 57 | + | ||
| 58 | +}; | ||
| 59 | + | ||
| 60 | +function created() { | ||
| 61 | + this.typeParse(this.termString); | ||
| 62 | +} | ||
| 63 | + | ||
| 64 | +module.exports = { | ||
| 65 | + data, computed, methods, created | ||
| 66 | +}; | ||
| ... | \ No newline at end of file | ... | \ No newline at end of file |
resources/assets/js/vues/vues.js
0 → 100644
| 1 | + | ||
| 2 | +function exists(id) { | ||
| 3 | + return document.getElementById(id) !== null; | ||
| 4 | +} | ||
| 5 | + | ||
| 6 | +let vueMapping = { | ||
| 7 | + 'search-system': require('./search') | ||
| 8 | +}; | ||
| 9 | + | ||
| 10 | +Object.keys(vueMapping).forEach(id => { | ||
| 11 | + if (exists(id)) { | ||
| 12 | + let config = vueMapping[id]; | ||
| 13 | + config.el = '#' + id; | ||
| 14 | + new Vue(config); | ||
| 15 | + } | ||
| 16 | +}); | ||
| ... | \ No newline at end of file | ... | \ No newline at end of file |
| ... | @@ -6,8 +6,8 @@ | ... | @@ -6,8 +6,8 @@ |
| 6 | font-style: normal; | 6 | font-style: normal; |
| 7 | font-weight: 100; | 7 | font-weight: 100; |
| 8 | src: local('Roboto Thin'), local('Roboto-Thin'), | 8 | src: local('Roboto Thin'), local('Roboto-Thin'), |
| 9 | - url('../fonts/roboto-v15-cyrillic_latin-100.woff2') format('woff2'), /* Chrome 26+, Opera 23+ */ | 9 | + url('assets/fonts/roboto-v15-cyrillic_latin-100.woff2') format('woff2'), /* Chrome 26+, Opera 23+ */ |
| 10 | - url('../fonts/roboto-v15-cyrillic_latin-100.woff') format('woff'); /* Chrome 6+, Firefox 3.6+, IE 9+, Safari 5.1+ */ | 10 | + url('assets/fonts/roboto-v15-cyrillic_latin-100.woff') format('woff'); /* Chrome 6+, Firefox 3.6+, IE 9+, Safari 5.1+ */ |
| 11 | } | 11 | } |
| 12 | /* roboto-100italic - cyrillic_latin */ | 12 | /* roboto-100italic - cyrillic_latin */ |
| 13 | @font-face { | 13 | @font-face { |
| ... | @@ -15,8 +15,8 @@ | ... | @@ -15,8 +15,8 @@ |
| 15 | font-style: italic; | 15 | font-style: italic; |
| 16 | font-weight: 100; | 16 | font-weight: 100; |
| 17 | src: local('Roboto Thin Italic'), local('Roboto-ThinItalic'), | 17 | src: local('Roboto Thin Italic'), local('Roboto-ThinItalic'), |
| 18 | - url('../fonts/roboto-v15-cyrillic_latin-100italic.woff2') format('woff2'), /* Chrome 26+, Opera 23+ */ | 18 | + url('assets/fonts/roboto-v15-cyrillic_latin-100italic.woff2') format('woff2'), /* Chrome 26+, Opera 23+ */ |
| 19 | - url('../fonts/roboto-v15-cyrillic_latin-100italic.woff') format('woff'); /* Chrome 6+, Firefox 3.6+, IE 9+, Safari 5.1+ */ | 19 | + url('assets/fonts/roboto-v15-cyrillic_latin-100italic.woff') format('woff'); /* Chrome 6+, Firefox 3.6+, IE 9+, Safari 5.1+ */ |
| 20 | } | 20 | } |
| 21 | /* roboto-300 - cyrillic_latin */ | 21 | /* roboto-300 - cyrillic_latin */ |
| 22 | @font-face { | 22 | @font-face { |
| ... | @@ -24,8 +24,8 @@ | ... | @@ -24,8 +24,8 @@ |
| 24 | font-style: normal; | 24 | font-style: normal; |
| 25 | font-weight: 300; | 25 | font-weight: 300; |
| 26 | src: local('Roboto Light'), local('Roboto-Light'), | 26 | src: local('Roboto Light'), local('Roboto-Light'), |
| 27 | - url('../fonts/roboto-v15-cyrillic_latin-300.woff2') format('woff2'), /* Chrome 26+, Opera 23+ */ | 27 | + url('assets/fonts/roboto-v15-cyrillic_latin-300.woff2') format('woff2'), /* Chrome 26+, Opera 23+ */ |
| 28 | - url('../fonts/roboto-v15-cyrillic_latin-300.woff') format('woff'); /* Chrome 6+, Firefox 3.6+, IE 9+, Safari 5.1+ */ | 28 | + url('assets/fonts/roboto-v15-cyrillic_latin-300.woff') format('woff'); /* Chrome 6+, Firefox 3.6+, IE 9+, Safari 5.1+ */ |
| 29 | } | 29 | } |
| 30 | /* roboto-300italic - cyrillic_latin */ | 30 | /* roboto-300italic - cyrillic_latin */ |
| 31 | @font-face { | 31 | @font-face { |
| ... | @@ -33,8 +33,8 @@ | ... | @@ -33,8 +33,8 @@ |
| 33 | font-style: italic; | 33 | font-style: italic; |
| 34 | font-weight: 300; | 34 | font-weight: 300; |
| 35 | src: local('Roboto Light Italic'), local('Roboto-LightItalic'), | 35 | src: local('Roboto Light Italic'), local('Roboto-LightItalic'), |
| 36 | - url('../fonts/roboto-v15-cyrillic_latin-300italic.woff2') format('woff2'), /* Chrome 26+, Opera 23+ */ | 36 | + url('assets/fonts/roboto-v15-cyrillic_latin-300italic.woff2') format('woff2'), /* Chrome 26+, Opera 23+ */ |
| 37 | - url('../fonts/roboto-v15-cyrillic_latin-300italic.woff') format('woff'); /* Chrome 6+, Firefox 3.6+, IE 9+, Safari 5.1+ */ | 37 | + url('assets/fonts/roboto-v15-cyrillic_latin-300italic.woff') format('woff'); /* Chrome 6+, Firefox 3.6+, IE 9+, Safari 5.1+ */ |
| 38 | } | 38 | } |
| 39 | /* roboto-regular - cyrillic_latin */ | 39 | /* roboto-regular - cyrillic_latin */ |
| 40 | @font-face { | 40 | @font-face { |
| ... | @@ -42,8 +42,8 @@ | ... | @@ -42,8 +42,8 @@ |
| 42 | font-style: normal; | 42 | font-style: normal; |
| 43 | font-weight: 400; | 43 | font-weight: 400; |
| 44 | src: local('Roboto'), local('Roboto-Regular'), | 44 | src: local('Roboto'), local('Roboto-Regular'), |
| 45 | - url('../fonts/roboto-v15-cyrillic_latin-regular.woff2') format('woff2'), /* Chrome 26+, Opera 23+ */ | 45 | + url('assets/fonts/roboto-v15-cyrillic_latin-regular.woff2') format('woff2'), /* Chrome 26+, Opera 23+ */ |
| 46 | - url('../fonts/roboto-v15-cyrillic_latin-regular.woff') format('woff'); /* Chrome 6+, Firefox 3.6+, IE 9+, Safari 5.1+ */ | 46 | + url('assets/fonts/roboto-v15-cyrillic_latin-regular.woff') format('woff'); /* Chrome 6+, Firefox 3.6+, IE 9+, Safari 5.1+ */ |
| 47 | } | 47 | } |
| 48 | /* roboto-italic - cyrillic_latin */ | 48 | /* roboto-italic - cyrillic_latin */ |
| 49 | @font-face { | 49 | @font-face { |
| ... | @@ -51,8 +51,8 @@ | ... | @@ -51,8 +51,8 @@ |
| 51 | font-style: italic; | 51 | font-style: italic; |
| 52 | font-weight: 400; | 52 | font-weight: 400; |
| 53 | src: local('Roboto Italic'), local('Roboto-Italic'), | 53 | src: local('Roboto Italic'), local('Roboto-Italic'), |
| 54 | - url('../fonts/roboto-v15-cyrillic_latin-italic.woff2') format('woff2'), /* Chrome 26+, Opera 23+ */ | 54 | + url('assets/fonts/roboto-v15-cyrillic_latin-italic.woff2') format('woff2'), /* Chrome 26+, Opera 23+ */ |
| 55 | - url('../fonts/roboto-v15-cyrillic_latin-italic.woff') format('woff'); /* Chrome 6+, Firefox 3.6+, IE 9+, Safari 5.1+ */ | 55 | + url('assets/fonts/roboto-v15-cyrillic_latin-italic.woff') format('woff'); /* Chrome 6+, Firefox 3.6+, IE 9+, Safari 5.1+ */ |
| 56 | } | 56 | } |
| 57 | /* roboto-500 - cyrillic_latin */ | 57 | /* roboto-500 - cyrillic_latin */ |
| 58 | @font-face { | 58 | @font-face { |
| ... | @@ -60,8 +60,8 @@ | ... | @@ -60,8 +60,8 @@ |
| 60 | font-style: normal; | 60 | font-style: normal; |
| 61 | font-weight: 500; | 61 | font-weight: 500; |
| 62 | src: local('Roboto Medium'), local('Roboto-Medium'), | 62 | src: local('Roboto Medium'), local('Roboto-Medium'), |
| 63 | - url('../fonts/roboto-v15-cyrillic_latin-500.woff2') format('woff2'), /* Chrome 26+, Opera 23+ */ | 63 | + url('assets/fonts/roboto-v15-cyrillic_latin-500.woff2') format('woff2'), /* Chrome 26+, Opera 23+ */ |
| 64 | - url('../fonts/roboto-v15-cyrillic_latin-500.woff') format('woff'); /* Chrome 6+, Firefox 3.6+, IE 9+, Safari 5.1+ */ | 64 | + url('assets/fonts/roboto-v15-cyrillic_latin-500.woff') format('woff'); /* Chrome 6+, Firefox 3.6+, IE 9+, Safari 5.1+ */ |
| 65 | } | 65 | } |
| 66 | /* roboto-500italic - cyrillic_latin */ | 66 | /* roboto-500italic - cyrillic_latin */ |
| 67 | @font-face { | 67 | @font-face { |
| ... | @@ -69,8 +69,8 @@ | ... | @@ -69,8 +69,8 @@ |
| 69 | font-style: italic; | 69 | font-style: italic; |
| 70 | font-weight: 500; | 70 | font-weight: 500; |
| 71 | src: local('Roboto Medium Italic'), local('Roboto-MediumItalic'), | 71 | src: local('Roboto Medium Italic'), local('Roboto-MediumItalic'), |
| 72 | - url('../fonts/roboto-v15-cyrillic_latin-500italic.woff2') format('woff2'), /* Chrome 26+, Opera 23+ */ | 72 | + url('assets/fonts/roboto-v15-cyrillic_latin-500italic.woff2') format('woff2'), /* Chrome 26+, Opera 23+ */ |
| 73 | - url('../fonts/roboto-v15-cyrillic_latin-500italic.woff') format('woff'); /* Chrome 6+, Firefox 3.6+, IE 9+, Safari 5.1+ */ | 73 | + url('assets/fonts/roboto-v15-cyrillic_latin-500italic.woff') format('woff'); /* Chrome 6+, Firefox 3.6+, IE 9+, Safari 5.1+ */ |
| 74 | } | 74 | } |
| 75 | /* roboto-700 - cyrillic_latin */ | 75 | /* roboto-700 - cyrillic_latin */ |
| 76 | @font-face { | 76 | @font-face { |
| ... | @@ -78,8 +78,8 @@ | ... | @@ -78,8 +78,8 @@ |
| 78 | font-style: normal; | 78 | font-style: normal; |
| 79 | font-weight: 700; | 79 | font-weight: 700; |
| 80 | src: local('Roboto Bold'), local('Roboto-Bold'), | 80 | src: local('Roboto Bold'), local('Roboto-Bold'), |
| 81 | - url('../fonts/roboto-v15-cyrillic_latin-700.woff2') format('woff2'), /* Chrome 26+, Opera 23+ */ | 81 | + url('assets/fonts/roboto-v15-cyrillic_latin-700.woff2') format('woff2'), /* Chrome 26+, Opera 23+ */ |
| 82 | - url('../fonts/roboto-v15-cyrillic_latin-700.woff') format('woff'); /* Chrome 6+, Firefox 3.6+, IE 9+, Safari 5.1+ */ | 82 | + url('assets/fonts/roboto-v15-cyrillic_latin-700.woff') format('woff'); /* Chrome 6+, Firefox 3.6+, IE 9+, Safari 5.1+ */ |
| 83 | } | 83 | } |
| 84 | /* roboto-700italic - cyrillic_latin */ | 84 | /* roboto-700italic - cyrillic_latin */ |
| 85 | @font-face { | 85 | @font-face { |
| ... | @@ -87,8 +87,8 @@ | ... | @@ -87,8 +87,8 @@ |
| 87 | font-style: italic; | 87 | font-style: italic; |
| 88 | font-weight: 700; | 88 | font-weight: 700; |
| 89 | src: local('Roboto Bold Italic'), local('Roboto-BoldItalic'), | 89 | src: local('Roboto Bold Italic'), local('Roboto-BoldItalic'), |
| 90 | - url('../fonts/roboto-v15-cyrillic_latin-700italic.woff2') format('woff2'), /* Chrome 26+, Opera 23+ */ | 90 | + url('assets/fonts/roboto-v15-cyrillic_latin-700italic.woff2') format('woff2'), /* Chrome 26+, Opera 23+ */ |
| 91 | - url('../fonts/roboto-v15-cyrillic_latin-700italic.woff') format('woff'); /* Chrome 6+, Firefox 3.6+, IE 9+, Safari 5.1+ */ | 91 | + url('assets/fonts/roboto-v15-cyrillic_latin-700italic.woff') format('woff'); /* Chrome 6+, Firefox 3.6+, IE 9+, Safari 5.1+ */ |
| 92 | } | 92 | } |
| 93 | 93 | ||
| 94 | /* roboto-mono-regular - latin */ | 94 | /* roboto-mono-regular - latin */ |
| ... | @@ -97,6 +97,6 @@ | ... | @@ -97,6 +97,6 @@ |
| 97 | font-style: normal; | 97 | font-style: normal; |
| 98 | font-weight: 400; | 98 | font-weight: 400; |
| 99 | src: local('Roboto Mono'), local('RobotoMono-Regular'), | 99 | src: local('Roboto Mono'), local('RobotoMono-Regular'), |
| 100 | - url('../fonts/roboto-mono-v4-latin-regular.woff2') format('woff2'), /* Chrome 26+, Opera 23+ */ | 100 | + url('assets/fonts/roboto-mono-v4-latin-regular.woff2') format('woff2'), /* Chrome 26+, Opera 23+ */ |
| 101 | - url('../fonts/roboto-mono-v4-latin-regular.woff') format('woff'); /* Chrome 6+, Firefox 3.6+, IE 9+, Safari 5.1+ */ | 101 | + url('assets/fonts/roboto-mono-v4-latin-regular.woff') format('woff'); /* Chrome 6+, Firefox 3.6+, IE 9+, Safari 5.1+ */ |
| 102 | } | 102 | } |
| ... | \ No newline at end of file | ... | \ No newline at end of file | ... | ... |
| ... | @@ -84,6 +84,7 @@ | ... | @@ -84,6 +84,7 @@ |
| 84 | </div> | 84 | </div> |
| 85 | @yield('bottom') | 85 | @yield('bottom') |
| 86 | <script src="{{ versioned_asset('js/common.js') }}"></script> | 86 | <script src="{{ versioned_asset('js/common.js') }}"></script> |
| 87 | +<script src="{{ versioned_asset('js/vues.js') }}"></script> | ||
| 87 | @yield('scripts') | 88 | @yield('scripts') |
| 88 | </body> | 89 | </body> |
| 89 | </html> | 90 | </html> | ... | ... |
| ... | @@ -2,6 +2,9 @@ | ... | @@ -2,6 +2,9 @@ |
| 2 | 2 | ||
| 3 | @section('content') | 3 | @section('content') |
| 4 | 4 | ||
| 5 | + <input type="hidden" name="searchTerm" value="{{$searchTerm}}"> | ||
| 6 | + | ||
| 7 | +<div id="search-system"> | ||
| 5 | <div class="faded-small toolbar"> | 8 | <div class="faded-small toolbar"> |
| 6 | <div class="container"> | 9 | <div class="container"> |
| 7 | <div class="row"> | 10 | <div class="row"> |
| ... | @@ -15,40 +18,41 @@ | ... | @@ -15,40 +18,41 @@ |
| 15 | </div> | 18 | </div> |
| 16 | 19 | ||
| 17 | 20 | ||
| 18 | - <div class="container" ng-non-bindable> | 21 | + <div class="container" ng-non-bindable id="searchSystem"> |
| 19 | 22 | ||
| 20 | <h1>{{ trans('entities.search_results') }}</h1> | 23 | <h1>{{ trans('entities.search_results') }}</h1> |
| 21 | 24 | ||
| 22 | - <p> | 25 | + <input type="text" v-model="termString"> |
| 23 | - {{--TODO - Remove these pages--}} | ||
| 24 | - Remove these links (Commented out) | ||
| 25 | - {{--@if(count($pages) > 0)--}} | ||
| 26 | - {{--<a href="{{ baseUrl("/search/pages?term={$searchTerm}") }}" class="text-page"><i class="zmdi zmdi-file-text"></i>{{ trans('entities.search_view_pages') }}</a>--}} | ||
| 27 | - {{--@endif--}} | ||
| 28 | - | ||
| 29 | - {{--@if(count($chapters) > 0)--}} | ||
| 30 | - {{-- --}} | ||
| 31 | - {{--<a href="{{ baseUrl("/search/chapters?term={$searchTerm}") }}" class="text-chapter"><i class="zmdi zmdi-collection-bookmark"></i>{{ trans('entities.search_view_chapters') }}</a>--}} | ||
| 32 | - {{--@endif--}} | ||
| 33 | - | ||
| 34 | - {{--@if(count($books) > 0)--}} | ||
| 35 | - {{-- --}} | ||
| 36 | - {{--<a href="{{ baseUrl("/search/books?term={$searchTerm}") }}" class="text-book"><i class="zmdi zmdi-book"></i>{{ trans('entities.search_view_books') }}</a>--}} | ||
| 37 | - {{--@endif--}} | ||
| 38 | - </p> | ||
| 39 | 26 | ||
| 40 | <div class="row"> | 27 | <div class="row"> |
| 28 | + | ||
| 41 | <div class="col-md-6"> | 29 | <div class="col-md-6"> |
| 42 | - <h3><a href="{{ baseUrl("/search/pages?term={$searchTerm}") }}" class="no-color">{{ trans('entities.pages') }}</a></h3> | 30 | + @include('partials/entity-list', ['entities' => $entities]) |
| 43 | - @include('partials/entity-list', ['entities' => $entities, 'style' => 'detailed']) | ||
| 44 | </div> | 31 | </div> |
| 32 | + | ||
| 45 | <div class="col-md-5 col-md-offset-1"> | 33 | <div class="col-md-5 col-md-offset-1"> |
| 46 | - Sidebar filter controls | 34 | + <h3>Search Filters</h3> |
| 35 | + | ||
| 36 | + <p><strong>Content Type</strong></p> | ||
| 37 | + <div class="form-group"> | ||
| 38 | + <label><input type="checkbox" v-on:change="typeChange" v-model="search.type.page" value="page"> Page</label> | ||
| 39 | + <label><input type="checkbox" v-on:change="typeChange" v-model="search.type.chapter" value="chapter"> Chapter</label> | ||
| 40 | + <label><input type="checkbox" v-on:change="typeChange" v-model="search.type.book" value="book"> Book</label> | ||
| 41 | + </div> | ||
| 42 | + | ||
| 47 | </div> | 43 | </div> |
| 44 | + | ||
| 48 | </div> | 45 | </div> |
| 49 | 46 | ||
| 50 | 47 | ||
| 51 | </div> | 48 | </div> |
| 49 | +</div> | ||
| 50 | + | ||
| 51 | +@stop | ||
| 52 | + | ||
| 53 | +@section('scripts') | ||
| 54 | + <script> | ||
| 52 | 55 | ||
| 53 | 56 | ||
| 57 | + </script> | ||
| 54 | @stop | 58 | @stop |
| ... | \ No newline at end of file | ... | \ No newline at end of file | ... | ... |
| ... | @@ -123,10 +123,7 @@ Route::group(['middleware' => 'auth'], function () { | ... | @@ -123,10 +123,7 @@ Route::group(['middleware' => 'auth'], function () { |
| 123 | Route::get('/link/{id}', 'PageController@redirectFromLink'); | 123 | Route::get('/link/{id}', 'PageController@redirectFromLink'); |
| 124 | 124 | ||
| 125 | // Search | 125 | // Search |
| 126 | - Route::get('/search', 'SearchController@searchAll'); | 126 | + Route::get('/search', 'SearchController@search'); |
| 127 | - Route::get('/search/pages', 'SearchController@searchPages'); | ||
| 128 | - Route::get('/search/books', 'SearchController@searchBooks'); | ||
| 129 | - Route::get('/search/chapters', 'SearchController@searchChapters'); | ||
| 130 | Route::get('/search/book/{bookId}', 'SearchController@searchBook'); | 127 | Route::get('/search/book/{bookId}', 'SearchController@searchBook'); |
| 131 | 128 | ||
| 132 | // Other Pages | 129 | // Other Pages | ... | ... |
webpack.mix.js
0 → 100644
| 1 | +const { mix } = require('laravel-mix'); | ||
| 2 | + | ||
| 3 | +/* | ||
| 4 | + |-------------------------------------------------------------------------- | ||
| 5 | + | Mix Asset Management | ||
| 6 | + |-------------------------------------------------------------------------- | ||
| 7 | + | | ||
| 8 | + | Mix provides a clean, fluent API for defining some Webpack build steps | ||
| 9 | + | for your Laravel application. By default, we are compiling the Sass | ||
| 10 | + | file for the application as well as bundling up all the JS files. | ||
| 11 | + | | ||
| 12 | + */ | ||
| 13 | + | ||
| 14 | +mix.js('resources/assets/js/global.js', './public/js/common.js') | ||
| 15 | + .js('resources/assets/js/vues/vues.js', './public/js/vues.js') | ||
| 16 | + .sass('resources/assets/sass/styles.scss', 'public/css') | ||
| 17 | + .sass('resources/assets/sass/print-styles.scss', 'public/css') | ||
| 18 | + .sass('resources/assets/sass/export-styles.scss', 'public/css'); |
-
Please register or sign in to post a comment