Your IP : 3.129.247.57


Current Path : /var/www/www-root/data/www/monolith-realty.ru/bitrix/js/ui/entity-selector/src/dialog/tabs/
Upload File :
Current File : /var/www/www-root/data/www/monolith-realty.ru/bitrix/js/ui/entity-selector/src/dialog/tabs/tab.js

import { Type, Tag, Dom, Cache, Reflection } from 'main.core';
import ItemNode from '../../item/item-node';
import Dialog from '../dialog';
import BaseStub from './base-stub';
import DefaultStub from './default-stub';
import BaseHeader from '../header/base-header';
import BaseFooter from '../footer/base-footer';
import TextNode from '../../common/text-node';
import encodeUrl from '../../common/encode-url';

import type { TabLabelState, TabLabelStates, TabOptions } from './tab-options';
import type { HeaderContent, HeaderOptions } from '../header/header-content';
import type { FooterContent, FooterOptions } from '../footer/footer-content';
import type { TextNodeOptions } from '../../common/text-node-options';

/**
 * @memberof BX.UI.EntitySelector
 */
export default class Tab
{
	id: string = null;
	title: ?TextNode = null;
	rootNode: ItemNode = null;

	dialog: Dialog = null;
	stub: BaseStub = null;

	visible: boolean = true;
	rendered: boolean = false;
	locked: boolean = false;
	selected: boolean = false;
	hovered: boolean = false;

	icon: TabLabelStates = {};
	textColor: TabLabelStates = {};
	bgColor: TabLabelStates = {};

	itemMaxDepth: number = 5;

	header: BaseHeader = null;
	showDefaultHeader = true;
	footer: BaseFooter = null;
	showDefaultFooter = true;
	showAvatars: ?boolean = null;
	cache = new Cache.MemoryCache();

	constructor(dialog: Dialog, tabOptions: TabOptions)
	{
		const options: TabOptions = Type.isPlainObject(tabOptions) ? tabOptions : {};

		if (!Type.isStringFilled(options.id))
		{
			throw new Error('EntitySelector.Tab: "id" parameter is required.');
		}

		this.setDialog(dialog);
		this.id = options.id;
		this.showDefaultHeader = options.showDefaultHeader !== false;
		this.showDefaultFooter = options.showDefaultFooter !== false;

		this.rootNode = new ItemNode(null, { itemOrder: options.itemOrder });
		this.rootNode.setTab(this);

		this.setVisible(options.visible);
		this.setTitle(options.title);
		this.setItemMaxDepth(options.itemMaxDepth);
		this.setIcon(options.icon);
		this.setTextColor(options.textColor);
		this.setBgColor(options.bgColor);
		this.setStub(options.stub, options.stubOptions);
		this.setHeader(options.header, options.headerOptions);
		this.setFooter(options.footer, options.footerOptions);
		this.setShowAvatars(options.showAvatars);
	}

	getId(): string
	{
		return this.id;
	}

	/**
	 * @internal
	 */
	setDialog(dialog: Dialog): void
	{
		this.dialog = dialog;
	}

	getDialog(): Dialog
	{
		return this.dialog;
	}

	getStub(): ?BaseStub
	{
		return this.stub;
	}

	setStub(stub?: boolean | string | Function, stubOptions?: { [option: string]: any }): void
	{
		let instance = null;
		const options = Type.isPlainObject(stubOptions) ? stubOptions : {};

		if (Type.isString(stub) || Type.isFunction(stub))
		{
			const className = Type.isString(stub) ? Reflection.getClass(stub) : stub;
			if (Type.isFunction(className))
			{
				instance = new className(this, options);
				if (!(instance instanceof BaseStub))
				{
					console.error('EntitySelector: stub is not an instance of BaseStub.');
					instance = null;
				}
			}
		}

		if (!instance && stub !== false)
		{
			instance = new DefaultStub(this, options);
		}

		this.stub = instance;
	}

	getHeader(): ?BaseHeader
	{
		return this.header;
	}

	setHeader(headerContent: ?HeaderContent, headerOptions?: HeaderOptions)
	{
		/** @var {BaseHeader} */
		let header = null;
		if (headerContent !== null)
		{
			header = Dialog.createHeader(this, headerContent, headerOptions);
			if (header === null)
			{
				return;
			}
		}

		if (this.isRendered() && this.getHeader() !== null)
		{
			Dom.remove(this.getHeader().getContainer());
			this.getDialog().adjustHeader();
		}

		this.header = header;

		if (this.isRendered())
		{
			this.getDialog().appendHeader(header);
			this.getDialog().adjustHeader();
		}
	}

	canShowDefaultHeader(): boolean
	{
		return this.showDefaultHeader;
	}

	enableDefaultHeader(): void
	{
		this.showDefaultHeader = true;
		this.getDialog().adjustHeader();
	}

	disableDefaultHeader(): void
	{
		this.showDefaultHeader = false;
		this.getDialog().adjustHeader();
	}

