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/calendar/sync/interface/src/syncwizard/

Upload File :
current_dir [ Writeable] document_root [ Writeable]

 

Command :


[ Back ]     

Current File : /home/bitrix/ext_www/rospirotorg.ru/bitrix/js/calendar/sync/interface/src/syncwizard/syncwizard.js
// @flow

'use strict';

import { Cache, Dom, Event, Loc, Tag, Text, Type } from 'main.core';
import { Util } from 'calendar.util';
import { Entry } from 'calendar.entry';
import { EventEmitter } from 'main.core.events';

export default class SyncWizard extends EventEmitter
{
	TYPE = 'undefined';
	SLIDER_NAME = 'calendar:sync-wizard-slider';
	SLIDER_WIDTH = 450;
	LOADER_NAME = "calendar:loader";
	cache = new Cache.MemoryCache();
	syncStagesList = [];
	accountName = '';
	HELPDESK_CODE = 11828176;
	MIN_UPDATE_STATE_DELAY = 1500; // in ms
	CONFETTI_DELAY = 1000;

	constructor(options = {})
	{
		super();
		this.setEventNamespace('BX.Calendar.Sync.Interface.SyncWizard');

		this.BX = window.top.BX || window.BX;

		this.pullWizardEventHandler = this.handlePullNewEvent.bind(this);
		this.lastUpdateStateTimestamp = Date.now();
		this.logoIconClass = '';

		this.mode = Type.isStringFilled(options.mode) ? this.getValidatedMode(options.mode) : 'default';
	}

	getValidatedMode(mode: string): string
	{
		if (['default', 'reconnect'].includes(mode))
		{
			return mode;
		}

		return 'default';
	}

	openSlider()
	{
		const content = this.getContent();
		if (this.mode !== 'reconnect')
		{
			BX.SidePanel.Instance.open(this.SLIDER_NAME, {
				contentCallback: (slider) => {
					return new Promise((resolve, reject) => {
						resolve(content);
					});
				},
				allowChangeHistory: false,
				events: {
					onLoad: () => {
						this.displaySyncStages();
						this.bindButtonsHandlers();
					},
					onDestroy: this.handleCloseWizard.bind(this),
				},
				cacheable: false,
				width: this.SLIDER_WIDTH,
				loader: this.LOADER_NAME,
			});
		}

		this.slider = BX.SidePanel.Instance.getTopSlider();
		this.syncIsFinished = false;
		this.errorStatus = false;
	}

	getContent()
	{
		return Tag.render`
			<div class="calendar-sync__wrapper calendar-sync__scope">
				<div class="calendar-sync__content --border-radius">
					<div class="calendar-sync__content-block --space-bottom">
						${this.getTitleWrapper()}
						${this.getSyncStagesWrapper()}
						${this.getInfoStatusWrapper()}
						${this.getErrorWrapper()}
						${this.getFinalCheckWrapper()}
						${this.getHelpLinkWrapper()}
						${this.getButtonWrapper()}
					</div>
				</div>
			</div>
		`;
	}

	getTitleWrapper()
	{
		this.syncTitleWrapper = Tag.render`
			<div class="calendar-sync__account">
				<div class="calendar-sync__account-logo">
					<div class="calendar-sync__account-logo--image ${this.getLogoIconClass()}"></div>
				</div>
				<div class="calendar-sync__account-content">
					${this.getAccountNameNode()}
					<div class="calendar-sync__account-info">
						<div class="calendar-sync__account-info--icon --animate"></div>
						${this.getActiveStatusNode()}
					</div>
				</div>
			</div>
		`;
		return this.syncTitleWrapper;
	}

	getSyncStagesWrapper()
	{
		this.syncStagesWrapper = Tag.render`<div class="calendar-sync-stages-wrap"></div>`;
		return this.syncStagesWrapper;
	}

	getInfoStatusWrapper()
	{
		this.infoStatusWrapper = Tag.render`
			<div class="calendar-sync__content-block --space-bottom-xl" style="display: none;">
				<div class="calendar-sync__notification">
					<div class="calendar-sync__notification-title">${Loc.getMessage('CAL_INFO_STATUS_CONG_1')}</div>
					<div class="calendar-sync__notification-message">${Loc.getMessage('CAL_INFO_STATUS_CONG_2')}</div>
				</div>
			</div>
		`;
		return this.infoStatusWrapper;
	}

