Merge pull request #2200 from bengu-thon-mai-mochi/item-input-search
Fetch items only after default character limit is reached
This commit is contained in:
@ -207,6 +207,9 @@ abstract class DocumentForm extends Base
|
|||||||
|
|
||||||
/** @var bool */
|
/** @var bool */
|
||||||
public $isPurchasePrice;
|
public $isPurchasePrice;
|
||||||
|
|
||||||
|
/** @var int */
|
||||||
|
public $searchCharLimit;
|
||||||
/** Items Component End */
|
/** Items Component End */
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -240,7 +243,7 @@ abstract class DocumentForm extends Base
|
|||||||
bool $hideItems = false, bool $hideName = false, bool $hideDescription = false, bool $hideQuantity = false,
|
bool $hideItems = false, bool $hideName = false, bool $hideDescription = false, bool $hideQuantity = false,
|
||||||
bool $hidePrice = false, bool $hideDiscount = false, bool $hideAmount = false,
|
bool $hidePrice = false, bool $hideDiscount = false, bool $hideAmount = false,
|
||||||
bool $hideEditItemColumns = false,
|
bool $hideEditItemColumns = false,
|
||||||
bool $isSalePrice = false, bool $isPurchasePrice = false
|
bool $isSalePrice = false, bool $isPurchasePrice = false, int $searchCharLimit = 0
|
||||||
/** Items Component End */
|
/** Items Component End */
|
||||||
) {
|
) {
|
||||||
$this->type = $type;
|
$this->type = $type;
|
||||||
@ -325,6 +328,7 @@ abstract class DocumentForm extends Base
|
|||||||
$this->hideEditItemColumns = $hideEditItemColumns;
|
$this->hideEditItemColumns = $hideEditItemColumns;
|
||||||
$this->isSalePrice = $isSalePrice;
|
$this->isSalePrice = $isSalePrice;
|
||||||
$this->isPurchasePrice = $isPurchasePrice;
|
$this->isPurchasePrice = $isPurchasePrice;
|
||||||
|
$this->searchCharLimit = $this->getSearchCharLimit($type, $searchCharLimit);
|
||||||
/** Items Component End */
|
/** Items Component End */
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1020,4 +1024,25 @@ abstract class DocumentForm extends Base
|
|||||||
|
|
||||||
return setting($this->getSettingKey($this->type, 'notes'));
|
return setting($this->getSettingKey($this->type, 'notes'));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected function getSearchCharLimit($type, $searchCharLimit)
|
||||||
|
{
|
||||||
|
if (!empty($searchCharLimit)) {
|
||||||
|
return $searchCharLimit;
|
||||||
|
}
|
||||||
|
|
||||||
|
// if you use settting translation
|
||||||
|
if ($settingCharLimit = setting($this->getSettingKey($type, 'item_search_chart_limit'), false)) {
|
||||||
|
return $settingCharLimit;
|
||||||
|
}
|
||||||
|
|
||||||
|
$hide = $this->getHideFromConfig($type, 'item_search_char_limit');
|
||||||
|
|
||||||
|
if ($hide) {
|
||||||
|
return $hide;
|
||||||
|
}
|
||||||
|
|
||||||
|
// @todo what return value invoice or always false??
|
||||||
|
return setting('invoice.item_search_char_limit', $searchCharLimit);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -16,16 +16,20 @@ class SelectItemButton extends Component
|
|||||||
/** @var bool */
|
/** @var bool */
|
||||||
public $isPurchase;
|
public $isPurchase;
|
||||||
|
|
||||||
|
/** @var int */
|
||||||
|
public $searchCharLimit;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a new component instance.
|
* Create a new component instance.
|
||||||
*
|
*
|
||||||
* @return void
|
* @return void
|
||||||
*/
|
*/
|
||||||
public function __construct(string $type = 'sale', bool $isSale = false, bool $isPurchase = false)
|
public function __construct(string $type = 'sale', bool $isSale = false, bool $isPurchase = false, int $searchCharLimit = 3)
|
||||||
{
|
{
|
||||||
$this->type = $type;
|
$this->type = $type;
|
||||||
$this->isSale = $isSale;
|
$this->isSale = $isSale;
|
||||||
$this->isPurchase = $isPurchase;
|
$this->isPurchase = $isPurchase;
|
||||||
|
$this->searchCharLimit = $searchCharLimit;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -122,6 +122,7 @@ return [
|
|||||||
'color' => env('SETTING_FALLBACK_INVOICE_COLOR', '#55588b'),
|
'color' => env('SETTING_FALLBACK_INVOICE_COLOR', '#55588b'),
|
||||||
'logo_size_width' => env('SETTING_FALLBACK_INVOICE_LOGO_SIZE_WIDTH', 128),
|
'logo_size_width' => env('SETTING_FALLBACK_INVOICE_LOGO_SIZE_WIDTH', 128),
|
||||||
'logo_size_height' => env('SETTING_FALLBACK_INVOICE_LOGO_SIZE_HEIGHT', 128),
|
'logo_size_height' => env('SETTING_FALLBACK_INVOICE_LOGO_SIZE_HEIGHT', 128),
|
||||||
|
'item_search_char_limit' => env('SETTING_FALLBACK_INVOICE_ITEM_SEARCH_CHAR_LIMIT', 3),
|
||||||
],
|
],
|
||||||
'bill' => [
|
'bill' => [
|
||||||
'number_prefix' => env('SETTING_FALLBACK_BILL_NUMBER_PREFIX', 'BILL-'),
|
'number_prefix' => env('SETTING_FALLBACK_BILL_NUMBER_PREFIX', 'BILL-'),
|
||||||
@ -133,6 +134,7 @@ return [
|
|||||||
'payment_terms' => env('SETTING_FALLBACK_BILL_PAYMENT_TERMS', '0'),
|
'payment_terms' => env('SETTING_FALLBACK_BILL_PAYMENT_TERMS', '0'),
|
||||||
'template' => env('SETTING_FALLBACK_BILL_TEMPLATE', 'default'),
|
'template' => env('SETTING_FALLBACK_BILL_TEMPLATE', 'default'),
|
||||||
'color' => env('SETTING_FALLBACK_BILL_COLOR', '#55588b'),
|
'color' => env('SETTING_FALLBACK_BILL_COLOR', '#55588b'),
|
||||||
|
'item_search_char_limit' => env('SETTING_FALLBACK_BILL_ITEM_SEARCH_CHAR_LIMIT', 3),
|
||||||
],
|
],
|
||||||
'default' => [
|
'default' => [
|
||||||
'currency' => env('SETTING_FALLBACK_DEFAULT_CURRENCY', 'USD'),
|
'currency' => env('SETTING_FALLBACK_DEFAULT_CURRENCY', 'USD'),
|
||||||
|
@ -33,7 +33,7 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<ul class="aka-select-menu-options">
|
<ul class="aka-select-menu-options">
|
||||||
<div class="aka-select-menu-option" v-for="(item, index) in sortItems" :key="index" @click="onItemSeleted(index, item.id)">
|
<div class="aka-select-menu-option" v-for="(item, index) in sortedItems" :key="index" @click="onItemSeleted(index, item.id)">
|
||||||
<div class="item-select w-100">
|
<div class="item-select w-100">
|
||||||
<div class="item-select-column item-select-info w-75">
|
<div class="item-select-column item-select-info w-75">
|
||||||
<b class="item-select-info-name"><span>{{ item.name }}</span></b>
|
<b class="item-select-info-name"><span>{{ item.name }}</span></b>
|
||||||
@ -52,7 +52,7 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="aka-select-menu-option" v-if="!sortItems.length">
|
<div class="aka-select-menu-option" v-if="!sortedItems.length">
|
||||||
<div>
|
<div>
|
||||||
<strong class="text-strong" v-if="!items.length && !search">
|
<strong class="text-strong" v-if="!items.length && !search">
|
||||||
<span>{{ noDataText }}</span>
|
<span>{{ noDataText }}</span>
|
||||||
@ -128,7 +128,6 @@ export default {
|
|||||||
default: () => [],
|
default: () => [],
|
||||||
description: 'List of Items'
|
description: 'List of Items'
|
||||||
},
|
},
|
||||||
|
|
||||||
addNew: {
|
addNew: {
|
||||||
type: Object,
|
type: Object,
|
||||||
default: function () {
|
default: function () {
|
||||||
@ -187,18 +186,22 @@ export default {
|
|||||||
},
|
},
|
||||||
description: "Default currency"
|
description: "Default currency"
|
||||||
},
|
},
|
||||||
|
searchCharLimit: {
|
||||||
|
type: Number,
|
||||||
|
default: 3,
|
||||||
|
description: "Character limit for item search input"
|
||||||
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
item_list: [],
|
item_list: [],
|
||||||
selected_items: [],
|
selected_items: [],
|
||||||
search: '', // search cloumn model
|
search: '', // search column model
|
||||||
show: {
|
show: {
|
||||||
item_selected: false,
|
item_selected: false,
|
||||||
item_list: false,
|
item_list: false,
|
||||||
},
|
},
|
||||||
|
|
||||||
form: {},
|
form: {},
|
||||||
add_new: {
|
add_new: {
|
||||||
text: this.addNew.text,
|
text: this.addNew.text,
|
||||||
@ -266,9 +269,18 @@ export default {
|
|||||||
},
|
},
|
||||||
|
|
||||||
onInput() {
|
onInput() {
|
||||||
|
//to optimize performance we kept the condition that checks for if search exists or not
|
||||||
if (!this.search) {
|
if (!this.search) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
//condition that checks if input is below the given character limit
|
||||||
|
if (this.search.length < this.searchCharLimit) {
|
||||||
|
this.setItemList(this.items); //once the user deletes the search input, we show the overall item list
|
||||||
|
this.sortItems(); // we order it as wanted
|
||||||
|
this.$emit('input', this.search); // keep the input binded to v-model
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
window.axios.get(url + '/common/items?search="' + this.search + '" limit:10')
|
window.axios.get(url + '/common/items?search="' + this.search + '" limit:10')
|
||||||
.then(response => {
|
.then(response => {
|
||||||
@ -496,13 +508,6 @@ export default {
|
|||||||
this.setItemList(this.items);
|
this.setItemList(this.items);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
},
|
|
||||||
|
|
||||||
created() {
|
|
||||||
this.setItemList(this.items);
|
|
||||||
},
|
|
||||||
|
|
||||||
computed: {
|
|
||||||
sortItems() {
|
sortItems() {
|
||||||
this.item_list.sort(function (a, b) {
|
this.item_list.sort(function (a, b) {
|
||||||
var nameA = a.value.toUpperCase(); // ignore upper and lowercase
|
var nameA = a.value.toUpperCase(); // ignore upper and lowercase
|
||||||
@ -520,9 +525,21 @@ export default {
|
|||||||
return 0;
|
return 0;
|
||||||
});
|
});
|
||||||
|
|
||||||
return this.item_list.filter(item => {
|
const sortedItemList = this.item_list.filter(item =>
|
||||||
return item.value.toLowerCase().includes(this.search.toLowerCase())
|
item.value.toLowerCase().includes(this.search.toLowerCase())
|
||||||
});
|
);
|
||||||
|
|
||||||
|
return sortedItemList;
|
||||||
|
},
|
||||||
|
},
|
||||||
|
|
||||||
|
created() {
|
||||||
|
this.setItemList(this.items);
|
||||||
|
},
|
||||||
|
|
||||||
|
computed: {
|
||||||
|
sortedItems() {
|
||||||
|
return this.sortItems();
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -68,6 +68,7 @@
|
|||||||
text-amount="{{ $textAmount }}"
|
text-amount="{{ $textAmount }}"
|
||||||
is-sale-price="{{ $isSalePrice }}"
|
is-sale-price="{{ $isSalePrice }}"
|
||||||
is-purchase-price="{{ $isPurchasePrice }}"
|
is-purchase-price="{{ $isPurchasePrice }}"
|
||||||
|
search-char-limit="{{ $searchCharLimit }}"
|
||||||
notes-setting="{{ $notesSetting }}"
|
notes-setting="{{ $notesSetting }}"
|
||||||
/>
|
/>
|
||||||
|
|
||||||
|
@ -77,6 +77,7 @@
|
|||||||
type="{{ $type }}"
|
type="{{ $type }}"
|
||||||
is-sale="{{ $isSalePrice }}"
|
is-sale="{{ $isSalePrice }}"
|
||||||
is-purchase="{{ $isPurchasePrice }}"
|
is-purchase="{{ $isPurchasePrice }}"
|
||||||
|
search-char-limit="{{ $searchCharLimit }}"
|
||||||
/>
|
/>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
|
@ -44,6 +44,7 @@
|
|||||||
text-amount="{{ $textAmount }}"
|
text-amount="{{ $textAmount }}"
|
||||||
is-sale-price="{{ $isSalePrice }}"
|
is-sale-price="{{ $isSalePrice }}"
|
||||||
is-purchase-price="{{ $isPurchasePrice }}"
|
is-purchase-price="{{ $isPurchasePrice }}"
|
||||||
|
search-char-limit="{{ $searchCharLimit }}"
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<x-documents.form.totals
|
<x-documents.form.totals
|
||||||
|
@ -6,6 +6,7 @@
|
|||||||
price="{{ $price }}"
|
price="{{ $price }}"
|
||||||
:dynamic-currency="currency"
|
:dynamic-currency="currency"
|
||||||
:items="{{ json_encode($items) }}"
|
:items="{{ json_encode($items) }}"
|
||||||
|
:search-char-limit="{{ $searchCharLimit }}"
|
||||||
@item="onSelectedItem($event)"
|
@item="onSelectedItem($event)"
|
||||||
add-item-text="{{ trans('general.form.add_an', ['field' => trans_choice('general.items', 1)]) }}"
|
add-item-text="{{ trans('general.form.add_an', ['field' => trans_choice('general.items', 1)]) }}"
|
||||||
create-new-item-text="{{ trans('general.title.create', ['type' => trans_choice('general.items', 1)]) }}"
|
create-new-item-text="{{ trans('general.title.create', ['type' => trans_choice('general.items', 1)]) }}"
|
||||||
|
Reference in New Issue
Block a user