	getFooter(): ?BaseFooter
	{
		return this.footer;
	}

	setFooter(footerContent: ?FooterContent, footerOptions?: FooterOptions)
	{
		/** @var {BaseFooter} */
		let footer = null;
		if (footerContent !== null)
		{
			footer = Dialog.createFooter(this, footerContent, footerOptions);
			if (footer === null)
			{
				return;
			}
		}

		if (this.isRendered() && this.getFooter() !== null)
		{
			Dom.remove(this.getFooter().getContainer());
			this.getDialog().adjustFooter();
		}

		this.footer = footer;

		if (this.isRendered())
		{
			this.getDialog().appendFooter(footer);
			this.getDialog().adjustFooter();
		}
	}

	canShowDefaultFooter(): boolean
	{
		return this.showDefaultFooter;
	}

	enableDefaultFooter(): void
	{
		this.showDefaultFooter = true;
		this.getDialog().adjustFooter();
	}

	disableDefaultFooter(): void
	{
		this.showDefaultFooter = false;
		this.getDialog().adjustFooter();
	}

	setShowAvatars(flag: ?boolean): void
	{
		if (Type.isBoolean(flag) || flag === null)
		{
			this.showAvatars = flag;

			if (this.isRendered())
			{
				this.renderContainer();
			}
		}
	}

	shouldShowAvatars(): boolean
	{
		return this.showAvatars ?? this.getDialog().shouldShowAvatars();
	}

	getRootNode(): ItemNode
	{
		return this.rootNode;
	}

	setTitle(title: ?string | TextNodeOptions): void
	{
		if (Type.isStringFilled(title) || Type.isPlainObject(title) || title === null)
		{
			this.title = title === null ? null : new TextNode(title);

			if (this.isRendered())
			{
				this.renderLabel();
			}
		}
	}

	getTitle(): string
	{
		const titleNode = this.getTitleNode();

		return titleNode !== null && !titleNode.isNullable() ? titleNode.getText() : '';
	}

	getTitleNode(): TextNode | null
	{
		return this.title;
	}

	setIcon(icon: TabLabelStates | string): void
	{
		return this.setProperty('icon', icon);
	}

	getIcon(state?: TabLabelState): ?string
	{
		return this.getPropertyByState('icon', state);
	}

	setBgColor(bgColor: TabLabelStates | string): void
	{
		return this.setProperty('bgColor', bgColor);
	}

	getBgColor(state?: TabLabelState): ?string
	{
		return this.getPropertyByState('bgColor', state);
	}

	setTextColor(textColor: TabLabelStates | string): void
	{
		return this.setProperty('textColor', textColor);
	}

	getTextColor(state?: TabLabelState): ?string
	{
		return this.getPropertyByState('textColor', state);
	}

	/**
	 * @private
	 */
	setProperty(name: string, states: TabLabelStates | string): void
	{
		const property = this[name];
		if (!property)
		{
			return;
		}

		if (Type.isPlainObject(states))
		{
			Object.keys(states).forEach(state => {
				if (Type.isStringFilled(states[state]))
				{
					property[state] = states[state];
				}
			});
		}
		else if (Type.isStringFilled(states))
		{
			property['default'] = states;
		}
	}

	/**
	 * @private
	 */
	getPropertyByState(name: string, state?: TabLabelState): ?string
	{
		const property = this[name];
		const labelState = Type.isStringFilled(state) ? state : 'default';

		if (!Type.isUndefined(property) && !Type.isUndefined(property[labelState]))
		{
			return property[labelState];
		}

		return null;
	}

	/**
	 * @private
	 */
	getPropertyByCurrentState(name: string): ?string
	{
		const property = this[name];
		if (this.isSelected() && this.isHovered() && property.selectedHovered)
		{
			return property.selectedHovered;
		}
		else if (this.isSelected() && property.selected)
		{
			return property.selected;
		}
		else if (this.isHovered() && property.hovered)
		{
			return property.hovered;
		}
		else if (property.default)
		{
			return property.default;
		}

		return null;
	}

	setItemMaxDepth(depth: number): void
	{
		if (Type.isNumber(depth) && depth > 0)
		{
			this.itemMaxDepth = depth;
		}
	}

	getItemMaxDepth(): number
	{
		return this.itemMaxDepth;
	}

	getContainer(): HTMLElement
	{
		return this.cache.remember('container', () => {
			return Tag.render`
				<div class="ui-selector-tab-content">${this.getItemsContainer()}</div>
			`;
		});
	}

	getLabelContainer(): HTMLElement
	{
		return this.cache.remember('label', () => {
			const className = this.isVisible() ? '' : ' ui-selector-tab-label-hidden';
			return Tag.render`
				<div
					class="ui-selector-tab-label${className}"
					onclick="${this.handleLabelClick.bind(this)}"
					onmouseenter="${this.handleLabelMouseEnter.bind(this)}"
					onmouseleave="${this.handleLabelMouseLeave.bind(this)}"
				>
					${this.getIconContainer()}
					${this.getTitleContainer()}
				</div>
			`;
		});
	}

