AnonSec Shell
Server IP : 85.193.89.191  /  Your IP : 3.149.245.245
Web Server : Apache
System : Linux 956367-cx40159.tmweb.ru 3.10.0-1160.105.1.el7.x86_64 #1 SMP Thu Dec 7 15:39:45 UTC 2023 x86_64
User : bitrix ( 600)
PHP Version : 8.1.27
Disable Function : NONE
MySQL : OFF  |  cURL : OFF  |  WGET : ON  |  Perl : ON  |  Python : ON  |  Sudo : ON  |  Pkexec : ON
Directory :  /home/bitrix/www/bitrix/js/ui/menu-configurable/src/

Upload File :
current_dir [ Writeable ] document_root [ Writeable ]

 

Command :


[ HOME ]     

Current File : /home/bitrix/www/bitrix/js/ui/menu-configurable/src/menu-configurable.js
import {Runtime, Dom, Type, Loc} from 'main.core';
import {EventEmitter, BaseEvent} from 'main.core.events';
import {Menu as MainMenu, MenuManager} from 'main.popup';
import type {MenuItemOptions} from "main.popup";
import {Draggable} from 'ui.draganddrop.draggable';

export type Parameters = {
	id: string,
	items: Item[],
	bindElement: ?HTMLElement,
	maxVisibleItems: ?number,
}

export type Item = {
	isHidden: boolean,
	text: ?string,
	html: ?string,
	id: ?string,
	onclick: ?Function,
}

export class Menu extends EventEmitter
{
	#id: string;
	#items: Array;
	#menu: MainMenu;
	#bindElement: ?HTMLElement;
	#draggable: Draggable;
	#promise: Promise;
	#closeResolver: Function;
	#maxVisibleItems: number = 0;

	constructor(parameters: Parameters)
	{
		super();

		this.#id = Type.isStringFilled(parameters.id) ? parameters.id : 'settings-popup-' + Math.random().toString().substring(2);
		this.#items = parameters.items;
		this.#bindElement = parameters.bindElement;
		this.#maxVisibleItems = Number(parameters.maxVisibleItems);
		this.#createMenu();

		this.setEventNamespace('BX.UI.MenuConfigurable.Menu');
	}

	open(bindElement: ?HTMLElement): Promise
	{
		if (bindElement)
		{
			this.#menu?.getPopupWindow().setBindElement(bindElement);
		}
		this.#menu?.show();

		if (!this.#promise)
		{
			this.#promise = new Promise((resolve) => {
				this.#closeResolver = resolve;
			});
		}

