Source: components/filter/filter-result/filter-result-element/search-result-panel-item.js

import jQ from "jquery";
import BaseComponent from "../../../base-component";
import Labels from "../../../../helpers/labels";
import Globals from "../../../../helpers/globals";
import Class from "../../../../helpers/class";
import SearchResultPanels from "./search-result-panels";
import FilterApi from "../../../../api/filter-api";
import ProductPaginationDefault from "./pagination/product-pagination-default";

/**
 * Search result panel item
 * @extends BaseComponent
 */
class SearchResultPanelItem extends BaseComponent {
	/**
	 * @constructs
	 */
	constructor(panelBlock, type) {
		super();
		this.$element = null;
		this.data = panelBlock;
		this.type = type;
		this.eventType = 'init';
		this.isRenderPanelContent = false;
		this.limit = 25;
		this.page = 1;
		this.active = panelBlock.active;

		// Set the panel limit by pageSize, exclude the product panel
		if (this.type == SearchResultPanelItem.Enum.PRODUCT) {
			this.limit = Settings.getSettingValue('general.limit');
			this.page = Globals.queryParams.page;
		} else if (panelBlock.hasOwnProperty('pageSize')) {
			this.limit = parseInt(panelBlock.pageSize);
		}
	}

	/**
	 * Get Enum of Search result panel item
	 */
	static get Enum() {
		return {
			COLLECTION: 'collections',
			PRODUCT: 'products',
			PAGE: 'pages'
		}
	}
	/**
	 * Get the rebots meta tag for document head
	 * @requires {String} Raw html template
	 */
	getTemplate() {
		return `
			<li class="{{class.searchResultPanelItem}}">
				<button>{{panelItemLabel}} ({{panelItemCount}})</button>
			</li>
		`;
	}

	/**
	 * Replace the brackets in raw html template with proper values
	 * @returns {String} HTML string
	 */
	compileTemplate() {
		// Get the label of search result panel item
		var defaultLabel = '';
		switch(this.type) {
			case SearchResultPanelItem.Enum.COLLECTION:
				defaultLabel = Labels.search.searchPanelCollection;
				break;
			case SearchResultPanelItem.Enum.PAGE:
				defaultLabel = Labels.search.searchPanelPage;
				break;
			default:
				defaultLabel = Labels.search.searchPanelProduct;
		}
		var label = this.data.hasOwnProperty('label') ? this.data.label : defaultLabel;

		return this.getTemplate()
			.replace(/{{panelItemLabel}}/g, label)
			.replace(/{{panelItemCount}}/g, this.totalResult)
			.replace(/{{class.searchResultPanelItem}}/g, Class.searchResultPanelItem);
	}

	/**
	 * Returns whether or not the search result panel item is activated
	 * @returns {Boolean} TRUE or FALSE
	 */
	isActive() {
		return SearchResultPanels.isPanelActive(this.type);
	}

	/**
	 * Returns whether or not the search result panel item is rendered
	 * - Products: Always render after API callback.
	 * - Collection, Pages: Just render on first load
	 * @returns {Boolean} TRUE or FALSE
	 */
	isRender() {
		return this.type == SearchResultPanelItem.Enum.PRODUCT 
			|| (this.active && this.totalResult && this.eventType == 'init');
	}

	/**
	 * Render the search result panels
	 */
	render() {
		this.$element = jQ(this.compileTemplate());
		if (this.isActive()) {
			this.$element.addClass('boost-active');
		}
	}

	/**
	 * Bind the events on the Search result panel item
	 */
	bindEvents() {
		if (this.$element) {
			this.$element.on('click', this._onClickPanelItem.bind(this));
		}
	}

	/**
	 * Set data fpr Search result panel
	 * @param {Object} data - The filter result data
	 */
	setData(data, eventType) {
		var total = 0;
		this.eventType = eventType;
		switch (this.type) {
			case SearchResultPanelItem.Enum.COLLECTION:
				total = data.total_collection;
				break;
			case SearchResultPanelItem.Enum.PAGE:
				total = data.total_page;
				break;
			default:
				total = data.total_product;
		}
		this.totalResult = total;

		if (this.type == SearchResultPanelItem.Enum.PRODUCT) {
			this.page = Globals.queryParams.page;
		}
	}

	/**
	 * Bind click event on search result panel item
	 * @private
	 */
	_onClickPanelItem(event) {
		event.preventDefault();
		// Set global data
		Globals.searchDisplay = this.type;
		FilterApi.setParam('limit', this.limit);
		FilterApi.setParam('page', this.page);

		var panalList = this.parent;
		var filterResult = panalList.parent;
		var searchResultTotal = filterResult.searchResultTotal;
		
		if (!this.isRenderPanelContent && this.type !== SearchResultPanelItem.Enum.PRODUCT) {
			FilterApi.getFilterData('search', this._searchPanelCallback.bind(this));
		}
		// Active the current item 
		this.$element.addClass('boost-active');
		this.$element.siblings().removeClass('boost-active');

		switch (this.type) {
			case SearchResultPanelItem.Enum.COLLECTION:
				panalList.showPanelCollection();
				break;
			case SearchResultPanelItem.Enum.PAGE:
				panalList.showPanelPage();
				break;
			default:
				panalList.showPanelProduct();
		}
		// Update search result total
		searchResultTotal.setData(this.totalResult, this.type);
		searchResultTotal.refresh();

		// Update toolbar URL
		this.isRenderPanelContent = true;
	}

	/**
	 * Build Collection list, Page list after open collection panel, page panel
	 * @param {Object} data - Search result data
	 */
	_searchPanelCallback(data) {
		var panelContent = this.parent.parent.collectionList;
		var pagination = this.parent.parent.collectionListPagination;
		var totalPage = data.hasOwnProperty('total_collection') ? data.total_collection : false;
		if (Globals.searchDisplay === SearchResultPanelItem.Enum.PAGE) {
			panelContent = this.parent.parent.pageList;
			pagination = this.parent.parent.pageListPagination;
			totalPage = data.hasOwnProperty('total_page') ? data.total_page : false;
		}
		
		panelContent.setData(data);
		panelContent.refresh();

		pagination.setData(data, totalPage, this.limit, this.page);
		pagination.refresh();
	}
}

export default SearchResultPanelItem;