Your IP : 18.191.171.26


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

import { Extension, Runtime, Type } from 'main.core';
import { OrderedArray } from 'main.core.collections';

import SearchField from '../search/search-field';
import TextNode from '../common/text-node';

import type Item from '../item/item';
import type { EntityOptions } from './entity-options';
import type { SearchFieldOptions } from '../search/search-field-options';
import type { ItemBadgeOptions } from '../item/item-badge-options';
import type { EntityBadgeOptions } from './entity-badge-options';
import type { EntityFilterOptions } from "./entity-filter-options";
import EntityFilter from './entity-filter';

/**
 * @memberof BX.UI.EntitySelector
 */
export default class Entity
{
	static extensions: string[] = null;
	static defaultOptions: { [entityId: string]: { [key: string]: any } } = null;

	id: string = null;
	options: { [key: string]: any } = {};
	searchable: boolean = true;
	searchFields: OrderedArray<SearchField> = null;
	dynamicLoad: boolean = false;
	dynamicSearch: boolean = false;
	substituteEntityId: string = null;
	searchCacheLimits: RegExp[] = [];
	filters: Map<string, EntityFilter> = new Map();

	itemOptions: { [key: string]: any } = {};
	tagOptions: { [key: string]: any } = {};
	badgeOptions: ItemBadgeOptions[] = [];
	textNodes: Map<string, Map<string, TextNode>> = new Map();

	constructor(entityOptions: EntityOptions)
	{
		let options: EntityOptions = Type.isPlainObject(entityOptions) ? entityOptions : {};
		if (!Type.isStringFilled(options.id))
		{
			throw new Error('EntitySelector.Entity: "id" parameter is required.');
		}

		const defaultOptions = this.constructor.getEntityDefaultOptions(options.id) || {};
		options = Runtime.merge(JSON.parse(JSON.stringify(defaultOptions)), options);

		this.id = options.id.toLowerCase();
		this.options = Type.isPlainObject(options.options) ? options.options : {};
		this.itemOptions = Type.isPlainObject(options.itemOptions) ? options.itemOptions : {};
		this.tagOptions = Type.isPlainObject(options.tagOptions) ? options.tagOptions : {};
		this.badgeOptions = Type.isArray(options.badgeOptions) ? options.badgeOptions : [];
		this.substituteEntityId = Type.isStringFilled(options.substituteEntityId) ? options.substituteEntityId : null;

		if (Type.isArray(options.filters))
		{
			options.filters.forEach((filterOptions: EntityFilterOptions) => {
				this.addFilter(filterOptions);
			});
		}

		this.searchFields = new OrderedArray((fieldA: SearchField, fieldB: SearchField) => {
			if (fieldA.getSort() !== null && fieldB.getSort() === null)
			{
				return -1;
			}
			else if (fieldA.getSort() === null && fieldB.getSort() !== null)
			{
				return 1;
			}
			else if (fieldA.getSort() === null && fieldB.getSort() === null)
			{
				return -1;
			}
			else
			{
				return fieldA.getSort() - fieldB.getSort();
			}
		});

		this.setSearchable(options.searchable);
		this.setDynamicLoad(options.dynamicLoad);
		this.setDynamicSearch(options.dynamicSearch);
		this.setSearchFields(options.searchFields);
		this.setSearchCacheLimits(options.searchCacheLimits);
	}

	static getDefaultOptions()
	{
		if (this.defaultOptions === null)
		{
			this.defaultOptions = {};
			this.getExtensions().forEach((extension: string) => {
				const settings = Extension.getSettings(extension);
				const entities: [] = settings.get('entities', []);
				entities.forEach(entity => {
					if (Type.isStringFilled(entity.id) && Type.isPlainObject(entity.options))
					{
						this.defaultOptions[entity.id] = JSON.parse(JSON.stringify(entity.options)); // clone
					}
				});
			});
		}

		return this.defaultOptions;
	}

	static getExtensions(): string[]
	{
		if (this.extensions === null)
		{
			const settings = Extension.getSettings('ui.entity-selector');
			this.extensions = settings.get('extensions', []);
		}

		return this.extensions;
	}

	static getEntityDefaultOptions(entityId: string)
	{
		return this.getDefaultOptions()[entityId] || null;
	}

	static getItemOptions(entityId: string, entityType: string)
	{
		if (!Type.isStringFilled(entityId))
		{
			return null;
		}

		const options = this.getEntityDefaultOptions(entityId);
		const itemOptions = options && options['itemOptions'] ? options['itemOptions'] : null;

		if (Type.isUndefined(entityType))
		{
			return itemOptions;
		}
		else
		{
			return itemOptions && !Type.isUndefined(itemOptions[entityType]) ? itemOptions[entityType] : null;
		}
	}

	static getTagOptions(entityId: string, entityType?: string)
	{
		if (!Type.isStringFilled(entityId))
		{
			return null;
		}

		const options = this.getEntityDefaultOptions(entityId);
		const tagOptions = options && options['tagOptions'] ? options['tagOptions'] : null;

		if (Type.isUndefined(entityType))
		{
			return tagOptions;
		}
		else
		{
			return tagOptions && !Type.isUndefined(tagOptions[entityType]) ? tagOptions[entityType] : null;
		}
	}

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

	getOptions(): { [key: string]: any }
	{
		return this.options;
	}

	getItemOptions(): { [key: string]: any }
	{
		return this.itemOptions;
	}

	static getItemOption(entityId: string, option: string, entityType?: string): any
	{
		return this.getOptionInternal(this.getItemOptions(entityId), option, entityType);
	}