	getIconContainer(): HTMLElement
	{
		return this.cache.remember('icon', () => {
			return Tag.render`
				<div class="ui-selector-tab-icon"></div>
			`;
		});
	}

	getTitleContainer(): HTMLElement
	{
		return this.cache.remember('title', () => {
			return Tag.render`
				<div class="ui-selector-tab-title"></div>
			`;
		});
	}

	getItemsContainer(): HTMLElement
	{
		return this.cache.remember('items', () => {
			return Tag.render`
				<div class="ui-selector-items"></div>
			`;
		});
	}

	render(): void
	{
		this.getRootNode().render();
		this.rendered = true;
	}

	/** @internal **/
	renderLabel(): void
	{
		Dom.style(this.getTitleContainer(), 'color', this.getPropertyByCurrentState('textColor'));
		Dom.style(this.getLabelContainer(), 'background-color', this.getPropertyByCurrentState('bgColor'));

		const icon = this.getPropertyByCurrentState('icon');
		Dom.style(this.getIconContainer(), 'background-image', icon ? `url('${encodeUrl(icon)}')` : null);

		const titleNode = this.getTitleNode();
		if (titleNode)
		{
			this.getTitleNode().renderTo(this.getTitleContainer());
		}
		else
		{
			this.getTitleContainer().textContent = '';
		}
	}

	/** @internal **/
	renderContainer(): void
	{
		const className = 'ui-selector-tab-content--hide-avatars';
		if (this.shouldShowAvatars())
		{
			Dom.removeClass(this.getContainer(), className);
		}
		else
		{
			Dom.addClass(this.getContainer(), className);
		}
	}

	isVisible(): boolean
	{
		return this.visible;
	}

	setVisible(flag: boolean): void
	{
		if (Type.isBoolean(flag))
		{
			this.visible = flag;

			if (this.isRendered())
			{
				if (this.visible)
				{
					Dom.remove(this.getLabelContainer(), 'ui-selector-tab-label-hidden');
				}
				else
				{
					Dom.addClass(this.getLabelContainer(), 'ui-selector-tab-label-hidden');
				}
			}
		}
	}

	isRendered(): boolean
	{
		return this.rendered && this.getDialog() && this.getDialog().isRendered();
	}

	/**
	 * @internal
	 */
	select(): void
	{
		if (this.isSelected())
		{
			return;
		}

		Dom.addClass(this.getContainer(), 'ui-selector-tab-content-active');
		if (this.isVisible())
		{
			Dom.addClass(this.getLabelContainer(), 'ui-selector-tab-label-active');
			this.renderLabel();
		}

		this.selected = true;

		if (this.isVisible())
		{
			this.renderLabel();
		}

		if (this.getHeader())
		{
			this.getHeader().show();
		}

		if (this.getFooter())
		{
			this.getFooter().show();
		}

		this.getDialog().emit('Tab:onSelect', { tab: this });
	}

	/**
	 * @internal
	 */
	deselect(): void
	{
		if (!this.isSelected())
		{
			return;
		}

		Dom.removeClass(this.getContainer(), 'ui-selector-tab-content-active');
		if (this.isVisible())
		{
			Dom.removeClass(this.getLabelContainer(), 'ui-selector-tab-label-active');
		}

		this.selected = false;

		if (this.isVisible())
		{
			this.renderLabel();
		}

		if (this.getHeader())
		{
			this.getHeader().hide();
		}

		if (this.getFooter())
		{
			this.getFooter().hide();
		}

		this.getDialog().emit('Tab:onDeselect', { tab: this	});
	}

	hover(): void
	{
		if (this.isHovered())
		{
			return;
		}

		Dom.addClass(this.getLabelContainer(), 'ui-selector-tab-label-hover');
		this.hovered = true;

		this.renderLabel();
	}

	unhover(): void
	{
		if (!this.isHovered())
		{
			return;
		}

		Dom.removeClass(this.getLabelContainer(), 'ui-selector-tab-label-hover');
		this.hovered = false;

		this.renderLabel();
	}

	isSelected(): boolean
	{
		return this.selected;
	}

	isHovered(): boolean
	{
		return this.hovered;
	}

	lock(): void
	{
		this.locked = true;
		Dom.addClass(this.getContainer(), 'ui-selector-tab-content-locked');
	}

	unlock(): void
	{
		this.locked = false;
		Dom.removeClass(this.getContainer(), 'ui-selector-tab-content-locked');
	}

	isLocked(): boolean
	{
		return this.locked;
	}

	handleLabelClick(): void
	{
		this.getDialog().selectTab(this.getId());
	}

	handleLabelMouseEnter(): void
	{
		this.hover();
	}

	handleLabelMouseLeave(): void
	{
		this.unhover();
	}
}