Newer
Older
smart-home-server / webclient / src / js / components / screens / areas / areas-placeto-component.js
@Eugene Sukhodolskiy Eugene Sukhodolskiy 1 day ago 5 KB Bugfixes. Webclient. DataProvider
let selector, container, loadedAreas, currentParentAreaId, sh_api, type;
const typeMap = {
	area: "areas",
	device: "devices",
	action: "scripts"
};

function setServerCurrentSelectedAreaName() {
	const currentAreaDisplayContainer = selector.querySelector(".current-area");

	const found = loadedAreas.find(area => area.id == currentParentAreaId);
	currentAreaDisplayContainer.innerHTML = found
		? found.display_name
		: `Area ID ${currentParentAreaId}`;

	autoDisplayingRmParentIdBtn();
}

function removeParentAreaId(targetId) {
	sh_api[typeMap[type]].unassign_from_area(targetId, (err, resp, meta) => {
		console.log(`sh_api[${typeMap[type]}].unassign_from_area`, err, resp, meta);

		if(!resp || resp.data.status) {
			return Toasts.createError(
				`Error of unassigning`,
				(!resp) ? `Error of request` : resp.data.error_alias
			).show();
		}

		DataProvider.invalidate("raw.areas.list");

		currentParentAreaId = 0;
		setServerCurrentSelectedAreaName();
		hidePlaceInAreaSelector();

		Toasts.createSuccess(
			`Successfully unassigning`,
			`Successfully unassigning`
		).show();

		Screens.reinit();
	});
}

function placeInAreaRequest(sh_api, payload) {
	sh_api[typeMap[type]].place_in_area(
		payload, 
		(err, resp, meta) => {
			console.log("sh_api.areas.place_in_area", err, resp, meta);

			if(!resp) {
				return console.error("Component placeInArea", err, resp, meta);
			}

			if(!resp.status) {
				return console.error("Component placeInArea", err, resp, meta);
			}

			const currentAreaDisplayContainer = selector.querySelector(".current-area");

			DataProvider.invalidate("raw.areas.list");

			Toasts.createSuccess(
				`Successfully applied`,
				`Successfully applied`
			).show();

			currentParentAreaId = payload.place_in_area_id;
			setServerCurrentSelectedAreaName();
			hidePlaceInAreaSelector();

			Screens.reinit();

			console.log("Success", resp);
		}
	);
}

function loadAreasList(targetId, changePlaceCb) {
	DataProvider.getOrFetch(
		"raw.areas.list",
		(cb) => sh_api.areas.list((err, resp) => cb(err, resp?.data)),
		(err, data) => {
			if(!data) {
				return console.error("sh_api.areas.list", err);
			}

			loadedAreas = data.areas;

			setServerCurrentSelectedAreaName();

			const areas = {};
			for(let item of data.areas) {
				if(type == "area" && item.id == targetId) {
					continue;
				}

				areas[item.id] = item.display_name;
			}

			const advs = advancedSelect(
				selector.querySelector(".select-area"),
				areas,
				"Nothing found"
			);
			selector.querySelector(".advanced-select-container").append(advs);

			advs.advancedSelect.addEventListener("changed", self => {
				changePlaceCb(self, data.areas);
			});

			container.innerHTML = "";
			container.append(selector);
		}
	);
}

function hidePlaceInAreaSelector() {
	const formContainer = selector.querySelector(".form-container");
	formContainer.classList.remove("a-show");
	formContainer.classList.add("a-hide");
	setTimeout(() => formContainer.classList.remove("a-hide"), 300);
}

function autoDisplayingRmParentIdBtn() {
	const btn = selector.querySelector(".remove-parent-id");
	if(currentParentAreaId == 0) {
		btn.classList.add("d-none");
	} else {
		btn.classList.remove("d-none");
	}
}

/**
 * Поместить девайс, экшн или area в другой area
 * @param  {[type]} sh_api 
 * @param  {[type]} container Сюда мы поместим ui для выбора area
 * @param  {string} type area | device | action
 * @param  {int} targetId ID цели, которую будем помещать в area
 */
export function placeInArea(_sh_api, _container, _type, targetId, _currentParentAreaId) {
	sh_api = _sh_api;
	container = _container;
	currentParentAreaId = _currentParentAreaId;
	type = _type;

	selector = document.createElement("div");
	selector.classList.add("component");
	selector.classList.add("place-in-area-component");
	selector.innerHTML = `
		<span class="current-area"></span>
		<button class="btn-icon without-hover remove-parent-id"><i class="ph ph-backspace"></i></button>
		<button class="btn btn-primary with-icon show-place-in-area">
			<i class="ph ph-map-pin-line"></i>
			Place In Area
		</button>
		<div class="block form-group form-container">
			<button class="btn-icon hide-place-in-area">
				<i class="ph ph-x"></i>
			</button>
			<label class="label">
				Select Area
				<i class="ph ph-magnifying-glass"></i>
				<input type="text" class="input select-area" placeholder="Search">
			</label>
			<div class="advanced-select-container"></div>
		</div>
	`;
	
	loadAreasList(targetId, (advSelect, areasList) => {
		const value = advSelect.advancedSelect.value();
		if(!value.isOption) {
			return ;
		}

		const areaId = Object.keys(value.option)[0];
		const payload = { 
			target_id: targetId, 
			place_in_area_id: areaId 
		}

		placeInAreaRequest(sh_api, payload);
	});

	const formContainer = selector.querySelector(".form-container");

	selector.querySelector("button.show-place-in-area").addEventListener("click", e => {
		if(formContainer.classList.contains("a-show")) {
			formContainer.classList.remove("a-show");
			formContainer.classList.add("a-hide");
			setTimeout(() => formContainer.classList.remove("a-hide"), 300);
		} else {
			formContainer.classList.add("a-show");
		}
	});

	selector.querySelector("button.hide-place-in-area").addEventListener("click", e => {
		hidePlaceInAreaSelector();
	});

	selector.querySelector("button.remove-parent-id").addEventListener("click", e => {
		removeParentAreaId(targetId);
	});
}