]> BookStack Code Mirror - bookstack/commitdiff
Started search interface, Added in vue and moved fonts
authorDan Brown <redacted>
Sun, 9 Apr 2017 19:59:57 +0000 (20:59 +0100)
committerDan Brown <redacted>
Sun, 9 Apr 2017 19:59:57 +0000 (20:59 +0100)
36 files changed:
.gitignore
app/Http/Controllers/SearchController.php
app/Services/SearchService.php
gulpfile.js [deleted file]
package.json
public/mix-manifest.json [new file with mode: 0644]
resources/assets/fonts/roboto-mono-v4-latin-regular.woff [moved from public/fonts/roboto-mono-v4-latin-regular.woff with 100% similarity]
resources/assets/fonts/roboto-mono-v4-latin-regular.woff2 [moved from public/fonts/roboto-mono-v4-latin-regular.woff2 with 100% similarity]
resources/assets/fonts/roboto-v15-cyrillic_latin-100.woff [moved from public/fonts/roboto-v15-cyrillic_latin-100.woff with 100% similarity]
resources/assets/fonts/roboto-v15-cyrillic_latin-100.woff2 [moved from public/fonts/roboto-v15-cyrillic_latin-100.woff2 with 100% similarity]
resources/assets/fonts/roboto-v15-cyrillic_latin-100italic.woff [moved from public/fonts/roboto-v15-cyrillic_latin-100italic.woff with 100% similarity]
resources/assets/fonts/roboto-v15-cyrillic_latin-100italic.woff2 [moved from public/fonts/roboto-v15-cyrillic_latin-100italic.woff2 with 100% similarity]
resources/assets/fonts/roboto-v15-cyrillic_latin-300.woff [moved from public/fonts/roboto-v15-cyrillic_latin-300.woff with 100% similarity]
resources/assets/fonts/roboto-v15-cyrillic_latin-300.woff2 [moved from public/fonts/roboto-v15-cyrillic_latin-300.woff2 with 100% similarity]
resources/assets/fonts/roboto-v15-cyrillic_latin-300italic.woff [moved from public/fonts/roboto-v15-cyrillic_latin-300italic.woff with 100% similarity]
resources/assets/fonts/roboto-v15-cyrillic_latin-300italic.woff2 [moved from public/fonts/roboto-v15-cyrillic_latin-300italic.woff2 with 100% similarity]
resources/assets/fonts/roboto-v15-cyrillic_latin-500.woff [moved from public/fonts/roboto-v15-cyrillic_latin-500.woff with 100% similarity]
resources/assets/fonts/roboto-v15-cyrillic_latin-500.woff2 [moved from public/fonts/roboto-v15-cyrillic_latin-500.woff2 with 100% similarity]
resources/assets/fonts/roboto-v15-cyrillic_latin-500italic.woff [moved from public/fonts/roboto-v15-cyrillic_latin-500italic.woff with 100% similarity]
resources/assets/fonts/roboto-v15-cyrillic_latin-500italic.woff2 [moved from public/fonts/roboto-v15-cyrillic_latin-500italic.woff2 with 100% similarity]
resources/assets/fonts/roboto-v15-cyrillic_latin-700.woff [moved from public/fonts/roboto-v15-cyrillic_latin-700.woff with 100% similarity]
resources/assets/fonts/roboto-v15-cyrillic_latin-700.woff2 [moved from public/fonts/roboto-v15-cyrillic_latin-700.woff2 with 100% similarity]
resources/assets/fonts/roboto-v15-cyrillic_latin-700italic.woff [moved from public/fonts/roboto-v15-cyrillic_latin-700italic.woff with 100% similarity]
resources/assets/fonts/roboto-v15-cyrillic_latin-700italic.woff2 [moved from public/fonts/roboto-v15-cyrillic_latin-700italic.woff2 with 100% similarity]
resources/assets/fonts/roboto-v15-cyrillic_latin-italic.woff [moved from public/fonts/roboto-v15-cyrillic_latin-italic.woff with 100% similarity]
resources/assets/fonts/roboto-v15-cyrillic_latin-italic.woff2 [moved from public/fonts/roboto-v15-cyrillic_latin-italic.woff2 with 100% similarity]
resources/assets/fonts/roboto-v15-cyrillic_latin-regular.woff [moved from public/fonts/roboto-v15-cyrillic_latin-regular.woff with 100% similarity]
resources/assets/fonts/roboto-v15-cyrillic_latin-regular.woff2 [moved from public/fonts/roboto-v15-cyrillic_latin-regular.woff2 with 100% similarity]
resources/assets/js/global.js
resources/assets/js/vues/search.js [new file with mode: 0644]
resources/assets/js/vues/vues.js [new file with mode: 0644]
resources/assets/sass/_fonts.scss
resources/views/base.blade.php
resources/views/search/all.blade.php
routes/web.php
webpack.mix.js [new file with mode: 0644]

index 5f41a864e58092fd0467efe1ffbeac7c6dd8558c..856cf37222195a285877fc301603fac73dcc338a 100644 (file)
@@ -7,6 +7,7 @@ Homestead.yaml
 /public/plugins
 /public/css
 /public/js
 /public/plugins
 /public/css
 /public/js
+/public/fonts
 /public/bower
 /storage/images
 _ide_helper.php
 /public/bower
 /storage/images
 _ide_helper.php