	getItemOption(option: string, entityType?: string): any
	{
		return this.constructor.getOptionInternal(this.itemOptions, option, entityType);
	}

	getTagOptions(): { [key: string]: any }
	{
		return this.tagOptions;
	}

	static getTagOption(entityId: string, option: string, entityType?: string): any
	{
		return this.getOptionInternal(this.getTagOptions(entityId), option, entityType);
	}

	getTagOption(option: string, entityType?: string): any
	{
		return this.constructor.getOptionInternal(this.tagOptions, option, entityType);
	}

	static getOptionInternal(options, option: string, type?: string): any
	{
		if (!Type.isPlainObject(options))
		{
			return null;
		}

		if (options[type] && !Type.isUndefined(options[type][option]))
		{
			return options[type][option];
		}
		else if (options['default'] && !Type.isUndefined(options['default'][option]))
		{
			return options['default'][option];
		}

		return null;
	}

	getBadges(item: Item): EntityBadgeOptions[]
	{
		const entityTypeBadges = this.getItemOption('badges', item.getEntityType()) || [];
		const badges = [...entityTypeBadges];

		this.badgeOptions.forEach((badge: EntityBadgeOptions) => {
			if (Type.isPlainObject(badge.conditions))
			{
				for (const condition in badge.conditions)
				{
					if (item.getCustomData().get(condition) !== badge.conditions[condition])
					{
						return;
					}
				}

				badges.push(badge);
			}
		});

		return badges;
	}

	getOptionTextNode(option: string, entityType?: string): ?TextNode
	{
		if (!Type.isString(option))
		{
			return null;
		}

		if (!Type.isString(entityType))
		{
			entityType = 'default';
		}

		let optionNodes = this.textNodes.get(option);
		let node = optionNodes ? optionNodes.get(entityType) : undefined;

		if (Type.isUndefined(node))
		{
			if (!optionNodes)
			{
				optionNodes = new Map();
				this.textNodes.set(option, optionNodes);
			}

			const itemOption = this.getItemOption(option, entityType);
			node = Type.isString(itemOption) || Type.isPlainObject(itemOption) ? new TextNode(itemOption) : null;

			optionNodes.set(entityType, node);
		}

		return node;
	}

	isSearchable(): boolean
	{
		return this.searchable;
	}

	setSearchable(flag: boolean): void
	{
		if (Type.isBoolean(flag))
		{
			this.searchable = flag;
		}
	}

	getSearchFields(): OrderedArray<SearchField>
	{
		return this.searchFields;
	}

	setSearchFields(searchFields: SearchFieldOptions[]): void
	{
		this.searchFields.clear();

		// Default Search Fields
		const titleField = new SearchField({ name: 'title', searchable: true, system: true, type: 'string' });
		const subtitleField = new SearchField({ name: 'subtitle', searchable: true, system: true, type: 'string' });
		this.searchFields.add(titleField);
		this.searchFields.add(subtitleField);

		// Custom Search Fields
		const customFields = Type.isArray(searchFields) ? searchFields : [];
		customFields.forEach(fieldOptions => {
			const field = new SearchField(fieldOptions);
			if (field.isSystem()) // Entity can override default fields.
			{
				// delete a default title field
				if (field.getName() === 'title')
				{
					this.searchFields.delete(titleField);
				}
				else if (field.getName() === 'subtitle')
				{
					this.searchFields.delete(subtitleField);
				}
			}

			this.searchFields.add(field);
		});

		this.searchFields.forEach((field: SearchField, index: number) => {
			field.setSort(index);
		});
	}

	setSearchCacheLimits(limits: string[]): void
	{
		if (Type.isArrayFilled(limits))
		{
			limits.forEach((limit: string) => {
				if (Type.isStringFilled(limit))
				{
					this.searchCacheLimits.push(new RegExp(limit, 'i'));
				}
			});
		}
	}

	getSearchCacheLimits(): RegExp[]
	{
		return this.searchCacheLimits;
	}

	hasDynamicLoad(): boolean
	{
		return this.dynamicLoad;
	}

	setDynamicLoad(flag: boolean): void
	{
		if (Type.isBoolean(flag))
		{
			this.dynamicLoad = flag;
		}
	}

	hasDynamicSearch(): boolean
	{
		return this.dynamicSearch;
	}

	setDynamicSearch(flag: boolean): void
	{
		if (Type.isBoolean(flag))
		{
			this.dynamicSearch = flag;
		}
	}

	getFilters(): EntityFilter[]
	{
		return Array.from(this.filters.values());
	}

	addFilters(filters: EntityFilterOptions[]): void
	{
		if (Type.isArray(filters))
		{
			filters.forEach((filterOptions: EntityFilterOptions) => {
				this.addFilter(filterOptions);
			});
		}
	}

	addFilter(filterOptions: EntityFilterOptions): void
	{
		if (Type.isPlainObject(filterOptions))
		{
			const filter = new EntityFilter(filterOptions);
			this.filters.set(filter.getId(), filter);
		}
	}

	getFilter(id: string): ?Filter
	{
		return this.filters.get(id) || null;
	}

	getSubstituteEntityId(): string | null
	{
		return this.substituteEntityId;
	}

	toJSON()
	{
		return {
			id: this.getId(),
			options: this.getOptions(),
			searchable: this.isSearchable(),
			dynamicLoad: this.hasDynamicLoad(),
			dynamicSearch: this.hasDynamicSearch(),
			filters: this.getFilters(),
			substituteEntityId: this.getSubstituteEntityId(),
		};
	}
}