diff --git a/app/Http/Controllers/Common/BulkActions.php b/app/Http/Controllers/Common/BulkActions.php index e84694553..ef43531a8 100644 --- a/app/Http/Controllers/Common/BulkActions.php +++ b/app/Http/Controllers/Common/BulkActions.php @@ -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 { /** diff --git a/app/View/Components/SearchString.php b/app/View/Components/SearchString.php new file mode 100644 index 000000000..d7f615cad --- /dev/null +++ b/app/View/Components/SearchString.php @@ -0,0 +1,196 @@ +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; + } +} diff --git a/config/search-string.php b/config/search-string.php index 355e1a988..c8895694f 100644 --- a/config/search-string.php +++ b/config/search-string.php @@ -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', ], ], diff --git a/public/css/custom.css b/public/css/custom.css index daf4d6f16..6421a2500 100644 --- a/public/css/custom.css +++ b/public/css/custom.css @@ -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 --*/ \ No newline at end of file diff --git a/public/vendor/js-cookie/js.cookie.js b/public/vendor/js-cookie/js.cookie.js index 9a0945ed8..98f13c735 100644 --- a/public/vendor/js-cookie/js.cookie.js +++ b/public/vendor/js-cookie/js.cookie.js @@ -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) { diff --git a/resources/assets/js/components/AkauntingSearch.vue b/resources/assets/js/components/AkauntingSearch.vue index 3d49182a4..cdbe637ea 100644 --- a/resources/assets/js/components/AkauntingSearch.vue +++ b/resources/assets/js/components/AkauntingSearch.vue @@ -1,170 +1,681 @@ +
- - + + diff --git a/resources/assets/js/views/auth/roles.js b/resources/assets/js/views/auth/roles.js index 41bd92bd8..09da7f69a 100644 --- a/resources/assets/js/views/auth/roles.js +++ b/resources/assets/js/views/auth/roles.js @@ -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 = []; } }, diff --git a/resources/lang/en-GB/general.php b/resources/lang/en-GB/general.php index 7c3426789..6d6a1a153 100644 --- a/resources/lang/en-GB/general.php +++ b/resources/lang/en-GB/general.php @@ -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', diff --git a/resources/lang/en-GB/search_string.php b/resources/lang/en-GB/search_string.php new file mode 100644 index 000000000..c80e57706 --- /dev/null +++ b/resources/lang/en-GB/search_string.php @@ -0,0 +1,9 @@ + [ + 'last_logged_in_at' => 'Last Login', + ], + +]; diff --git a/resources/views/auth/permissions/index.blade.php b/resources/views/auth/permissions/index.blade.php index 54d53b2e0..381594d41 100644 --- a/resources/views/auth/permissions/index.blade.php +++ b/resources/views/auth/permissions/index.blade.php @@ -18,10 +18,7 @@ 'class' => 'mb-0' ]) !!}