template_code.py 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324
  1. LINKTERMINATION = """
  2. {% if value %}
  3. {% if value.parent_object %}
  4. <a href="{{ value.parent_object.get_absolute_url }}">{{ value.parent_object }}</a>
  5. <i class="mdi mdi-chevron-right"></i>
  6. {% endif %}
  7. <a href="{{ value.get_absolute_url }}">{{ value }}</a>
  8. {% endif %}
  9. """
  10. CABLE_LENGTH = """
  11. {% load helpers %}
  12. {% if record.length %}{{ record.length|simplify_decimal }} {{ record.length_unit }}{% endif %}
  13. """
  14. CABLE_TERMINATION_PARENT = """
  15. {% if value.device %}
  16. <a href="{{ value.device.get_absolute_url }}">{{ value.device }}</a>
  17. {% elif value.circuit %}
  18. <a href="{{ value.circuit.get_absolute_url }}">{{ value.circuit }}</a>
  19. {% elif value.power_panel %}
  20. <a href="{{ value.power_panel.get_absolute_url }}">{{ value.power_panel }}</a>
  21. {% endif %}
  22. """
  23. DEVICE_LINK = """
  24. <a href="{% url 'dcim:device' pk=record.pk %}">
  25. {{ record.name|default:'<span class="badge bg-info">Unnamed device</span>' }}
  26. </a>
  27. """
  28. DEVICEBAY_STATUS = """
  29. {% if record.installed_device_id %}
  30. <span class="badge bg-{{ record.installed_device.get_status_class }}">
  31. {{ record.installed_device.get_status_display }}
  32. </span>
  33. {% else %}
  34. <span class="badge bg-secondary">Vacant</span>
  35. {% endif %}
  36. """
  37. INTERFACE_IPADDRESSES = """
  38. <div class="table-badge-group">
  39. {% for ip in record.ip_addresses.all %}
  40. {% if ip.status != 'active' %}
  41. <a href="{{ ip.get_absolute_url }}" class="table-badge badge bg-{{ ip.get_status_class }}" data-bs-toggle="tooltip" data-bs-placement="left" title="{{ ip.get_status_display }}">{{ ip }}</a>
  42. {% else %}
  43. <a href="{{ ip.get_absolute_url }}" class="table-badge">{{ ip }}</a>
  44. {% endif %}
  45. {% endfor %}
  46. </div>
  47. """
  48. INTERFACE_FHRPGROUPS = """
  49. <div class="table-badge-group">
  50. {% for assignment in value.all %}
  51. <a href="{{ assignment.group.get_absolute_url }}">{{ assignment.group.get_protocol_display }}: {{ assignment.group.group_id }}</a>
  52. {% endfor %}
  53. </div>
  54. """
  55. INTERFACE_TAGGED_VLANS = """
  56. {% if record.mode == 'tagged' %}
  57. {% for vlan in record.tagged_vlans.all %}
  58. <a href="{{ vlan.get_absolute_url }}">{{ vlan }}</a><br />
  59. {% endfor %}
  60. {% elif record.mode == 'tagged-all' %}
  61. All
  62. {% endif %}
  63. """
  64. INTERFACE_WIRELESS_LANS = """
  65. {% for wlan in record.wireless_lans.all %}
  66. <a href="{{ wlan.get_absolute_url }}">{{ wlan }}</a><br />
  67. {% endfor %}
  68. """
  69. POWERFEED_CABLE = """
  70. <a href="{{ value.get_absolute_url }}">{{ value }}</a>
  71. <a href="{% url 'dcim:powerfeed_trace' pk=record.pk %}" class="btn btn-primary btn-sm" title="Trace">
  72. <i class="mdi mdi-transit-connection-variant" aria-hidden="true"></i>
  73. </a>
  74. """
  75. POWERFEED_CABLETERMINATION = """
  76. <a href="{{ value.parent_object.get_absolute_url }}">{{ value.parent_object }}</a>
  77. <i class="mdi mdi-chevron-right"></i>
  78. <a href="{{ value.get_absolute_url }}">{{ value }}</a>
  79. """
  80. LOCATION_ELEVATIONS = """
  81. <a href="{% url 'dcim:rack_elevation_list' %}?site={{ record.site.slug }}&location_id={{ record.pk }}" class="btn btn-sm btn-primary" title="View elevations">
  82. <i class="mdi mdi-server"></i>
  83. </a>
  84. """
  85. #
  86. # Device component buttons
  87. #
  88. CONSOLEPORT_BUTTONS = """
  89. {% if record.cable %}
  90. <a href="{% url 'dcim:consoleport_trace' pk=record.pk %}" class="btn btn-primary btn-sm" title="Trace"><i class="mdi mdi-transit-connection-variant"></i></a>
  91. {% include 'dcim/inc/cable_toggle_buttons.html' with cable=record.cable %}
  92. {% if perms.dcim.delete_cable %}
  93. <a href="{% url 'dcim:cable_delete' pk=record.cable.pk %}?return_url={% url 'dcim:device_consoleports' pk=object.pk %}" title="Remove cable" class="btn btn-danger btn-sm">
  94. <i class="mdi mdi-ethernet-cable-off" aria-hidden="true"></i>
  95. </a>
  96. {% endif %}
  97. {% elif perms.dcim.add_cable %}
  98. <a href="#" class="btn btn-outline-dark btn-sm disabled"><i class="mdi mdi-transit-connection-variant" aria-hidden="true"></i></a>
  99. <a href="#" class="btn btn-outline-dark btn-sm disabled"><i class="mdi mdi-lan-connect" aria-hidden="true"></i></a>
  100. <span class="dropdown">
  101. <button type="button" class="btn btn-success btn-sm dropdown-toggle" data-bs-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
  102. <span class="mdi mdi-ethernet-cable" aria-hidden="true"></span>
  103. </button>
  104. <ul class="dropdown-menu dropdown-menu-end">
  105. <li><a class="dropdown-item" href="{% url 'dcim:consoleport_connect' termination_a_id=record.pk termination_b_type='console-server-port' %}?return_url={% url 'dcim:device_consoleports' pk=object.pk %}">Console Server Port</a></li>
  106. <li><a class="dropdown-item" href="{% url 'dcim:consoleport_connect' termination_a_id=record.pk termination_b_type='front-port' %}?return_url={% url 'dcim:device_consoleports' pk=object.pk %}">Front Port</a></li>
  107. <li><a class="dropdown-item" href="{% url 'dcim:consoleport_connect' termination_a_id=record.pk termination_b_type='rear-port' %}?return_url={% url 'dcim:device_consoleports' pk=object.pk %}">Rear Port</a></li>
  108. </ul>
  109. </span>
  110. {% else %}
  111. <a href="#" class="btn btn-outline-dark btn-sm disabled"><i class="mdi mdi-ethernet-cable" aria-hidden="true"></i></a>
  112. {% endif %}
  113. """
  114. CONSOLESERVERPORT_BUTTONS = """
  115. {% if record.cable %}
  116. <a href="{% url 'dcim:consoleserverport_trace' pk=record.pk %}" class="btn btn-primary btn-sm" title="Trace"><i class="mdi mdi-transit-connection-variant"></i></a>
  117. {% include 'dcim/inc/cable_toggle_buttons.html' with cable=record.cable %}
  118. {% if perms.dcim.delete_cable %}
  119. <a href="{% url 'dcim:cable_delete' pk=record.cable.pk %}?return_url={% url 'dcim:device_consoleserverports' pk=object.pk %}" title="Remove cable" class="btn btn-danger btn-sm">
  120. <i class="mdi mdi-ethernet-cable-off" aria-hidden="true"></i>
  121. </a>
  122. {% endif %}
  123. {% elif perms.dcim.add_cable %}
  124. <a href="#" class="btn btn-outline-dark btn-sm disabled"><i class="mdi mdi-transit-connection-variant" aria-hidden="true"></i></a>
  125. <a href="#" class="btn btn-outline-dark btn-sm disabled"><i class="mdi mdi-lan-connect" aria-hidden="true"></i></a>
  126. <span class="dropdown">
  127. <button type="button" class="btn btn-success btn-sm dropdown-toggle" data-bs-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
  128. <span class="mdi mdi-ethernet-cable" aria-hidden="true"></span>
  129. </button>
  130. <ul class="dropdown-menu dropdown-menu-end">
  131. <li><a class="dropdown-item" href="{% url 'dcim:consoleserverport_connect' termination_a_id=record.pk termination_b_type='console-port' %}?return_url={% url 'dcim:device_consoleserverports' pk=object.pk %}">Console Port</a></li>
  132. <li><a class="dropdown-item" href="{% url 'dcim:consoleserverport_connect' termination_a_id=record.pk termination_b_type='front-port' %}?return_url={% url 'dcim:device_consoleserverports' pk=object.pk %}">Front Port</a></li>
  133. <li><a class="dropdown-item" href="{% url 'dcim:consoleserverport_connect' termination_a_id=record.pk termination_b_type='rear-port' %}?return_url={% url 'dcim:device_consoleserverports' pk=object.pk %}">Rear Port</a></li>
  134. </ul>
  135. </span>
  136. {% else %}
  137. <a href="#" class="btn btn-outline-dark btn-sm disabled"><i class="mdi mdi-ethernet-cable" aria-hidden="true"></i></a>
  138. {% endif %}
  139. """
  140. POWERPORT_BUTTONS = """
  141. {% if record.cable %}
  142. <a href="{% url 'dcim:powerport_trace' pk=record.pk %}" class="btn btn-primary btn-sm" title="Trace"><i class="mdi mdi-transit-connection-variant"></i></a>
  143. {% include 'dcim/inc/cable_toggle_buttons.html' with cable=record.cable %}
  144. {% if perms.dcim.delete_cable %}
  145. <a href="{% url 'dcim:cable_delete' pk=record.cable.pk %}?return_url={% url 'dcim:device_powerports' pk=object.pk %}" title="Remove cable" class="btn btn-danger btn-sm">
  146. <i class="mdi mdi-ethernet-cable-off" aria-hidden="true"></i>
  147. </a>
  148. {% endif %}
  149. {% elif perms.dcim.add_cable %}
  150. <a href="#" class="btn btn-outline-dark btn-sm disabled"><i class="mdi mdi-transit-connection-variant" aria-hidden="true"></i></a>
  151. <a href="#" class="btn btn-outline-dark btn-sm disabled"><i class="mdi mdi-lan-connect" aria-hidden="true"></i></a>
  152. <span class="dropdown">
  153. <button type="button" class="btn btn-success btn-sm dropdown-toggle" data-bs-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
  154. <span class="mdi mdi-ethernet-cable" aria-hidden="true"></span>
  155. </button>
  156. <ul class="dropdown-menu dropdown-menu-end">
  157. <li><a class="dropdown-item" href="{% url 'dcim:powerport_connect' termination_a_id=record.pk termination_b_type='power-outlet' %}?return_url={% url 'dcim:device_powerports' pk=object.pk %}">Power Outlet</a></li>
  158. <li><a class="dropdown-item" href="{% url 'dcim:powerport_connect' termination_a_id=record.pk termination_b_type='power-feed' %}?return_url={% url 'dcim:device_powerports' pk=object.pk %}">Power Feed</a></li>
  159. </ul>
  160. </span>
  161. {% else %}
  162. <a href="#" class="btn btn-outline-dark btn-sm disabled"><i class="mdi mdi-ethernet-cable" aria-hidden="true"></i></a>
  163. {% endif %}
  164. """
  165. POWEROUTLET_BUTTONS = """
  166. {% if record.cable %}
  167. <a href="{% url 'dcim:poweroutlet_trace' pk=record.pk %}" class="btn btn-primary btn-sm" title="Trace"><i class="mdi mdi-transit-connection-variant"></i></a>
  168. {% include 'dcim/inc/cable_toggle_buttons.html' with cable=record.cable %}
  169. {% if perms.dcim.delete_cable %}
  170. <a href="{% url 'dcim:cable_delete' pk=record.cable.pk %}?return_url={% url 'dcim:device_poweroutlets' pk=object.pk %}" title="Remove cable" class="btn btn-danger btn-sm">
  171. <i class="mdi mdi-ethernet-cable-off" aria-hidden="true"></i>
  172. </a>
  173. {% endif %}
  174. {% elif perms.dcim.add_cable %}
  175. <a href="#" class="btn btn-outline-dark btn-sm disabled"><i class="mdi mdi-transit-connection-variant" aria-hidden="true"></i></a>
  176. <a href="#" class="btn btn-outline-dark btn-sm disabled"><i class="mdi mdi-lan-connect" aria-hidden="true"></i></a>
  177. {% if not record.mark_connected %}
  178. <a href="{% url 'dcim:poweroutlet_connect' termination_a_id=record.pk termination_b_type='power-port' %}?return_url={% url 'dcim:device_poweroutlets' pk=object.pk %}" title="Connect" class="btn btn-success btn-sm">
  179. <i class="mdi mdi-ethernet-cable" aria-hidden="true"></i>
  180. </a>
  181. {% else %}
  182. <a href="#" class="btn btn-outline-dark btn-sm disabled"><i class="mdi mdi-ethernet-cable" aria-hidden="true"></i></a>
  183. {% endif %}
  184. {% endif %}
  185. """
  186. INTERFACE_BUTTONS = """
  187. {% if perms.ipam.add_ipaddress %}
  188. <a href="{% url 'ipam:ipaddress_add' %}?interface={{ record.pk }}&return_url={% url 'dcim:device_interfaces' pk=object.pk %}" class="btn btn-sm btn-success" title="Add IP address">
  189. <i class="mdi mdi-plus-thick" aria-hidden="true"></i>
  190. </a>
  191. {% endif %}
  192. {% if record.link %}
  193. <a href="{% url 'dcim:interface_trace' pk=record.pk %}" class="btn btn-primary btn-sm" title="Trace"><i class="mdi mdi-transit-connection-variant"></i></a>
  194. {% endif %}
  195. {% if record.cable %}
  196. {% include 'dcim/inc/cable_toggle_buttons.html' with cable=record.cable %}
  197. {% if perms.dcim.delete_cable %}
  198. <a href="{% url 'dcim:cable_delete' pk=record.cable.pk %}?return_url={% url 'dcim:device_interfaces' pk=object.pk %}" title="Remove cable" class="btn btn-danger btn-sm">
  199. <i class="mdi mdi-ethernet-cable-off" aria-hidden="true"></i>
  200. </a>
  201. {% endif %}
  202. {% elif record.wireless_link %}
  203. {% if perms.wireless.delete_wirelesslink %}
  204. <a href="{% url 'wireless:wirelesslink_delete' pk=record.wireless_link.pk %}?return_url={% url 'dcim:device_interfaces' pk=object.pk %}" title="Delete wireless link" class="btn btn-danger btn-sm">
  205. <i class="mdi mdi-wifi-off" aria-hidden="true"></i>
  206. </a>
  207. {% endif %}
  208. {% elif record.is_wired and perms.dcim.add_cable %}
  209. <a href="#" class="btn btn-outline-dark btn-sm disabled"><i class="mdi mdi-transit-connection-variant" aria-hidden="true"></i></a>
  210. <a href="#" class="btn btn-outline-dark btn-sm disabled"><i class="mdi mdi-lan-connect" aria-hidden="true"></i></a>
  211. {% if not record.mark_connected %}
  212. <span class="dropdown">
  213. <button type="button" class="btn btn-success btn-sm dropdown-toggle" data-bs-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
  214. <span class="mdi mdi-ethernet-cable" aria-hidden="true"></span>
  215. </button>
  216. <ul class="dropdown-menu dropdown-menu-end">
  217. <li><a class="dropdown-item" href="{% url 'dcim:interface_connect' termination_a_id=record.pk termination_b_type='interface' %}?return_url={% url 'dcim:device_interfaces' pk=object.pk %}">Interface</a></li>
  218. <li><a class="dropdown-item" href="{% url 'dcim:interface_connect' termination_a_id=record.pk termination_b_type='front-port' %}?return_url={% url 'dcim:device_interfaces' pk=object.pk %}">Front Port</a></li>
  219. <li><a class="dropdown-item" href="{% url 'dcim:interface_connect' termination_a_id=record.pk termination_b_type='rear-port' %}?return_url={% url 'dcim:device_interfaces' pk=object.pk %}">Rear Port</a></li>
  220. <li><a class="dropdown-item" href="{% url 'dcim:interface_connect' termination_a_id=record.pk termination_b_type='circuit-termination' %}?return_url={% url 'dcim:device_interfaces' pk=object.pk %}">Circuit Termination</a></li>
  221. </ul>
  222. </span>
  223. {% else %}
  224. <a href="#" class="btn btn-outline-dark btn-sm disabled"><i class="mdi mdi-ethernet-cable" aria-hidden="true"></i></a>
  225. {% endif %}
  226. {% elif record.is_wireless and perms.wireless.add_wirelesslink %}
  227. <a href="{% url 'wireless:wirelesslink_add' %}?site_a={{ record.device.site.pk }}&location_a={{ record.device.location.pk }}&device_a={{ record.device.pk }}&interface_a={{ record.pk }}&site_b={{ record.device.site.pk }}&location_b={{ record.device.location.pk }}" class="btn btn-success btn-sm">
  228. <span class="mdi mdi-wifi-plus" aria-hidden="true"></span>
  229. </a>
  230. {% endif %}
  231. """
  232. FRONTPORT_BUTTONS = """
  233. {% if record.cable %}
  234. <a href="{% url 'dcim:frontport_trace' pk=record.pk %}" class="btn btn-primary btn-sm" title="Trace"><i class="mdi mdi-transit-connection-variant"></i></a>
  235. {% include 'dcim/inc/cable_toggle_buttons.html' with cable=record.cable %}
  236. {% if perms.dcim.delete_cable %}
  237. <a href="{% url 'dcim:cable_delete' pk=record.cable.pk %}?return_url={% url 'dcim:device_frontports' pk=object.pk %}" title="Remove cable" class="btn btn-danger btn-sm">
  238. <i class="mdi mdi-ethernet-cable-off" aria-hidden="true"></i>
  239. </a>
  240. {% endif %}
  241. {% elif perms.dcim.add_cable %}
  242. <a href="#" class="btn btn-outline-dark btn-sm disabled"><i class="mdi mdi-transit-connection-variant" aria-hidden="true"></i></a>
  243. <a href="#" class="btn btn-outline-dark btn-sm disabled"><i class="mdi mdi-lan-connect" aria-hidden="true"></i></a>
  244. {% if not record.mark_connected %}
  245. <span class="dropdown">
  246. <button type="button" class="btn btn-success btn-sm dropdown-toggle" data-bs-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
  247. <span class="mdi mdi-ethernet-cable" aria-hidden="true"></span>
  248. </button>
  249. <ul class="dropdown-menu dropdown-menu-end">
  250. <li><a class="dropdown-item" href="{% url 'dcim:frontport_connect' termination_a_id=record.pk termination_b_type='interface' %}?return_url={% url 'dcim:device_frontports' pk=object.pk %}">Interface</a></li>
  251. <li><a class="dropdown-item" href="{% url 'dcim:frontport_connect' termination_a_id=record.pk termination_b_type='console-server-port' %}?return_url={% url 'dcim:device_frontports' pk=object.pk %}">Console Server Port</a></li>
  252. <li><a class="dropdown-item" href="{% url 'dcim:frontport_connect' termination_a_id=record.pk termination_b_type='console-port' %}?return_url={% url 'dcim:device_frontports' pk=object.pk %}">Console Port</a></li>
  253. <li><a class="dropdown-item" href="{% url 'dcim:frontport_connect' termination_a_id=record.pk termination_b_type='front-port' %}?return_url={% url 'dcim:device_frontports' pk=object.pk %}">Front Port</a></li>
  254. <li><a class="dropdown-item" href="{% url 'dcim:frontport_connect' termination_a_id=record.pk termination_b_type='rear-port' %}?return_url={% url 'dcim:device_frontports' pk=object.pk %}">Rear Port</a></li>
  255. <li><a class="dropdown-item" href="{% url 'dcim:frontport_connect' termination_a_id=record.pk termination_b_type='circuit-termination' %}?return_url={% url 'dcim:device_frontports' pk=object.pk %}">Circuit Termination</a></li>
  256. </ul>
  257. </span>
  258. {% else %}
  259. <a href="#" class="btn btn-outline-dark btn-sm disabled"><i class="mdi mdi-ethernet-cable" aria-hidden="true"></i></a>
  260. {% endif %}
  261. {% endif %}
  262. """
  263. REARPORT_BUTTONS = """
  264. {% if record.cable %}
  265. <a href="{% url 'dcim:rearport_trace' pk=record.pk %}" class="btn btn-primary btn-sm" title="Trace"><i class="mdi mdi-transit-connection-variant"></i></a>
  266. {% include 'dcim/inc/cable_toggle_buttons.html' with cable=record.cable %}
  267. {% if perms.dcim.delete_cable %}
  268. <a href="{% url 'dcim:cable_delete' pk=record.cable.pk %}?return_url={% url 'dcim:device_rearports' pk=object.pk %}" title="Remove cable" class="btn btn-danger btn-sm">
  269. <i class="mdi mdi-ethernet-cable-off" aria-hidden="true"></i>
  270. </a>
  271. {% endif %}
  272. {% elif perms.dcim.add_cable %}
  273. <a href="#" class="btn btn-outline-dark btn-sm disabled"><i class="mdi mdi-transit-connection-variant" aria-hidden="true"></i></a>
  274. <a href="#" class="btn btn-outline-dark btn-sm disabled"><i class="mdi mdi-lan-connect" aria-hidden="true"></i></a>
  275. {% if not record.mark_connected %}
  276. <span class="dropdown">
  277. <button type="button" class="btn btn-success btn-sm dropdown-toggle" data-bs-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
  278. <span class="mdi mdi-ethernet-cable" aria-hidden="true"></span>
  279. </button>
  280. <ul class="dropdown-menu dropdown-menu-end">
  281. <li><a class="dropdown-item" href="{% url 'dcim:rearport_connect' termination_a_id=record.pk termination_b_type='interface' %}?return_url={% url 'dcim:device_rearports' pk=object.pk %}">Interface</a></li>
  282. <li><a class="dropdown-item" href="{% url 'dcim:rearport_connect' termination_a_id=record.pk termination_b_type='front-port' %}?return_url={% url 'dcim:device_rearports' pk=object.pk %}">Front Port</a></li>
  283. <li><a class="dropdown-item" href="{% url 'dcim:rearport_connect' termination_a_id=record.pk termination_b_type='rear-port' %}?return_url={% url 'dcim:device_rearports' pk=object.pk %}">Rear Port</a></li>
  284. <li><a class="dropdown-item" href="{% url 'dcim:rearport_connect' termination_a_id=record.pk termination_b_type='circuit-termination' %}?return_url={% url 'dcim:device_rearports' pk=object.pk %}">Circuit Termination</a></li>
  285. </ul>
  286. </span>
  287. {% else %}
  288. <a href="#" class="btn btn-outline-dark btn-sm disabled"><i class="mdi mdi-ethernet-cable" aria-hidden="true"></i></a>
  289. {% endif %}
  290. {% endif %}
  291. """
  292. DEVICEBAY_BUTTONS = """
  293. {% if perms.dcim.change_devicebay %}
  294. {% if record.installed_device %}
  295. <a href="{% url 'dcim:devicebay_depopulate' pk=record.pk %}?return_url={% url 'dcim:device_devicebays' pk=object.pk %}" class="btn btn-danger btn-sm">
  296. <i class="mdi mdi-minus-thick" aria-hidden="true" title="Remove device"></i>
  297. </a>
  298. {% else %}
  299. <a href="{% url 'dcim:devicebay_populate' pk=record.pk %}?return_url={% url 'dcim:device_devicebays' pk=object.pk %}" class="btn btn-success btn-sm">
  300. <i class="mdi mdi-plus-thick" aria-hidden="true" title="Install device"></i>
  301. </a>
  302. {% endif %}
  303. {% endif %}
  304. """