1import {css, html, LitElement} from 'lit'; 2import {customElement, property} from 'lit/decorators.js'; 3 4import {Device, Notifiable, SimulationInfo, simulationState,} from './device-observer.js'; 5 6@customElement('ns-device-list') 7export class DeviceList extends LitElement implements Notifiable { 8 @property() deviceData: Device[] = []; 9 10 connectedCallback(): void { 11 // eslint-disable-next-line 12 super.connectedCallback(); 13 simulationState.registerObserver(this); 14 } 15 16 disconnectedCallback(): void { 17 // eslint-disable-next-line 18 super.disconnectedCallback(); 19 simulationState.removeObserver(this); 20 } 21 22 static styles = css` 23 :host { 24 justify-content: center; 25 display: flex; 26 flex-wrap: wrap; 27 gap: 1rem; 28 margin: 0; 29 padding: 0; 30 list-style: none; 31 } 32 33 li { 34 border-style: solid; 35 border-color: lightgray; 36 flex-grow: 0; 37 flex-shrink: 0; 38 flex-basis: 125px; 39 } 40 41 li center { 42 font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif; 43 margin: 8px; 44 } 45 46 .box { 47 position: relative; 48 width: 80vw; 49 height: 60vh; 50 border: solid 1px rgb(198, 210, 255); 51 margin: 2.5em auto; 52 } 53 `; 54 55 onNotify(data: SimulationInfo): void { 56 this.deviceData = data.devices; 57 this.requestUpdate(); 58 } 59 60 checkBle(device: Device): 61 boolean{return device.chips.at(0)?.bleBeacon !== undefined} 62 63 render() { 64 const rainbow = [ 65 'red', 66 'orange', 67 'yellow', 68 'green', 69 'blue', 70 'indigo', 71 'purple', 72 ]; 73 74 // Repeating templates with map 75 return html` 76 ${ 77 this.deviceData.map( 78 (device, idx) => html` 79 <li> 80 <center> 81 ${ 82 true ? // TODO manage device.visible in Web UI 83 this.checkBle(device) ? html`<ns-pyramid-sprite 84 id=${device.name} 85 color=${rainbow[idx % rainbow.length]} 86 size="30px" 87 style="opacity:0.5;" 88 role="listitem" 89 tabindex="0" 90 aria-label="${device.name} in Device Legends" 91 ></ns-pyramid-sprite 92 >${device.name} ` : 93 html`<ns-cube-sprite 94 id=${device.name} 95 color=${rainbow[idx % rainbow.length]} 96 size="30px" 97 style="opacity:0.5;" 98 role="listitem" 99 tabindex="0" 100 aria-label="${device.name} in Device Legends" 101 ></ns-cube-sprite 102 >${device.name} ` : 103 this.checkBle(device) ? 104 html`<ns-device-dragzone action="move"> 105 <ns-pyramid-sprite 106 id=${device.name} 107 color=${rainbow[idx % rainbow.length]} 108 size="30px" 109 role="listitem" 110 tabindex="0" 111 aria-label="${device.name} in Device Legends" 112 ></ns-pyramid-sprite> </ns-device-dragzone 113 >${device.name}` : 114 html`<ns-device-dragzone action="move"> 115 <ns-cube-sprite 116 id=${device.name} 117 color=${rainbow[idx % rainbow.length]} 118 size="30px" 119 role="listitem" 120 tabindex="0" 121 aria-label="${device.name} in Device Legends" 122 ></ns-cube-sprite> </ns-device-dragzone 123 >${device.name}`} 124 </center> 125 </li> 126 `)} 127 <li> 128 <center> 129 <ns-pyramid-sprite 130 id="1234" 131 color=${rainbow[this.deviceData.length % rainbow.length]} 132 size="30px" 133 style="opacity:0.5;" 134 role="listitem" 135 tabindex="0" 136 aria-label="beacon in Device Legends" 137 ></ns-pyramid-sprite 138 >beacon 139 </center> 140 </li> 141 <li> 142 <center> 143 <ns-pyramid-sprite 144 id="5678" 145 color=${rainbow[(this.deviceData.length + 1) % rainbow.length]} 146 size="30px" 147 style="opacity:0.5;" 148 role="listitem" 149 tabindex="0" 150 aria-label="anchor in Device Legends" 151 ></ns-pyramid-sprite 152 >anchor 153 </center> 154 </li> 155 `; 156 } 157} 158