403Webshell
Server IP : 80.87.202.40  /  Your IP : 216.73.216.169
Web Server : Apache
System : Linux rospirotorg.ru 5.14.0-539.el9.x86_64 #1 SMP PREEMPT_DYNAMIC Thu Dec 5 22:26:13 UTC 2024 x86_64
User : bitrix ( 600)
PHP Version : 8.2.27
Disable Function : NONE
MySQL : OFF |  cURL : ON |  WGET : ON |  Perl : ON |  Python : OFF |  Sudo : ON |  Pkexec : ON
Directory :  /home/bitrix/ext_www/rospirotorg.ru/bitrix/js/catalog/store-selector/src/

Upload File :
current_dir [ Writeable] document_root [ Writeable]

 

Command :


[ Back ]     

Current File : /home/bitrix/ext_www/rospirotorg.ru/bitrix/js/catalog/store-selector/src/store-search-input.js
import {ajax, Browser, Cache, Dom, Event, Loc, Tag, Text, Type} from 'main.core';
import {Dialog} from 'ui.entity-selector';
import './component.css';
import {StoreSelector} from 'catalog.store-selector';
import 'ui.notification';
import {SelectorErrorCode} from "./selector-error-code";

export class StoreSearchInput
{
	selector: StoreSelector;
	cache = new Cache.MemoryCache();
	inputName: String;
	isEnabledDetailLink: Boolean;
	allowCreateItem: Boolean;
	disableByRights: Boolean;
	disabledHint: ?String;

	constructor(id, options = {})
	{
		this.id = id || Text.getRandom();
		this.selector = options.selector;
		if (!(this.selector instanceof StoreSelector))
		{
			throw new Error('Store selector instance not found.');
		}

		this.isEnabledDetailLink = options.isEnabledDetailLink;
		this.inputName = options.inputName || '';
		this.allowCreateItem = options.allowCreateItem !== undefined ? options.allowCreateItem : true;
		this.disableByRights = options.disableByRights ?? false;
		this.disabledHint = options.disabledHint ?? Loc.getMessage('CATALOG_STORE_SELECTOR_HAS_PERMISSION_VIEW_STORES_HINT');
	}

	getId()
	{
		return this.id;
	}

	toggleIcon(icon, value)
	{
		if (Type.isDomNode(icon))
		{
			Dom.style(icon, 'display', value);
		}
	}

	getNameBlock(): HTMLElement
	{
		if (this.disableByRights)
		{
			return Tag.render`
				<div
					class="ui-ctl ui-ctl-w100 ui-ctl-before-icon ui-ctl-after-icon ui-ctl-disabled"
					data-hint="${this.disabledHint}"
					data-hint-no-icon
				>
					<div class="ui-ctl-before catalog-store-field-input-access-denied-lock"></div>
					<div class="ui-ctl-after catalog-store-field-input-access-denied-hint"></div>
					<div class="ui-ctl-element">${Loc.getMessage('CATALOG_STORE_SELECTOR_HAS_PERMISSION_VIEW_STORES_TITLE')}</div>
				</div>
			`
		}

		return this.cache.remember('nameBlock', () => {
			return Tag.render`
				<div class="ui-ctl ui-ctl-textbox ui-ctl-w100">
					${this.getNameInput()}
					${this.getHiddenNameInput()}
				</div>
			`;
		});
	}

	getNameInput(): HTMLInputElement
	{
		return this.cache.remember('nameInput', () => {
			return Tag.render`
				<input type="text"
					class="ui-ctl-element ui-ctl-textbox"
					autocomplete="off"
					value="${Text.encode(this.selector.getStoreTitle())}"
					placeholder="${Text.encode(this.getPlaceholder())}"
					title="${Text.encode(this.selector.getStoreTitle())}"
					onchange="${this.handleNameInputHiddenChange.bind(this)}"
				>
			`;
		});
	}

	getHiddenNameInput(): HTMLInputElement
	{
		return this.cache.remember('hiddenNameInput', () => {
			return Tag.render`
				<input
				 	type="hidden"
					name="${Text.encode(this.inputName)}"
					value="${Text.encode(this.selector.getStoreTitle())}"
				>
			`;
		});
	}

	handleNameInputHiddenChange(event: UIEvent)
	{
		this.getHiddenNameInput().value = event.target.value;
	}

