Newer
Older
smart-home-server / webclient / dist / js / main.js
(()=>{var ee=Object.defineProperty;var q=Object.getOwnPropertySymbols;var te=Object.prototype.hasOwnProperty,se=Object.prototype.propertyIsEnumerable;var x=(s,e,t)=>e in s?ee(s,e,{enumerable:!0,configurable:!0,writable:!0,value:t}):s[e]=t,h=(s,e)=>{for(var t in e||(e={}))te.call(e,t)&&x(s,t,e[t]);if(q)for(var t of q(e))se.call(e,t)&&x(s,t,e[t]);return s};var C=(s,e,t)=>new Promise((a,n)=>{var r=o=>{try{c(t.next(o))}catch(d){n(d)}},i=o=>{try{c(t.throw(o))}catch(d){n(d)}},c=o=>o.done?a(o.value):Promise.resolve(o.value).then(r,i);c((t=t.apply(s,e)).next())});var m,S,j;function ae(){m.dataset.navState="displayed",m.classList.remove("state-off"),m.classList.add("state-on"),S.classList.add("a-show")}function I(){m.dataset.navState="hidden",m.classList.remove("state-on"),m.classList.add("state-off"),S.classList.add("a-hide"),S.classList.remove("a-show"),setTimeout(()=>{S.classList.remove("a-hide")},300)}function U(){console.log("HUD init"),m=document.querySelector(".hud .nav-toggle"),S=document.querySelector(".hud .navigation"),j=document.querySelector(".hud .reload-screen"),m.addEventListener("click",s=>{s.currentTarget.dataset.navState!="displayed"?ae():I()}),j.addEventListener("click",s=>{Screens.reload()})}var y=class{constructor(e,t,a){this.screens={},this.routesMap={},this.currentScreen=null,this.eventsHandlers={switch:[],reload:[],reinit:[]},this.screensContainer=document.querySelector(e),this.loader=document.querySelector(t),this.errorScreen=document.querySelector(a),console.log("Screens Init")}add(e,t){if(typeof t!="object")return console.error("Screens: screens must be object");if(typeof(t==null?void 0:t.alias)=="undefined")return console.error("Screens: undefined alias");if(typeof(t==null?void 0:t.renderer)!="function")return console.error("Screens: renderer must be function");this.screens[t.alias]=h({route:e},t),this.routesMap[e]=t.alias}switch(e){var a;if(this.runSwitchHandlers(e),this.hideErrorScreen(),this.showLoader(),(a=this.currentScreen)==null||a.DOMObject.remove(),typeof this.screens[e]=="undefined"){console.error(`Screens: "${e}" not found`);return}this.currentScreen=this.screens[e];let t=document.createElement("div");t.classList.add("screen"),t.id=e,t.dataset.alias=e,t.innerHTML=this.currentScreen.renderer(),this.currentScreen.DOMObject=t,this.screensContainer.append(this.currentScreen.DOMObject),this.currentScreen.initer(this)}reload(){this.currentScreen&&(this.runReloadHandlers(this.currentScreen.alias),this.switch(this.currentScreen.alias))}reinit(){this.currentScreen&&(this.currentScreen.initer(this),this.runReinitHandlers())}routing(){setInterval(()=>{let e=document.location.hash.split("#!")[1];if(typeof e=="undefined"||e=="")return;let t=typeof this.routesMap[e]=="undefined"?"not-found-screen":this.routesMap[e];(!this.currentScreen||this.currentScreen.alias!=t)&&this.switch(t)},50)}ready(){this.currentScreen!=null&&(this.currentScreen.DOMObject||(this.currentScreen.DOMObject=document.getElementsById(this.currentScreen.alias)),this.hideLoader(),this.currentScreen.DOMObject.classList.add("a-show"))}error(e,t){var a;(a=this.currentScreen)==null||a.DOMObject.remove(),this.errorScreen.querySelector(".error-title").innerHTML=e,this.errorScreen.querySelector(".error-text").innerHTML=t,this.showErrorScreen()}hideLoader(){this.loader.classList.remove("a-show")}showLoader(){this.loader.classList.add("a-show")}showErrorScreen(){this.errorScreen.classList.add("a-show")}hideErrorScreen(){this.errorScreen.classList.remove("a-show")}getScreens(){return this.screens}getRoutesMap(){return this.routesMap}onSwitch(e){this.eventsHandlers.switch.push(e)}onReaload(e){this.eventsHandlers.reload.push(e)}onReinit(e){this.eventsHandlers.reinit.push(e)}runSwitchHandlers(e){for(let t of this.eventsHandlers.switch)t(this,e)}runReloadHandlers(e){for(let t of this.eventsHandlers.reload)t(this,e)}runReinitHandlers(){for(let e of this.eventsHandlers.reinit)e(this)}};function ne(s,e,t,a){return`
		<div class="toast toast-${s}" role="alert">
	    <div class="toast-content">
	      <h4 class="toast-title">${e} ${t}</h4>
	      <p class="toast-text">${a}</p>
	    </div>
	    <button class="btn-icon toast-close" type="button" aria-label="Close">\u2715</button>
	  </div>
	`}function re(s,e){if(e!=null&&e.alone&&document.querySelectorAll(".toast").forEach(t=>t.close()),s.close=function(){this.classList.add("a-hide"),setTimeout(()=>{this.remove()},300)},s.querySelector(".toast-close").addEventListener("click",t=>{s.close()}),s.show=function(){document.querySelector("body").append(s),setTimeout(()=>{s.classList.add("a-show")},10)},Screens.onSwitch((t,a)=>{setTimeout(()=>{s==null||s.close()},1e4)}),s.addEventListener("mouseover",t=>s.ishovered=!0),s.addEventListener("mouseout",t=>s.ishovered=!1),e!=null&&e.lifetime){console.log(e);let t=setInterval(()=>{s.ishovered||(s.close(),clearInterval(t))},e==null?void 0:e.lifetime)}return s}function _(s,e,t,a,n){let r=document.createElement("div");return r.innerHTML=ne(s,e,t,a),re(r.childNodes[1],n)}function ie(s,e,t){return typeof t=="undefined"&&(t={}),typeof t.lifetime=="undefined"&&(t.lifetime=4e3),typeof t.alone=="undefined"&&(t.alone=!0),_("success",'<i class="ph ph-check-circle"></i>',s,e,t)}function oe(s,e,t){return _("info",'<i class="ph ph-info"></i>',s,e,t)}function ce(s,e,t){return _("warning",'<i class="ph ph-warning"></i>',s,e,t)}function P(s,e,t){return _("danger",'<i class="ph ph-warning-octagon"></i>',s,e,t)}var F={create:_,createInfo:oe,createSuccess:ie,createWarning:ce,createError:P,createDanger:P};function le(s){let e="";for(let t of s){let a="",n="";t.route&&(a=`<a class="list-action" href="${t.route}">`,n="</a>"),e+=`
			<li class="list-item ${t.is_active?"list-item-active":""}">
				${a}${t.content}${n}
			</li>
		`}return`
		<div class="sidebar block">
			<ul class="list list-nav">
				${e} 
			</ul>
		</div>
	`}function de(s,e,t,a){let n='<tr class="table-row">',r=0;for(let o in e)n+=`<th scope="col">${e[o]}</th>`,r++;n+="</tr>";let i="";for(let o of t){i+='<tr class="table-row">';for(let d in e)i+=`<td>${o[d]}</td>`;i+="</tr>"}let c="";return typeof a!="undefined"&&(c=`
			<tfoot class="table-foot">
				<tr class="table-row">
					<td colspan="${r}">
						${a}
					</td>
				</tr>
			</tfoot>
		`),`
		<table class="table devices-lists">
			<caption class="table-caption">${s}</caption>
			<thead class="table-head">${n}</thead>
			<tbody class="table-body">${i}</tbody>
			${c}
		</table>
	`}function J(s,e,t){let a=document.createElement(s);for(let[n,r]of Object.entries(e))n==="class"?a.className=r:n==="dataset"?Object.assign(a.dataset,r):a.setAttribute(n,r);return a.innerHTML=typeof t!="undefined"?t:"",a}function ue(s,e){return["primary","success","secondary","info","warning","error","danger"].indexOf(s)<0?console.error("createAlert()","Error of type: "+s):J("div",{class:`alert alert-${s}`},e)}function pe(s){let e={device_name:"name",device_hard_id:"device_id",device_ip:"ip",device_type:"type",ip_address:"ip",mac_address:"mac",device_mac:"mac",core_version:"firmware_core_version"},t={};for(let a in s){if(typeof e[a]!="undefined"){t[e[a]]=s[a];continue}t[a]=s[a]}return t}function fe(s,e){if((s==null?void 0:s.isLoading)==e)return!1;if(e)s.isLoading=!0,s.originalContent=s.innerHTML,s.classList.contains("with-icon")?s.originalWithIcon=!0:s.classList.add("with-icon"),s.classList.add("loading-state"),s.setAttribute("disabled","disabled"),s.innerHTML='<i class="ph-bold ph-spinner"></i> Loading';else{if(s.isLoading=!1,!s.originalContent)return!1;s.removeAttribute("disabled"),s.classList.remove("loading-state"),s.originalWithIcon||s.classList.remove("with-icon"),s.innerHTML=s.originalContent}return s}var B={template:{sidebarNav:le,table:de,createElement:J,createAlert:ue},unification:{deviceFieldsUnification:pe},states:{btnLoadingState:fe}};var w=class{constructor(e){this.core=e}actions_list(e){return this.core.api_get("/api/v1/scripts/actions/list",e)}scopes_list(e){return this.core.api_get("/api/v1/scripts/scopes/list",e)}regular_list(e){return this.core.api_get("/api/v1/scripts/regular/list",e)}scope_get_by_filename(e,t){let a=encodeURIComponent(String(e||""));return this.core.api_get(`/api/v1/scripts/scopes/name/${a}`,t,{})}scope_create(e,t){return this.core.api_post("/api/v1/scripts/scopes/new",e,t)}scope_update(e,t){return this.core.api_post("/api/v1/scripts/scopes/update",e,t)}action_enable(e,t){let a=encodeURIComponent(String(e||""));return this.core.api_get(`/api/v1/scripts/actions/alias/${a}/enable`,t)}action_disable(e,t){let a=encodeURIComponent(String(e||""));return this.core.api_get(`/api/v1/scripts/actions/alias/${a}/disable`,t)}regular_enable(e,t){let a=encodeURIComponent(String(e||""));return this.core.api_get(`/api/v1/scripts/regular/alias/${a}/enable`,t)}regular_disable(e,t){let a=encodeURIComponent(String(e||""));return this.core.api_get(`/api/v1/scripts/regular/alias/${a}/disable`,t)}scope_enable(e,t){let a=encodeURIComponent(String(e||""));return this.core.api_get(`/api/v1/scripts/scopes/name/${a}/enable`,t)}scope_disable(e,t){let a=encodeURIComponent(String(e||""));return this.core.api_get(`/api/v1/scripts/scopes/name/${a}/disable`,t)}scope_remove(e,t){let a=encodeURIComponent(String(e||""));return this.core.api_get(`/api/v1/scripts/scopes/name/${a}/remove`,t)}run(e,t){return this.core.api_post("/api/v1/scripts/actions/run",e,t)}};var $=class{constructor(e){this.core=e}list(e){return this.core.api_get("/api/v1/devices/list",e)}scanning_setup(e){return this.core.api_get("/api/v1/devices/scanning/setup",e)}scanning_all(e){return this.core.api_get("/api/v1/devices/scanning/all",e)}setup_new_device(e,t){return this.core.api_post("/api/v1/devices/setup/new-device",e,t)}info(e,t){let a=encodeURIComponent(String(e));return this.core.api_get(`/api/v1/devices/id/${a}/info`,t)}get(e,t){let a=encodeURIComponent(String(e));return this.core.api_get(`/api/v1/devices/id/${a}`,t)}status(e,t){let a=encodeURIComponent(String(e));return this.core.api_get(`/api/v1/devices/id/${a}/status`,t)}action(e,t){return this.core.api_post("/api/v1/devices/action",e,t)}remove(e,t){let a=encodeURIComponent(String(e));return this.core.api_get(`/api/v1/devices/id/${a}/remove`,t)}reboot(e,t){let a=encodeURIComponent(String(e));return this.core.api_get(`/api/v1/devices/id/${a}/reboot`,t)}};var T=class{constructor(e){this.core=e}list(e){return this.core.api_get("/api/v1/areas/list",e)}inner_list(e,t){let a=encodeURIComponent(String(e));return this.core.api_get(`/api/v1/areas/id/${a}/list`,t)}new_area(e,t){return this.core.api_post("/api/v1/areas/new-area",e,t)}remove(e,t){let a=encodeURIComponent(String(e));return this.core.api_get(`/api/v1/areas/id/${a}/remove`,t)}place_in_area(e,t){return this.core.api_post("/api/v1/areas/place-in-area",e,t)}update_display_name(e,t){return this.core.api_post("/api/v1/areas/update-display-name",e,t)}update_alias(e,t){return this.core.api_post("/api/v1/areas/update-alias",e,t)}devices(e,t){let a=encodeURIComponent(String(e));return this.core.api_get(`/api/v1/areas/id/${a}/devices`,t)}unassign_from_area(e,t){let a=encodeURIComponent(String(e));return this.core.api_get(`/api/v1/areas/id/${a}/unassign-from-area`,t)}types_list(e){return this.core.api_get("/api/v1/areas/types/list",e)}reboot_devices(e,t){if(e==null)return this.core.api_get("/api/v1/areas/reboot_devices",t);let a=encodeURIComponent(String(e));return this.core.api_get(`/api/v1/areas/id/${a}/reboot_devices`,t)}};function z(s){if(!s||typeof s!="object")return"";let e=new URLSearchParams;Object.entries(s).forEach(([a,n])=>{n!=null&&e.append(a,String(n))});let t=e.toString();return t?`?${t}`:""}function be(s,e){let t=String(s||"").replace(/\/+$/,""),a=String(e||"").replace(/^\/+/,"");return`${t}/${a}`}function me(s){try{return{ok:!0,data:JSON.parse(s)}}catch(e){return{ok:!1,error:e}}}var L=class{constructor(e){this.base_url=(e==null?void 0:e.base_url)||"",this.token=(e==null?void 0:e.token)||"",this.timeout_ms=Number.isFinite(e==null?void 0:e.timeout_ms)?e.timeout_ms:15e3,this.default_headers=(e==null?void 0:e.default_headers)||{},this.on_unauthorized=typeof(e==null?void 0:e.on_unauthorized)=="function"?e.on_unauthorized:null,this.proxy_path=(e==null?void 0:e.proxy_path)||"",this.scripts=new w(this),this.devices=new $(this),this.areas=new T(this)}set_base_url(e){this.base_url=e||""}set_token(e){this.token=e||""}set_proxy_path(e){this.proxy_path=e||""}_wrap_path(e,t){if(!this.proxy_path)return t?`${e}${z(t)}`:e;let a=h({path:e},t||{});return`${this.proxy_path}${z(a)}`}request(e,t,a,n,r){let i=typeof n=="function"?n:()=>{},c=be(this.base_url,t),o=new AbortController,d=Number.isFinite(r==null?void 0:r.timeout_ms)?r.timeout_ms:this.timeout_ms,u=setTimeout(()=>o.abort(),d),v=h(h({},this.default_headers),(r==null?void 0:r.headers)||{});this.token&&(v.Authorization=`Bearer ${this.token}`);let R;a!=null&&(v["Content-Type"]="application/json",R=JSON.stringify(a)),fetch(c,{method:e,headers:v,body:R,signal:o.signal}).then(l=>C(this,null,function*(){clearTimeout(u);let f={url:c,method:e,status_code:l.status,headers:l.headers},p=yield l.text(),D=me(p),b=D.ok?D.data:p;if(!l.ok){let g={type:"http_error",message:`HTTP ${l.status}`,status_code:l.status,raw:b};if((l.status===401||l.status===403)&&this.on_unauthorized)try{this.on_unauthorized({error:g,meta:f})}catch(M){}return i(g,null,f)}if(D.ok&&b&&typeof b=="object"){let g=b.status;if(g===!1||g==="error"){let M={type:"api_error",message:b.message||"API error",status_code:l.status,raw:b,field:b.field};return i(M,null,f)}}return i(null,b,f)})).catch(l=>{clearTimeout(u);let p=l&&(l.name==="AbortError"||String(l).includes("AbortError"))?{type:"timeout",message:`Timeout after ${d}ms`}:{type:"network_error",message:(l==null?void 0:l.message)||"Network error",details:l};return i(p,null,{url:c,method:e,status_code:0,headers:null})})}get(e,t,a){return this.request("GET",e,null,t,a)}post(e,t,a,n){return this.request("POST",e,t,a,n)}api_get(e,t,a,n){return this.get(this._wrap_path(e,a),t,n)}api_post(e,t,a,n,r){return this.post(this._wrap_path(e,n),t,a,r)}};function E(s){return Helper.template.sidebarNav([{content:'<span class="list-label"><i class="ph ph-cpu"></i> Devices</span>',route:"/#!/devices",is_active:s=="devices"},{content:'<span class="list-label"><i class="ph ph-magnifying-glass"></i> Scanning</span>',route:"/#!/devices/scanning",is_active:s=="scanning"},{content:'<span class="list-label"><i class="ph ph-play"></i> Actions</span>',route:"/#!/devices/actions",is_active:s=="actions"}])}function H(s,e,t){Helper.states.btnLoadingState(e,!0);let a=e.dataset.deviceId,n=e.dataset.deviceName,r=e.dataset.deviceAlias;s.devices.reboot(a,(i,c,o)=>{Helper.states.btnLoadingState(e,!1),console.log("Reboot done",i,c,o),t==null||t.close(),c?(setTimeout(()=>Screens.reinit(),8e3),Toasts.createSuccess("Reboot successful",`Device: ${n}<br>
					Alias: <b>${r}</b>`).show()):Toasts.createError("Reboot failed",`Device: ${n}<br>
					Alias: <b>${r}</b>`).show()})}function W(s,e){return console.log(s),Modals.create("device-popup",{title:`Device ${s.name}`,body:t=>{let a="";for(let n in s)a+=`
					<tr class="table-row">
						<th>${n}: </th>
						<td>${s[n]}</td>
					</tr>
				`;return`
				<div class="block">
					<table class="table" style="border: 0">
						<tbody class="table-body">
							${a}
						</tbody>
					</table>
				</div>
			`},actions:t=>{let a=Helper.template.createElement("button",{class:"btn btn-primary"},"Close"),n=Helper.template.createElement("button",{class:"btn btn-warning with-icon"},'<i class="ph ph-arrow-clockwise"></i> Reboot'),r=Helper.template.createElement("button",{class:"btn btn-danger with-icon"},'<i class="ph ph-trash"></i> Remove');return a.addEventListener("click",i=>{t.close()}),n.dataset.deviceId=s.id,n.dataset.deviceName=s.name,n.dataset.deviceAlias=s.alias,n.addEventListener("click",i=>{n.getAttribute("disabled")||H(e,i.currentTarget,t)}),r.addEventListener("click",i=>{r.getAttribute("disabled")||(Helper.states.btnLoadingState(r,!0),confirmPopup("Are you sure you want to remove this device?",()=>{e.devices.remove(s.id,(c,o,d)=>{Helper.states.btnLoadingState(r,!1),console.log("Was removed"),t.close(),Screens.reinit(),setTimeout(()=>{Toasts.createSuccess("Removed",`
										Device: ${s.name}<br>
										Alias: <b>${s.alias}</b><br>
										IP: <b>${s.ip}</b>
										`).show()},300)})},()=>{Helper.states.btnLoadingState(r,!1),console.log("CANCELED")}))}),[a,n,r]}})}function he(s){let e=[];for(let t of s.devices){t=Helper.unification.deviceFieldsUnification(t);let a=t.connection_state=="active"?'<span class="badge badge-success">Online</span>':'<span class="badge badge-warning">Offline</span>';e.push({deviceName:t.name,alias:t.alias,status:a,ip:`<code class="code">${t.ip}</code>`,actions:`
				<button 
					class="btn btn-secondary btn-small details-btn" 
					data-device='${JSON.stringify(t)}'
					type="button"
				>Details</button>

				<button 
					class="btn btn-warning btn-small reboot-btn" 
					data-device-id="${t.id}" 
					data-device-name="${t.name}" 
					data-device-alias="${t.alias}" 
					type="button"
				>Reboot</button>
			`})}return e}function ve(s,e,t){s.currentScreen.DOMObject.querySelector(".devices-container").innerHTML=Helper.template.table("Devices list",{deviceName:"Device name",alias:"Device alias",status:"Status",ip:"IP",actions:"Actions"},e,`<span class="table-meta">Total: <span class="total">${t}</span> devices</span>`)}function ge(s,e){s.currentScreen.DOMObject.querySelectorAll(".reboot-btn").forEach(t=>{t.addEventListener("click",a=>{a.currentTarget.getAttribute("disabled")||H(e,a.currentTarget)})}),s.currentScreen.DOMObject.querySelectorAll(".details-btn").forEach(t=>{t.addEventListener("click",a=>{let n=JSON.parse(a.currentTarget.dataset.device);W(n,e).show()})})}function Y(s){return{alias:"devices",renderer:()=>`
				<div class="container">
					<div class="row g-6">
						<div class="col sidebar-container">
							${E("devices")}
						</div>
						<div class="col devices-container"></div>
					</div>
				</div>
			`,initer:e=>{s.devices.list((t,a,n)=>{if(console.log("sh_api.devices.list",t,a,n),n.status_code!=200)return e.error("Server API ERROR","");ve(e,he(a.data),a.data.total),ge(e,s),e.ready()})}}}function G(s,e){return s=Helper.unification.deviceFieldsUnification(s),Modals.create("device-setup",{title:`Setup new device ${s.ip}`,body:t=>{let a="";for(let r in s)r[0]!="_"&&(a+=`
					<tr class="table-row">
						<th>${r}: </th>
						<td>${s[r]}</td>
					</tr>
				`);return`
				<div class="row g-6">
					<div class="col device-info">
						${`
				<div class="block">
					<table class="table" style="border: 0">
						<tbody class="table-body">
							${a}
						</tbody>
					</table>
				</div>
			`}
					</div>

					<div class="col setup-form w-100">
						<div class="block form-group">
							<label class="label">
								Device alias
								<i class="ph ph-asterisk"></i>
								<input type="text" name="alias" class="input" placeholder="Input alias">
							</label>
						</div>

						<div class="block form-group">
							<label class="label">
								Device name
								<i class="ph ph-asterisk"></i>
								<input type="text" name="name" class="input" placeholder="Input name">
							</label>
						</div>

						<div class="block form-group">
							<label class="label">
								About device
								<i class="ph ph-note-pencil"></i>
								<textarea class="input" name="description" placeholder="Input description"></textarea>
							</label>
						</div>

						<div class="alert-container"></div>
					</div>
				</div>
			`},actions:t=>{let a=Helper.template.createElement("button",{class:"btn btn-primary"},"Cancel");a.addEventListener("click",r=>{t.close()});let n=Helper.template.createElement("button",{class:"btn btn-success with-icon"},'<i class="ph ph-gear"></i> Setup');return n.addEventListener("click",r=>{if(r.currentTarget.getAttribute("disabled"))return!1;let i={device_ip:s.ip},c=document.querySelector("#device-setup .setup-form");if(c.querySelectorAll("input[type='text']").forEach(u=>{u.dispatchEvent(new Event("input",{bubbles:!0}))}),c.querySelectorAll(".label.error").length)return!1;let o=c.querySelectorAll("input"),d=c.querySelector("textarea");for(let u of o)i[u.getAttribute("name")]=u.value;i[d.getAttribute("name")]=d.value,Helper.states.btnLoadingState(n,!0),e.devices.setup_new_device(i,(u,v,R)=>{var l,f;if(Helper.states.btnLoadingState(n,!1),(u==null?void 0:u.type)=="api_error"){if(console.error("ERR! sh_api.devices.setup_new_device",u.raw),(l=u.raw)!=null&&l.failed_fields)for(let p of u.raw.failed_fields)t.querySelector(`[name="${p}"]`).parentNode.classList.add("error");if((f=u.raw)!=null&&f.msg){let p=t.querySelector(".setup-form .alert-container");p.innerHTML="",p==null||p.append(Helper.template.createAlert("error",u.raw.msg))}return!1}if(!v)return!1;o.forEach(p=>p.value=""),d.value="",t.close(),Screens.reinit(),setTimeout(()=>{Toasts.createSuccess("Setup successful",`Added new device <b>ID ${s.device_id}</b>`).show()},300)})}),[a,n]},onready:t=>{t.querySelector(".setup-form").querySelectorAll("input").forEach(n=>{n.addEventListener("input",r=>{var i;r.currentTarget.value.length?(r.currentTarget.parentNode.classList.remove("error"),(i=r.currentTarget.parentNode.parentNode.querySelector(".input-info.error"))==null||i.remove()):(r.currentTarget.parentNode.classList.add("error"),r.currentTarget.parentNode.parentNode.querySelector(".input-info.error")||r.currentTarget.parentNode.parentNode.append(Helper.template.createElement("div",{class:"input-info error"},'<i class="ph ph-warning-circle"></i> Field cannot be empty')))})})}})}function Se(s){let e=[];for(let t of s.devices)t=Helper.unification.deviceFieldsUnification(t),e.push({deviceId:t.device_id,deviceName:t.name,deviceType:t.type,status:`<span class="badge badge-primary">${t.status}</span>`,ip:`<code class="code">${t.ip}</code>`,mac:`<code class="code">${t.mac}</code>`,wifiSignal:t.wifi_signal,actions:t.status=="setup"?`
				<button 
					class="btn btn-secondary btn-small setup-btn" 
					data-device='${JSON.stringify(t)}'
					type="button"
				>Setup</button>
			`:""});return e}function _e(s,e,t){s.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"},e,`<span class="table-meta">Total: <span class="total">${t}</span> devices</span>`)}function ye(s,e){s.currentScreen.DOMObject.querySelectorAll(".setup-btn").forEach(t=>{t.addEventListener("click",a=>{let n=JSON.parse(a.currentTarget.dataset.device);G(n,e).show()})})}function K(s){return{alias:"devices-scanning",renderer:()=>`
				<div class="container">
					<div class="row g-6">
						<div class="col sidebar-container">
							${E("scanning")}
						</div>
						<div class="col devices-container"></div>
					</div>
				</div>
			`,initer:e=>{s.devices.scanning_all((t,a,n)=>{if(console.log("sh_api.devices.scanning_all",t,a),n.status_code!=200)return e.error("Server API ERROR","");_e(e,Se(a.data),a.data.devices.length),ye(e,s),e.ready()})}}}var A={list:Y,scanning:K};function O(s){return Helper.template.sidebarNav([{content:'<span class="list-label"><i class="ph ph-cpu"></i> Scopes</span>',route:"/#!/scripts/scopes",is_active:s=="scopes"},{content:'<span class="list-label"><i class="ph ph-play"></i> Actions</span>',route:"/#!/scripts/actions",is_active:s=="actions"},{content:'<span class="list-label"><i class="ph ph-magnifying-glass"></i> Regular</span>',route:"/#!/scripts/regular",is_active:s=="regular"}])}function we(s){let e=[];for(let t of s.scopes){let a=t.state=="enabled"?'<span class="badge badge-success">Enabled</span>':'<span class="badge badge-primary">Disabled</span>',n=t.state=="disabled"?`<button 
					class="btn btn-success btn-small change-state-btn" 
					data-scope='${JSON.stringify(t)}'
					type="button"
					data-value="enable"
				>Enable</button>`:`<button 
					class="btn btn-warning btn-small change-state-btn" 
					data-scope='${JSON.stringify(t)}'
					type="button"
					data-value="disable"
				>Disable</button>`;e.push({name:t.name,filename:`${t.filename}<br><code><small>${t.path}</small></code>`,state:a,actions:`
				${n}
			`})}return e}function $e(s,e,t){console.log("renderingScopesTable",e),s.currentScreen.DOMObject.querySelector(".scopes-container").innerHTML=Helper.template.table("Scopes list",{name:"Scope name",filename:"Filename",state:"Status",actions:"Actions"},e,`<span class="table-meta">Total: <span class="total">${t}</span> scopes</span>`)}function Te(s,e){s.currentScreen.DOMObject.querySelectorAll(".change-state-btn").forEach(t=>{t.addEventListener("click",a=>{let n=a.currentTarget;if(n.getAttribute("disabled"))return;let r=n.dataset.value=="enable"?"scope_enable":"scope_disable",i=JSON.parse(n.dataset.scope);Helper.states.btnLoadingState(n,!0),e.scripts[r](i.name,(c,o,d)=>{Helper.states.btnLoadingState(n,!1),o?(setTimeout(()=>Screens.reinit(),250),Toasts.createSuccess("Request Success",`State of <b>${i.name}</b> was changed`).show()):Toasts.createError("Request failed","Scope state not changed").show()})})})}function Q(s){return{title:"Scripts Scopes",alias:"scripts-scopes",renderer:()=>`
				<div class="container">
					<div class="row g-6">
						<div class="col sidebar-container">
							${O("scopes")}
						</div>
						<div class="col scopes-container w-100"></div>
					</div>
				</div>
			`,initer:e=>{s.scripts.scopes_list((t,a,n)=>{if(console.log("sh_api.scripts.scopes_list",t,a,n),n.status_code!=200)return e.error("Server API ERROR","");$e(e,we(a.data),a.data.total),Te(e,s),e.ready()})}}}function Le(s){let e=[];for(let t of s.scripts){let a=t.state=="enabled"?'<span class="badge badge-success">Enabled</span>':'<span class="badge badge-primary">Disabled</span>',n=t.state=="disabled"?`<button 
					class="btn btn-success btn-small change-state-btn" 
					data-script='${JSON.stringify(t)}'
					type="button"
					data-value="enable"
				>Enable</button>`:`<button 
					class="btn btn-warning btn-small change-state-btn" 
					data-script='${JSON.stringify(t)}'
					type="button"
					data-value="disable"
				>Disable</button>`;e.push({alias:`${t.alias}<br><small class="text-muted">by ${t.created_by}</small>`,name:`${t.name}<div class="mt-1"><small>${t.description}</small></div>`,filename:`${t.filename}<br><code><small>${t.path}</small></code>`,state:a,actions:`
				${n}
			`})}return e}function Ee(s,e,t){console.log("renderingRegularScriptsTable",e),s.currentScreen.DOMObject.querySelector(".main-container").innerHTML=Helper.template.table("Regular scripts list",{alias:"Alias",name:"Script name",filename:"Filename",state:"Status",actions:"Actions"},e,`<span class="table-meta">Total: <span class="total">${t}</span> scripts</span>`)}function He(s,e){s.currentScreen.DOMObject.querySelectorAll(".change-state-btn").forEach(t=>{t.addEventListener("click",a=>{let n=a.currentTarget;if(n.getAttribute("disabled"))return;let r=n.dataset.value=="enable"?"regular_enable":"regular_disable",i=JSON.parse(n.dataset.script);Helper.states.btnLoadingState(n,!0),e.scripts[r](i.alias,(c,o,d)=>{Helper.states.btnLoadingState(n,!1),o?(setTimeout(()=>Screens.reinit(),250),Toasts.createSuccess("Request Success",`State of <b>${i.alias}</b> was changed`).show()):Toasts.createError("Request failed","Regular script state not changed").show()})})})}function V(s){return{title:"Scripts Regular",alias:"scripts-regular",renderer:()=>`
				<div class="container">
					<div class="row g-6">
						<div class="col sidebar-container">
							${O("regular")}
						</div>
						<div class="col main-container w-100"></div>
					</div>
				</div>
			`,initer:e=>{s.scripts.regular_list((t,a,n)=>{if(console.log("sh_api.scripts.regular_list",t,a,n),n.status_code!=200)return e.error("Server API ERROR","");Ee(e,Le(a.data),a.data.total),He(e,s),e.ready()})}}}var N={scopes:Q,regular:V};function X(s,e){s.add("/",{alias:"home",renderer:()=>'<h2 class="mt-4">Hello world</h2>',initer:t=>{setTimeout(()=>t.ready(),1e3),setTimeout(()=>t.error("Error","Just testing"),2e3)}}),s.add("-",{alias:"not-found-screen",renderer:()=>'<h2 class="mt-4">404 NOT FOUND</h2>',initer:t=>{t.ready()}}),s.add("/devices",A.list(e)),s.add("/devices/scanning",A.scanning(e)),s.add("/scripts/scopes",N.scopes(e)),s.add("/scripts/regular",N.regular(e))}function Oe(s,e,t){return`
		<div class="modal" aria-hidden="true" id="${s}">
      <div class="modal-backdrop"></div>

      <div class="modal-panel" role="dialog" aria-modal="true" aria-labelledby="modal-title-basic">
        <header class="modal-header">
          <h4 class="modal-title" id="modal-title-basic">${e}</h4>
          <button class="btn-icon modal-close" type="button" aria-label="Close">\u2715</button>
        </header>

        <div class="modal-body"></div>
        <footer class="modal-footer">${t}</footer>
      </div>
    </div>
	`}function Re(s,e){return s.show=function(){document.querySelector("body").append(s),setTimeout(()=>{this.classList.add("a-show")},10)},s.close=function(){this.classList.add("a-hide"),setTimeout(()=>{this.remove()},300)},s.querySelector(".modal-close").addEventListener("click",t=>{s.close()}),typeof e=="function"&&e(s),s}function De(s,e){let t=e.title||"",a=e.footer||"",n=document.createElement("div");n.innerHTML=Oe(s,t,a);let r=n.childNodes[1],i=r.querySelector(".modal-body"),c=r.querySelector(".modal-footer");if(typeof e.actions=="function"){let o=e.actions(r);if(typeof o[0]=="object"){let d=document.createElement("div");d.classList.add("actions");for(let u of o)d.append(u);c.append(d)}}if(typeof e.body=="function"){let o=e.body(r);typeof o=="object"?i.append(o):typeof o=="string"&&(i.innerHTML=o)}return Re(r,e==null?void 0:e.onready)}var Z={create:De};function k(s,e,t){Modals.create("confirm-popup",{title:"Requires confirmation",body:a=>`
				<p>${s}</p>
			`,actions:a=>{let n=Helper.template.createElement("button",{class:"btn btn-primary"},"NO"),r=Helper.template.createElement("button",{class:"btn btn-warning"},"YES");return n.addEventListener("click",i=>{a.close(),t()}),r.addEventListener("click",i=>{a.close(),e()}),[n,r]}}).show()}document.addEventListener("DOMContentLoaded",s=>{console.log("App init"),window.Toasts=F,window.Helper=B,window.Modals=Z,window.confirmPopup=k,U();let e=new L({base_url:"http://shswebclient.local",token:"YOUR_TOKEN",timeout_ms:3e3,on_unauthorized:({error:a})=>console.log("auth problem:",a),proxy_path:"/proxy.php"}),t=new y(".screens",".load-screen",".error-screen");X(t,e),console.log(t.getScreens()),t.onSwitch((a,n)=>{I()}),t.routing(),window.Screens=t});})();
//# sourceMappingURL=main.js.map