	getErrorWrapper()
	{
		this.errorWrapper = Tag.render`
			<div class="calendar-sync__content-block --space-bottom-xl" style="display: none;">
				<div class="calendar-sync__error">
					<div class="calendar-sync__notification-message">
						<div class="calendar-sync__notification-message-inner">
							${Loc.getMessage('CAL_ERROR_WARN_1')}
						</div>
						${Loc.getMessage('CAL_ERROR_WARN_2')}</div>
				</div>
			</div>
		`;
		return this.errorWrapper;
	}

	getHelpLinkWrapper()
	{
		this.helpLinkWrapper = Tag.render`
			<div class="calendar-sync__content-block" style="display: none;"></div>
		`;
		return this.helpLinkWrapper;
	}

	getFinalCheckWrapper()
	{
		this.finalCheckWrapper = Tag.render`
			<div class="calendar-sync__content-block" style="display: none;"></div>
		`;
		return this.finalCheckWrapper;
	}

	getButtonWrapper()
	{
		this.buttonWrapper = Tag.render`
			<div style="display: none" class="calendar-sync__content-block --align-center">
				<a class="ui-btn ui-btn-lg ui-btn-primary ui-btn-round" data-role="continue_btn">
					${Loc.getMessage('CAL_BUTTON_CONTINUE')}
				</a>
				<a style="display: none" class="ui-btn ui-btn-lg ui-btn-light-border ui-btn-round" data-role="everything_is_fine_btn">
					${Loc.getMessage('CAL_BUTTON_EVERYTHING_IS_FINE')}
				</a>
				<a style="display: none" class="ui-btn ui-btn-lg ui-btn-light-border ui-btn-round" data-role="close_button">
					${Loc.getMessage('CAL_ERROR_CLOSE')}
				</a>
			</div>
		`;

		return this.buttonWrapper;
	}

	getNewEventCardWrapper()
	{
		this.newEventCardWrapper = Tag.render`
			<div class="calendar-sync__content-block --space-bottom" style="display: none;"></div>
		`;
		return this.newEventCardWrapper;
	}

	getSkeletonWrapper()
	{
		this.skeletonWrapper = Tag.render`
			<div class="calendar-sync__content-block --space-bottom">
					<div class="calendar-sync__balloon --skeleton">
						<div class="calendar-sync__balloon__skeleton-box">
							<div class="calendar-sync__balloon__skeleton-inline-box">
								<div class="calendar-sync__balloon__skeleton-circle"></div>
								<div class="calendar-sync__balloon__skeleton-line"></div>
							</div>
							<div class="calendar-sync__balloon__skeleton-line"></div>
						</div>
						<div class="calendar-sync__content-text">${this.getSkeletonTitle()}</div>
					</div>
				</div>
		`;
		return this.skeletonWrapper;
	}

	getSkeletonTitle()
	{
		return '';
	}

	getExtraInfoWithCheckIcon()
	{
		const alreadyConnected = Object.values(this.connectionsProviders).filter(item => {
			return item.mainPanel && item.status;
		}).length > 0;

		return Tag.render`
			<div class="calendar-sync__content-text --icon-check${(alreadyConnected ? ' --disabled' : '')}">
				${Loc.getMessage('CAL_SYNC_INFO_PROMO')}
			</div>
		`;
	}

	getAccountNameNode()
	{
		if (!Type.isElementNode(this.accountNameNode))
		{
			this.accountNameNode = Tag.render`
			<div class="calendar-sync__account-title">${this.getAccountName()}</div>
		`;
		}
		return this.accountNameNode;
	}

	setAccountName(value)
	{
		this.accountName = value;
	}

	getAccountName()
	{
		return this.accountName;
	}

	getActiveStatusNode()
	{
		if (!Type.isElementNode(this.activeStatusNode))
		{
			this.activeStatusNode = Tag.render`
				<span class="calendar-active-status-node-carousel">
					<span class="calendar-active-status-node-phrase">
						${Loc.getMessage('CAL_STATUS_SYNC_IN_PROGRESS')}
					</span>
				</span>
			`;

			this.startStatusCarousel(this.activeStatusNode);
		}

		return this.activeStatusNode;
	}

