import jQ from "jquery";
import BaseComponent from "../../base-component";
import Class from "../../../helpers/class";
import InstantSearchResultItemPopular from "../instant-search-item/instant-search-result-item-popular";
import InstantSearchResultItemProduct from "../instant-search-item/instant-search-result-item-product";
import InstantSearchResultItemCollection from "../instant-search-item/instant-search-result-item-collection";
import InstantSearchResultItemPage from "../instant-search-item/instant-search-result-item-page";
import InstantSearchEnum from "../../../enum/instant-search-enum";
import InstantSearchResultBlockDym from "./instant-search-result-block-dym";
import Settings from "../../../helpers/settings";
/**
* Instant search result - result block
* @extends BaseComponent
*/
class InstantSearchResultBlock extends BaseComponent {
/**
* @constructs
* @param {Object} data The result block data
* @param {String} data.type The block type
* @param {String} data.status The block status
* @param {String} data.number The max suggest items of block
* @param {String} data.label The block label
*/
constructor(data) {
super();
this.type = data.type;
this.status = data.status;
this.maxSuggesionItems = data.number;
this.label = data.label;
this.notFoundLabel = data.label;
this.isShow = false;
this.isShowDYM = false;
// init Did you mean block for product block
if (this.type && this.type === InstantSearchEnum.ResultType.PRODUCTS) {
this.blockDym = new InstantSearchResultBlockDym();
}
this.settings = {
suggesionMaxItems: Settings.getSettingValue('search.suggesionMaxItems')
}
}
/**
* Initialize the instant search result block component
* @todo: Add the instant search result item for all result block
*/
init() {
switch(this.type){
case InstantSearchEnum.ResultType.SUGGESTIONS:
// FIXME: We fix the max suggestion items by 10 to cover "No search result suggestion"
this.maxSuggesionItems = this.settings.suggesionMaxItems;
for (var i = 0; i < this.maxSuggesionItems; i++){
this.addComponent(new InstantSearchResultItemPopular());
}
break;
case InstantSearchEnum.ResultType.PRODUCTS:
// FIXME: We fix the max suggestion items by 10 to cover "No search result suggestion"
this.maxSuggesionItems = this.settings.suggesionMaxItems;
for (var i = 0; i < this.maxSuggesionItems; i++){
this.addComponent(new InstantSearchResultItemProduct());
}
break;
case InstantSearchEnum.ResultType.COLLECTIONS:
for (var i = 0; i < this.maxSuggesionItems; i++){
this.addComponent(new InstantSearchResultItemCollection());
}
break;
case InstantSearchEnum.ResultType.PAGES:
for (var i = 0; i < this.maxSuggesionItems; i++){
this.addComponent(new InstantSearchResultItemPage());
}
break;
}
}
/**
* Get the raw HTML template of instant search result block
* @param {String} [tempType] The template type <br />
* - 'dym': Get raw HTML template of Did you mean block <br />
* - Default: Get raw HTML template of instant search result block
* @default Empty
*/
getTemplate(tempType) {
switch (tempType) {
case 'dym':
return `
<li class="{{class.searchSuggestionItem}} {{class.searchSuggestion}}-dym" aria-label="Did you mean">{{dymContent}}</li>
`;
default:
return `
<li class="{{class.searchSuggestionGroup}}" data-group="{{type}}" aria-label="{{label}}">
<ul>
<li class="{{class.searchSuggestionHeader}}-{{type}} {{class.searchSuggestionHeader}}" aria-label="{{label}}">{{label}}</li>
{{resultItems}}
</ul>
</li>
`;
}
}
/**
* Replace the brackets in raw html template with proper values
* @returns {String} HTML string
*/
compileTemplate() {
if ((this.status != 'active' || !this.isShow) && !this._isShowDYM()) {
return '';
}
var label = this.isAllEmpty ? this.notFoundLabel : this.label;
return this.getTemplate()
.replace(/{{type}}/g, this.type)
.replace(/{{label}}/g, label)
.replace(/{{class.searchSuggestionHeader}}/g, Class.searchSuggestionHeader)
.replace(/{{class.searchSuggestionGroup}}/g, Class.searchSuggestionGroup)
.replace(/{{resultItems}}/g, '');
}
/**
* Render the instant search result block
* @returns {Object} jQuery object
*/
render() {
this.$element = jQ(this.compileTemplate());
// Add Did you mean block in product block
if (this.type && this.type === InstantSearchEnum.ResultType.PRODUCTS) {
this.blockDym.render();
if (this.blockDym.$element) {
this.$element = jQ(this.compileTemplate());
this.$element.find('> ul').append(this.blockDym.$element);
}
}
this.children.forEach((child) => {
if (child.$element) {
this.$element.find('> ul').append(child.$element);
}
});
}
/**
* Return whether or not the DYM of product block is shown
*/
_isShowDYM() {
return this.isShowDYM && this.type == InstantSearchEnum.ResultType.PRODUCTS;
}
/**
* Set data for Instant search result block
* @param {Object} data The result data of block
*/
setData(data, isAllEmpty) {
this.data = data;
this.isAllEmpty = isAllEmpty;
// Set block label for product, suggestion when empty result
if (data.hasOwnProperty('notFoundLabel')) {
this.notFoundLabel = data.notFoundLabel;
}
this.children.forEach((child, index) => {
if (data && data.length > index) {
child.setData(data[index]);
} else {
child.setData(null);
}
});
if (this.blockDym) {
this.blockDym.setData(this.parent.data);
this.isShowDYM = this.blockDym.isShow;
}
this.isShow = data && data.length > 0;
}
}
export default InstantSearchResultBlock;