Merge pull request #1657 from cuneytsenturk/search-filter
Search & Filter enhancement feature..
This commit is contained in:
		| @@ -6,9 +6,7 @@ use App\Abstracts\Http\Controller; | ||||
| use App\Http\Requests\Common\BulkAction as Request; | ||||
| use Illuminate\Support\Str; | ||||
|  | ||||
| class | ||||
|  | ||||
| BulkActions extends Controller | ||||
| class BulkActions extends Controller | ||||
| { | ||||
|  | ||||
|     /** | ||||
|   | ||||
							
								
								
									
										196
									
								
								app/View/Components/SearchString.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										196
									
								
								app/View/Components/SearchString.php
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,196 @@ | ||||
| <?php | ||||
|  | ||||
| namespace App\View\Components; | ||||
|  | ||||
| use Illuminate\View\Component; | ||||
| use Illuminate\Support\Str; | ||||
| use Symfony\Component\Routing\Exception\RouteNotFoundException; | ||||
|  | ||||
| class SearchString extends Component | ||||
| { | ||||
|     public $filters; | ||||
|  | ||||
|     public $model; | ||||
|  | ||||
|     /** | ||||
|      * Create a new component instance. | ||||
|      * | ||||
|      * @return void | ||||
|      */ | ||||
|     public function __construct($model) | ||||
|     { | ||||
|         $this->model = $model; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Get the view / contents that represent the component. | ||||
|      * | ||||
|      * @return \Illuminate\Contracts\View\View|string | ||||
|      */ | ||||
|     public function render() | ||||
|     { | ||||
|         $searc_string = config('search-string'); | ||||
|  | ||||
|         $this->filters = []; | ||||
|  | ||||
|         if (!empty($searc_string[$this->model])) { | ||||
|             $columns = $searc_string[$this->model]['columns']; | ||||
|  | ||||
|             foreach ($columns as $column => $options) { | ||||
|                 // This column skip for filter | ||||
|                 if (!empty($options['searchable'])) { | ||||
|                     continue; | ||||
|                 } | ||||
|      | ||||
|                 if (!is_array($options)) { | ||||
|                     $column = $options; | ||||
|                 } | ||||
|                  | ||||
|                 if (!$this->isFilter($column, $options)) { | ||||
|                     continue; | ||||
|                 } | ||||
|  | ||||
|                 $this->filters[] = [ | ||||
|                     'key' => $this->getFilterKey($column, $options), | ||||
|                     'value' => $this->getFilterName($column), | ||||
|                     'type' => $this->getFilterType($options), | ||||
|                     'url' => $this->getFilterUrl($column, $options), | ||||
|                     'values' => $this->getFilterValues($column, $options), | ||||
|                 ]; | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         return view('components.search-string'); | ||||
|     } | ||||
|  | ||||
|     protected function isFilter($column, $options) | ||||
|     { | ||||
|         $filter = true; | ||||
|      | ||||
|         if (empty($this->getFilterUrl($column, $options)) && (!isset($options['date']) && !isset($options['boolean']))) { | ||||
|             $filter = false; | ||||
|         } | ||||
|  | ||||
|         return $filter; | ||||
|     } | ||||
|  | ||||
|     protected function getFilterKey($column, $options) | ||||
|     { | ||||
|         if (isset($options['relationship'])) { | ||||
|             $column .= '.id'; | ||||
|         } | ||||
|  | ||||
|         return $column; | ||||
|     } | ||||
|  | ||||
|     protected function getFilterName($column) | ||||
|     { | ||||
|         if (strpos($column, '_id') !== false) { | ||||
|             $column = str_replace('_id', '', $column); | ||||
|         } else if (strpos($column, '_code') !== false) { | ||||
|             $column = str_replace('_code', '', $column); | ||||
|         } | ||||
|  | ||||
|         $plural = Str::plural($column, 2); | ||||
|  | ||||
|         if (trans_choice('general.' . $plural, 1) !== 'general.' . $plural) { | ||||
|             return trans_choice('general.' . $plural, 1); | ||||
|         } elseif (trans_choice('search_string.columns.' . $plural, 1) !== 'search_string.columns.' . $plural) { | ||||
|             return trans_choice('search_string.columns.' . $plural, 1); | ||||
|         } | ||||
|  | ||||
|         $name = trans('general.' . $column); | ||||
|      | ||||
|         if ($name == 'general.' . $column) { | ||||
|             $name = trans('search_string.columns.' . $column); | ||||
|         } | ||||
|  | ||||
|         return $name; | ||||
|     } | ||||
|  | ||||
|     protected function getFilterType($options)  | ||||
|     { | ||||
|         $type = 'select'; | ||||
|  | ||||
|         if (isset($options['boolean'])) { | ||||
|             $type = 'boolean'; | ||||
|         } | ||||
|  | ||||
|         if (isset($options['date'])) { | ||||
|             $type = 'date'; | ||||
|         } | ||||
|  | ||||
|         return $type; | ||||
|     } | ||||
|  | ||||
|     protected function getFilterUrl($column, $options)  | ||||
|     { | ||||
|         $url = ''; | ||||
|  | ||||
|         if (isset($options['boolean']) || isset($options['date'])) { | ||||
|             return $url; | ||||
|         } | ||||
|  | ||||
|         if (!empty($options['route'])) { | ||||
|             if (is_array($options['route'])) { | ||||
|                 $url = route($options['route'][0], $options['route'][1]); | ||||
|             } else { | ||||
|                 $url = route($options['route']); | ||||
|             } | ||||
|         } else { | ||||
|             if (strpos($this->model, 'Modules') !== false) { | ||||
|                 $module_class = explode('\\', $this->model); | ||||
|  | ||||
|                 $url .= Str::slug($module_class[1], '-') . '::'; | ||||
|             } | ||||
|              | ||||
|             if (strpos($column, '_id') !== false) { | ||||
|                 $column = str_replace('_id', '', $column); | ||||
|             } | ||||
|      | ||||
|             $plural = Str::plural($column, 2); | ||||
|  | ||||
|             try { | ||||
|                 $url = route($url . $plural . '.index'); | ||||
|             } catch (\Exception $e) { | ||||
|                 $url = ''; | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         return $url; | ||||
|     } | ||||
|  | ||||
|     protected function getFilterValues($column, $options)  | ||||
|     { | ||||
|         $values = []; | ||||
|  | ||||
|         if (isset($options['boolean'])) { | ||||
|             $values = [ | ||||
|                 [ | ||||
|                     'key' => 0, | ||||
|                     'value' => trans('general.no'), | ||||
|                 ], | ||||
|                 [ | ||||
|                     'key' => 1, | ||||
|                     'value' => trans('general.yes'), | ||||
|                 ], | ||||
|             ]; | ||||
|         } else if ($search = request()->get('search', false)) { | ||||
|             $fields = explode(' ', $search); | ||||
|  | ||||
|             foreach ($fields as $field) { | ||||
|                 if (strpos($field, ':') === false) { | ||||
|                     continue; | ||||
|                 } | ||||
|  | ||||
|                 $filters = explode(':', $field); | ||||
|  | ||||
|                 if ($filters[0] != $column) { | ||||
|                     continue; | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         return $values; | ||||
|     } | ||||
| } | ||||
| @@ -69,7 +69,9 @@ return [ | ||||
|             'number' => ['searchable' => true], | ||||
|             'bank_name' => ['searchable' => true], | ||||
|             'bank_address' => ['searchable' => true], | ||||
|             'currency' => ['relationship' => true], | ||||
|             'currency_code' => [ | ||||
|                 'route' => 'currencies.index' | ||||
|             ], | ||||
|             'enabled' => ['boolean' => true], | ||||
|         ], | ||||
|     ], | ||||
| @@ -87,16 +89,24 @@ return [ | ||||
|     App\Models\Banking\Transaction::class => [ | ||||
|         'columns' => [ | ||||
|             'type', | ||||
|             'account_id', | ||||
|             'account_id' => [ | ||||
|                 'route' => 'accounts.index' | ||||
|             ], | ||||
|             'paid_at' => ['date' => true], | ||||
|             'amount', | ||||
|             'currency_code', | ||||
|             'currency_code' => [ | ||||
|                 'route' => 'currencies.index' | ||||
|             ], | ||||
|             'document_id', | ||||
|             'contact_id', | ||||
|             'contact_id' => [ | ||||
|                 'route' => 'customers.index' | ||||
|             ], | ||||
|             'description' => ['searchable' => true], | ||||
|             'payment_method', | ||||
|             'reference', | ||||
|             'category_id', | ||||
|             'category_id' => [ | ||||
|                 'route' => 'categories.index' | ||||
|             ], | ||||
|             'parent_id', | ||||
|         ], | ||||
|     ], | ||||
| @@ -120,8 +130,10 @@ return [ | ||||
|             'name' => ['searchable' => true], | ||||
|             'description' => ['searchable' => true], | ||||
|             'enabled' => ['boolean' => true], | ||||
|             'category_id' => ['key' => 'category_id'], | ||||
|             'sale_price', | ||||
|             'category_id' => [ | ||||
|                 'route' => ['categories.index', 'search=type:item'] | ||||
|             ], | ||||
|             'sales_price', | ||||
|             'purchase_price', | ||||
|         ], | ||||
|     ], | ||||
| @@ -135,7 +147,9 @@ return [ | ||||
|             'phone' => ['searchable' => true], | ||||
|             'address' => ['searchable' => true], | ||||
|             'website' => ['searchable' => true], | ||||
|             'currency_code', | ||||
|             'currency_code' => [ | ||||
|                 'route' => 'currencies.index' | ||||
|             ], | ||||
|             'reference', | ||||
|             'user_id', | ||||
|             'enabled' => ['boolean' => true], | ||||
| @@ -150,14 +164,20 @@ return [ | ||||
|             'billed_at' => ['date' => true], | ||||
|             'due_at' => ['date' => true], | ||||
|             'amount', | ||||
|             'currency_code', | ||||
|             'contact_id', | ||||
|             'currency_code' => [ | ||||
|                 'route' => 'currencies.index' | ||||
|             ], | ||||
|             'contact_id' => [ | ||||
|                 'route' => 'vendors.index' | ||||
|             ], | ||||
|             'contact_name' => ['searchable' => true], | ||||
|             'contact_email' => ['searchable' => true], | ||||
|             'contact_tax_number', | ||||
|             'contact_phone' => ['searchable' => true], | ||||
|             'contact_address' => ['searchable' => true], | ||||
|             'category_id', | ||||
|             'category_id' => [ | ||||
|                 'route' => 'categories.index' | ||||
|             ], | ||||
|             'parent_id', | ||||
|         ], | ||||
|     ], | ||||
| @@ -170,14 +190,20 @@ return [ | ||||
|             'invoiced_at' => ['date' => true], | ||||
|             'due_at' => ['date' => true], | ||||
|             'amount', | ||||
|             'currency_code', | ||||
|             'contact_id', | ||||
|             'currency_code' => [ | ||||
|                 'route' => 'currencies.index' | ||||
|             ], | ||||
|             'contact_id' => [ | ||||
|                 'route' => 'customer.index' | ||||
|             ], | ||||
|             'contact_name' => ['searchable' => true], | ||||
|             'contact_email' => ['searchable' => true], | ||||
|             'contact_tax_number', | ||||
|             'contact_phone' => ['searchable' => true], | ||||
|             'contact_address' => ['searchable' => true], | ||||
|             'category_id', | ||||
|             'category_id' => [ | ||||
|                 'route' => 'categories.index' | ||||
|             ], | ||||
|             'parent_id', | ||||
|         ], | ||||
|     ], | ||||
|   | ||||
							
								
								
									
										6
									
								
								public/css/custom.css
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										6
									
								
								public/css/custom.css
									
									
									
									
										vendored
									
									
								
							| @@ -846,3 +846,9 @@ table .align-items-center td span.badge { | ||||
|     border: 1px solid #3c3f72; | ||||
| } | ||||
| /*--lightbox Finish--*/ | ||||
|  | ||||
| /*-- Search string & BulkAction Start --*/ | ||||
| #app > .card > .card-header { | ||||
|     min-height: 88px; | ||||
| } | ||||
| /*-- Search string & BulkAction Finish --*/ | ||||
							
								
								
									
										24
									
								
								public/vendor/js-cookie/js.cookie.js
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										24
									
								
								public/vendor/js-cookie/js.cookie.js
									
									
									
									
										vendored
									
									
								
							| @@ -7,19 +7,26 @@ | ||||
|  */ | ||||
| ;(function (factory) { | ||||
| 	var registeredInModuleLoader = false; | ||||
|  | ||||
| 	if (typeof define === 'function' && define.amd) { | ||||
| 		define(factory); | ||||
|  | ||||
| 		registeredInModuleLoader = true; | ||||
| 	} | ||||
|  | ||||
| 	if (typeof exports === 'object') { | ||||
| 		module.exports = factory(); | ||||
|  | ||||
| 		registeredInModuleLoader = true; | ||||
| 	} | ||||
|  | ||||
| 	if (!registeredInModuleLoader) { | ||||
| 		var OldCookies = window.Cookies; | ||||
| 		var api = window.Cookies = factory(); | ||||
|  | ||||
| 		api.noConflict = function () { | ||||
| 			window.Cookies = OldCookies; | ||||
|  | ||||
| 			return api; | ||||
| 		}; | ||||
| 	} | ||||
| @@ -27,24 +34,27 @@ | ||||
| 	function extend () { | ||||
| 		var i = 0; | ||||
| 		var result = {}; | ||||
|  | ||||
| 		for (; i < arguments.length; i++) { | ||||
| 			var attributes = arguments[ i ]; | ||||
|  | ||||
| 			for (var key in attributes) { | ||||
| 				result[key] = attributes[key]; | ||||
| 			} | ||||
| 		} | ||||
|  | ||||
| 		return result; | ||||
| 	} | ||||
|  | ||||
| 	function init (converter) { | ||||
| 		function api (key, value, attributes) { | ||||
| 			var result; | ||||
|  | ||||
| 			if (typeof document === 'undefined') { | ||||
| 				return; | ||||
| 			} | ||||
|  | ||||
| 			// Write | ||||
|  | ||||
| 			if (arguments.length > 1) { | ||||
| 				attributes = extend({ | ||||
| 					path: '/' | ||||
| @@ -52,7 +62,9 @@ | ||||
|  | ||||
| 				if (typeof attributes.expires === 'number') { | ||||
| 					var expires = new Date(); | ||||
|  | ||||
| 					expires.setMilliseconds(expires.getMilliseconds() + attributes.expires * 864e+5); | ||||
|  | ||||
| 					attributes.expires = expires; | ||||
| 				} | ||||
|  | ||||
| @@ -61,6 +73,7 @@ | ||||
|  | ||||
| 				try { | ||||
| 					result = JSON.stringify(value); | ||||
|  | ||||
| 					if (/^[\{\[]/.test(result)) { | ||||
| 						value = result; | ||||
| 					} | ||||
| @@ -83,17 +96,20 @@ | ||||
| 					if (!attributes[attributeName]) { | ||||
| 						continue; | ||||
| 					} | ||||
|  | ||||
| 					stringifiedAttributes += '; ' + attributeName; | ||||
|  | ||||
| 					if (attributes[attributeName] === true) { | ||||
| 						continue; | ||||
| 					} | ||||
|  | ||||
| 					stringifiedAttributes += '=' + attributes[attributeName]; | ||||
| 				} | ||||
|  | ||||
| 				return (document.cookie = key + '=' + value + stringifiedAttributes); | ||||
| 			} | ||||
|  | ||||
| 			// Read | ||||
|  | ||||
| 			if (!key) { | ||||
| 				result = {}; | ||||
| 			} | ||||
| @@ -115,6 +131,7 @@ | ||||
|  | ||||
| 				try { | ||||
| 					var name = parts[0].replace(rdecode, decodeURIComponent); | ||||
|  | ||||
| 					cookie = converter.read ? | ||||
| 						converter.read(cookie, name) : converter(cookie, name) || | ||||
| 						cookie.replace(rdecode, decodeURIComponent); | ||||
| @@ -140,14 +157,17 @@ | ||||
| 		} | ||||
|  | ||||
| 		api.set = api; | ||||
|  | ||||
| 		api.get = function (key) { | ||||
| 			return api.call(api, key); | ||||
| 		}; | ||||
|  | ||||
| 		api.getJSON = function () { | ||||
| 			return api.apply({ | ||||
| 				json: true | ||||
| 			}, [].slice.call(arguments)); | ||||
| 		}; | ||||
|  | ||||
| 		api.defaults = {}; | ||||
|  | ||||
| 		api.remove = function (key, attributes) { | ||||
|   | ||||
| @@ -1,170 +1,681 @@ | ||||
| <template> | ||||
|   <div :id="'search-field-' + _uid" class="searh-field tags-input__wrapper"> | ||||
|     <div class="tags-group" v-for="(filter, index) in filtered" :index="index"> | ||||
|       <span v-if="filter.option" class="el-tag el-tag--primary el-tag--small el-tag--light el-tag-option"> | ||||
|         {{ filter.option }} | ||||
|       </span> | ||||
|  | ||||
|     <el-select | ||||
|         :class="'pl-20 mr-40'" | ||||
|         v-model="real_model" | ||||
|         @input="change" | ||||
|         filterable | ||||
|         remote | ||||
|         reserve-keyword | ||||
|       <span v-if="filter.operator" class="el-tag el-tag--primary el-tag--small el-tag--light el-tag-operator"> | ||||
|         {{ (filter.operator == '=') ? operatorIsText : operatorIsNotText }} | ||||
|       </span> | ||||
|  | ||||
|       <span v-if="filter.value" class="el-tag el-tag--primary el-tag--small el-tag--light el-tag-value"> | ||||
|         {{ filter.value }} | ||||
|         <i class="el-tag__close el-icon-close" @click="onFilterDelete(index)"></i> | ||||
|       </span> | ||||
|     </div> | ||||
|  | ||||
|     <div class="dropdown input-full"> | ||||
|       <input | ||||
|         v-if="!show_date" | ||||
|         type="text" | ||||
|         class="form-control" | ||||
|         :placeholder="placeholder" | ||||
|         :remote-method="remoteMethod" | ||||
|         :loading="loading"> | ||||
|         <div v-if="loading" class="el-select-dropdown__wrap" slot="empty"> | ||||
|             <p class="el-select-dropdown__empty loading"> | ||||
|                 {{ loadingText }} | ||||
|             </p> | ||||
|         </div> | ||||
|         :ref="'input-search-field-' + _uid" | ||||
|         v-model="search" | ||||
|         @focus="onInputFocus" | ||||
|         @input="onInput" | ||||
|         @keyup.enter="onInputConfirm" | ||||
|       /> | ||||
|  | ||||
|         <div v-else-if="options.length != 0" class="el-select-dropdown__wrap" slot="empty"> | ||||
|             <p class="el-select-dropdown__empty"> | ||||
|                 {{ noMatchingDataText }} | ||||
|             </p> | ||||
|         </div> | ||||
|       <flat-picker | ||||
|         v-else | ||||
|         @on-open="onInputFocus" | ||||
|         :config="dateConfig" | ||||
|         class="form-control datepicker" | ||||
|         :placeholder="placeholder" | ||||
|         :ref="'input-search-date-field-' + _uid" | ||||
|         v-model="search" | ||||
|         @focus="onInputFocus" | ||||
|         @input="onInputDateSelected" | ||||
|         @keyup.enter="onInputConfirm" | ||||
|       > | ||||
|       </flat-picker> | ||||
|  | ||||
|         <div v-else-if="options.length == 0" slot="empty"> | ||||
|             <p class="el-select-dropdown__empty"> | ||||
|                 {{ noDataText }} | ||||
|             </p> | ||||
|         </div> | ||||
|       <button type="button" class="btn btn-link clear" @click="onSearchAndFilterClear"> | ||||
|         <i class="el-tag__close el-icon-close"></i> | ||||
|       </button> | ||||
|  | ||||
|         <template v-if="icon" slot="prefix"> | ||||
|             <span class="el-input__suffix-inner el-select-icon"> | ||||
|                 <i :class="'select-icon-position el-input__icon fa fa-' + icon"></i> | ||||
|             </span> | ||||
|         </template> | ||||
|       <div :id="'search-field-option-' + _uid" class="dropdown-menu" :class="[{'show': visible.options}]"> | ||||
|         <li ref="" class="dropdown-item" v-for="option in filteredOptions" :data-value="option.key"> | ||||
|           <button type="button" class="btn btn-link" @click="onOptionSelected(option.key)">{{ option.value }}</button> | ||||
|         </li> | ||||
|         <li ref="" v-if="search" class="dropdown-item"> | ||||
|           <button type="button" class="btn btn-link" @click="onInputConfirm">{{ searchText }}</button> | ||||
|         </li> | ||||
|       </div> | ||||
|  | ||||
|         <el-option v-if="!group" v-for="option in selectOptions" | ||||
|             :key="option.id" | ||||
|             :label="option.name" | ||||
|             :value="option.id"> | ||||
|         </el-option> | ||||
|  | ||||
|         <el-option-group | ||||
|             v-if="group" | ||||
|             v-for="(options, name) in selectOptions" | ||||
|             :key="name" | ||||
|             :label="name"> | ||||
|             <el-option | ||||
|                 v-for="(label, value) in options" | ||||
|                 :key="value" | ||||
|                 :label="label" | ||||
|                 :value="value"> | ||||
|             </el-option> | ||||
|         </el-option-group> | ||||
|     </el-select> | ||||
|       <div :id="'search-field-operator-' + _uid" class="dropdown-menu" :class="[{'show': visible.operator}]"> | ||||
|         <li ref="" class="dropdown-item"> | ||||
|           <button type="button" class="btn btn-link" @click="onOperatorSelected('=')">{{ operatorIsText }}<span class="btn-helptext d-none">is</span></button> | ||||
|         </li> | ||||
|         <li ref="" class="dropdown-item"> | ||||
|           <button type="button" class="btn btn-link" @click="onOperatorSelected('!=')">{{ operatorIsNotText }}<span class="btn-helptext d-none">is not</span></button> | ||||
|         </li> | ||||
|       </div> | ||||
|  | ||||
|       <div :id="'search-field-value-' + _uid" class="dropdown-menu" :class="[{'show': visible.values}]"> | ||||
|         <li ref="" class="dropdown-item" v-for="(value) in filteredValues" :data-value="value.key"> | ||||
|           <button type="button" class="btn btn-link" @click="onValueSelected(value.key)">{{ value.value }}</button> | ||||
|         </li> | ||||
|         <li ref="" class="dropdown-item" v-if="!filteredValues.length"> | ||||
|           <button type="button" class="btn btn-link">{{ noMatchingDataText }}</button> | ||||
|         </li> | ||||
|       </div> | ||||
|     </div> | ||||
|   </div> | ||||
| </template> | ||||
|  | ||||
| <style> | ||||
|     .el-select { | ||||
|         display: inline; | ||||
|     } | ||||
| </style> | ||||
|  | ||||
| <script> | ||||
|     import { Select, Option, OptionGroup } from 'element-ui'; | ||||
| import flatPicker from "vue-flatpickr-component"; | ||||
| import "flatpickr/dist/flatpickr.css"; | ||||
|  | ||||
|     export default { | ||||
|         name: 'akaunting-select', | ||||
| export default { | ||||
|   name: 'akaunting-search', | ||||
|  | ||||
|         components: { | ||||
|             [Select.name]: Select, | ||||
|             [Option.name]: Option, | ||||
|             [OptionGroup.name]: OptionGroup, | ||||
|         }, | ||||
|   components: { | ||||
|     flatPicker | ||||
|   }, | ||||
|  | ||||
|         props: { | ||||
|             name: { | ||||
|                 type: String, | ||||
|                 default: null, | ||||
|                 description: "Selectbox attribute name" | ||||
|             }, | ||||
|             placeholder: { | ||||
|                 type: String, | ||||
|                 default: '', | ||||
|                 description: "Selectbox input placeholder text" | ||||
|             }, | ||||
|             options: null, | ||||
|             value: { | ||||
|                 type: String, | ||||
|                 default: null, | ||||
|                 description: "Selectbox selected value" | ||||
|             }, | ||||
|   props: { | ||||
|     placeholder: { | ||||
|       type: String, | ||||
|       default: 'Search or filter results...', | ||||
|       description: 'Input placeholder' | ||||
|     }, | ||||
|     searchText: { | ||||
|       type: String, | ||||
|       default: 'Search for this text', | ||||
|       description: 'Input placeholder' | ||||
|     }, | ||||
|     operatorIsText: { | ||||
|       type: String, | ||||
|       default: 'is', | ||||
|       description: 'Operator is "="' | ||||
|     }, | ||||
|     operatorIsNotText: { | ||||
|       type: String, | ||||
|       default: 'is not', | ||||
|       description: 'Operator is not "!="' | ||||
|     }, | ||||
|     noDataText: { | ||||
|         type: String, | ||||
|         default: 'No Data', | ||||
|         description: "Selectbox empty options message" | ||||
|     }, | ||||
|     noMatchingDataText: { | ||||
|         type: String, | ||||
|         default: 'No Matchign Data', | ||||
|         description: "Selectbox search option not found item message" | ||||
|     }, | ||||
|     value: { | ||||
|       type: String, | ||||
|       default: null, | ||||
|       description: 'Search attribute value' | ||||
|     }, | ||||
|     filters: { | ||||
|       type: Array, | ||||
|       default: () => [], | ||||
|       description: 'List of filters' | ||||
|     }, | ||||
|  | ||||
|             icon: { | ||||
|                 type: String, | ||||
|                 description: "Prepend icon (left)" | ||||
|             }, | ||||
|     dateConfig: null, | ||||
|   }, | ||||
|  | ||||
|             group:  { | ||||
|                 type: Boolean, | ||||
|                 default: false, | ||||
|                 description: "Selectbox option group status" | ||||
|             }, | ||||
|   model: { | ||||
|     prop: 'value', | ||||
|     event: 'change' | ||||
|   }, | ||||
|  | ||||
|             loadingText: { | ||||
|                 type: String, | ||||
|                 default: 'Loading...', | ||||
|                 description: "Selectbox loading message" | ||||
|             }, | ||||
|             noDataText: { | ||||
|                 type: String, | ||||
|                 default: 'No Data', | ||||
|                 description: "Selectbox empty options message" | ||||
|             }, | ||||
|             noMatchingDataText: { | ||||
|                 type: String, | ||||
|                 default: 'No Matchign Data', | ||||
|                 description: "Selectbox search option not found item message" | ||||
|             }, | ||||
|   data() { | ||||
|     return { | ||||
|       filter_list: this.filters, // set filters prop assing it. | ||||
|       search: '', // search cloumn model | ||||
|       filtered:[], // Show selected filters | ||||
|       filter_index: 0, // added filter count | ||||
|       filter_last_step: 'options', // last fitler step | ||||
|       visible: { // Which visible dropdown | ||||
|         options: false, | ||||
|         operator: false, | ||||
|         values: false, | ||||
|       }, | ||||
|  | ||||
|             remoteAction: { | ||||
|                 type: String, | ||||
|                 default: null, | ||||
|                 description: "Selectbox remote action path" | ||||
|             }, | ||||
|         }, | ||||
|       option_values: [], | ||||
|       selected_options: [], | ||||
|       selected_values: [], | ||||
|       values: [], | ||||
|       current_value: null, | ||||
|       show_date: false, | ||||
|     }; | ||||
|   }, | ||||
|  | ||||
|         data() { | ||||
|             return { | ||||
|                 list: [], | ||||
|                 selectOptions: this.options, | ||||
|                 real_model: this.model, | ||||
|                 loading: false, | ||||
|   methods: { | ||||
|     onInputFocus() { | ||||
|       if (!this.filter_list.length) { | ||||
|         return; | ||||
|       } | ||||
|  | ||||
|       if (this.filter_last_step != 'values' || (this.filter_last_step == 'values' && this.selected_options[this.filter_index].type != 'date')) { | ||||
|         this.visible[this.filter_last_step] = true; | ||||
|  | ||||
|         this.$nextTick(() => { | ||||
|           this.$refs['input-search-field-' + this._uid].focus(); | ||||
|         }); | ||||
|       } else { | ||||
|         this.show_date = true; | ||||
|  | ||||
|         this.$nextTick(() => { | ||||
|           this.$refs['input-search-date-field-' + this._uid].focus(); | ||||
|         }); | ||||
|       } | ||||
|  | ||||
|       console.log('Focus :' + this.filter_last_step); | ||||
|     }, | ||||
|  | ||||
|     onInputDateSelected(event) { | ||||
|       this.filtered[this.filter_index].value = event; | ||||
|  | ||||
|       this.selected_values.push({ | ||||
|         key: event, | ||||
|         value: event, | ||||
|       }); | ||||
|  | ||||
|       this.$emit('change', this.filtered); | ||||
|  | ||||
|       this.show_date = false; | ||||
|       this.search = ''; | ||||
|  | ||||
|       this.$nextTick(() => { | ||||
|         this.$refs['input-search-field-' + this._uid].focus(); | ||||
|       }); | ||||
|  | ||||
|       this.filter_index++; | ||||
|  | ||||
|       if (this.filter_list.length) { | ||||
|         this.visible = { | ||||
|           options: true, | ||||
|           operator: false, | ||||
|           values: false, | ||||
|         }; | ||||
|       } else { | ||||
|         this.visible = { | ||||
|           options: false, | ||||
|           operator: false, | ||||
|           values: false, | ||||
|         }; | ||||
|       } | ||||
|  | ||||
|       this.show_date = false; | ||||
|  | ||||
|       this.filter_last_step = 'options'; | ||||
|     }, | ||||
|  | ||||
|     onInput(evt) { | ||||
|       this.search = evt.target.value; | ||||
|  | ||||
|       let option_url = this.selected_options[this.filter_index].url; | ||||
|  | ||||
|       if (this.search) { | ||||
|         option_url += '?search=' + this.search; | ||||
|       } | ||||
|  | ||||
|       if (option_url) { | ||||
|         window.axios.get(option_url) | ||||
|         .then(response => { | ||||
|             this.values = []; | ||||
|  | ||||
|             let data = response.data.data; | ||||
|  | ||||
|             data.forEach(function (item) { | ||||
|               this.values.push({ | ||||
|                 key: item.id, | ||||
|                 value: item.name | ||||
|               }); | ||||
|             }, this); | ||||
|  | ||||
|             this.option_values[value] = this.values; | ||||
|         }) | ||||
|         .catch(error => { | ||||
|  | ||||
|         }); | ||||
|       } | ||||
|  | ||||
|       this.$emit('input', evt.target.value); | ||||
|     }, | ||||
|  | ||||
|     onInputConfirm() { | ||||
|       let path = window.location.href.replace(window.location.search, ''); | ||||
|       let args = ''; | ||||
|  | ||||
|       if (this.search) { | ||||
|         args += '?search=' + this.search + ' '; | ||||
|       } | ||||
|  | ||||
|       let now = new Date(); | ||||
|       now.setTime(now.getTime() + 1 * 3600 * 1000); | ||||
|       let expires = now.toUTCString(); | ||||
|  | ||||
|       let serach_string = {}; | ||||
|       serach_string[path] = {}; | ||||
|  | ||||
|       this.filtered.forEach(function (filter, index) { | ||||
|         if (!args) { | ||||
|           args += '?search='; | ||||
|         } | ||||
|  | ||||
|         args += this.selected_options[index].key + ':' + this.selected_values[index].key + ' '; | ||||
|  | ||||
|         serach_string[path][this.selected_options[index].key] = { | ||||
|           'key': this.selected_values[index].key, | ||||
|           'value': this.selected_values[index].value | ||||
|         }; | ||||
|       }, this); | ||||
|  | ||||
|       Cookies.set('search-string', serach_string, expires); | ||||
|  | ||||
|       window.location = path + args; | ||||
|     }, | ||||
|  | ||||
|     onOptionSelected(value) { | ||||
|       this.current_value = value; | ||||
|  | ||||
|       let option = false; | ||||
|       let option_url = false; | ||||
|  | ||||
|       for (let i = 0; i < this.filter_list.length; i++) { | ||||
|         if (this.filter_list[i].key == value) { | ||||
|           option = this.filter_list[i].value; | ||||
|  | ||||
|           if (typeof this.filter_list[i].url !== 'undefined' && this.filter_list[i].url) { | ||||
|             option_url = this.filter_list[i].url; | ||||
|           } | ||||
|  | ||||
|           if (typeof this.filter_list[i].type !== 'undefined' && this.filter_list[i].type == 'boolean') { | ||||
|             this.option_values[value] = this.filter_list[i].values; | ||||
|           } | ||||
|  | ||||
|           this.selected_options.push(this.filter_list[i]); | ||||
|           this.filter_list.splice(i, 1); | ||||
|           break; | ||||
|         } | ||||
|       } | ||||
|  | ||||
|       // Set filtered select option | ||||
|       this.filtered.push({ | ||||
|         option: option, | ||||
|         operator: false, | ||||
|         value: false | ||||
|       }); | ||||
|  | ||||
|       this.$emit('change', this.filtered); | ||||
|  | ||||
|       this.search = ''; | ||||
|  | ||||
|       if (!this.option_values[value] && option_url) { | ||||
|         window.axios.get(option_url) | ||||
|         .then(response => { | ||||
|             let data = response.data.data; | ||||
|  | ||||
|             data.forEach(function (item) { | ||||
|               this.values.push({ | ||||
|                 key: (item.code) ? item.code : item.id, | ||||
|                 value: (item.title) ? item.title : (item.display_name) ? item.display_name : item.name | ||||
|               }); | ||||
|             }, this); | ||||
|  | ||||
|             this.option_values[value] = this.values; | ||||
|         }) | ||||
|         .catch(error => { | ||||
|  | ||||
|         }); | ||||
|       } else { | ||||
|         this.values = (this.option_values[value]) ? this.option_values[value] : []; | ||||
|       } | ||||
|  | ||||
|       this.$nextTick(() => { | ||||
|         this.$refs['input-search-field-' + this._uid].focus(); | ||||
|       }); | ||||
|  | ||||
|       this.visible = { | ||||
|         options: false, | ||||
|         operator: true, | ||||
|         values: false, | ||||
|       }; | ||||
|  | ||||
|       this.filter_last_step = 'operator'; | ||||
|     }, | ||||
|  | ||||
|     onOperatorSelected(value) { | ||||
|       this.filtered[this.filter_index].operator = value; | ||||
|  | ||||
|       this.$emit('change', this.filtered); | ||||
|  | ||||
|       if (this.selected_options[this.filter_index].type != 'date') { | ||||
|         this.$nextTick(() => { | ||||
|           this.$refs['input-search-field-' + this._uid].focus(); | ||||
|         }); | ||||
|  | ||||
|         this.visible = { | ||||
|           options: false, | ||||
|           operator: false, | ||||
|           values: true, | ||||
|         }; | ||||
|       } else { | ||||
|         this.show_date = true; | ||||
|  | ||||
|         this.$nextTick(() => { | ||||
|           this.$refs['input-search-date-field-' + this._uid].focus(); | ||||
|         }); | ||||
|  | ||||
|         this.visible = { | ||||
|           options: false, | ||||
|           operator: false, | ||||
|           values: false, | ||||
|         }; | ||||
|       } | ||||
|  | ||||
|       this.filter_last_step = 'values'; | ||||
|     }, | ||||
|  | ||||
|     onValueSelected(value) { | ||||
|       let select_value = false; | ||||
|  | ||||
|       for (let i = 0; i < this.values.length; i++) { | ||||
|         if (this.values[i].key == value) { | ||||
|           select_value = this.values[i].value; | ||||
|  | ||||
|           this.selected_values.push(this.values[i]); | ||||
|           this.option_values[this.current_value].splice(i, 1); | ||||
|           break; | ||||
|         } | ||||
|       } | ||||
|  | ||||
|       this.filtered[this.filter_index].value = select_value; | ||||
|  | ||||
|       this.$emit('change', this.filtered); | ||||
|  | ||||
|       this.$nextTick(() => { | ||||
|         this.$refs['input-search-field-' + this._uid].focus(); | ||||
|       }); | ||||
|  | ||||
|       this.filter_index++; | ||||
|  | ||||
|       if (this.filter_list.length) { | ||||
|         this.visible = { | ||||
|           options: true, | ||||
|           operator: false, | ||||
|           values: false, | ||||
|         }; | ||||
|       } else { | ||||
|         this.visible = { | ||||
|           options: false, | ||||
|           operator: false, | ||||
|           values: false, | ||||
|         }; | ||||
|       } | ||||
|  | ||||
|       this.show_date = false; | ||||
|  | ||||
|       this.filter_last_step = 'options'; | ||||
|     }, | ||||
|  | ||||
|     onFilterDelete(index) { | ||||
|       this.filter_list.push(this.selected_options[index]); | ||||
|  | ||||
|       this.filter_index--; | ||||
|  | ||||
|       this.filtered.splice(index, 1); | ||||
|       this.selected_options.splice(index, 1); | ||||
|     }, | ||||
|  | ||||
|     onSearchAndFilterClear() { | ||||
|       this.filtered = []; | ||||
|       this.search = ''; | ||||
|  | ||||
|       Cookies.remove('search-string'); | ||||
|  | ||||
|       this.onInputConfirm(); | ||||
|     }, | ||||
|  | ||||
|     closeIfClickedOutside(event) { | ||||
|       if (!document.getElementById('search-field-' + this._uid).contains(event.target) && event.target.className != 'btn btn-link') { | ||||
|           this.visible.options = false; | ||||
|           this.visible.operator = false; | ||||
|           this.visible.values = false; | ||||
|  | ||||
|           document.removeEventListener('click', this.closeIfClickedOutside); | ||||
|       } | ||||
|     }, | ||||
|   }, | ||||
|  | ||||
|   created() { | ||||
|     let path = window.location.href.replace(window.location.search, ''); | ||||
|  | ||||
|     let cookie = Cookies.get('search-string'); | ||||
|  | ||||
|     cookie = JSON.parse(cookie)[path]; | ||||
|  | ||||
|     if (this.value) { | ||||
|       let serach_string = this.value.split(' '); | ||||
|  | ||||
|       serach_string.forEach(function (string) { | ||||
|         if (string.search(':') === -1) { | ||||
|           this.search = string; | ||||
|         } else { | ||||
|           let filter = string.split(':'); | ||||
|           let option = ''; | ||||
|           let value = ''; | ||||
|  | ||||
|           this.filter_list.forEach(function (_filter, i) { | ||||
|             if (_filter.key == filter[0]) { | ||||
|               option = _filter.value; | ||||
|  | ||||
|               _filter.values.forEach(function (_value) { | ||||
|                 if (_value.key == filter[1]) { | ||||
|                   value = _value.value; | ||||
|                 } | ||||
|               }, this); | ||||
|  | ||||
|               if (!value && cookie[_filter.key]) { | ||||
|                 value = cookie[_filter.key].value; | ||||
|               } | ||||
|  | ||||
|               this.selected_options.push(this.filter_list[i]); | ||||
|               this.filter_list.splice(i, 1); | ||||
|  | ||||
|               this.option_values[_filter.key] = _filter.values; | ||||
|  | ||||
|               _filter.values.forEach(function (value, j) { | ||||
|                 if (value.key == filter[1]) { | ||||
|                   this.selected_values.push(value); | ||||
|  | ||||
|                   this.option_values[_filter.key].splice(j, 1); | ||||
|                 } | ||||
|               }, this); | ||||
|  | ||||
|               if (cookie[_filter.key]) { | ||||
|                   this.selected_values.push(cookie[_filter.key]); | ||||
|               } | ||||
|             } | ||||
|         }, | ||||
|           }, this); | ||||
|  | ||||
|         mounted() { | ||||
|             this.real_model = this.value; | ||||
|           this.filtered.push({ | ||||
|             option: option, | ||||
|             operator: '=', | ||||
|             value: value | ||||
|           }); | ||||
|  | ||||
|             this.$emit('interface', this.real_model); | ||||
|         }, | ||||
|  | ||||
|         methods: { | ||||
|             change() { | ||||
|                 this.$emit('change', this.real_model); | ||||
|                 this.$emit('interface', this.real_model); | ||||
|  | ||||
|                 this.selectOptions.forEach(item => { | ||||
|                     if (item.id == this.real_model) { | ||||
|                         this.$emit('label', item.name); | ||||
|                         this.$emit('option', item); | ||||
|  | ||||
|                         return; | ||||
|                     } | ||||
|                 }); | ||||
|             }, | ||||
|             remoteMethod() { | ||||
|  | ||||
|             }, | ||||
|         }, | ||||
|  | ||||
|         watch: { | ||||
|             options: function (options) { | ||||
|                 // update options | ||||
|                 //this.selectOptions = options; | ||||
|             } | ||||
|         }, | ||||
|           this.filter_index++; | ||||
|         } | ||||
|       }, this); | ||||
|     } | ||||
|   }, | ||||
|  | ||||
|   computed: { | ||||
|     filteredOptions() { | ||||
|       this.filter_list.sort(function (a, b) { | ||||
|           var nameA = a.value.toUpperCase(); // ignore upper and lowercase | ||||
|           var nameB = b.value.toUpperCase(); // ignore upper and lowercase | ||||
|  | ||||
|           if (nameA < nameB) { | ||||
|             return -1; | ||||
|           } | ||||
|  | ||||
|           if (nameA > nameB) { | ||||
|             return 1; | ||||
|           } | ||||
|  | ||||
|           // names must be equal | ||||
|           return 0; | ||||
|       }); | ||||
|  | ||||
|       return this.filter_list.filter(option => { | ||||
|         return option.value.toLowerCase().includes(this.search.toLowerCase()) | ||||
|       }); | ||||
|     }, | ||||
|  | ||||
|     filteredValues() { | ||||
|       this.values.sort(function (a, b) { | ||||
|           var nameA = a.value.toUpperCase(); // ignore upper and lowercase | ||||
|           var nameB = b.value.toUpperCase(); // ignore upper and lowercase | ||||
|  | ||||
|           if (nameA < nameB) { | ||||
|             return -1; | ||||
|           } | ||||
|  | ||||
|           if (nameA > nameB) { | ||||
|             return 1; | ||||
|           } | ||||
|  | ||||
|           // names must be equal | ||||
|           return 0; | ||||
|       }); | ||||
|  | ||||
|       return this.values.filter(value => { | ||||
|         return value.value.toLowerCase().includes(this.search.toLowerCase()) | ||||
|       }) | ||||
|     } | ||||
|   }, | ||||
|  | ||||
|    watch: { | ||||
|       visible: { | ||||
|         handler: function(newValue) { | ||||
|             if (newValue) { | ||||
|                 document.addEventListener('click', this.closeIfClickedOutside); | ||||
|             } | ||||
|         }, | ||||
|         deep: true | ||||
|       } | ||||
|     }, | ||||
| }; | ||||
| </script> | ||||
|  | ||||
| <style> | ||||
| .searh-field { | ||||
|     border: 1px solid #dee2e6; | ||||
|     border-radius: 0.25rem; | ||||
| } | ||||
|  | ||||
| .searh-field .tags-group { | ||||
|   display: contents; | ||||
| } | ||||
|  | ||||
| .searh-field .el-tag.el-tag--primary { | ||||
|   background: #f6f9fc; | ||||
|   background-color: #f6f9fc; | ||||
|   border-color: #f6f9fc; | ||||
|   color: #8898aa; | ||||
|   margin-top: 7px; | ||||
| } | ||||
|  | ||||
| .searh-field .tags-group:hover > span { | ||||
|   background:#cbd4de; | ||||
|   background-color: #cbd4de; | ||||
|   border-color: #cbd4de; | ||||
| } | ||||
|  | ||||
| .searh-field .el-tag.el-tag--primary .el-tag__close.el-icon-close { | ||||
|   color: #8898aa; | ||||
| } | ||||
|  | ||||
| .searh-field .el-tag-option { | ||||
|   border-radius: 0.25rem 0 0 0.25rem; | ||||
|   margin-left: 10px; | ||||
| } | ||||
|  | ||||
| .searh-field .el-tag-operator { | ||||
|   border-radius: 0; | ||||
|   margin-left: -1px; | ||||
|   margin-right: -1px; | ||||
| } | ||||
|  | ||||
| .searh-field .el-tag-value { | ||||
|   border-radius: 0 0.25rem 0.25rem 0; | ||||
|   margin-right: 10px; | ||||
| } | ||||
|  | ||||
| .searh-field .el-select.input-new-tag { | ||||
|     width: 100%; | ||||
| } | ||||
|  | ||||
| .searh-field .input-full { | ||||
|   width: 100%; | ||||
| } | ||||
|  | ||||
| .searh-field .btn.btn-link { | ||||
|   width: inherit; | ||||
|   text-align: left; | ||||
|   display: flex; | ||||
|   margin: 0; | ||||
|   text-overflow: inherit; | ||||
|   text-align: left; | ||||
|   text-overflow: ellipsis; | ||||
|   padding: unset; | ||||
|   color: #212529; | ||||
| } | ||||
|  | ||||
| .searh-field .btn.btn-link.clear { | ||||
|   position: absolute; | ||||
|   top: 0; | ||||
|   right: 0; | ||||
|   width: 45px; | ||||
|   height: 45px; | ||||
|   -webkit-box-pack: center; | ||||
|   -ms-flex-pack: center; | ||||
|   justify-content: center; | ||||
|   -webkit-box-align: center; | ||||
|   -ms-flex-align: center; | ||||
|   align-items: center; | ||||
|   color: #adb5bd; | ||||
|   opacity: 1; | ||||
| } | ||||
|  | ||||
| .searh-field .btn.btn-link.clear:hover { | ||||
|   color: #8898aa; | ||||
| } | ||||
|  | ||||
| .searh-field .btn-helptext { | ||||
|   margin-left: auto; | ||||
|   color: var(--gray); | ||||
| } | ||||
|  | ||||
| .searh-field .btn:not(:disabled):not(.disabled):active:focus, | ||||
| .searh-field .btn:not(:disabled):not(.disabled).active:focus { | ||||
|   -webkit-box-shadow: none !important; | ||||
|     box-shadow: none !important; | ||||
| } | ||||
|  | ||||
| .searh-field .form-control.datepicker.flatpickr-input { | ||||
|   padding: inherit !important; | ||||
| } | ||||
| </style> | ||||
|   | ||||
							
								
								
									
										2
									
								
								resources/assets/js/views/auth/roles.js
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										2
									
								
								resources/assets/js/views/auth/roles.js
									
									
									
									
										vendored
									
									
								
							| @@ -26,7 +26,7 @@ const app = new Vue({ | ||||
|     ], | ||||
|  | ||||
|     mounted() { | ||||
|         if (!this.form.permissions.length) { | ||||
|         if (typeof this.form.permissions !== 'undefined' && !this.form.permissions.length) { | ||||
|             this.form.permissions = []; | ||||
|         } | ||||
|     }, | ||||
|   | ||||
| @@ -105,6 +105,7 @@ return [ | ||||
|     'to'                    => 'To', | ||||
|     'print'                 => 'Print', | ||||
|     'search'                => 'Search', | ||||
|     'search_text'           => 'Search for this text', | ||||
|     'search_placeholder'    => 'Type to search..', | ||||
|     'filter'                => 'Filter', | ||||
|     'help'                  => 'Help', | ||||
| @@ -152,6 +153,8 @@ return [ | ||||
|     'no_matching_data'      => 'No matching data', | ||||
|     'clear_cache'           => 'Clear Cache', | ||||
|     'go_to_dashboard'       => 'Go to dashboard', | ||||
|     'is'                    => 'is', | ||||
|     'isnot'                 => 'is not',  | ||||
|  | ||||
|     'card' => [ | ||||
|         'name'                  => 'Name on Card', | ||||
| @@ -181,6 +184,11 @@ return [ | ||||
|         'no_file_selected'  => 'No file selected...', | ||||
|     ], | ||||
|  | ||||
|     'placeholder' => [ | ||||
|         'search'            => 'Type to search..', | ||||
|         'search_and_filter' => 'Search or filter results..', | ||||
|     ], | ||||
|  | ||||
|     'date_range' => [ | ||||
|         'today' => 'Today', | ||||
|         'yesterday' => 'Yesterday', | ||||
|   | ||||
							
								
								
									
										9
									
								
								resources/lang/en-GB/search_string.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										9
									
								
								resources/lang/en-GB/search_string.php
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,9 @@ | ||||
| <?php | ||||
|  | ||||
| return [ | ||||
|  | ||||
|     'columns' => [ | ||||
|         'last_logged_in_at' => 'Last Login', | ||||
|     ], | ||||
|  | ||||
| ]; | ||||
| @@ -18,10 +18,7 @@ | ||||
|                 'class' => 'mb-0' | ||||
|             ]) !!} | ||||
|                 <div class="align-items-center" v-if="!bulk_action.show"> | ||||
|                     <akaunting-search | ||||
|                         :placeholder="'{{ trans('general.search_placeholder') }}'" | ||||
|                         :options="{{ json_encode([]) }}" | ||||
|                     ></akaunting-search> | ||||
|                     <x-search-string model="App\Models\Auth\Permission" /> | ||||
|                 </div> | ||||
|  | ||||
|                 {{ Form::bulkActionRowGroup('general.permissions', $bulk_actions, ['group' => 'auth', 'type' => 'permissions']) }} | ||||
|   | ||||
| @@ -18,10 +18,7 @@ | ||||
|                 'class' => 'mb-0' | ||||
|             ]) !!} | ||||
|                 <div class="align-items-center" v-if="!bulk_action.show"> | ||||
|                     <akaunting-search | ||||
|                         :placeholder="'{{ trans('general.search_placeholder') }}'" | ||||
|                         :options="{{ json_encode([]) }}" | ||||
|                     ></akaunting-search> | ||||
|                     <x-search-string model="App\Models\Auth\Role" /> | ||||
|                 </div> | ||||
|  | ||||
|                 {{ Form::bulkActionRowGroup('general.roles', $bulk_actions, ['group' => 'auth', 'type' => 'roles']) }} | ||||
|   | ||||
| @@ -11,21 +11,12 @@ | ||||
| @section('content') | ||||
|     <div class="card"> | ||||
|         <div class="card-header border-bottom-0" :class="[{'bg-gradient-primary': bulk_action.show}]"> | ||||
|             {!! Form::open([ | ||||
|                 'method' => 'GET', | ||||
|                 'route' => 'users.index', | ||||
|                 'role' => 'form', | ||||
|                 'class' => 'mb-0' | ||||
|             ]) !!} | ||||
|  | ||||
|                 <div class="align-items-center" v-if="!bulk_action.show"> | ||||
|                     <akaunting-search | ||||
|                         :placeholder="'{{ trans('general.search_placeholder') }}'" | ||||
|                         :options="{{ json_encode([]) }}" | ||||
|                     ></akaunting-search> | ||||
|                     <x-search-string model="App\Models\Auth\User" /> | ||||
|                 </div> | ||||
|  | ||||
|                 {{ Form::bulkActionRowGroup('general.users', $bulk_actions, ['group' => 'auth', 'type' => 'users']) }} | ||||
|             {!! Form::close() !!} | ||||
|         </div> | ||||
|  | ||||
|         <div class="table-responsive"> | ||||
|   | ||||
| @@ -18,10 +18,7 @@ | ||||
|                 'class' => 'mb-0' | ||||
|             ]) !!} | ||||
|                 <div class="align-items-center" v-if="!bulk_action.show"> | ||||
|                     <akaunting-search | ||||
|                         :placeholder="'{{ trans('general.search_placeholder') }}'" | ||||
|                         :options="{{ json_encode([]) }}" | ||||
|                     ></akaunting-search> | ||||
|                     <x-search-string model="App\Models\Banking\Account" /> | ||||
|                 </div> | ||||
|  | ||||
|                 {{ Form::bulkActionRowGroup('general.accounts', $bulk_actions, ['group' => 'banking', 'type' => 'accounts']) }} | ||||
|   | ||||
| @@ -9,7 +9,7 @@ | ||||
| @endsection | ||||
|  | ||||
| @section('content') | ||||
|     @if ($reconciliations->count()) | ||||
|     @if ($reconciliations->count() || request()->get('search', false)) | ||||
|         <div class="card"> | ||||
|             <div class="card-header border-bottom-0" :class="[{'bg-gradient-primary': bulk_action.show}]"> | ||||
|                 {!! Form::open([ | ||||
| @@ -19,10 +19,7 @@ | ||||
|                     'class' => 'mb-0' | ||||
|                 ]) !!} | ||||
|                     <div class="align-items-center" v-if="!bulk_action.show"> | ||||
|                         <akaunting-search | ||||
|                             :placeholder="'{{ trans('general.search_placeholder') }}'" | ||||
|                             :options="{{ json_encode([]) }}" | ||||
|                         ></akaunting-search> | ||||
|                         <x-search-string model="App\Models\Banking\Reconciliation" /> | ||||
|                     </div> | ||||
|  | ||||
|                     {{ Form::bulkActionRowGroup('general.reconciliations', $bulk_actions, ['group' => 'banking', 'type' => 'reconciliations']) }} | ||||
|   | ||||
| @@ -22,10 +22,7 @@ | ||||
|                 'role' => 'form', | ||||
|                 'class' => 'mb-0' | ||||
|             ]) !!} | ||||
|                 <akaunting-search | ||||
|                     :placeholder="'{{ trans('general.search_placeholder') }}'" | ||||
|                     :options="{{ json_encode([]) }}" | ||||
|                 ></akaunting-search> | ||||
|                 <x-search-string model="App\Models\Banking\Transaction" /> | ||||
|             {!! Form::close() !!} | ||||
|         </div> | ||||
|  | ||||
|   | ||||
| @@ -11,7 +11,7 @@ | ||||
| @endsection | ||||
|  | ||||
| @section('content') | ||||
|     @if ($transfers->count()) | ||||
|     @if ($transfers->count() || request()->get('search', false)) | ||||
|         <div class="card"> | ||||
|             <div class="card-header border-bottom-0" :class="[{'bg-gradient-primary': bulk_action.show}]"> | ||||
|                 {!! Form::open([ | ||||
| @@ -21,10 +21,7 @@ | ||||
|                     'class' => 'mb-0' | ||||
|                 ]) !!} | ||||
|                     <div class="align-items-center" v-if="!bulk_action.show"> | ||||
|                         <akaunting-search | ||||
|                             :placeholder="'{{ trans('general.search_placeholder') }}'" | ||||
|                             :options="{{ json_encode([]) }}" | ||||
|                         ></akaunting-search> | ||||
|                         <x-search-string model="App\Models\Banking\Transfer" /> | ||||
|                     </div> | ||||
|  | ||||
|                     {{ Form::bulkActionRowGroup('general.transfers', $bulk_actions, ['group' => 'banking', 'type' => 'transfers']) }} | ||||
|   | ||||
| @@ -18,10 +18,7 @@ | ||||
|                 'class' => 'mb-0' | ||||
|             ]) !!} | ||||
|                 <div class="align-items-center" v-if="!bulk_action.show"> | ||||
|                     <akaunting-search | ||||
|                         :placeholder="'{{ trans('general.search_placeholder') }}'" | ||||
|                         :options="{{ json_encode([]) }}" | ||||
|                     ></akaunting-search> | ||||
|                     <x-search-string model="App\Models\Common\Company" /> | ||||
|                 </div> | ||||
|  | ||||
|                 {{ Form::bulkActionRowGroup('general.companies', $bulk_actions, ['group' => 'common', 'type' => 'companies']) }} | ||||
|   | ||||
| @@ -18,10 +18,7 @@ | ||||
|                 'class' => 'mb-0' | ||||
|             ]) !!} | ||||
|                 <div class="align-items-center" v-if="!bulk_action.show"> | ||||
|                     <akaunting-search | ||||
|                         :placeholder="'{{ trans('general.search_placeholder') }}'" | ||||
|                         :options="{{ json_encode([]) }}" | ||||
|                     ></akaunting-search> | ||||
|                     <x-search-string model="App\Models\Common\Dashboard" /> | ||||
|                 </div> | ||||
|  | ||||
|                 {{ Form::bulkActionRowGroup('general.dashboards', $bulk_actions, ['group' => 'common', 'type' => 'dashboards']) }} | ||||
|   | ||||
| @@ -11,7 +11,7 @@ | ||||
| @endsection | ||||
|  | ||||
| @section('content') | ||||
|     @if ($items->count()) | ||||
|     @if ($items->count() || request()->get('search', false)) | ||||
|         <div class="card"> | ||||
|             <div class="card-header border-bottom-0" :class="[{'bg-gradient-primary': bulk_action.show}]"> | ||||
|                 {!! Form::open([ | ||||
| @@ -21,10 +21,7 @@ | ||||
|                     'class' => 'mb-0' | ||||
|                 ]) !!} | ||||
|                     <div class="align-items-center" v-if="!bulk_action.show"> | ||||
|                         <akaunting-search | ||||
|                             :placeholder="'{{ trans('general.search_placeholder') }}'" | ||||
|                             :options="{{ json_encode([]) }}" | ||||
|                         ></akaunting-search> | ||||
|                         <x-search-string model="App\Models\Common\Item" /> | ||||
|                     </div> | ||||
|  | ||||
|                     {{ Form::bulkActionRowGroup('general.items', $bulk_actions, ['group' => 'common', 'type' => 'items']) }} | ||||
|   | ||||
							
								
								
									
										22
									
								
								resources/views/components/search-string.blade.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										22
									
								
								resources/views/components/search-string.blade.php
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,22 @@ | ||||
| <akaunting-search | ||||
|     placeholder="{{ (!empty($filters)) ? trans('general.placeholder.search_and_filter') : trans('general.search_placeholder')}}" | ||||
|     search-text="{{ trans('general.search_text') }}" | ||||
|     operator-is-text="{{ trans('general.is') }}" | ||||
|     operator-is-not-text="{{ trans('general.isnot') }}"  | ||||
|     no-data-text="{{ trans('general.no_data') }}" | ||||
|     no-matching-data-text="{{ trans('general.no_matching_data') }}" | ||||
|     value="{{ request()->get('search', null) }}" | ||||
|     :filters="{{ json_encode($filters) }}" | ||||
|     :date-config="{ | ||||
|         allowInput: true, | ||||
|         altInput: true, | ||||
|         altFormat: 'Y-m-d', | ||||
|         dateFormat: 'Y-m-d', | ||||
|         @if (!empty($attributes['min-date'])) | ||||
|         minDate: {{ $attributes['min-date'] }} | ||||
|         @endif | ||||
|         @if (!empty($attributes['max-date'])) | ||||
|         maxDate: {{ $attributes['max-date'] }} | ||||
|         @endif | ||||
|     }" | ||||
| ></akaunting-search> | ||||
| @@ -11,7 +11,7 @@ | ||||
| @endsection | ||||
|  | ||||
| @section('content') | ||||
|     @if ($bills->count()) | ||||
|     @if ($bills->count() || request()->get('search', false)) | ||||
|         <div class="card"> | ||||
|             <div class="card-header border-bottom-0" :class="[{'bg-gradient-primary': bulk_action.show}]"> | ||||
|                 {!! Form::open([ | ||||
| @@ -21,10 +21,7 @@ | ||||
|                     'class' => 'mb-0' | ||||
|                 ]) !!} | ||||
|                     <div class="align-items-center" v-if="!bulk_action.show"> | ||||
|                         <akaunting-search | ||||
|                             :placeholder="'{{ trans('general.search_placeholder') }}'" | ||||
|                             :options="{{ json_encode([]) }}" | ||||
|                         ></akaunting-search> | ||||
|                         <x-search-string model="App\Models\Purchase\Bill" /> | ||||
|                     </div> | ||||
|  | ||||
|                     {{ Form::bulkActionRowGroup('general.bills', $bulk_actions, ['group' => 'purchases', 'type' => 'bills']) }} | ||||
|   | ||||
| @@ -11,7 +11,7 @@ | ||||
| @endsection | ||||
|  | ||||
| @section('content') | ||||
|     @if ($payments->count()) | ||||
|     @if ($payments->count() || request()->get('search', false)) | ||||
|         <div class="card"> | ||||
|             <div class="card-header border-bottom-0" :class="[{'bg-gradient-primary': bulk_action.show}]"> | ||||
|                 {!! Form::open([ | ||||
| @@ -21,10 +21,7 @@ | ||||
|                     'class' => 'mb-0' | ||||
|                 ]) !!} | ||||
|                     <div class="align-items-center" v-if="!bulk_action.show"> | ||||
|                         <akaunting-search | ||||
|                             :placeholder="'{{ trans('general.search_placeholder') }}'" | ||||
|                             :options="{{ json_encode([]) }}" | ||||
|                         ></akaunting-search> | ||||
|                         <x-search-string model="App\Models\Banking\Transaction" /> | ||||
|                     </div> | ||||
|  | ||||
|                     {{ Form::bulkActionRowGroup('general.payments', $bulk_actions, ['group' => 'purchases', 'type' => 'payments']) }} | ||||
|   | ||||
| @@ -11,7 +11,7 @@ | ||||
| @endsection | ||||
|  | ||||
| @section('content') | ||||
|     @if ($vendors->count()) | ||||
|     @if ($vendors->count() || request()->get('search', false)) | ||||
|         <div class="card"> | ||||
|             <div class="card-header border-bottom-0" :class="[{'bg-gradient-primary': bulk_action.show}]"> | ||||
|                 {!! Form::open([ | ||||
| @@ -21,10 +21,7 @@ | ||||
|                     'class' => 'mb-0' | ||||
|                 ]) !!} | ||||
|                     <div class="align-items-center" v-if="!bulk_action.show"> | ||||
|                         <akaunting-search | ||||
|                             :placeholder="'{{ trans('general.search_placeholder') }}'" | ||||
|                             :options="{{ json_encode([]) }}" | ||||
|                         ></akaunting-search> | ||||
|                         <x-search-string model="App\Models\Common\Contact" /> | ||||
|                     </div> | ||||
|  | ||||
|                     {{ Form::bulkActionRowGroup('general.vendors', $bulk_actions, ['group' => 'purchases', 'type' => 'vendors']) }} | ||||
|   | ||||
| @@ -11,7 +11,7 @@ | ||||
| @endsection | ||||
|  | ||||
| @section('content') | ||||
|     @if ($customers->count()) | ||||
|     @if ($customers->count() || request()->get('search', false)) | ||||
|         <div class="card"> | ||||
|             <div class="card-header border-bottom-0" :class="[{'bg-gradient-primary': bulk_action.show}]"> | ||||
|                 {!! Form::open([ | ||||
| @@ -21,10 +21,7 @@ | ||||
|                     'class' => 'mb-0' | ||||
|                 ]) !!} | ||||
|                     <div class="align-items-center" v-if="!bulk_action.show"> | ||||
|                         <akaunting-search | ||||
|                             :placeholder="'{{ trans('general.search_placeholder') }}'" | ||||
|                             :options="{{ json_encode([]) }}" | ||||
|                         ></akaunting-search> | ||||
|                         <x-search-string model="App\Models\Common\Contact" /> | ||||
|                     </div> | ||||
|  | ||||
|                     {{ Form::bulkActionRowGroup('general.customers', $bulk_actions, ['group' => 'sales', 'type' => 'customers']) }} | ||||
|   | ||||
| @@ -11,7 +11,7 @@ | ||||
| @endsection | ||||
|  | ||||
| @section('content') | ||||
|     @if ($invoices->count()) | ||||
|     @if ($invoices->count() || request()->get('search', false)) | ||||
|         <div class="card"> | ||||
|             <div class="card-header border-bottom-0" :class="[{'bg-gradient-primary': bulk_action.show}]"> | ||||
|                 {!! Form::open([ | ||||
| @@ -21,10 +21,7 @@ | ||||
|                     'class' => 'mb-0' | ||||
|                 ]) !!} | ||||
|                     <div class="align-items-center" v-if="!bulk_action.show"> | ||||
|                         <akaunting-search | ||||
|                             :placeholder="'{{ trans('general.search_placeholder') }}'" | ||||
|                             :options="{{ json_encode([]) }}" | ||||
|                         ></akaunting-search> | ||||
|                         <x-search-string model="App\Models\Sale\Invoice" /> | ||||
|                     </div> | ||||
|  | ||||
|                     {{ Form::bulkActionRowGroup('general.invoices', $bulk_actions, ['group' => 'sales', 'type' => 'invoices']) }} | ||||
|   | ||||
| @@ -11,7 +11,7 @@ | ||||
| @endsection | ||||
|  | ||||
| @section('content') | ||||
|     @if ($revenues->count()) | ||||
|     @if ($revenues->count() || request()->get('search', false)) | ||||
|         <div class="card"> | ||||
|             <div class="card-header border-bottom-0" :class="[{'bg-gradient-primary': bulk_action.show}]"> | ||||
|                 {!! Form::open([ | ||||
| @@ -21,10 +21,7 @@ | ||||
|                     'class' => 'mb-0' | ||||
|                 ]) !!} | ||||
|                     <div class="align-items-center" v-if="!bulk_action.show"> | ||||
|                         <akaunting-search | ||||
|                             :placeholder="'{{ trans('general.search_placeholder') }}'" | ||||
|                             :options="{{ json_encode([]) }}" | ||||
|                         ></akaunting-search> | ||||
|                         <x-search-string model="App\Models\Banking\Transaction" /> | ||||
|                     </div> | ||||
|  | ||||
|                     {{ Form::bulkActionRowGroup('general.revenues', $bulk_actions, ['group' => 'sales', 'type' => 'revenues']) }} | ||||
|   | ||||
| @@ -18,10 +18,7 @@ | ||||
|                 'class' => 'mb-0' | ||||
|             ]) !!} | ||||
|                 <div class="align-items-center" v-if="!bulk_action.show"> | ||||
|                     <akaunting-search | ||||
|                         :placeholder="'{{ trans('general.search_placeholder') }}'" | ||||
|                         :options="{{ json_encode([]) }}" | ||||
|                     ></akaunting-search> | ||||
|                     <x-search-string model="App\Models\Setting\Category" /> | ||||
|                 </div> | ||||
|  | ||||
|                 {{ Form::bulkActionRowGroup('general.categories', $bulk_actions, ['group' => 'settings', 'type' => 'categories']) }} | ||||
|   | ||||
| @@ -18,10 +18,7 @@ | ||||
|                 'class' => 'mb-0' | ||||
|             ]) !!} | ||||
|                 <div class="align-items-center" v-if="!bulk_action.show"> | ||||
|                     <akaunting-search | ||||
|                         :placeholder="'{{ trans('general.search_placeholder') }}'" | ||||
|                         :options="{{ json_encode([]) }}" | ||||
|                     ></akaunting-search> | ||||
|                     <x-search-string model="App\Models\Setting\Currency" /> | ||||
|                 </div> | ||||
|  | ||||
|                 {{ Form::bulkActionRowGroup('general.currencies', $bulk_actions, ['group' => 'settings', 'type' => 'currencies']) }} | ||||
|   | ||||
| @@ -9,7 +9,7 @@ | ||||
| @endcan | ||||
|  | ||||
| @section('content') | ||||
|     @if ($taxes->count()) | ||||
|     @if ($taxes->count() || request()->get('search', false)) | ||||
|         <div class="card"> | ||||
|             <div class="card-header border-bottom-0" :class="[{'bg-gradient-primary': bulk_action.show}]"> | ||||
|                 {!! Form::open([ | ||||
| @@ -19,10 +19,7 @@ | ||||
|                     'class' => 'mb-0' | ||||
|                 ]) !!} | ||||
|                     <div class="align-items-center" v-if="!bulk_action.show"> | ||||
|                         <akaunting-search | ||||
|                             :placeholder="'{{ trans('general.search_placeholder') }}'" | ||||
|                             :options="{{ json_encode([]) }}" | ||||
|                         ></akaunting-search> | ||||
|                         <x-search-string model="App\Models\Setting\Tax" /> | ||||
|                     </div> | ||||
|  | ||||
|                     {{ Form::bulkActionRowGroup('general.taxes', $bulk_actions, ['group' => 'settings', 'type' => 'taxes']) }} | ||||
|   | ||||
		Reference in New Issue
	
	Block a user