	startStatusCarousel(statusNode)
	{
		const progressStatuses = [
			Loc.getMessage('CAL_STATUS_SYNC_IN_PROGRESS_STATUSES_FIRST'),
			Loc.getMessage('CAL_STATUS_SYNC_IN_PROGRESS_STATUSES_SECOND')
		];

		let dotCycle = 1;

		this.statusCarouselInterval = setInterval(() => {
			const currentPhraseNode = statusNode.firstElementChild;
			if (this.countDots(currentPhraseNode.innerText) < 3)
			{
				currentPhraseNode.innerText += '.';
				statusNode.style.width = (currentPhraseNode.offsetWidth + 1) + 'px';
				return;
			}
			if (dotCycle < 2)
			{
				dotCycle++;
				currentPhraseNode.innerText = currentPhraseNode.innerText.slice(0, -3);
				return;
			}
			dotCycle = 1;

			if (progressStatuses.length > 0)
			{
				const status = progressStatuses.shift();
				this.animateNextStatus(statusNode, status);
			}
			else
			{
				const almostDoneStatus = Loc.getMessage('CAL_STATUS_SYNC_IN_PROGRESS_ALMOST_DONE');
				this.animateNextStatus(statusNode, almostDoneStatus);
				statusNode.style.width = '';
				clearInterval(this.statusCarouselInterval);
			}
		}, 900);
	}

	animateNextStatus(carousel, phraseText)
	{
		const currentPhraseNode = carousel.firstElementChild;
		const nextPhraseNode = Tag.render`
			<span class="calendar-active-status-node-phrase">${phraseText}</span>
		`;
		carousel.append(nextPhraseNode);

		const maxWidth = Math.max(nextPhraseNode.offsetWidth, currentPhraseNode.offsetWidth);
		carousel.style.width = (maxWidth + 1) + 'px';

		currentPhraseNode.style.transition = ''; // turn on animation
		currentPhraseNode.style.transform = `translateX(-${currentPhraseNode.offsetWidth}px)`;
		nextPhraseNode.style.transform = `translateX(-${currentPhraseNode.offsetWidth}px)`;

		setTimeout(() => {
			currentPhraseNode.remove();
			nextPhraseNode.style.transition = 'none'; // turn off animation
			nextPhraseNode.style.transform = '';
		}, 300);
	}

	countDots(string)
	{
		return (string.match(/\./g) || []).length;
	}

	setSyncStages()
	{
		this.syncStagesList = [];
	}

	getSyncStages()
	{
		return this.syncStagesList;
	}

	getHelpDeskCode()
	{
		return this.HELPDESK_CODE;
	}

	displaySyncStages()
	{
		Dom.clean(this.syncStagesWrapper);
		this.getSyncStages().forEach(stage => {
			stage.renderTo(this.syncStagesWrapper);
		});
	}

	bindButtonsHandlers()
	{
		const continueButton = this.buttonWrapper.querySelector('.ui-btn[data-role="continue_btn"]');
		if (Type.isElementNode(continueButton))
		{
			Event.bind(continueButton, 'click', this.handleContinueButtonClick.bind(this));
		}

		const eifButton = this.buttonWrapper.querySelector('.ui-btn[data-role="everything_is_fine_btn"]');
		if (Type.isElementNode(eifButton))
		{
			Event.bind(eifButton, 'click', this.handleFinalCloseButtonClick.bind(this));
		}
	}

	handleContinueButtonClick()
	{
		this.showFinalStage();
	}

	showFinalStage()
	{
		this.syncIsFinished = true;

		const eifButton = this.buttonWrapper.querySelector('.ui-btn[data-role="everything_is_fine_btn"]');
		if (Type.isElementNode(eifButton))
		{
			eifButton.style.display = '';
		}

		const continueButton = this.buttonWrapper.querySelector('.ui-btn[data-role="continue_btn"]');
		if (Type.isElementNode(continueButton))
		{
			continueButton.style.display = 'none';
		}

		this.showFinalCheckWrapper();
		this.showHelpLinkWrapper();
		this.hideSyncStagesWrapper();
		this.hideInfoStatusWrapper();

		Util.getBX().Event.EventEmitter.subscribe(
			'onPullEvent-calendar',
			this.pullWizardEventHandler
		);

		this.emit('startWizardWaitingMode');
	}

	isSyncFinished()
	{
		return this.syncIsFinished;
	}

	handleFinalCloseButtonClick()
	{
		BX.SidePanel.Instance.getOpenSliders().forEach(slider =>
		{
			if (['calendar:sync-slider', 'calendar:section-slider', this.SLIDER_NAME].includes(slider.getUrl()))
			{
				slider.close();
			}
		});
	}

	handleUpdateState(stateData)
	{
		const currentTimestamp = Date.now();
		if (currentTimestamp - this.lastUpdateStateTimestamp > this.MIN_UPDATE_STATE_DELAY)
		{
			this.updateState(stateData);
		}
		else
		{
			setTimeout(() => {
				this.handleUpdateState(stateData);
			}, this.MIN_UPDATE_STATE_DELAY);
		}
	}