	getClearIcon(): HTMLElement
	{
		return this.cache.remember('closeIcon', () => {
			return Tag.render`
				<button
					class="ui-ctl-after ui-ctl-icon-clear"
					onclick="${this.handleClearIconClick.bind(this)}"
				></button>
			`;
		});
	}

	getArrowIcon(): HTMLElement
	{
		return this.cache.remember('arrowIcon', () => {
			return Tag.render`
				<a
					href="${this.selector.getDetailPath()}"
					target="_blank"
					class="ui-ctl-after ui-ctl-icon-forward"
				></button>
			`;
		});
	}

	getSearchIcon(): HTMLElement
	{
		return this.cache.remember('searchIcon', () => {
			return Tag.render`
				<button
					class="ui-ctl-after ui-ctl-icon-search"
					onclick="${this.handleSearchIconClick.bind(this)}"
				></button>
			`;
		});
	}

	clearInputCache()
	{
		this.cache.delete('dialog');
		this.cache.delete('nameBlock');
		this.cache.delete('nameInput');
		this.cache.delete('hiddenNameInput');
	}

	clearDialogCache()
	{
		this.cache.delete('dialog');
	}

	layout(): HTMLElement
	{
		this.clearInputCache();
		const block = Tag.render`<div class="ui-ctl ui-ctl-w100 ui-ctl-after-icon"></div>`;

		Dom.append(this.getSearchIcon(), block)
		this.toggleIcon(this.getSearchIcon(), 'none');

		Dom.append(this.getClearIcon(), block)
		this.toggleIcon(this.getClearIcon(), 'none');

		if (this.showDetailLink() && Type.isStringFilled(this.selector.getStoreTitle()))
		{
			this.toggleIcon(this.getArrowIcon(), 'block');
			Dom.append(this.getArrowIcon(), block)
		}
		else
		{
			this.toggleIcon(this.getSearchIcon(), 'block');
		}

		Event.bind(this.getNameInput(), 'click', this.handleNameInputClick.bind(this));
		Event.bind(this.getNameInput(), 'input', this.handleNameInput.bind(this));
		Event.bind(this.getNameInput(), 'blur', this.handleNameInputBlur.bind(this));
		Event.bind(this.getNameInput(), 'keydown', this.handleNameInputKeyDown.bind(this));

		Dom.append(this.getNameBlock(), block);
		BX.UI.Hint.init(block);

		return block;
	}

	handleNameInputClick(event: UIEvent)
	{
		this.searchInDialog(event.target.value);
		this.handleIconsSwitchingOnNameInput(event);
	}

	handleNameInput(event: UIEvent)
	{
		if (!Type.isStringFilled(event.target.value))
		{
			this.selector.onClear();

			return;
		}

		this.searchInDialog(event.target.value);
		this.handleIconsSwitchingOnNameInput(event);
	}

	showDetailLink(): string
	{
		return this.isEnabledDetailLink;
	}

	getDialog(): ?Dialog
	{
		return this.cache.remember('dialog', () => {
			const stubOptions = {
				title: Tag.message`${'CATALOG_STORE_SELECTOR_IS_EMPTY_TITLE'}`,
			};
			if (this.allowCreateItem)
			{
				stubOptions.subtitle = Tag.message`${'CATALOG_STORE_SELECTOR_IS_EMPTY_SUBTITLE'}`;
				stubOptions.arrow = true;
			}

			const params = {
				id: this.id + '_store',
				height: 300,
				context: 'catalog-store',
				targetNode: this.getNameInput(),
				enableSearch: false,
				multiple: false,
				dropdownMode: true,
				searchTabOptions: {
					stubOptions,
					stub: true,
				},
				events: {
					'Item:onSelect': this.onStoreSelect.bind(this),
					'onSearch': this.onSearch.bind(this),
					'Search:onItemCreateAsync': this.createStore.bind(this),
				},
				entities: [
					{
						id: 'store',
						options: {
							productId: this.selector.getProductId(),
						},
						searchFields: [
							{ name: 'subtitle', type: 'string', system: true, searchable: false },
						],
						dynamicLoad: true,
						dynamicSearch: true,
					}
				],
				searchOptions: {
					allowCreateItem: this.allowCreateItem
				},
			};

			return new Dialog(params);
		});
	}