		return this.#promise;
	}

	#resolveWithCancel(): void
	{
		this.#promise = null;
		if (this.#closeResolver)
		{
			this.#closeResolver({isCanceled: true});
		}
		this.#closeResolver = null;
	}

	#resolveWithItems(): void
	{
		this.#promise = null;
		if (this.#closeResolver)
		{
			this.#closeResolver({items: this.#items});
		}
		this.#closeResolver = null;
	}

	close(): void
	{
		this.#createMenu();
		this.#resolveWithCancel();
	}

	setItems(items: Item[]): this
	{
		this.#items = items;

		return this;
	}

	#getItemById(id: string): ?Item
	{
		return this.#items.find(item => item.id === id);
	}

	getItemsFromMenu(): Item[]
	{
		const items = [];
		let isHidden = false;

		this.#menu.itemsContainer.querySelectorAll('.menu-configurable-item').forEach((node: HTMLElement) => {
			if (node.classList.contains('menu-configurable-hidden-section-title'))
			{
				isHidden = true;
			}
			const itemId = node.dataset.id;
			const item = this.#getItemById(itemId);
			if (item)
			{
				const clonedItem = Runtime.clone(item);
				clonedItem.isHidden = isHidden;
				items.push(clonedItem);
			}
		});

		return items;
	}

	#createMenu(bindElement: ?HTLMElement): Menu
	{
		if (this.#menu)
		{
			this.#menu.destroy();
			this.#draggable = null;
		}

		const menuItems = [];
		menuItems.push(this.#getVisibleSectionTitleItem());
		const visibleItems = this.#items.filter(item => !item.isHidden);
		const hiddenItems = this.#items.filter(item => item.isHidden);
		visibleItems.forEach((item) => {
			menuItems.push(this.#getMenuItem(item));
		});
		menuItems.push(this.#getHiddenSectionTitleItem());
		hiddenItems.forEach((item) => {
			menuItems.push(this.#getMenuItem(item));
		});
		menuItems.push(this.#getSaveItem());
		menuItems.push(this.#getCancelItem());

		this.#menu = MenuManager.create({
			id: this.#id,
			items: menuItems,
			bindElement: bindElement ?? this.#bindElement,
			events: {
				onClose: this.close.bind(this),
			}
		});

		this.#initDraggable();

		return this.#menu;
	}

	#getSaveItem(): MenuItemOptions
	{
		return {
			text: Loc.getMessage('UI_JS_MENU_CONFIGURABLE_SAVE'),
			onclick: this.#save.bind(this),
		}
	}

	#getCancelItem(): MenuItemOptions
	{
		return {
			text: Loc.getMessage('UI_JS_MENU_CONFIGURABLE_CANCEL'),
			onclick: this.#cancel.bind(this),
		}
	}

	#save(): void
	{
		const event = new BaseEvent();
		this.emit('Save', event);
		if (event.isDefaultPrevented())
		{
			return;
		}

		this.#saveItemsFromMenu();
		this.#resolveWithItems();
		this.#createMenu();
	}

	#cancel(): void
	{
		const event = new BaseEvent();
		this.emit('Cancel', event);
		if (event.isDefaultPrevented())
		{
			return;
		}

		this.close();
	}

	#getMenuItem(item: Item): MenuItemOptions
	{
		return {
			id: item.id,
			text: item.text,
			html: item.html,
			className: 'menu-configurable-item',
			dataset: {
				id: item.id,
			},
		}
	}

	#getVisibleSectionTitleItem(): MenuItemOptions
	{
		return {
			delimiter: true,
			html: '<span>' + Loc.getMessage('UI_JS_MENU_CONFIGURABLE_VISIBLE') + '</span>',
			className: 'menu-configurable-visible-section-title menu-configurable-delimiter-item',
		}
	}

	#getHiddenSectionTitleItem(): MenuItemOptions
	{
		return {
			delimiter: true,
			html: '<span>' + Loc.getMessage('UI_JS_MENU_CONFIGURABLE_HIDDEN') + '</span>',
			className: 'menu-configurable-hidden-section-title menu-configurable-delimiter-item menu-configurable-item',
		}
	}

	#initDraggable(): void
	{
		this.#draggable = new Draggable({
			container: this.#menu.itemsContainer,
			draggable: '.menu-configurable-item',
			dragElement: '.menu-popup-item-icon',
			type: Draggable.MOVE,
		});
		this.#draggable.subscribe('end', this.#adjustMaxVisibleItems.bind(this));
	}

	#saveItemsFromMenu(): void
	{
		this.setItems(this.getItemsFromMenu());
	}

	#getItemNode(item: Item): ?HTMLElement
	{
		return this.#menu.itemsContainer.querySelector('.menu-configurable-item[data-id="' + item.id + '"]');
	}

	#getHiddenSectionTitleNode(): ?HTMLElement
	{
		return this.#menu.itemsContainer.querySelector('.menu-configurable-hidden-section-title');
	}

	#adjustMaxVisibleItems(): void
	{
		if (this.#maxVisibleItems <= 0)
		{
			return;
		}

		const runtimeItems = this.getItemsFromMenu();
		const visibleItems = runtimeItems.filter(item => !item.isHidden);
		const visibleItemsCount = visibleItems.length;
		const hiddenSectionTitleNode = this.#getHiddenSectionTitleNode();
		if (hiddenSectionTitleNode && visibleItemsCount > this.#maxVisibleItems)
		{
			for (let index = this.#maxVisibleItems; index < visibleItemsCount; index++)
			{
				const item = visibleItems[index];
				const node = this.#getItemNode(item);
				if (node)
				{
					Dom.insertAfter(node, hiddenSectionTitleNode);
				}
			}
		}
	}
}

Anon7 - 2022
AnonSec Team