	updateState(stateData)
	{
		if (this.errorStatus)
		{
			return;
		}

		if (stateData.stage === 'connection_created'
			&& stateData.accountName
			&& Type.isElementNode(this.accountNameNode)
		)
		{
			this.setAccountName(stateData.accountName);
			this.accountNameNode.innerHTML = Text.encode(stateData.accountName)
		}

		this.lastUpdateStateTimestamp = Date.now();
	}

	setActiveStatusFinished()
	{
		this.activeStatusNode.style.width = '';
		clearInterval(this.statusCarouselInterval);
		this.syncIsFinished = true;
		if (Type.isElementNode(this.activeStatusNode))
		{
			this.activeStatusNode.innerHTML = Text.encode(Loc.getMessage('CAL_STATUS_SYNC_SUCCESS').toUpperCase())
			Dom.remove(this.syncTitleWrapper.querySelector('.calendar-sync__account-info--icon'));
		}
	}

	showButtonWrapper()
	{
		if (Type.isElementNode(this.buttonWrapper))
		{
			this.buttonWrapper.style.display = '';
		}
	}

	hideButtonWrapper()
	{
		if (Type.isElementNode(this.buttonWrapper))
		{
			this.buttonWrapper.style.display = 'none';
		}
	}

	showInfoStatusWrapper()
	{
		if (Type.isElementNode(this.infoStatusWrapper))
		{
			this.infoStatusWrapper.style.display = '';
		}
	}

	hideInfoStatusWrapper()
	{
		if (Type.isElementNode(this.infoStatusWrapper))
		{
			this.infoStatusWrapper.style.display = 'none';
		}
	}

	showErrorWrapper()
	{
		if (Type.isElementNode(this.errorWrapper))
		{
			this.errorWrapper.style.display = '';
		}
	}

	hideErrorWrapper()
	{
		if (Type.isElementNode(this.errorWrapper))
		{
			this.errorWrapper.style.display = 'none';
		}
	}

	showFinalCheckWrapper()
	{
		if (Type.isElementNode(this.finalCheckWrapper))
		{
			this.finalCheckWrapper.style.display = '';
		}
	}

	hideFinalCheckWrapper()
	{
		if (Type.isElementNode(this.finalCheckWrapper))
		{
			this.finalCheckWrapper.style.display = 'none';
		}
	}

	showSyncStagesWrapper()
	{
		if (Type.isElementNode(this.syncStagesWrapper))
		{
			this.syncStagesWrapper.style.display = '';
		}
	}

	hideSyncStagesWrapper()
	{
		if (Type.isElementNode(this.syncStagesWrapper))
		{
			this.syncStagesWrapper.style.display = 'none';
		}
	}

	showHelpLinkWrapper()
	{
		if (Type.isElementNode(this.helpLinkWrapper))
		{
			this.helpLinkWrapper.style.display = '';
		}
	}

	hideHelpLinkWrapper()
	{
		if (Type.isElementNode(this.helpLinkWrapper))
		{
			this.helpLinkWrapper.style.display = 'none';
		}
	}

	handlePullNewEvent(event)
	{
		if (event && Type.isFunction(event.getData))
		{
			const data = {
				command: event.getData()[0],
				...event.getData()[1]
			};

			if (
				data.command === 'edit_event'
				&& data.newEvent
			)
			{
				if (Type.isElementNode(this.finalCheckWrapper))
				{
					const syncBalloon = this.finalCheckWrapper.querySelector('.calendar-sync__balloon');
					if (Type.isElementNode(syncBalloon) && Dom.hasClass(syncBalloon, '--progress'))
					{
						Dom.removeClass(syncBalloon, '--progress');
						Dom.addClass(syncBalloon, '--done');
					}
				}

				const entry = new Entry({ data: data.fields });
				this.displayNewEvent(entry);

				Util.getBX().Event.EventEmitter.unsubscribe(
					'onPullEvent-calendar',
					this.pullWizardEventHandler
				);

				const eifButton = this.buttonWrapper.querySelector('.ui-btn[data-role="everything_is_fine_btn"]');
				if (Type.isElementNode(eifButton))
				{
					eifButton.innerHTML = Text.encode(Loc.getMessage('CAL_BUTTON_KEEP_GOING'));
					Dom.addClass(eifButton, 'ui-btn-primary');
					Dom.removeClass(eifButton, 'ui-btn-light-border');
				}

				this.emit('endWizardWaitingMode');
			}
		}
	}