	handleNameInputKeyDown(event: KeyboardEvent): void
	{
		const dialog = this.getDialog();
		if (event.key === 'Enter' && dialog.getActiveTab() === dialog.getSearchTab())
		{
			// prevent a form submit
			event.preventDefault();

			if ((Browser.isMac() && event.metaKey) || event.ctrlKey)
			{
				dialog.getSearchTab().getFooter().createItem();
			}
		}
	}

	handleIconsSwitchingOnNameInput(event: UIEvent): void
	{
		this.toggleIcon(this.getArrowIcon(), 'none');

		if (Type.isStringFilled(event.target.value))
		{
			this.toggleIcon(this.getClearIcon(), 'block');
			this.toggleIcon(this.getSearchIcon(), 'none');
		}
		else
		{
			this.toggleIcon(this.getClearIcon(), 'none');
			this.toggleIcon(this.getSearchIcon(), 'block');
		}
	}

	handleClearIconClick(event: UIEvent)
	{
		this.selector.onClear();

		event.stopPropagation();
		event.preventDefault();
	}

	focusName()
	{
		requestAnimationFrame(() => this.getNameInput().focus());
	}

	searchInDialog(searchQuery: string = '')
	{
		const dialog = this.getDialog();
		if (dialog)
		{
			dialog.show();
			dialog.search(searchQuery);
		}
	}

	handleShowSearchDialog(event: UIEvent)
	{
		this.searchInDialog(event.target.value);
	}

	handleNameInputBlur(event: UIEvent)
	{
		// timeout to toggle clear icon handler while cursor is inside of name input
		setTimeout(() => {
			this.toggleIcon(this.getClearIcon(), 'none');

			if (this.showDetailLink() && Type.isStringFilled(this.selector.getStoreTitle()))
			{
				this.toggleIcon(this.getSearchIcon(), 'none');
				this.toggleIcon(this.getArrowIcon(), 'block');
			}
			else
			{
				this.toggleIcon(this.getArrowIcon(), 'none');
				this.toggleIcon(this.getSearchIcon(), 'block');
			}
		}, 200);

		if (this.selector.isDisabledEmpty())
		{
			setTimeout(() => {
				if (this.selector.getStoreId() === '')
				{
					this.selector.setEmptyError();
				}
				else
				{
					this.selector.clearErrorLayout();
					this.selector.clearEmptyError();
				}
			}, 200);
		}
	}

	handleSearchIconClick(event: UIEvent)
	{
		this.searchInDialog();
		this.focusName();

		event.stopPropagation();
		event.preventDefault();
	}

	onSearch(event)
	{
		const { query } = event.getData();
		if (query === '' || query === this.selector.getStoreTitle())
		{
			event.target?.searchTab?.getFooter()?.hide();
		}
		else
		{
			event.target?.searchTab?.getFooter()?.show();
		}
	}

	onStoreSelect(event)
	{
		const item = event.getData().item;
		item.getDialog().getTargetNode().value = item.getTitle();

		if (this.selector)
		{
			this.selector.onStoreSelect(item.getId(), item.getTitle());
		}
		this.toggleIcon(this.getSearchIcon(), 'none');
		this.selector.clearLayout();
		this.selector.layout();

		this.cache.delete('dialog');
	}

	createStore(event): Promise
	{
		const {searchQuery} = event.getData();
		const name = searchQuery.getQuery();

		return new Promise(
			(resolve, reject) => {
				if (!Type.isStringFilled(name))
				{
					reject();
					return;
				}

				const dialog: Dialog = event.getTarget();
				dialog.showLoader();
				ajax.runAction(
						'catalog.storeSelector.createStore',
						{
							json: {name}
						}
					)
					.then(response => {
						dialog.hideLoader();
						const id = Text.toInteger(response.data.id);
						const item = dialog.addItem({
							id,
							entityId: 'store',
							title: name,
							tabs: dialog.getRecentTab().getId(),
						});

						if (item)
						{
							item.select();
						}

						dialog.hide();
						resolve();
					})
					.catch(response => {
						console.error(response);
						reject();
					})
				;
			});
	}

	getPlaceholder(): string
	{
		return Loc.getMessage('CATALOG_STORE_SELECTOR_BEFORE_SEARCH_TITLE');
	}

	disable(hint: string|null): void
	{
		this.disableByRights = true;
		if (hint)
		{
			this.disabledHint = hint;
		}
	}
}

Youez - 2016 - github.com/yon3zu
LinuXploit