index dca5fa0afe5b9e7893f0a7eea5f8c178900d4185..6d29ab17b67c5530e7eb0ab0e1af3ef5edfff789 100644 (file)
@@ -31,11 +31,8 @@ class SearchController extends Controller
      * @return \Illuminate\View\View
      * @internal param string $searchTerm
      */
      * @return \Illuminate\View\View
      * @internal param string $searchTerm
      */
-    public function searchAll(Request $request)
+    public function search(Request $request)
     {
     {
-        if (!$request->has('term')) {
-            return redirect()->back();
-        }
         $searchTerm = $request->get('term');
 //        $paginationAppends = $request->only('term'); TODO - Check pagination
         $this->setPageTitle(trans('entities.search_for_term', ['term' => $searchTerm]));
         $searchTerm = $request->get('term');
 //        $paginationAppends = $request->only('term'); TODO - Check pagination
         $this->setPageTitle(trans('entities.search_for_term', ['term' => $searchTerm]));
@@ -48,65 +45,6 @@ class SearchController extends Controller
         ]);
     }
 
         ]);
     }
 
-    /**
-     * Search only the pages in the system.
-     * @param Request $request
-     * @return \Illuminate\Http\RedirectResponse|\Illuminate\View\View
-     */
-    public function searchPages(Request $request)
-    {
-        if (!$request->has('term')) return redirect()->back();
-
-        $searchTerm = $request->get('term');
-        $paginationAppends = $request->only('term');
-        $pages = $this->entityRepo->getBySearch('page', $searchTerm, [], 20, $paginationAppends);
-        $this->setPageTitle(trans('entities.search_page_for_term', ['term' => $searchTerm]));
-        return view('search/entity-search-list', [
-            'entities'   => $pages,
-            'title'      => trans('entities.search_results_page'),
-            'searchTerm' => $searchTerm
-        ]);
-    }
-
-    /**
-     * Search only the chapters in the system.
-     * @param Request $request
-     * @return \Illuminate\Http\RedirectResponse|\Illuminate\View\View
-     */
-    public function searchChapters(Request $request)
-    {
-        if (!$request->has('term')) return redirect()->back();
-
-        $searchTerm = $request->get('term');
-        $paginationAppends = $request->only('term');
-        $chapters = $this->entityRepo->getBySearch('chapter', $searchTerm, [], 20, $paginationAppends);
-        $this->setPageTitle(trans('entities.search_chapter_for_term', ['term' => $searchTerm]));
-        return view('search/entity-search-list', [
-            'entities'   => $chapters,
-            'title'      => trans('entities.search_results_chapter'),
-            'searchTerm' => $searchTerm
-        ]);
-    }
-
-    /**
-     * Search only the books in the system.
-     * @param Request $request
-     * @return \Illuminate\Http\RedirectResponse|\Illuminate\View\View
-     */
-    public function searchBooks(Request $request)
-    {
-        if (!$request->has('term')) return redirect()->back();
-
-        $searchTerm = $request->get('term');
-        $paginationAppends = $request->only('term');
-        $books = $this->entityRepo->getBySearch('book', $searchTerm, [], 20, $paginationAppends);
-        $this->setPageTitle(trans('entities.search_book_for_term', ['term' => $searchTerm]));
-        return view('search/entity-search-list', [
-            'entities'   => $books,
-            'title'      => trans('entities.search_results_book'),
-            'searchTerm' => $searchTerm
-        ]);
-    }
 
     /**
      * Searches all entities within a book.
 
     /**
      * Searches all entities within a book.
@@ -144,6 +82,7 @@ class SearchController extends Controller
         if ($searchTerm !== false) {
             foreach (['page', 'chapter', 'book'] as $entityType) {
                 if ($entityTypes->contains($entityType)) {
         if ($searchTerm !== false) {
             foreach (['page', 'chapter', 'book'] as $entityType) {
                 if ($entityTypes->contains($entityType)) {
+                    // TODO - Update to new system
                     $entities = $entities->merge($this->entityRepo->getBySearch($entityType, $searchTerm)->items());
                 }
             }
                     $entities = $entities->merge($this->entityRepo->getBySearch($entityType, $searchTerm)->items());
                 }
             }
index ec505af00d87b541d3a80c6346897b559245f3c2..8202b4997fd9f6c1dd4f3e97dadd1afed71a64d7 100644 (file)
@@ -52,7 +52,7 @@ class SearchService
 
     /**
      * Search all entities in the system.
 
     /**
      * Search all entities in the system.
-     * @param $searchString
+     * @param string $searchString
      * @param string $entityType
      * @param int $page
      * @param int $count
      * @param string $entityType
      * @param int $page
      * @param int $count
@@ -60,35 +60,45 @@ class SearchService
      */
     public function searchEntities($searchString, $entityType = 'all', $page = 0, $count = 20)
     {
      */
     public function searchEntities($searchString, $entityType = 'all', $page = 0, $count = 20)
     {
+        $terms = $this->parseSearchString($searchString);
+        $entityTypes = array_keys($this->entities);
+        $entityTypesToSearch = $entityTypes;
+        $results = collect();
+
+        if ($entityType !== 'all') {
+            $entityTypesToSearch = $entityType;
+        } else if (isset($terms['filters']['type'])) {
+            $entityTypesToSearch = explode('|', $terms['filters']['type']);
+        }
+
         // TODO - Check drafts don't show up in results
         // TODO - Check drafts don't show up in results
-       if ($entityType !== 'all') return $this->searchEntityTable($searchString, $entityType, $page, $count);
+        foreach ($entityTypesToSearch as $entityType) {
+            if (!in_array($entityType, $entityTypes)) continue;
+            $search = $this->searchEntityTable($terms, $entityType, $page, $count);
+            $results = $results->merge($search);
+        }
 
 
-       $bookSearch = $this->searchEntityTable($searchString, 'book', $page, $count);
-       $chapterSearch = $this->searchEntityTable($searchString, 'chapter', $page, $count);
-       $pageSearch = $this->searchEntityTable($searchString, 'page', $page, $count);
-       return collect($bookSearch)->merge($chapterSearch)->merge($pageSearch)->sortByDesc('score');
+        return $results->sortByDesc('score');
     }
 
     /**
      * Search across a particular entity type.
     }
 
     /**
      * Search across a particular entity type.
-     * @param string $searchString
+     * @param array $terms
      * @param string $entityType
      * @param int $page
      * @param int $count
      * @return \Illuminate\Database\Eloquent\Collection|static[]
      */
      * @param string $entityType
      * @param int $page
      * @param int $count
      * @return \Illuminate\Database\Eloquent\Collection|static[]
      */
-    public function searchEntityTable($searchString, $entityType = 'page', $page = 0, $count = 20)
+    public function searchEntityTable($terms, $entityType = 'page', $page = 0, $count = 20)
     {
     {
-        $searchTerms = $this->parseSearchString($searchString);
-
         $entity = $this->getEntity($entityType);
         $entitySelect = $entity->newQuery();
 
         // Handle normal search terms
         $entity = $this->getEntity($entityType);
         $entitySelect = $entity->newQuery();
 
         // Handle normal search terms
-        if (count($searchTerms['search']) > 0) {
+        if (count($terms['search']) > 0) {
             $subQuery = $this->db->table('search_terms')->select('entity_id', 'entity_type', \DB::raw('SUM(score) as score'));
             $subQuery = $this->db->table('search_terms')->select('entity_id', 'entity_type', \DB::raw('SUM(score) as score'));
-            $subQuery->where(function(Builder $query) use ($searchTerms) {
-                foreach ($searchTerms['search'] as $inputTerm) {
+            $subQuery->where(function(Builder $query) use ($terms) {
+                foreach ($terms['search'] as $inputTerm) {
                     $query->orWhere('term', 'like', $inputTerm .'%');
                 }
             })->groupBy('entity_type', 'entity_id');
                     $query->orWhere('term', 'like', $inputTerm .'%');
                 }
             })->groupBy('entity_type', 'entity_id');
@@ -99,9 +109,9 @@ class SearchService
         }
 
         // Handle exact term matching
         }
 
         // Handle exact term matching
-        if (count($searchTerms['exact']) > 0) {
-            $entitySelect->where(function(\Illuminate\Database\Eloquent\Builder $query) use ($searchTerms, $entity) {
-                foreach ($searchTerms['exact'] as $inputTerm) {
+        if (count($terms['exact']) > 0) {
+            $entitySelect->where(function(\Illuminate\Database\Eloquent\Builder $query) use ($terms, $entity) {
+                foreach ($terms['exact'] as $inputTerm) {
                     $query->where(function (\Illuminate\Database\Eloquent\Builder $query) use ($inputTerm, $entity) {
                         $query->where('name', 'like', '%'.$inputTerm .'%')
                             ->orWhere($entity->textField, 'like', '%'.$inputTerm .'%');
                     $query->where(function (\Illuminate\Database\Eloquent\Builder $query) use ($inputTerm, $entity) {
                         $query->where('name', 'like', '%'.$inputTerm .'%')
                             ->orWhere($entity->textField, 'like', '%'.$inputTerm .'%');
@@ -111,16 +121,14 @@ class SearchService
         }
 
         // Handle tag searches
         }
 
         // Handle tag searches
-        foreach ($searchTerms['tags'] as $inputTerm) {
+        foreach ($terms['tags'] as $inputTerm) {
             $this->applyTagSearch($entitySelect, $inputTerm);
         }
 
         // Handle filters
             $this->applyTagSearch($entitySelect, $inputTerm);
         }
 
         // Handle filters
-        foreach ($searchTerms['filters'] as $filterTerm) {
-            $splitTerm = explode(':', $filterTerm);
-            $functionName = camel_case('filter_' . $splitTerm[0]);
-            $param = count($splitTerm) > 1 ? $splitTerm[1] : '';
-            if (method_exists($this, $functionName)) $this->$functionName($entitySelect, $entity, $param);
+        foreach ($terms['filters'] as $filterTerm => $filterValue) {
+            $functionName = camel_case('filter_' . $filterTerm);
+            if (method_exists($this, $functionName)) $this->$functionName($entitySelect, $entity, $filterValue);
         }
 
         $entitySelect->skip($page * $count)->take($count);
         }
 
         $entitySelect->skip($page * $count)->take($count);
@@ -149,6 +157,7 @@ class SearchService
             'filters' => '/\{(.*?)\}/'
         ];
 
             'filters' => '/\{(.*?)\}/'
         ];
 
+        // Parse special terms
         foreach ($patterns as $termType => $pattern) {
             $matches = [];
             preg_match_all($pattern, $searchString, $matches);
         foreach ($patterns as $termType => $pattern) {
             $matches = [];
             preg_match_all($pattern, $searchString, $matches);
@@ -158,10 +167,19 @@ class SearchService
             }
         }
 
             }
         }
 
+        // Parse standard terms
         foreach (explode(' ', trim($searchString)) as $searchTerm) {
             if ($searchTerm !== '') $terms['search'][] = $searchTerm;
         }
 
         foreach (explode(' ', trim($searchString)) as $searchTerm) {
             if ($searchTerm !== '') $terms['search'][] = $searchTerm;
         }
 
+        // Split filter values out
+        $splitFilters = [];
+        foreach ($terms['filters'] as $filter) {
+            $explodedFilter = explode(':', $filter, 1);
+            $splitFilters[$explodedFilter[0]] = (count($explodedFilter) > 1) ? $explodedFilter[1] : '';
+        }
+        $terms['filters'] = $splitFilters;
+
         return $terms;
     }
 
         return $terms;
     }
 
diff --git a/gulpfile.js b/gulpfile.js
deleted file mode 100644 (file)
index 9d789d9..0000000
+++ /dev/null
@@ -1,8 +0,0 @@
-var elixir = require('laravel-elixir');
-
-elixir(mix => {
-    mix.sass('styles.scss');
-    mix.sass('print-styles.scss');
-    mix.sass('export-styles.scss');
-    mix.browserify('global.js', './public/js/common.js');
-});
index b0805c91836ff5ac9e12a1e9d1f6790fbc5c707b..1d7e8e26882cfb08ad1a1efaef657eb67febe8f4 100644 (file)
@@ -1,9 +1,13 @@
 {
   "private": true,
   "scripts": {
 {
   "private": true,
   "scripts": {
-    "build": "gulp --production",
-    "dev": "gulp watch",
-    "watch": "gulp watch"
+    "dev": "npm run development",
+    "development": "cross-env NODE_ENV=development node_modules/webpack/bin/webpack.js --progress --hide-modules --config=node_modules/laravel-mix/setup/webpack.config.js",
+    "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",
+    "watch-poll": "npm run watch -- --watch-poll",
+    "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",
+    "prod": "npm run production",
+    "production": "cross-env NODE_ENV=production node_modules/webpack/bin/webpack.js --progress --hide-modules --config=node_modules/laravel-mix/setup/webpack.config.js"
   },
   "devDependencies": {
     "angular": "^1.5.5",
   },
   "devDependencies": {
     "angular": "^1.5.5",
     "angular-resource": "^1.5.5",
     "angular-sanitize": "^1.5.5",
     "angular-ui-sortable": "^0.15.0",
     "angular-resource": "^1.5.5",
     "angular-sanitize": "^1.5.5",
     "angular-ui-sortable": "^0.15.0",
+    "cross-env": "^3.2.3",
     "dropzone": "^4.0.1",
     "gulp": "^3.9.0",
     "dropzone": "^4.0.1",
     "gulp": "^3.9.0",
-    "laravel-elixir": "^6.0.0-11",
-    "laravel-elixir-browserify-official": "^0.1.3",
+    "laravel-mix": "0.*",
     "marked": "^0.3.5",
     "moment": "^2.12.0"
   },
   "dependencies": {
     "marked": "^0.3.5",
     "moment": "^2.12.0"
   },
   "dependencies": {
-    "clipboard": "^1.5.16"
+    "axios": "^0.16.1",
+    "clipboard": "^1.5.16",
+    "vue": "^2.2.6"
   }
 }
   }
 }
diff --git a/public/mix-manifest.json b/public/mix-manifest.json
new file mode 100644 (file)
index 0000000..3885bcd
--- /dev/null
@@ -0,0 +1,7 @@
+{
+  "/js/common.js": "/js/common.js",
+  "/css/styles.css": "/css/styles.css",
+  "/css/print-styles.css": "/css/print-styles.css",
+  "/css/export-styles.css": "/css/export-styles.css",
+  "/js/vues.js": "/js/vues.js"
+}
\ No newline at end of file
index 650919f85e7c243837c02cafce0827bece3fa0ea..7c980f6e9acf7eb698968c48097a816869c70e5e 100644 (file)
@@ -1,12 +1,5 @@
 "use strict";
 
 "use strict";
 
-// AngularJS - Create application and load components
-import angular from "angular";
-import "angular-resource";
-import "angular-animate";
-import "angular-sanitize";
-import "angular-ui-sortable";
-
 // Url retrieval function
 window.baseUrl = function(path) {
     let basePath = document.querySelector('meta[name="base-url"]').getAttribute('content');
 // Url retrieval function
 window.baseUrl = function(path) {
     let basePath = document.querySelector('meta[name="base-url"]').getAttribute('content');
@@ -15,6 +8,28 @@ window.baseUrl = function(path) {
     return basePath + '/' + path;
 };
 
     return basePath + '/' + path;
 };
 
+// Vue and axios setup
+import vue from "vue/dist/vue.common";
+import axios from "axios";
+
+let axiosInstance = axios.create({
+    headers: {
+        'X-CSRF-TOKEN': document.querySelector('meta[name=token]').getAttribute('content'),
+        'baseURL': baseUrl('')
+    }
+});
+
+window.Vue = vue;
+window.axios = axiosInstance;
+Vue.prototype.$http = axiosInstance;
+
+// AngularJS - Create application and load components
+import angular from "angular";
+import "angular-resource";
+import "angular-animate";
+import "angular-sanitize";
+import "angular-ui-sortable";
+
 let ngApp = angular.module('bookStack', ['ngResource', 'ngAnimate', 'ngSanitize', 'ui.sortable']);
 
 // Translation setup
 let ngApp = angular.module('bookStack', ['ngResource', 'ngAnimate', 'ngSanitize', 'ui.sortable']);
 
 // Translation setup
@@ -47,6 +62,7 @@ class EventManager {
 }
 
 window.Events = new EventManager();
 }
 
 window.Events = new EventManager();
+Vue.prototype.$events = window.Events;
 
 // Load in angular specific items
 import Services from './services';
 
 // Load in angular specific items
 import Services from './services';
diff --git a/resources/assets/js/vues/search.js b/resources/assets/js/vues/search.js
new file mode 100644 (file)
index 0000000..1fcd690
--- /dev/null
@@ -0,0 +1,66 @@
+
+let termString = document.querySelector('[name=searchTerm]').value;
+let terms = termString.split(' ');
+
+let data = {
+    terms: terms,
+        termString : termString,
+        search: {
+        type: {
+            page: true,
+            chapter: true,
+            book: true
+        }
+    }
+};
+
+let computed = {
+
+};
+
+let methods = {
+
+    appendTerm(term) {
+        if (this.termString.slice(-1) !== " ") this.termString += ' ';
+        this.termString += term;
+    },
+
+    typeParse(searchString) {
+        let typeFilter = /{\s?type:\s?(.*?)\s?}/;
+        let match = searchString.match(typeFilter);
+        let type = this.search.type;
+        if (!match) {
+            type.page = type.book = type.chapter = true;
+            return;
+        }
+        let splitTypes = match[1].replace(/ /g, '').split('|');
+        type.page = (splitTypes.indexOf('page') !== -1);
+        type.chapter = (splitTypes.indexOf('chapter') !== -1);
+        type.book = (splitTypes.indexOf('book') !== -1);
+    },
+
+    typeChange() {
+        let typeFilter = /{\s?type:\s?(.*?)\s?}/;
+        let type = this.search.type;
+        if (type.page === type.chapter && type.page === type.book) {
+            this.termString = this.termString.replace(typeFilter, '');
+            return;
+        }
+        let selectedTypes = Object.keys(type).filter(type => {return this.search.type[type];}).join('|');
+        let typeTerm = '{type:'+selectedTypes+'}';
+        if (this.termString.match(typeFilter)) {
+            this.termString = this.termString.replace(typeFilter, typeTerm);
+            return;
+        }
+        this.appendTerm(typeTerm);
+    }
+
+};
+
+function created() {
+    this.typeParse(this.termString);
+}
+
+module.exports = {
+    data, computed, methods, created
+};
\ No newline at end of file
diff --git a/resources/assets/js/vues/vues.js b/resources/assets/js/vues/vues.js
new file mode 100644 (file)
index 0000000..d500185
--- /dev/null
@@ -0,0 +1,16 @@
+
+function exists(id) {
+    return document.getElementById(id) !== null;
+}
+
+let vueMapping = {
+    'search-system': require('./search')
+};
+
+Object.keys(vueMapping).forEach(id => {
+    if (exists(id)) {
+        let config = vueMapping[id];
+        config.el = '#' + id;
+        new Vue(config);
+    }
+});
\ No newline at end of file
index c8e8ea833482d56a751b48b925a04f2f1c35537b..7d19f051c63b0dcd9d591f616e512a7e2cbd9cf7 100644 (file)
@@ -6,8 +6,8 @@
   font-style: normal;
   font-weight: 100;
   src: local('Roboto Thin'), local('Roboto-Thin'),
   font-style: normal;
   font-weight: 100;
   src: local('Roboto Thin'), local('Roboto-Thin'),
-  url('../fonts/roboto-v15-cyrillic_latin-100.woff2') format('woff2'), /* Chrome 26+, Opera 23+ */
-  url('../fonts/roboto-v15-cyrillic_latin-100.woff') format('woff'); /* Chrome 6+, Firefox 3.6+, IE 9+, Safari 5.1+ */
+  url('assets/fonts/roboto-v15-cyrillic_latin-100.woff2') format('woff2'), /* Chrome 26+, Opera 23+ */
+  url('assets/fonts/roboto-v15-cyrillic_latin-100.woff') format('woff'); /* Chrome 6+, Firefox 3.6+, IE 9+, Safari 5.1+ */
 }
 /* roboto-100italic - cyrillic_latin */
 @font-face {
 }
 /* roboto-100italic - cyrillic_latin */
 @font-face {
@@ -15,8 +15,8 @@
   font-style: italic;
   font-weight: 100;
   src: local('Roboto Thin Italic'), local('Roboto-ThinItalic'),
   font-style: italic;
   font-weight: 100;
   src: local('Roboto Thin Italic'), local('Roboto-ThinItalic'),
-  url('../fonts/roboto-v15-cyrillic_latin-100italic.woff2') format('woff2'), /* Chrome 26+, Opera 23+ */
-  url('../fonts/roboto-v15-cyrillic_latin-100italic.woff') format('woff'); /* Chrome 6+, Firefox 3.6+, IE 9+, Safari 5.1+ */
+  url('assets/fonts/roboto-v15-cyrillic_latin-100italic.woff2') format('woff2'), /* Chrome 26+, Opera 23+ */
+  url('assets/fonts/roboto-v15-cyrillic_latin-100italic.woff') format('woff'); /* Chrome 6+, Firefox 3.6+, IE 9+, Safari 5.1+ */
 }
 /* roboto-300 - cyrillic_latin */
 @font-face {
 }
 /* roboto-300 - cyrillic_latin */
 @font-face {
@@ -24,8 +24,8 @@
   font-style: normal;
   font-weight: 300;
   src: local('Roboto Light'), local('Roboto-Light'),
   font-style: normal;
   font-weight: 300;
   src: local('Roboto Light'), local('Roboto-Light'),
-  url('../fonts/roboto-v15-cyrillic_latin-300.woff2') format('woff2'), /* Chrome 26+, Opera 23+ */
-  url('../fonts/roboto-v15-cyrillic_latin-300.woff') format('woff'); /* Chrome 6+, Firefox 3.6+, IE 9+, Safari 5.1+ */
+  url('assets/fonts/roboto-v15-cyrillic_latin-300.woff2') format('woff2'), /* Chrome 26+, Opera 23+ */
+  url('assets/fonts/roboto-v15-cyrillic_latin-300.woff') format('woff'); /* Chrome 6+, Firefox 3.6+, IE 9+, Safari 5.1+ */
 }
 /* roboto-300italic - cyrillic_latin */
 @font-face {
 }
 /* roboto-300italic - cyrillic_latin */
 @font-face {
@@ -33,8 +33,8 @@
   font-style: italic;
   font-weight: 300;
   src: local('Roboto Light Italic'), local('Roboto-LightItalic'),
   font-style: italic;
   font-weight: 300;
   src: local('Roboto Light Italic'), local('Roboto-LightItalic'),
-  url('../fonts/roboto-v15-cyrillic_latin-300italic.woff2') format('woff2'), /* Chrome 26+, Opera 23+ */
-  url('../fonts/roboto-v15-cyrillic_latin-300italic.woff') format('woff'); /* Chrome 6+, Firefox 3.6+, IE 9+, Safari 5.1+ */
+  url('assets/fonts/roboto-v15-cyrillic_latin-300italic.woff2') format('woff2'), /* Chrome 26+, Opera 23+ */
+  url('assets/fonts/roboto-v15-cyrillic_latin-300italic.woff') format('woff'); /* Chrome 6+, Firefox 3.6+, IE 9+, Safari 5.1+ */
 }
 /* roboto-regular - cyrillic_latin */
 @font-face {
 }
 /* roboto-regular - cyrillic_latin */
 @font-face {
@@ -42,8 +42,8 @@
   font-style: normal;
   font-weight: 400;
   src: local('Roboto'), local('Roboto-Regular'),
   font-style: normal;
   font-weight: 400;
   src: local('Roboto'), local('Roboto-Regular'),
-  url('../fonts/roboto-v15-cyrillic_latin-regular.woff2') format('woff2'), /* Chrome 26+, Opera 23+ */
-  url('../fonts/roboto-v15-cyrillic_latin-regular.woff') format('woff'); /* Chrome 6+, Firefox 3.6+, IE 9+, Safari 5.1+ */
+  url('assets/fonts/roboto-v15-cyrillic_latin-regular.woff2') format('woff2'), /* Chrome 26+, Opera 23+ */
+  url('assets/fonts/roboto-v15-cyrillic_latin-regular.woff') format('woff'); /* Chrome 6+, Firefox 3.6+, IE 9+, Safari 5.1+ */
 }
 /* roboto-italic - cyrillic_latin */
 @font-face {
 }
 /* roboto-italic - cyrillic_latin */
 @font-face {
@@ -51,8 +51,8 @@
   font-style: italic;
   font-weight: 400;
   src: local('Roboto Italic'), local('Roboto-Italic'),
   font-style: italic;
   font-weight: 400;
   src: local('Roboto Italic'), local('Roboto-Italic'),
-  url('../fonts/roboto-v15-cyrillic_latin-italic.woff2') format('woff2'), /* Chrome 26+, Opera 23+ */
-  url('../fonts/roboto-v15-cyrillic_latin-italic.woff') format('woff'); /* Chrome 6+, Firefox 3.6+, IE 9+, Safari 5.1+ */
+  url('assets/fonts/roboto-v15-cyrillic_latin-italic.woff2') format('woff2'), /* Chrome 26+, Opera 23+ */
+  url('assets/fonts/roboto-v15-cyrillic_latin-italic.woff') format('woff'); /* Chrome 6+, Firefox 3.6+, IE 9+, Safari 5.1+ */
 }
 /* roboto-500 - cyrillic_latin */
 @font-face {
 }
 /* roboto-500 - cyrillic_latin */
 @font-face {
@@ -60,8 +60,8 @@
   font-style: normal;
   font-weight: 500;
   src: local('Roboto Medium'), local('Roboto-Medium'),
   font-style: normal;
   font-weight: 500;
   src: local('Roboto Medium'), local('Roboto-Medium'),
-  url('../fonts/roboto-v15-cyrillic_latin-500.woff2') format('woff2'), /* Chrome 26+, Opera 23+ */
-  url('../fonts/roboto-v15-cyrillic_latin-500.woff') format('woff'); /* Chrome 6+, Firefox 3.6+, IE 9+, Safari 5.1+ */
+  url('assets/fonts/roboto-v15-cyrillic_latin-500.woff2') format('woff2'), /* Chrome 26+, Opera 23+ */
+  url('assets/fonts/roboto-v15-cyrillic_latin-500.woff') format('woff'); /* Chrome 6+, Firefox 3.6+, IE 9+, Safari 5.1+ */
 }
 /* roboto-500italic - cyrillic_latin */
 @font-face {
 }
 /* roboto-500italic - cyrillic_latin */
 @font-face {
@@ -69,8 +69,8 @@
   font-style: italic;
   font-weight: 500;
   src: local('Roboto Medium Italic'), local('Roboto-MediumItalic'),
   font-style: italic;
   font-weight: 500;
   src: local('Roboto Medium Italic'), local('Roboto-MediumItalic'),
-  url('../fonts/roboto-v15-cyrillic_latin-500italic.woff2') format('woff2'), /* Chrome 26+, Opera 23+ */
-  url('../fonts/roboto-v15-cyrillic_latin-500italic.woff') format('woff'); /* Chrome 6+, Firefox 3.6+, IE 9+, Safari 5.1+ */
+  url('assets/fonts/roboto-v15-cyrillic_latin-500italic.woff2') format('woff2'), /* Chrome 26+, Opera 23+ */
+  url('assets/fonts/roboto-v15-cyrillic_latin-500italic.woff') format('woff'); /* Chrome 6+, Firefox 3.6+, IE 9+, Safari 5.1+ */
 }
 /* roboto-700 - cyrillic_latin */
 @font-face {
 }
 /* roboto-700 - cyrillic_latin */
 @font-face {
@@ -78,8 +78,8 @@
   font-style: normal;
   font-weight: 700;
   src: local('Roboto Bold'), local('Roboto-Bold'),
   font-style: normal;
   font-weight: 700;
   src: local('Roboto Bold'), local('Roboto-Bold'),
-  url('../fonts/roboto-v15-cyrillic_latin-700.woff2') format('woff2'), /* Chrome 26+, Opera 23+ */
-  url('../fonts/roboto-v15-cyrillic_latin-700.woff') format('woff'); /* Chrome 6+, Firefox 3.6+, IE 9+, Safari 5.1+ */
+  url('assets/fonts/roboto-v15-cyrillic_latin-700.woff2') format('woff2'), /* Chrome 26+, Opera 23+ */
+  url('assets/fonts/roboto-v15-cyrillic_latin-700.woff') format('woff'); /* Chrome 6+, Firefox 3.6+, IE 9+, Safari 5.1+ */
 }
 /* roboto-700italic - cyrillic_latin */
 @font-face {
 }
 /* roboto-700italic - cyrillic_latin */
 @font-face {
@@ -87,8 +87,8 @@
   font-style: italic;
   font-weight: 700;
   src: local('Roboto Bold Italic'), local('Roboto-BoldItalic'),
   font-style: italic;
   font-weight: 700;
   src: local('Roboto Bold Italic'), local('Roboto-BoldItalic'),
-  url('../fonts/roboto-v15-cyrillic_latin-700italic.woff2') format('woff2'), /* Chrome 26+, Opera 23+ */
-  url('../fonts/roboto-v15-cyrillic_latin-700italic.woff') format('woff'); /* Chrome 6+, Firefox 3.6+, IE 9+, Safari 5.1+ */
+  url('assets/fonts/roboto-v15-cyrillic_latin-700italic.woff2') format('woff2'), /* Chrome 26+, Opera 23+ */
+  url('assets/fonts/roboto-v15-cyrillic_latin-700italic.woff') format('woff'); /* Chrome 6+, Firefox 3.6+, IE 9+, Safari 5.1+ */
 }
 
 /* roboto-mono-regular - latin */
 }
 
 /* roboto-mono-regular - latin */
@@ -97,6 +97,6 @@
   font-style: normal;
   font-weight: 400;
   src: local('Roboto Mono'), local('RobotoMono-Regular'),
   font-style: normal;
   font-weight: 400;
   src: local('Roboto Mono'), local('RobotoMono-Regular'),
-  url('../fonts/roboto-mono-v4-latin-regular.woff2') format('woff2'), /* Chrome 26+, Opera 23+ */
-  url('../fonts/roboto-mono-v4-latin-regular.woff') format('woff'); /* Chrome 6+, Firefox 3.6+, IE 9+, Safari 5.1+ */
+  url('assets/fonts/roboto-mono-v4-latin-regular.woff2') format('woff2'), /* Chrome 26+, Opera 23+ */
+  url('assets/fonts/roboto-mono-v4-latin-regular.woff') format('woff'); /* Chrome 6+, Firefox 3.6+, IE 9+, Safari 5.1+ */
 }
\ No newline at end of file
 }
\ No newline at end of file
index 95a9d72b0dcff779bfea147298a97ca208a37129..2251ed2dfebdba14e998017795caf83124584ffe 100644 (file)
@@ -84,6 +84,7 @@
     </div>
 @yield('bottom')
 <script src="{{ versioned_asset('js/common.js') }}"></script>
     </div>
 @yield('bottom')
 <script src="{{ versioned_asset('js/common.js') }}"></script>
+<script src="{{ versioned_asset('js/vues.js') }}"></script>
 @yield('scripts')
 </body>
 </html>
 @yield('scripts')
 </body>
 </html>
index 54626daf1d656d4f550b82e275df21ed40c169e2..eb8ef51f3569d0952f2a3e25add84c2be3016300 100644 (file)
@@ -2,6 +2,9 @@
 
 @section('content')
 
 
 @section('content')
 
+    <input type="hidden" name="searchTerm" value="{{$searchTerm}}">
+
+<div id="search-system">
     <div class="faded-small toolbar">
         <div class="container">
             <div class="row">
     <div class="faded-small toolbar">
         <div class="container">
             <div class="row">
     </div>
 
 
     </div>
 
 
-    <div class="container" ng-non-bindable>
+    <div class="container" ng-non-bindable id="searchSystem">
 
         <h1>{{ trans('entities.search_results') }}</h1>
 
 
         <h1>{{ trans('entities.search_results') }}</h1>
 
-        <p>
-            {{--TODO - Remove these pages--}}
-            Remove these links (Commented out)
-            {{--@if(count($pages) > 0)--}}
-                {{--<a href="{{ baseUrl("/search/pages?term={$searchTerm}") }}" class="text-page"><i class="zmdi zmdi-file-text"></i>{{ trans('entities.search_view_pages') }}</a>--}}
-            {{--@endif--}}
-
-            {{--@if(count($chapters) > 0)--}}
-                {{--&nbsp; &nbsp;&nbsp;--}}
-                {{--<a href="{{ baseUrl("/search/chapters?term={$searchTerm}") }}" class="text-chapter"><i class="zmdi zmdi-collection-bookmark"></i>{{ trans('entities.search_view_chapters') }}</a>--}}
-            {{--@endif--}}
-
-            {{--@if(count($books) > 0)--}}
-                {{--&nbsp; &nbsp;&nbsp;--}}
-                {{--<a href="{{ baseUrl("/search/books?term={$searchTerm}") }}" class="text-book"><i class="zmdi zmdi-book"></i>{{ trans('entities.search_view_books') }}</a>--}}
-            {{--@endif--}}
-        </p>
+        <input type="text" v-model="termString">
 
         <div class="row">
 
         <div class="row">
+
             <div class="col-md-6">
             <div class="col-md-6">
-                <h3><a href="{{ baseUrl("/search/pages?term={$searchTerm}") }}" class="no-color">{{ trans('entities.pages') }}</a></h3>
-                @include('partials/entity-list', ['entities' => $entities, 'style' => 'detailed'])
+                @include('partials/entity-list', ['entities' => $entities])
             </div>
             </div>
+
             <div class="col-md-5 col-md-offset-1">
             <div class="col-md-5 col-md-offset-1">
-                Sidebar filter controls
+               <h3>Search Filters</h3>
+
+                <p><strong>Content Type</strong></p>
+                <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>
+                </div>
+
             </div>
             </div>
+
         </div>
 
 
     </div>
         </div>
 
 
     </div>
+</div>
+
+@stop
+
+@section('scripts')
+    <script>
 
 
 
 
+    </script>
 @stop
\ No newline at end of file
 @stop
\ No newline at end of file
index f5ee3f827ee2815f03b842a81404556d26bbe690..dad7a55e56d0a21bf14a6b612c6ce2fe8e272b5e 100644 (file)
@@ -123,10 +123,7 @@ Route::group(['middleware' => 'auth'], function () {
     Route::get('/link/{id}', 'PageController@redirectFromLink');
 
     // Search
     Route::get('/link/{id}', 'PageController@redirectFromLink');
 
     // Search
-    Route::get('/search', 'SearchController@searchAll');
-    Route::get('/search/pages', 'SearchController@searchPages');
-    Route::get('/search/books', 'SearchController@searchBooks');
-    Route::get('/search/chapters', 'SearchController@searchChapters');
+    Route::get('/search', 'SearchController@search');
     Route::get('/search/book/{bookId}', 'SearchController@searchBook');
 
     // Other Pages
     Route::get('/search/book/{bookId}', 'SearchController@searchBook');
 
     // Other Pages
diff --git a/webpack.mix.js b/webpack.mix.js
new file mode 100644 (file)
index 0000000..2e691bd
--- /dev/null
@@ -0,0 +1,18 @@
+const { mix } = require('laravel-mix');
+
+/*
+ |--------------------------------------------------------------------------
+ | Mix Asset Management
+ |--------------------------------------------------------------------------
+ |
+ | Mix provides a clean, fluent API for defining some Webpack build steps
+ | for your Laravel application. By default, we are compiling the Sass
+ | file for the application as well as bundling up all the JS files.
+ |
+ */
+
+mix.js('resources/assets/js/global.js', './public/js/common.js')
+    .js('resources/assets/js/vues/vues.js', './public/js/vues.js')
+    .sass('resources/assets/sass/styles.scss', 'public/css')
+    .sass('resources/assets/sass/print-styles.scss', 'public/css')
+    .sass('resources/assets/sass/export-styles.scss', 'public/css');