Source: components/filter/filter-result/filter-result-element/search-result-panels.js

import jQ from "jquery";
import BaseComponent from "../../../base-component";
import Settings from "../../../../helpers/settings";
import Utils from "../../../../helpers/utils";
import Selector from "../../../../helpers/selector";
import Labels from "../../../../helpers/labels";
import SearchResultPanelItem from "./search-result-panel-item";
import Class from "../../../../helpers/class";

/**
 * Search result panels
 * @extends BaseComponent
 */
class SearchResultPanels extends BaseComponent {
	/**
	 * @constructs
	 */
	constructor() {
		super();
		this.$element = jQ(Selector.searchTopPanels);
		this.data = null;
		this.panelItems = [];
		this.eventType = 'init';
		// Selectors of Search page panel
		this.selector = {
			products: Selector.products,
			collections: Selector.collections,
			pages: Selector.pages,
			filterTree: Selector.filterTree,
			filterTreeMobileButton: Selector.filterTreeMobileButton,
			pagination: Selector.pagination,
			loadMore: Selector.loadMore,
			btnLoadPreviousPageWrapperSelector: Selector.btnLoadPreviousPageWrapperSelector,
			searchPanelsProductShow: Selector.searchPanelsProductShow,
			searchPanelsCollectionShow: Selector.searchPanelsCollectionShow,
			searchPanelsPageShow: Selector.searchPanelsPageShow
		};
		// Settings of Search page panel
		this.settings = {
			searchPanelDefault: Settings.getSettingValue('search.searchPanelDefault'),
			searchPanelList: Settings.getSettingValue('search.searchPanelList'),
			searchPanelBlocks: Settings.getSettingValue('search.searchPanelBlocks'),
		};
		this.isFetchedFilterData = false;
	}

	/**
	 * Return whether or not a search panel is activated
	 */
	static isPanelActive(panel) {
		return !Utils.isSearchPage() || SearchResultPanels.getPanelActive() == panel;
	}

	/**
	 * Get the active panel of Search panels
	 */
	static getPanelActive() {
		if (Globals.hasOwnProperty('searchDisplay') && Object.values(SearchResultPanelItem.Enum).indexOf(Globals.searchDisplay) > -1) {
			return Globals.searchDisplay;
		} else {
			return Settings.getSettingValue('search.searchPanelDefault');
		}
	}

	/**
	 * Initialize the search result panels component
	 * @todo: Add search result panels (Products / Collections / Pages) for search page.
	 */
	init() {
		this.panelItems = [];
		this.settings.searchPanelList.forEach((panelSlug) => {
			var panelBlock = this.settings.searchPanelBlocks[panelSlug];
			var panelItem = new SearchResultPanelItem(panelBlock, panelSlug);
			// Add component
			this.addComponent(panelItem);
			this.panelItems.push(panelItem);
		});
	}

	/**
	 * Returns whether or not the rebots meta tag is rendered
	 */
	isRender() {
		// FIXME: Dont use this.eventType == 'init', because need to update the product count when filtering
		return Utils.isSearchPage() && this.isFetchedFilterData;
	}

	/**
	 * Add meta[content="noindex,nofollow"] to head tag if the pf_xxx params is a part of a URL]
	 */
	render() {
		// Render search result panels
		var $panels = [];
		var numberPanelsActive = 0;
		this.panelItems.forEach(panel => {
			$panels.push(panel.$element);
			if (panel.isRendered) numberPanelsActive++;
		});
		this.$element.html($panels);

		// Show the active panel
		var activePanel = SearchResultPanels.getPanelActive();
		switch (activePanel) {
			case SearchResultPanelItem.Enum.COLLECTION:
				this.showPanelCollection();
				break;
			case SearchResultPanelItem.Enum.PAGE:
				this.showPanelPage();
				break;
			default:
				this.showPanelProduct();
		}
		// Add class baseon number of panels
		this.$element.addClass('boost-pfs-search-panel-items-' + numberPanelsActive);
	}

	/**
	 * Hide the products panel content
	 */
	hidePanelProduct() {
		jQ(this.selector.products).addClass(Class.hidden);
		jQ(this.selector.filterTreeMobileButton).addClass(Class.hidden);
		jQ(this.selector.filterTree).addClass(Class.hidden);
		jQ(this.selector.pagination).addClass(Class.hidden);
		jQ(this.selector.loadMore).addClass(Class.hidden);
		jQ(this.selector.btnLoadPreviousPageWrapperSelector).addClass(Class.hidden);
		jQ(this.selector.searchPanelsProductShow).addClass(Class.hidden);
	}

	/**
	 * Hide the collections panel content
	 */
	hidePanelCollection() {
		jQ(this.selector.collections).parent().addClass(Class.hidden);
		jQ(this.selector.searchPanelsCollectionShow).addClass(Class.hidden);
	}
	
	/**
	 * Hide the pages panel content
	 */
	hidePanelPage() {
		jQ(this.selector.pages).parent().addClass(Class.hidden);
		jQ(this.selector.searchPanelsPageShow).addClass(Class.hidden);
	}

	/**
	 * Hide the Products panel content
	 */
	showPanelProduct() {
		// Hide collection panel content
		this.hidePanelCollection();
		// Hide Page panel content
		this.hidePanelPage();
		// Show product panel content
		jQ(this.selector.products).removeClass(Class.hidden);
		jQ(this.selector.filterTree).removeClass(Class.hidden);
		jQ(this.selector.filterTreeMobileButton).removeClass(Class.hidden);
		jQ(this.selector.pagination).removeClass(Class.hidden);
		jQ(this.selector.loadMore).removeClass(Class.hidden);
		jQ(this.selector.btnLoadPreviousPageWrapperSelector).removeClass(Class.hidden);
		jQ(this.selector.searchPanelsProductShow).removeClass(Class.hidden);
	}

	/**
	 * Show the collections panel content
	 */
	showPanelCollection() {
		// Hide product panel content
		this.hidePanelProduct();
		// Hide page panel content
		this.hidePanelPage();
		// Show collection panel content
		jQ(this.selector.collections).parent().removeClass(Class.hidden);
		jQ(this.selector.searchPanelsCollectionShow).removeClass(Class.hidden);
	}

	/**
	 * Show the pages panel content
	 */
	showPanelPage() {
		// Hide product panel content
		this.hidePanelProduct();
		// Hide collection panel content
		this.hidePanelCollection();
		// Show page panel content
		jQ(this.selector.pages).parent().removeClass(Class.hidden);
		jQ(this.selector.searchPanelsPageShow).removeClass(Class.hidden);
	}

	/**
	 * Set data fpr Search result panel
	 * @param {Object} data - The filter result data
	 * @param {String} eventType - The event type of search (init, page, sort, etc)
	 */
	setData(data, eventType) {
		this.isFetchedFilterData = true;
		if (data) {
			this.data = data;
		}
		this.eventType = eventType;
		
		// Add search result panel item
		this.panelItems.forEach((panelItem) => {
			panelItem.setData(data, eventType);
		});
	}
}

export default SearchResultPanels;