	displayNewEvent(entry)
	{
		// Hide skeleton
		if (Type.isElementNode(this.skeletonWrapper))
		{
			Dom.remove(this.skeletonWrapper);
		}

		if (Type.isElementNode(this.newEventCardWrapper))
		{
			this.newEventCardWrapper.style.display = '';
			Dom.clean(this.newEventCardWrapper);
			this.newEventCardWrapper.appendChild(this.getNewEventCard(entry));
		}
	}

	getNewEventCard(entry)
	{
		const from = new Date(entry.from.getTime() - (parseInt(entry.data['~USER_OFFSET_FROM']) || 0) * 1000);
		const to = new Date(entry.to.getTime() - (parseInt(entry.data['~USER_OFFSET_TO']) || 0) * 1000);
		const fromTimestamp = from.getTime();
		const dateFrom = BX.date.format(Util.getDayMonthFormat(), fromTimestamp / 1000);
		const timeFrom = Util.formatTime(from.getHours(), from.getMinutes());
		const timeTo = Util.formatTime(to.getHours(), to.getMinutes());
		const timeField = entry.isFullDay()
				? Loc.getMessage('CAL_WIZARD_FULL_DAY')
				: timeFrom + ' - ' + timeTo;

		this.newEventCard = Tag.render`
			<div class="calendar-sync__balloon --calendar ${entry.isFullDay() ? '--fullday-event' : ''}">
				<div class="calendar-sync__content-text">
					${dateFrom}
					<span class="calendar-date-year">
						${BX.date.format('Y', fromTimestamp / 1000)}
					</span>
				</div>
				<div class="calendar-sync__content-text">${BX.date.format('l', fromTimestamp / 1000)}</div>
				<div class="calendar-sync__time-box">
					<div class="calendar-sync__time">
						<div class="calendar-sync__time-date">${timeFrom}</div>
						<div class="calendar-sync__time-line"></div>
					</div>
					<div class="calendar-sync__time-notification-box">
						<div class="calendar-sync__content-text">${Text.encode(entry.getName())}</div>
						<div class="calendar-sync__content-text">${timeField}</div>
					</div>
					<div class="calendar-sync__time">
						<div class="calendar-sync__time-date">${timeTo}</div>
						<div class="calendar-sync__time-line"></div>
					</div>
				</div>
			</div>
		`;

		return this.newEventCard;
	}

	handleCloseWizard()
	{
		this.slider = null;

		clearInterval(this.statusCarouselInterval);

		Util.getBX().Event.EventEmitter.unsubscribe(
			'onPullEvent-calendar',
			this.pullWizardEventHandler
		);

		this.emit('onClose');
	}

	showConfetti()
	{
		setTimeout(() => {
			const bx = Util.getBX();
			bx.UI.Confetti.fire({
				particleCount: 240,
				spread: 170,
				origin: { y: 0.3, x: 0.9 },
				zIndex: (bx.SidePanel.Instance.getTopSlider().getZindex() + 1)
			});
		}, this.CONFETTI_DELAY);
	}

	getLogoIconClass()
	{
		return this.logoIconClass;
	}

	getSlider()
	{
		return this.slider;
	}

	setErrorState()
	{
		this.errorStatus = true;
		this.showErrorWrapper();
		this.hideInfoStatusWrapper();
		this.hideSyncStagesWrapper();
		this.showButtonWrapper();
		Dom.addClass(this.syncTitleWrapper, '--error');
		if (Type.isElementNode(this.activeStatusNode))
		{
			this.activeStatusNode.innerHTML = Text.encode(Loc.getMessage('CAL_STATUS_SYNC_ERROR').toUpperCase())
		}

		const closeButton = this.buttonWrapper.querySelector('.ui-btn[data-role="close_button"]');
		if (Type.isElementNode(closeButton))
		{
			closeButton.style.display = '';
			Event.bind(closeButton, 'click', () => {
				BX.SidePanel.Instance.getOpenSliders().forEach(slider =>
				{
					if (['calendar:sync-slider', 'calendar:section-slider', this.SLIDER_NAME].includes(slider.getUrl()))
					{
						slider.close();
					}
				});
				BX.reload();
			});
		}

		const continueButton = this.buttonWrapper.querySelector('.ui-btn[data-role="continue_btn"]');
		if (Type.isElementNode(continueButton))
		{
			continueButton.style.display = 'none';
		}
	}
}

Youez - 2016 - github.com/yon3zu
LinuXploit