Newer
Older
smart-home-server / webclient / src / js / components / screens / devices / devices.js
import { deviceDetailsPopup } from "./device-details-popup.js";
import { deviceSetupFormPopup } from "./device-setup-form-popup.js";

function sidebarTemplate(active) {
	return Helper.template.sidebarNav([
		{
			content: `<span class="list-label"><i class="ph ph-cpu"></i> Devices</span>`,
			route: "/#!/devices",
			is_active: active == "devices"
		},
		{
			content: `<span class="list-label"><i class="ph ph-magnifying-glass"></i> Scanning</span>`,
			route: "/#!/devices/scanning",
			is_active: active == "scanning"
		}
	]);
}


function list(sh_api) {
	return {
		alias: "devices",
		renderer: () => {
			const sidebar = sidebarTemplate("devices");

			return `
				<div class="container">
					<div class="row g-6">
						<div class="col sidebar-container">
							${sidebar}
						</div>
						<div class="col devices-container"></div>
					</div>
				</div>
			`;
		},

		initer: scr => {
			sh_api.devices.list((err, resp, meta) => {
				console.log("sh_api.devices.list", err, resp, meta);

				if(meta.status_code != 200) {
					return scr.error("Server API ERROR", "");
				}

				const preparedData = [];
				for(let device of resp.data.devices) {
					device = Helper.unification.deviceFieldsUnification(device);

					const connectionState = device.connection_state == "active"
						? `<span class="badge badge-success">Online</span>`
						: `<span class="badge badge-warning">Offline</span>`;

					preparedData.push({
						deviceName: device.name,
						alias: device.alias,
						status: connectionState,
						ip: `<code class="code">${device.ip}</code>`,
						actions: `
							<button 
								class="btn btn-secondary btn-small details-btn" 
								data-device='${JSON.stringify(device)}'
								type="button"
							>Details</button>

							<button 
								class="btn btn-warning btn-small reboot-btn" 
								data-device-id="${device.id}" 
								data-device-name="${device.name}" 
								data-device-alias="${device.alias}" 
								type="button"
							>Reboot</button>
						`
					});
				}
				
				scr.currentScreen.DOMObject.querySelector(".devices-container").innerHTML = Helper.template.table(
					"Devices list", 
					{
						deviceName: "Device name", 
						alias: "Device alias", 
						status: "Status", 
						ip: "IP", 
						actions: "Actions"
					},
					preparedData,
					`<span class="table-meta">Total: <span class="total">${resp.data.total}</span> devices</span>`
				);

				scr.currentScreen.DOMObject.querySelectorAll(".reboot-btn").forEach(btn => {
					btn.addEventListener("click", e => {
						if(e.currentTarget.getAttribute("disabled")) {
							return ;
						}

						const btnReboot = e.currentTarget;
						Helper.states.btnLoadingState(btnReboot, true);
						const deviceId = e.currentTarget.dataset.deviceId;
						const deviceName = e.currentTarget.dataset.deviceName;
						const deviceAlias = e.currentTarget.dataset.deviceAlias;
						sh_api.devices.reboot(
							deviceId,
							(err, data, meta) => {
								Helper.states.btnLoadingState(btnReboot, false);
								
								console.log("Reboot done", err, data, meta);
								if(data) {
									Toasts.createSuccess(
										"Reboot successful",
										`Device: ${deviceName}<br>
										Alias: <b>${deviceAlias}</b>`
									).show();
								} else {
									Toasts.createError(
										"Reboot failed",
										`Device: ${deviceName}<br>
										Alias: <b>${deviceAlias}</b>`
									).show();
								}
							}
						);
					});
				});

				scr.currentScreen.DOMObject.querySelectorAll(".details-btn").forEach(btn => {
					btn.addEventListener("click", e => {
						const device = JSON.parse(e.currentTarget.dataset.device);
						deviceDetailsPopup(device, sh_api).show();
					});
				});

				scr.ready();
			});
		}
	};
}

function scanning(sh_api) {
	return {
		alias: "devices-scanning",
		renderer: () => {	
			const sidebar = sidebarTemplate("scanning");

			return `
				<div class="container">
					<div class="row g-6">
						<div class="col sidebar-container">
							${sidebar}
						</div>
						<div class="col devices-container"></div>
					</div>
				</div>
			`;
		},
		initer: scr => {
			sh_api.devices.scanning_all((err, resp, meta) => {
				console.log("sh_api.devices.scanning_all", err, resp);

				if(meta.status_code != 200) {
					return scr.error("Server API ERROR", "");
				}

				const preparedData = [];
				for(let device of resp.data.devices) {
					device = Helper.unification.deviceFieldsUnification(device);

					preparedData.push({
						deviceId: device.device_id,
						deviceName: device.name,
						deviceType: device.type,
						status: `<span class="badge badge-primary">${device.status}</span>`,
						ip: `<code class="code">${device.ip}</code>`,
						mac: `<code class="code">${device.mac}</code>`,
						wifiSignal: device.wifi_signal,
						actions: device.status == "setup" ? `
							<button 
								class="btn btn-secondary btn-small setup-btn" 
								data-device='${JSON.stringify(device)}'
								type="button"
							>Setup</button>
						` : ""
					});
				}

				scr.currentScreen.DOMObject.querySelector(".devices-container").innerHTML = Helper.template.table(
					"Found devices", 
					{
						deviceId: "Device ID",
						deviceName: "Device name", 
						deviceType: "Type", 
						status: "Status", 
						ip: "IP", 
						mac: "Mac",
						wifiSignal: "Signal", 
						actions: "Actions"
					},
					preparedData,
					`<span class="table-meta">Total: <span class="total">${resp.data.devices.length}</span> devices</span>`
				);

				scr.currentScreen.DOMObject.querySelectorAll(".setup-btn").forEach(btn => {
					btn.addEventListener("click", e => {
						const device = JSON.parse(e.currentTarget.dataset.device);
						deviceSetupFormPopup(device, sh_api).show();
					});
				});

				scr.ready();
			});
		}
	};
}

export default {
	list,
	scanning
}