mirror of
https://github.com/billz/raspap-webgui.git
synced 2023-10-10 13:37:24 +02:00
Merge branch 'master' into bridge-mode
This commit is contained in:
commit
8bda81adcb
@ -1,3 +1,11 @@
|
|||||||
|
/*
|
||||||
|
Theme Name: RaspAP default
|
||||||
|
Author: @billz
|
||||||
|
Author URI: https://github.com/billz
|
||||||
|
Description: Default theme for RaspAP
|
||||||
|
License: GNU General Public License v3.0
|
||||||
|
*/
|
||||||
|
|
||||||
body {
|
body {
|
||||||
color: #212529;
|
color: #212529;
|
||||||
}
|
}
|
||||||
|
@ -1,3 +1,11 @@
|
|||||||
|
/*
|
||||||
|
Theme Name: HackerNews
|
||||||
|
Author: @billz
|
||||||
|
Author URI: https://github.com/billz
|
||||||
|
Description: A theme inspired by HackerNews for RaspAP
|
||||||
|
License: GNU General Public License v3.0
|
||||||
|
*/
|
||||||
|
|
||||||
html * {
|
html * {
|
||||||
font-family: Verdana, Geneva, sans-serif;
|
font-family: Verdana, Geneva, sans-serif;
|
||||||
font-size: 0.9rem;
|
font-size: 0.9rem;
|
||||||
|
@ -1,7 +1,15 @@
|
|||||||
|
/*
|
||||||
|
Theme Name: Lights Out
|
||||||
|
Author: @billz
|
||||||
|
Author URI: https://github.com/billz
|
||||||
|
Description: A dark mode theme for RaspAP
|
||||||
|
License: GNU General Public License v3.0
|
||||||
|
*/
|
||||||
|
|
||||||
html * {
|
html * {
|
||||||
font-family: Courier New, Andale Mono, monospace;
|
font-family: Helvetica,Arial,sans-serif;
|
||||||
font-size: 1.0rem;
|
font-size: 1.0rem;
|
||||||
color: #2bcb02;
|
color: #afafaf;
|
||||||
}
|
}
|
||||||
|
|
||||||
h4 {
|
h4 {
|
||||||
@ -14,24 +22,25 @@ h5.card-title {
|
|||||||
|
|
||||||
.page-header {
|
.page-header {
|
||||||
padding: 0 20px;
|
padding: 0 20px;
|
||||||
border-left: .01rem solid #2bcb02;
|
border-left: .01rem solid #d2d2d2;
|
||||||
}
|
}
|
||||||
|
|
||||||
.navbar-logo {
|
.navbar-logo {
|
||||||
margin-top: 0.5em;
|
margin-top: 0.5em;
|
||||||
margin-left: 0.5em;
|
margin-left: 0.5em;
|
||||||
|
filter: brightness(70%);
|
||||||
}
|
}
|
||||||
|
|
||||||
.sidebar-light .nav-item.active .nav-link i {
|
.sidebar-light .nav-item.active .nav-link i {
|
||||||
color: #2bcb02;
|
color: #d2d2d2;
|
||||||
}
|
}
|
||||||
|
|
||||||
.sidebar .nav-item.active .nav-link {
|
.sidebar .nav-item.active .nav-link {
|
||||||
font-weight: 700;
|
font-weight: 400;
|
||||||
}
|
}
|
||||||
|
|
||||||
#wrapper #content-wrapper #content {
|
#wrapper #content-wrapper #content {
|
||||||
background-color: #000;
|
background-color: #202020;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Small devices (portait phones, up to 576px) */
|
/* Small devices (portait phones, up to 576px) */
|
||||||
@ -46,129 +55,110 @@ h5.card-title {
|
|||||||
}
|
}
|
||||||
|
|
||||||
.topbar {
|
.topbar {
|
||||||
background-color: #000;
|
background-color: #202020;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.nav-tabs {
|
||||||
|
border-bottom: 1px solid #404040;
|
||||||
|
}
|
||||||
.nav-tabs .nav-link.active,
|
.nav-tabs .nav-link.active,
|
||||||
.nav-tabs .nav-link {
|
.nav-tabs .nav-link {
|
||||||
font-size: 1.0rem;
|
font-size: 1.0rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
.nav-tabs>li.active>a,
|
.nav-tabs .nav-link:hover {
|
||||||
.nav-tabs>li.active>a:focus,
|
border-color: transparent;
|
||||||
.nav-tabs>li.active>a:hover,
|
|
||||||
.nav-tabs .nav-link:hover,
|
|
||||||
.input-group-addon {
|
|
||||||
color: #2bcb02;
|
|
||||||
cursor: default;
|
|
||||||
background-color: #000;
|
|
||||||
border: .01rem solid #2bcb02;
|
|
||||||
border-bottom-color: #2bcb02;
|
|
||||||
border-radius: inherit;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.nav-tabs>li>a,.nav-tabs>li>a:hover {
|
|
||||||
border: .01rem solid #2bcb02;
|
|
||||||
}
|
|
||||||
|
|
||||||
.nav-tabs {
|
|
||||||
border-bottom: .01rem solid #2bcb02;
|
|
||||||
}
|
|
||||||
|
|
||||||
.navbar-default .navbar-brand,
|
|
||||||
.navbar-default .navbar-brand:hover {
|
.navbar-default .navbar-brand:hover {
|
||||||
color: #2bcb02;
|
color: #d2d2d2;
|
||||||
}
|
}
|
||||||
|
|
||||||
.navbar-default .navbar-toggle {
|
.navbar-default .navbar-toggle {
|
||||||
border-color: #2bcb02;
|
border-color: #d2d2d2;
|
||||||
}
|
}
|
||||||
|
|
||||||
.navbar-default .navbar-toggle .icon-bar {
|
.navbar-default .navbar-toggle .icon-bar {
|
||||||
background-color: #2bcb02;
|
background-color: #d2d2d2;
|
||||||
}
|
}
|
||||||
|
|
||||||
.navbar-default .navbar-toggle:focus,
|
.navbar-default .navbar-toggle:focus,
|
||||||
.navbar-default .navbar-toggle:hover {
|
.navbar-default .navbar-toggle:hover {
|
||||||
background-color: #000;
|
background-color: #202020;
|
||||||
}
|
}
|
||||||
|
|
||||||
.nav-tabs .nav-link.active {
|
.nav-tabs .nav-link.active {
|
||||||
color: #000;
|
color: #d2d2d2;
|
||||||
background-color: #2bcb02;
|
background-color: #141414;
|
||||||
border-color: #2bcb02;
|
border-color: #404040 #404040 #141414;
|
||||||
border-radius: inherit;
|
|
||||||
}
|
|
||||||
|
|
||||||
.sidebar-brand-icon {
|
|
||||||
filter: invert(65%) sepia(900%) saturate(536%) hue-rotate(68deg) brightness(100%) contrast(120%);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
a:focus, a:hover {
|
a:focus, a:hover {
|
||||||
color: #2bcb02;
|
color: #d2d2d2;
|
||||||
}
|
}
|
||||||
|
|
||||||
.card>.card-header {
|
.card>.card-header {
|
||||||
border-color: #2bcb02;
|
border-color: #404040;
|
||||||
background-color: #2bcb02;
|
background-color: #202020;
|
||||||
color: #000;
|
color: #202020;
|
||||||
border-radius: unset;
|
border-top-right-radius: 3px;
|
||||||
|
border-top-left-radius: 3px;
|
||||||
font-size: 1.1rem;
|
font-size: 1.1rem;
|
||||||
font-weight: bold;
|
font-weight: 400;
|
||||||
}
|
}
|
||||||
|
|
||||||
.card>.card-header .fa {
|
.card>.card-header .fa {
|
||||||
color: #000;
|
color: #202020;
|
||||||
}
|
}
|
||||||
|
|
||||||
.card-header [class^="fa"] {
|
.card-header [class^="fa"] {
|
||||||
color: #000;
|
color: #afafaf;
|
||||||
font-size: 1.0rem;
|
font-size: 1.0rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
.col {
|
.col {
|
||||||
color: #000;
|
color: #afafaf;
|
||||||
}
|
}
|
||||||
|
|
||||||
.card, .card-body {
|
.card, .card-body {
|
||||||
margin-bottom: 20px;
|
border-color: #343434;
|
||||||
border: .01rem solid #2bcb02;
|
border-radius: 3px;
|
||||||
border-radius: 0px;
|
background-color: #141414;
|
||||||
background-color: #000;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
hr {
|
hr {
|
||||||
border-top: .01rem solid #2bcb02;
|
border-top: .01rem solid #d2d2d2;
|
||||||
}
|
}
|
||||||
|
|
||||||
.page-header {
|
.page-header {
|
||||||
font-size: 24pt;
|
font-size: 24pt;
|
||||||
margin: 10px 0 20px;
|
margin: 10px 0 20px;
|
||||||
border-bottom: .01rem solid #2bcb02;
|
border-bottom: .01rem solid #d2d2d2;
|
||||||
}
|
}
|
||||||
|
|
||||||
.sidebar-brand-text {
|
.sidebar-brand-text {
|
||||||
text-transform: none;
|
text-transform: none;
|
||||||
color: #2bcb02;
|
color: #ac1b3d;
|
||||||
font-size: 2.0rem;
|
font-size: 2.0rem;
|
||||||
font-weight: 500;
|
font-weight: 500;
|
||||||
font-family: inherit;
|
font-family: inherit;
|
||||||
}
|
}
|
||||||
|
|
||||||
.sidebar-light #sidebarToggle {
|
.sidebar-light #sidebarToggle {
|
||||||
background-color: #2bcb02;
|
background-color: #202020;
|
||||||
|
border: 1px solid #afafaf !important
|
||||||
}
|
}
|
||||||
|
|
||||||
.sidebar-light #sidebarToggle::after {
|
.sidebar-light #sidebarToggle::after {
|
||||||
color: #000;
|
color: #afafaf;
|
||||||
}
|
}
|
||||||
|
|
||||||
.sidebar-light .nav-item .nav-link:hover i {
|
.sidebar-light .nav-item .nav-link:hover i {
|
||||||
color: #81ff61;
|
color: #d2d2d2;
|
||||||
}
|
}
|
||||||
|
|
||||||
.sidebar-light #sidebarToggle:hover {
|
.sidebar-light #sidebarToggle:hover {
|
||||||
background-color: #81ff61;
|
background-color: #202020;
|
||||||
}
|
}
|
||||||
|
|
||||||
.sidebar.toggled .nav-item .nav-link span {
|
.sidebar.toggled .nav-item .nav-link span {
|
||||||
@ -182,8 +172,8 @@ hr {
|
|||||||
}
|
}
|
||||||
|
|
||||||
.card-footer {
|
.card-footer {
|
||||||
background-color: #000;
|
background-color: #202020;
|
||||||
border-top: .01rem solid #2bcb02;
|
border-top: 0px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.card>.card-header::before, .navbar-default::before {
|
.card>.card-header::before, .navbar-default::before {
|
||||||
@ -194,30 +184,35 @@ hr {
|
|||||||
left: 0;
|
left: 0;
|
||||||
bottom: 0;
|
bottom: 0;
|
||||||
right: 0;
|
right: 0;
|
||||||
background: linear-gradient(rgba(18, 16, 16, 0) 50%, rgba(0, 0, 0, 0.25) 50%), linear-gradient(90deg, rgba(255, 0, 0, 0.06), rgba(0, 255, 0, 0.02), rgba(0, 0, 255, 0.06));
|
|
||||||
z-index: 2;
|
z-index: 2;
|
||||||
background-size: 100% 2px, 3px 100%;
|
background-size: 100% 2px, 3px 100%;
|
||||||
pointer-events: none;
|
pointer-events: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
.sidebar-light, .sticky-footer {
|
.sidebar-light, .sticky-footer {
|
||||||
background-color: #000;
|
background-color: #202020;
|
||||||
}
|
}
|
||||||
|
|
||||||
.sidebar-light .nav-item .nav-link i {
|
.sidebar-light .nav-item .nav-link i {
|
||||||
color: #2bcb02;
|
color: rgba(230, 230, 230, .3);
|
||||||
}
|
}
|
||||||
|
|
||||||
.sidebar .nav-item .nav-link {
|
.sidebar .nav-item .nav-link {
|
||||||
padding: 0.6rem;
|
padding: 0.6rem;
|
||||||
|
padding-left: 1.2rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
.sidebar-light hr.sidebar-divider {
|
.sidebar-light hr.sidebar-divider {
|
||||||
border-top: .01rem solid #2bcb02;
|
border-top: 1px solid #404040;
|
||||||
|
padding-top: 0.5rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.sidebar .nav-item .nav-link span {
|
||||||
|
font-size: 1.0rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
.topbar .topbar-divider {
|
.topbar .topbar-divider {
|
||||||
border-right: .01rem solid #2bcb02;
|
border-right: 1px solid #404040;
|
||||||
}
|
}
|
||||||
|
|
||||||
.info-item {
|
.info-item {
|
||||||
@ -226,9 +221,9 @@ hr {
|
|||||||
}
|
}
|
||||||
|
|
||||||
.info-item-xs {
|
.info-item-xs {
|
||||||
font-family: Verdana, Arial, sans-serif;
|
|
||||||
font-size: 0.7rem;
|
font-size: 0.7rem;
|
||||||
margin-left: 0.3rem;
|
line-height: 1.5em;
|
||||||
|
margin-left: 0.5rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
.info-item-wifi {
|
.info-item-wifi {
|
||||||
@ -237,11 +232,11 @@ hr {
|
|||||||
}
|
}
|
||||||
|
|
||||||
.label-warning {
|
.label-warning {
|
||||||
background-color: #2bcb02;
|
background-color: #d2d2d2;
|
||||||
}
|
}
|
||||||
|
|
||||||
span.label.label-warning {
|
span.label.label-warning {
|
||||||
color: #000;
|
color: #202020;
|
||||||
}
|
}
|
||||||
|
|
||||||
.table>tbody>tr>td,
|
.table>tbody>tr>td,
|
||||||
@ -250,29 +245,27 @@ span.label.label-warning {
|
|||||||
.table>tfoot>tr>th,
|
.table>tfoot>tr>th,
|
||||||
.table>thead>tr>td,
|
.table>thead>tr>td,
|
||||||
.table>thead>tr>th {
|
.table>thead>tr>th {
|
||||||
background-color: #000;
|
background-color: #202020;
|
||||||
border-top: .01rem solid #000;
|
border-top: .01rem solid #202020;
|
||||||
}
|
}
|
||||||
|
|
||||||
.table>thead>tr>th {
|
.table>thead>tr>th {
|
||||||
vertical-align: bottom;
|
vertical-align: bottom;
|
||||||
border-bottom: .01rem solid #2bcb02;
|
border-bottom: .01rem solid #d2d2d2;
|
||||||
}
|
}
|
||||||
|
|
||||||
[class*="btn"], [class*="btn"]:focus, [class*="btn"]:disabled {
|
[class*="btn"], [class*="btn"]:focus, [class*="btn"]:disabled {
|
||||||
background-color: #000;
|
background-color: #202020;
|
||||||
border-color: #2bcb02;
|
border-color: #404040;
|
||||||
border-color: #2bcb02;
|
border-radius: 3px;
|
||||||
border-radius: 0px;
|
color: #d2d2d2;
|
||||||
color: #2bcb02;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
[class*="btn"]:hover {
|
[class*="btn"]:hover {
|
||||||
background-color: #81ff61;
|
border-radius: 3px;
|
||||||
border-color: #81ff61;
|
color: #d2d2d2;
|
||||||
border-color: #81ff61;
|
background-color: #202020;
|
||||||
border-radius: 0px;
|
border-color: #afafaf;
|
||||||
color: #000;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
[class*="btn"]:hover .disabled {
|
[class*="btn"]:hover .disabled {
|
||||||
@ -281,72 +274,67 @@ span.label.label-warning {
|
|||||||
|
|
||||||
[class*="alert"] {
|
[class*="alert"] {
|
||||||
border-radius: 0px;
|
border-radius: 0px;
|
||||||
color: #2bcb02;
|
color: #d2d2d2;
|
||||||
background-color: #000;
|
background-color: #202020;
|
||||||
border-color: #2bcb02;
|
border-color: #d2d2d2;
|
||||||
border: 1px dashed;
|
border: 1px dashed;
|
||||||
}
|
}
|
||||||
|
|
||||||
.close {
|
.close {
|
||||||
font-size: 18px;
|
font-size: 18px;
|
||||||
font-weight: normal;
|
font-weight: normal;
|
||||||
text-shadow: 0 0px 0 #000;
|
text-shadow: 0 0px 0 #202020;
|
||||||
opacity: 1;
|
opacity: 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
.form-control,
|
.form-control,
|
||||||
.form-control:focus {
|
.form-control:focus {
|
||||||
color: #2bcb02;
|
color: #d2d2d2;
|
||||||
background-color: #000;
|
background-color: #202020;
|
||||||
border: .01rem solid #2bcb02;
|
border: 1px solid #404040;
|
||||||
border-radius: 0px;
|
border-radius: 3px;
|
||||||
transition: unset;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.form-control:disabled,
|
.form-control:disabled,
|
||||||
.form-control[readonly] {
|
.form-control[readonly] {
|
||||||
background-color: #000;
|
background-color: #202020;
|
||||||
opacity: 0.5;
|
opacity: 0.5;
|
||||||
}
|
}
|
||||||
|
|
||||||
.form-control::-webkit-input-placeholder { color: #2bcb02; }
|
.form-control::-webkit-input-placeholder { color: #d2d2d2; }
|
||||||
.form-control:-moz-placeholder { color: #2bcb02; }
|
.form-control:-moz-placeholder { color: #d2d2d2; }
|
||||||
.form-control::-moz-placeholder { color: #2bcb02; }
|
.form-control::-moz-placeholder { color: #d2d2d2; }
|
||||||
.form-control:-ms-input-placeholder { color: #2bcb02; }
|
.form-control:-ms-input-placeholder { color: #d2d2d2; }
|
||||||
.form-control::-ms-input-placeholder { color: #2bcb02; }
|
.form-control::-ms-input-placeholder { color: #d2d2d2; }
|
||||||
|
|
||||||
input[type="text"]{
|
input[type="text"]{
|
||||||
color: #2bcb02 !important
|
color: #d2d2d2 !important
|
||||||
}
|
}
|
||||||
|
|
||||||
.progress {
|
.progress {
|
||||||
background-color: #000;
|
background-color: #202020;
|
||||||
border-radius: 0px;
|
border-radius: 0px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.progress-bar {
|
.progress-bar {
|
||||||
color: #000;
|
color: #202020;
|
||||||
}
|
}
|
||||||
|
|
||||||
.progress-bar.progress-bar-info.progress-bar-striped.active {
|
.progress-bar.progress-bar-info.progress-bar-striped.active {
|
||||||
background-color: #2bcb02;
|
background-color: #d2d2d2;
|
||||||
}
|
}
|
||||||
|
|
||||||
.logoutput {
|
.logoutput {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
height: 300px;
|
height: 300px;
|
||||||
background-color: #000;
|
background-color: #202020;
|
||||||
border-color: #2bcb02;
|
border-color: #404040;
|
||||||
}
|
}
|
||||||
|
|
||||||
.webconsole {
|
.webconsole {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
height: 100%;
|
height: 20rem;
|
||||||
border-color: #2bcb02;
|
border: 1px solid #404040;
|
||||||
border-bottom: .01rem solid;
|
|
||||||
border-left: .01rem solid;
|
|
||||||
border-top: 0px;
|
|
||||||
border-right: .01rem solid;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#console {
|
#console {
|
||||||
@ -354,11 +342,7 @@ color: #2bcb02 !important
|
|||||||
}
|
}
|
||||||
|
|
||||||
tspan, rect {
|
tspan, rect {
|
||||||
fill: #2bcb02;
|
fill: #d2d2d2;
|
||||||
}
|
|
||||||
|
|
||||||
.service-status {
|
|
||||||
border-width: 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
span.text.service-status {
|
span.text.service-status {
|
||||||
@ -366,16 +350,24 @@ span.text.service-status {
|
|||||||
margin-top: 0.2rem;
|
margin-top: 0.2rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.text-muted {
|
||||||
|
font-size: 0.8rem;
|
||||||
|
}
|
||||||
|
|
||||||
.fas.fa-circle {
|
.fas.fa-circle {
|
||||||
font-size: 0.5rem;
|
font-size: 0.5rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
i.fas.fa-circle.service-status-up {
|
.service-status-up {
|
||||||
color: #2bcb02;
|
color: #a1ec38 !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
i.fas.fa-circle.service-status-down {
|
.service-status-warn {
|
||||||
color: #2bcb02;
|
color: #f6f044 !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.service-status-down {
|
||||||
|
color: #f80107 !important;
|
||||||
animation: flash 1s linear infinite;
|
animation: flash 1s linear infinite;
|
||||||
}
|
}
|
||||||
@keyframes flash {
|
@keyframes flash {
|
||||||
@ -385,8 +377,8 @@ i.fas.fa-circle.service-status-down {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pre {
|
pre {
|
||||||
background-color: #000;
|
background-color: #202020;
|
||||||
border: #000;
|
border: #202020;
|
||||||
}
|
}
|
||||||
|
|
||||||
.dhcp-static-leases {
|
.dhcp-static-leases {
|
||||||
@ -420,3 +412,7 @@ canvas#divDBChartBandwidthhourly {
|
|||||||
.table {
|
.table {
|
||||||
margin-bottom: 0rem;
|
margin-bottom: 0rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.figure, .authors {
|
||||||
|
filter: brightness(70%) !important;
|
||||||
|
}
|
@ -356,7 +356,7 @@ function getCookie(cname) {
|
|||||||
var themes = {
|
var themes = {
|
||||||
"default": "custom.css",
|
"default": "custom.css",
|
||||||
"hackernews" : "hackernews.css",
|
"hackernews" : "hackernews.css",
|
||||||
"terminal" : "terminal.css",
|
"lightsout" : "lightsout.css",
|
||||||
}
|
}
|
||||||
|
|
||||||
// Toggles the sidebar navigation.
|
// Toggles the sidebar navigation.
|
||||||
|
@ -1,12 +1,12 @@
|
|||||||
// Link quality gauge for ChartJS
|
// Link quality gauge for ChartJS
|
||||||
|
|
||||||
// Support for dark terminal theme
|
// Support for dark theme
|
||||||
theme = getCookie('theme');
|
theme = getCookie('theme');
|
||||||
if (theme == 'terminal.css') {
|
if (theme == 'lightsout.css') {
|
||||||
var bgColor1 = '#000';
|
var bgColor1 = '#141414';
|
||||||
var bgColor2 = '#000';
|
var bgColor2 = '#141414';
|
||||||
var borderColor = 'rgba(46, 230, 0, 1)';
|
var borderColor = 'rgba(37, 153, 63, 1)';
|
||||||
var labelColor = 'rgba(46, 230, 0, 1)';
|
var labelColor = 'rgba(37, 153, 63, 1)';
|
||||||
} else {
|
} else {
|
||||||
var bgColor1 = '#d4edda';
|
var bgColor1 = '#d4edda';
|
||||||
var bgColor2 = '#eaecf4';
|
var bgColor2 = '#eaecf4';
|
||||||
|
98
app/pitft/stats.py
Normal file
98
app/pitft/stats.py
Normal file
@ -0,0 +1,98 @@
|
|||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
#
|
||||||
|
# Author: @billz
|
||||||
|
# Author URI: https://github.com/billz
|
||||||
|
# Description: RaspAP stats display for the Adafruit Mini PiTFT,
|
||||||
|
# a 135x240 Color TFT add-on for the Raspberry Pi.
|
||||||
|
# Based on Adafruit's rgb_display_ministats.py
|
||||||
|
# See: https://github.com/adafruit/Adafruit_CircuitPython_RGB_Display
|
||||||
|
# License: MIT License
|
||||||
|
|
||||||
|
import time
|
||||||
|
import subprocess
|
||||||
|
import digitalio
|
||||||
|
import board
|
||||||
|
from PIL import Image, ImageDraw, ImageFont
|
||||||
|
import adafruit_rgb_display.st7789 as st7789
|
||||||
|
|
||||||
|
# Configuration for CS and DC pins
|
||||||
|
cs_pin = digitalio.DigitalInOut(board.CE0)
|
||||||
|
dc_pin = digitalio.DigitalInOut(board.D25)
|
||||||
|
reset_pin = None
|
||||||
|
|
||||||
|
# Config for display baudrate (default max is 24mhz)
|
||||||
|
BAUDRATE = 64000000
|
||||||
|
|
||||||
|
# Setup SPI bus using hardware SPI
|
||||||
|
spi = board.SPI()
|
||||||
|
|
||||||
|
# Create the ST7789 display
|
||||||
|
disp = st7789.ST7789(spi, cs=cs_pin, dc=dc_pin, rst=reset_pin, baudrate=BAUDRATE,
|
||||||
|
width=135, height=240, x_offset=53, y_offset=40)
|
||||||
|
|
||||||
|
# Create blank image with mode 'RGB'
|
||||||
|
height = disp.width # swap height/width to rotate it to landscape
|
||||||
|
width = disp.height
|
||||||
|
image = Image.new('RGB', (width, height))
|
||||||
|
rotation = 90
|
||||||
|
|
||||||
|
# Get a drawing object and clear the image
|
||||||
|
draw = ImageDraw.Draw(image)
|
||||||
|
draw.rectangle((0, 0, width, height), outline=0, fill=(0, 0, 0))
|
||||||
|
disp.image(image,rotation)
|
||||||
|
|
||||||
|
# Define some constants
|
||||||
|
padding = -2
|
||||||
|
top = padding
|
||||||
|
bottom = height-padding
|
||||||
|
# Move left to right keeping track of the current x position
|
||||||
|
x = 0
|
||||||
|
|
||||||
|
# Load DejaVu TTF Font
|
||||||
|
# Install with: sudo apt-get install ttf-dejavu
|
||||||
|
font = ImageFont.truetype('/usr/share/fonts/truetype/dejavu/DejaVuSans.ttf', 24)
|
||||||
|
|
||||||
|
# Turn on the backlight
|
||||||
|
backlight = digitalio.DigitalInOut(board.D22)
|
||||||
|
backlight.switch_to_output()
|
||||||
|
backlight.value = True
|
||||||
|
|
||||||
|
while True:
|
||||||
|
# Draw a black filled box to clear the image
|
||||||
|
draw.rectangle((0, 0, width, height), outline=0, fill=0)
|
||||||
|
|
||||||
|
# Collect basic system stats
|
||||||
|
cmd = "hostname -I | cut -d\' \' -f1"
|
||||||
|
IP = "IP: "+subprocess.check_output(cmd, shell=True).decode("utf-8")
|
||||||
|
|
||||||
|
cmd = "pidof hostapd | wc -l | awk '{printf \"Hotspot: %s\", $1 == 1 ? \"Active\" : \"Down\"}'"
|
||||||
|
Hostapd = subprocess.check_output(cmd, shell=True).decode("utf-8")
|
||||||
|
|
||||||
|
cmd = "vnstat -i wlan0 | grep tx: | awk '{printf \"Data Tx: %d %s\", $5,$6}'"
|
||||||
|
DataTx = subprocess.check_output(cmd, shell=True).decode("utf-8")
|
||||||
|
|
||||||
|
cmd = "top -bn1 | grep load | awk '{printf \"CPU Load: %.2f\", $(NF-2)}'"
|
||||||
|
CPU = subprocess.check_output(cmd, shell=True).decode("utf-8")
|
||||||
|
|
||||||
|
cmd = "free -m | awk 'NR==2{printf \"Mem: %sMB %.2f%%\", $3,$3*100/$2 }'"
|
||||||
|
MemUsage = subprocess.check_output(cmd, shell=True).decode("utf-8")
|
||||||
|
|
||||||
|
cmd = "cat /sys/class/thermal/thermal_zone0/temp | awk \'{printf \"CPU Temp: %.1f C\", $(NF-0) / 1000}\'" # pylint: disable=line-too-long
|
||||||
|
Temp = subprocess.check_output(cmd, shell=True).decode("utf-8")
|
||||||
|
|
||||||
|
# Write five lines of stats
|
||||||
|
y = top
|
||||||
|
draw.text((x, y), IP, font=font, fill="#ffaaaa")
|
||||||
|
y += font.getsize(IP)[1]
|
||||||
|
draw.text((x, y), Hostapd, font=font, fill="#d46a6a")
|
||||||
|
y += font.getsize(Hostapd)[1]
|
||||||
|
draw.text((x, y), DataTx, font=font, fill="#aa3939")
|
||||||
|
y += font.getsize(DataTx)[1]
|
||||||
|
draw.text((x, y), MemUsage, font=font, fill="#801515")
|
||||||
|
y += font.getsize(MemUsage)[1]
|
||||||
|
draw.text((x, y), Temp, font=font, fill="#550000")
|
||||||
|
|
||||||
|
# Display image
|
||||||
|
disp.image(image, rotation)
|
||||||
|
time.sleep(.1)
|
||||||
|
|
@ -65,7 +65,12 @@ function DisplayDHCPConfig()
|
|||||||
foreach ($_POST['server'] as $server) {
|
foreach ($_POST['server'] as $server) {
|
||||||
$config .= "server=$server".PHP_EOL;
|
$config .= "server=$server".PHP_EOL;
|
||||||
}
|
}
|
||||||
|
if ($_POST['log-dhcp'] == "1") {
|
||||||
|
$config .= "log-dhcp".PHP_EOL;
|
||||||
|
}
|
||||||
|
if ($_POST['log-queries'] == "1") {
|
||||||
|
$config .= "log-queries".PHP_EOL;
|
||||||
|
}
|
||||||
if ($_POST['DNS1']) {
|
if ($_POST['DNS1']) {
|
||||||
$config .= "dhcp-option=6," . $_POST['DNS1'];
|
$config .= "dhcp-option=6," . $_POST['DNS1'];
|
||||||
if ($_POST['DNS2']) {
|
if ($_POST['DNS2']) {
|
||||||
@ -74,6 +79,7 @@ function DisplayDHCPConfig()
|
|||||||
$config .= PHP_EOL;
|
$config .= PHP_EOL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$config .= "log-facility=/tmp/dnsmasq.log".PHP_EOL;
|
||||||
$config .= "conf-dir=/etc/dnsmasq.d".PHP_EOL;
|
$config .= "conf-dir=/etc/dnsmasq.d".PHP_EOL;
|
||||||
|
|
||||||
file_put_contents("/tmp/dnsmasqdata", $config);
|
file_put_contents("/tmp/dnsmasqdata", $config);
|
||||||
|
@ -271,15 +271,15 @@ function ConvertToSecurity($security)
|
|||||||
/**
|
/**
|
||||||
* Renders a simple PHP template
|
* Renders a simple PHP template
|
||||||
*/
|
*/
|
||||||
function renderTemplate($name, $data = [])
|
function renderTemplate($name, $__template_data = [])
|
||||||
{
|
{
|
||||||
$file = realpath(dirname(__FILE__) . "/../templates/$name.php");
|
$file = realpath(dirname(__FILE__) . "/../templates/$name.php");
|
||||||
if (!file_exists($file)) {
|
if (!file_exists($file)) {
|
||||||
return "template $name ($file) not found";
|
return "template $name ($file) not found";
|
||||||
}
|
}
|
||||||
|
|
||||||
if (is_array($data)) {
|
if (is_array($__template_data)) {
|
||||||
extract($data);
|
extract($__template_data);
|
||||||
}
|
}
|
||||||
|
|
||||||
ob_start();
|
ob_start();
|
||||||
|
@ -8,12 +8,12 @@ function DisplayThemeConfig()
|
|||||||
$themes = [
|
$themes = [
|
||||||
"default" => "RaspAP (default)",
|
"default" => "RaspAP (default)",
|
||||||
"hackernews" => "HackerNews",
|
"hackernews" => "HackerNews",
|
||||||
"terminal" => "Terminal"
|
"lightsout" => "Lights Out"
|
||||||
];
|
];
|
||||||
$themeFiles = [
|
$themeFiles = [
|
||||||
"default" => "custom.css",
|
"default" => "custom.css",
|
||||||
"hackernews" => "hackernews.css",
|
"hackernews" => "hackernews.css",
|
||||||
"terminal" => "terminal.css"
|
"lightsout" => "lightsout.css"
|
||||||
];
|
];
|
||||||
$selectedTheme = array_search($_COOKIE['theme'], $themeFiles);
|
$selectedTheme = array_search($_COOKIE['theme'], $themeFiles);
|
||||||
|
|
||||||
|
@ -8,6 +8,7 @@ raspap_dir="/etc/raspap"
|
|||||||
raspap_user="www-data"
|
raspap_user="www-data"
|
||||||
webroot_dir="/var/www/html"
|
webroot_dir="/var/www/html"
|
||||||
version=`sed 's/\..*//' /etc/debian_version`
|
version=`sed 's/\..*//' /etc/debian_version`
|
||||||
|
git_source_url="https://github.com/$repo" # $repo from install.raspap.com
|
||||||
|
|
||||||
# Determine Raspbian version, set default home location for lighttpd and
|
# Determine Raspbian version, set default home location for lighttpd and
|
||||||
# php package to install
|
# php package to install
|
||||||
@ -108,6 +109,13 @@ function create_hostapd_scripts() {
|
|||||||
sudo chmod 750 "$raspap_dir/hostapd/"*.sh || install_error "Unable to change file permissions"
|
sudo chmod 750 "$raspap_dir/hostapd/"*.sh || install_error "Unable to change file permissions"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# Generate dnsmasq logfile
|
||||||
|
function create_dnsmasq_log() {
|
||||||
|
install_log "Creating dnsmasq logfile"
|
||||||
|
sudo touch /tmp/dnsmasq.log || install_error "Unable to create logfile /tmp/dnsmasq.log"
|
||||||
|
sudo chown dnsmasq:"$raspap_user" /tmp/dnsmasq.log || install_error "Unable to change file ownership"
|
||||||
|
}
|
||||||
|
|
||||||
# Generate lighttpd service control scripts
|
# Generate lighttpd service control scripts
|
||||||
function create_lighttpd_scripts() {
|
function create_lighttpd_scripts() {
|
||||||
install_log "Creating lighttpd control scripts"
|
install_log "Creating lighttpd control scripts"
|
||||||
@ -169,8 +177,8 @@ function download_latest_files() {
|
|||||||
fi
|
fi
|
||||||
|
|
||||||
install_log "Cloning latest files from github"
|
install_log "Cloning latest files from github"
|
||||||
# git clone --depth 1 https://github.com/billz/raspap-webgui /tmp/raspap-webgui || install_error "Unable to download files from github"
|
git clone --single-branch $branch --depth 1 $git_source_url /tmp/raspap-webgui || install_error "Unable to download files from github"
|
||||||
git clone --single-branch --branch bridge-mode --depth 1 https://github.com/Taikuh/raspap-webgui /tmp/raspap-webgui || install_error "Unable to download files from github"
|
|
||||||
sudo mv /tmp/raspap-webgui $webroot_dir || install_error "Unable to move raspap-webgui to web root"
|
sudo mv /tmp/raspap-webgui $webroot_dir || install_error "Unable to move raspap-webgui to web root"
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -256,6 +264,8 @@ function default_configuration() {
|
|||||||
'echo 1 > \/proc\/sys\/net\/ipv4\/ip_forward #RASPAP'
|
'echo 1 > \/proc\/sys\/net\/ipv4\/ip_forward #RASPAP'
|
||||||
'iptables -t nat -A POSTROUTING -j MASQUERADE #RASPAP'
|
'iptables -t nat -A POSTROUTING -j MASQUERADE #RASPAP'
|
||||||
'iptables -t nat -A POSTROUTING -s 192.168.50.0\/24 ! -d 192.168.50.0\/24 -j MASQUERADE #RASPAP'
|
'iptables -t nat -A POSTROUTING -s 192.168.50.0\/24 ! -d 192.168.50.0\/24 -j MASQUERADE #RASPAP'
|
||||||
|
'chown dnsmasq:www-data \/tmp\/dnsmasq.log #RASPAP'
|
||||||
|
'chown root:www-data \/tmp\/hostapd.log #RASPAP'
|
||||||
)
|
)
|
||||||
|
|
||||||
for line in "${lines[@]}"; do
|
for line in "${lines[@]}"; do
|
||||||
@ -451,6 +461,7 @@ function install_raspap() {
|
|||||||
download_latest_files
|
download_latest_files
|
||||||
change_file_ownership
|
change_file_ownership
|
||||||
create_hostapd_scripts
|
create_hostapd_scripts
|
||||||
|
create_dnsmasq_log
|
||||||
create_lighttpd_scripts
|
create_lighttpd_scripts
|
||||||
move_config_file
|
move_config_file
|
||||||
default_configuration
|
default_configuration
|
||||||
|
@ -24,9 +24,9 @@
|
|||||||
# Depending on options passed to the installer, ONE of the following
|
# Depending on options passed to the installer, ONE of the following
|
||||||
# additional shell scripts will be downloaded and sourced:
|
# additional shell scripts will be downloaded and sourced:
|
||||||
#
|
#
|
||||||
# https://raw.githubusercontent.com/billz/raspap-webgui/installers/common.sh
|
# https://raw.githubusercontent.com/billz/raspap-webgui/master/installers/common.sh
|
||||||
# - or -
|
# - or -
|
||||||
# https://raw.githubusercontent.com/billz/raspap-webgui/installers/mkcert.sh
|
# https://raw.githubusercontent.com/billz/raspap-webgui/master/installers/mkcert.sh
|
||||||
|
|
||||||
# Set defaults
|
# Set defaults
|
||||||
repo="billz/raspap-webgui"
|
repo="billz/raspap-webgui"
|
||||||
|
@ -11,7 +11,7 @@
|
|||||||
<div class="card-body text-center">
|
<div class="card-body text-center">
|
||||||
<h3><?php echo _("RaspAP") . " v" . RASPI_VERSION; ?></h3>
|
<h3><?php echo _("RaspAP") . " v" . RASPI_VERSION; ?></h3>
|
||||||
<h5><a href="https://github.com/billz/raspap-webgui/blob/master/LICENSE">GNU General Public License v3.0</a></h5>
|
<h5><a href="https://github.com/billz/raspap-webgui/blob/master/LICENSE">GNU General Public License v3.0</a></h5>
|
||||||
<p><img src="app/img/authors-8bit-200px.png"></p>
|
<p><img class="authors" src="app/img/authors-8bit-200px.png"></p>
|
||||||
<p>RaspAP is a co-creation of <a href="https://github.com/billz">@billz</a> and <a href="https://github.com/sirlagz">@SirLagz</a><br />
|
<p>RaspAP is a co-creation of <a href="https://github.com/billz">@billz</a> and <a href="https://github.com/sirlagz">@SirLagz</a><br />
|
||||||
with the contributions of our <a href="https://github.com/billz/raspap-webgui/graphs/contributors">community</a>.</p>
|
with the contributions of our <a href="https://github.com/billz/raspap-webgui/graphs/contributors">community</a>.</p>
|
||||||
<p><i class="fab fa-github"></i> <a href="https://github.com/billz/raspap-webgui">https://github.com/billz/raspap-webgui</a></p>
|
<p><i class="fab fa-github"></i> <a href="https://github.com/billz/raspap-webgui">https://github.com/billz/raspap-webgui</a></p>
|
||||||
|
@ -10,8 +10,9 @@
|
|||||||
<?php $buttons = ob_get_clean(); ob_end_clean() ?>
|
<?php $buttons = ob_get_clean(); ob_end_clean() ?>
|
||||||
|
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="col-lg-12">
|
<div class="col-lg-12">
|
||||||
<div class="card">
|
<div class="card">
|
||||||
|
|
||||||
<div class="card-header">
|
<div class="card-header">
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="col">
|
<div class="col">
|
||||||
@ -25,237 +26,36 @@
|
|||||||
</div>
|
</div>
|
||||||
</div><!-- /.row -->
|
</div><!-- /.row -->
|
||||||
</div><!-- /.card-header -->
|
</div><!-- /.card-header -->
|
||||||
|
|
||||||
<div class="card-body">
|
<div class="card-body">
|
||||||
<?php $status->showMessages(); ?>
|
<?php $status->showMessages(); ?>
|
||||||
<form method="POST" action="?page=dhcpd_conf" class="js-dhcp-settings-form">
|
<form method="POST" action="?page=dhcpd_conf" class="js-dhcp-settings-form">
|
||||||
<?php echo CSRFTokenFieldTag() ?>
|
<?php echo CSRFTokenFieldTag() ?>
|
||||||
|
|
||||||
<!-- Nav tabs -->
|
<!-- Nav tabs -->
|
||||||
<ul class="nav nav-tabs mb-4">
|
<ul class="nav nav-tabs mb-3">
|
||||||
<li class="nav-item"><a class="nav-link active" href="#server-settings" data-toggle="tab"><?php echo _("Server settings"); ?></a></li>
|
<li class="nav-item"><a class="nav-link active" href="#server-settings" data-toggle="tab"><?php echo _("Server settings"); ?></a></li>
|
||||||
<li class="nav-item"><a class="nav-link" href="#advanced" data-toggle="tab"><?php echo _("Advanced"); ?></a></li>
|
<li class="nav-item"><a class="nav-link" href="#advanced" data-toggle="tab"><?php echo _("Advanced"); ?></a></li>
|
||||||
<li class="nav-item"><a class="nav-link" href="#static-leases" data-toggle="tab"><?php echo _("Static Leases") ?></a></li>
|
<li class="nav-item"><a class="nav-link" href="#static-leases" data-toggle="tab"><?php echo _("Static Leases") ?></a></li>
|
||||||
<li class="nav-item"><a class="nav-link" href="#client-list" data-toggle="tab"><?php echo _("Client list"); ?></a></li>
|
<li class="nav-item"><a class="nav-link" href="#client-list" data-toggle="tab"><?php echo _("Client list"); ?></a></li>
|
||||||
|
<li class="nav-item"><a class="nav-link" href="#logging" data-toggle="tab"><?php echo _("Logging"); ?></a></li>
|
||||||
</ul>
|
</ul>
|
||||||
|
|
||||||
<!-- Tab panes -->
|
<!-- Tab panes -->
|
||||||
<div class="tab-content">
|
<div class="tab-content">
|
||||||
<div class="tab-pane active" id="server-settings">
|
<?php echo renderTemplate("dhcp/general", $__template_data) ?>
|
||||||
<h4 class="mt-3">DHCP server settings</h4>
|
<?php echo renderTemplate("dhcp/advanced", $__template_data) ?>
|
||||||
<div class="row">
|
<?php echo renderTemplate("dhcp/clients", $__template_data) ?>
|
||||||
<div class="form-group col-md-6">
|
<?php echo renderTemplate("dhcp/static_leases", $__template_data) ?>
|
||||||
<label for="code">Interface</label>
|
<?php echo renderTemplate("dhcp/logging", $__template_data) ?>
|
||||||
<select class="form-control" name="interface">
|
</div><!-- /.tab-content -->
|
||||||
<?php foreach ($interfaces as $if) : ?>
|
|
||||||
<?php $if_quoted = htmlspecialchars($if, ENT_QUOTES) ?>
|
|
||||||
<?php $selected = $if === $conf['interface'] ? ' selected="selected"' : '' ?>
|
|
||||||
<option value="<?php echo $if_quoted ?>"<?php echo $selected ?>><?php echo $if_quoted ?></option>
|
|
||||||
<?php endforeach ?>
|
|
||||||
</select>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="row">
|
|
||||||
<div class="form-group col-md-6">
|
|
||||||
<label for="code"><?php echo _("Starting IP Address"); ?></label>
|
|
||||||
<input type="text" class="form-control"name="RangeStart" value="<?php echo htmlspecialchars($RangeStart, ENT_QUOTES); ?>" />
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="row">
|
|
||||||
<div class="form-group col-md-6">
|
|
||||||
<label for="code"><?php echo _("Ending IP Address"); ?></label>
|
|
||||||
<input type="text" class="form-control" name="RangeEnd" value="<?php echo htmlspecialchars($RangeEnd, ENT_QUOTES); ?>" />
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="row">
|
|
||||||
<div class="form-group col-xs-3 col-sm-3">
|
|
||||||
<label for="code"><?php echo _("Lease Time"); ?></label>
|
|
||||||
<input type="text" class="form-control" name="RangeLeaseTime" value="<?php echo htmlspecialchars($arrRangeLeaseTime[1], ENT_QUOTES); ?>" />
|
|
||||||
</div>
|
|
||||||
<div class="col-xs-3 col-sm-3">
|
|
||||||
<label for="code"><?php echo _("Interval"); ?></label>
|
|
||||||
<select name="RangeLeaseTimeUnits" class="form-control" >
|
|
||||||
<option value="m"<?php echo $mselected; ?>><?php echo _("Minute(s)"); ?></option>
|
|
||||||
<option value="h"<?php echo $hselected; ?>><?php echo _("Hour(s)"); ?></option>
|
|
||||||
<option value="d"<?php echo $dselected; ?>><?php echo _("Day(s)"); ?></option>
|
|
||||||
<option value="infinite"<?php echo $infiniteselected; ?>><?php echo _("Infinite"); ?></option>
|
|
||||||
</select>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="row">
|
|
||||||
<div class="form-group col-md-6">
|
|
||||||
<label for="code"><?php echo _("DNS Server"); ?> 1</label>
|
|
||||||
<input type="text" class="form-control"name="DNS1" value="<?php echo htmlspecialchars($DNS1, ENT_QUOTES); ?>" />
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="row">
|
|
||||||
<div class="form-group col-md-6">
|
|
||||||
<label for="code"><?php echo _("DNS Server"); ?> 2</label>
|
|
||||||
<input type="text" class="form-control" name="DNS2" value="<?php echo htmlspecialchars($DNS2, ENT_QUOTES); ?>" />
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<?php echo $buttons ?>
|
<?php echo $buttons ?>
|
||||||
|
</form>
|
||||||
|
</div><!-- ./ card-body -->
|
||||||
|
|
||||||
</div><!-- /.tab-pane -->
|
<div class="card-footer"> <?php echo _("Information provided by Dnsmasq"); ?></div>
|
||||||
|
|
||||||
|
|
||||||
<!-- advanced tab -->
|
|
||||||
<div class="tab-pane" id="advanced">
|
|
||||||
|
|
||||||
<div class="row">
|
|
||||||
<div class="col-md-6">
|
|
||||||
<h5><?php echo _("Upstream DNS servers") ?></h5>
|
|
||||||
|
|
||||||
<div class="input-group">
|
|
||||||
<input type="hidden" name="no-resolv" value="0">
|
|
||||||
<div class="custom-control custom-switch">
|
|
||||||
<input class="custom-control-input" id="no-resolv" type="checkbox" name="no-resolv" value="1" <?php echo $conf['no-resolv'] ? ' checked="checked"' : "" ?> aria-describedby="no-resolv-description">
|
|
||||||
<label class="custom-control-label" for="no-resolv"><?php echo _("Only ever query DNS servers configured below") ?></label>
|
|
||||||
</div>
|
|
||||||
<p id="no-resolv-description">
|
|
||||||
<small><?php echo _("Enable this option if you want RaspAP to <b>send DNS queries to the servers configured below exclusively</b>. By default RaspAP also uses its upstream DHCP server's name servers.") ?></small>
|
|
||||||
<br><small class="text-muted"><?php echo _("This option adds <code>no-resolv</code> to the dnsmasq configuration.") ?></small>
|
|
||||||
</p>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="js-dhcp-upstream-servers">
|
|
||||||
<?php foreach ($upstreamServers as $server): ?>
|
|
||||||
<div class="form-group input-group input-group-sm js-dhcp-upstream-server">
|
|
||||||
<input type="text" class="form-control" name="server[]" value="<?php echo $server ?>">
|
|
||||||
<div class="input-group-append">
|
|
||||||
<button class="btn btn-outline-secondary js-remove-dhcp-upstream-server" type="button"><i class="fas fa-minus"></i></button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<?php endforeach ?>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="form-group">
|
|
||||||
<label for="add-dhcp-upstream-server-field"><?php echo _("Add upstream DNS server") ?></label>
|
|
||||||
<div class="input-group">
|
|
||||||
<input type="text" class="form-control" id="add-dhcp-upstream-server-field" aria-describedby="new-dhcp-upstream-server" placeholder="<?php printf(_("e.g. %s"), "208.67.222.222") ?>">
|
|
||||||
<div class="input-group-append">
|
|
||||||
<button type="button" class="btn btn-outline-secondary js-add-dhcp-upstream-server"><i class="fas fa-plus"></i></button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<p id="new-dhcp-upstream-server" class="form-text text-muted">
|
|
||||||
<small>
|
|
||||||
<?php echo _("Format: ") ?>
|
|
||||||
<code class="text-muted"><?php echo htmlspecialchars("[/[<domain>]/[domain/]][<ipaddr>[#<port>][@<source-ip>|<interface>[#<port>]]"); ?></code>
|
|
||||||
</small>
|
|
||||||
</p>
|
|
||||||
<select class="custom-select custom-select-sm js-field-preset" data-field-preset-target="#add-dhcp-upstream-server-field">
|
|
||||||
<option value=""><?php echo _("Choose a hosted server") ?></option>
|
|
||||||
<option disabled="disabled"></option>
|
|
||||||
<?php echo optionsForSelect(dnsServers()) ?>
|
|
||||||
</select>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<template id="dhcp-upstream-server">
|
|
||||||
<div class="form-group input-group input-group-sm js-dhcp-upstream-server">
|
|
||||||
<input type="text" class="form-control" name="server[]" value="{{ server }}">
|
|
||||||
<div class="input-group-append">
|
|
||||||
<button class="btn btn-outline-secondary js-remove-dhcp-upstream-server" type="button"><i class="fas fa-minus"></i></button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
</div><!-- /.row -->
|
|
||||||
|
|
||||||
<?php echo $buttons ?>
|
|
||||||
|
|
||||||
</div><!-- /.tab-pane | advanded tab -->
|
|
||||||
|
|
||||||
<div class="tab-pane fade" id="client-list">
|
|
||||||
<h4 class="mt-3 mb-3">Client list</h4>
|
|
||||||
<div class="row">
|
|
||||||
<div class="col-lg-12">
|
|
||||||
<div class="card">
|
|
||||||
<div class="card-header"><?php echo _("Active DHCP leases"); ?></div>
|
|
||||||
<!-- /.panel-heading -->
|
|
||||||
<div class="card-body">
|
|
||||||
<div class="table-responsive">
|
|
||||||
<table class="table table-hover">
|
|
||||||
<thead>
|
|
||||||
<tr>
|
|
||||||
<th><?php echo _("Expire time"); ?></th>
|
|
||||||
<th><?php echo _("MAC Address"); ?></th>
|
|
||||||
<th><?php echo _("IP Address"); ?></th>
|
|
||||||
<th><?php echo _("Host name"); ?></th>
|
|
||||||
<th><?php echo _("Client ID"); ?></th>
|
|
||||||
</tr>
|
|
||||||
</thead>
|
|
||||||
<tbody>
|
|
||||||
<?php foreach ($leases as $lease) : ?>
|
|
||||||
<tr>
|
|
||||||
<?php foreach (explode(' ', $lease) as $prop) : ?>
|
|
||||||
<td><?php echo htmlspecialchars($prop, ENT_QUOTES) ?></td>
|
|
||||||
<?php endforeach ?>
|
|
||||||
</tr>
|
|
||||||
<?php endforeach ?>
|
|
||||||
</tbody>
|
|
||||||
</table>
|
|
||||||
</div><!-- /.table-responsive -->
|
|
||||||
</div><!-- /.card-body -->
|
|
||||||
</div><!-- /.card -->
|
</div><!-- /.card -->
|
||||||
</div><!-- /.col-lg-12 -->
|
</div><!-- /.col-lg-12 -->
|
||||||
</div><!-- /.row -->
|
|
||||||
</div><!-- /.tab-pane -->
|
|
||||||
|
|
||||||
<div class="tab-pane fade" id="static-leases">
|
|
||||||
<div class="dhcp-static-leases js-dhcp-static-lease-container">
|
|
||||||
<?php foreach ($dhcpHost as $host) : ?>
|
|
||||||
<?php list($mac, $ip) = array_map("trim", explode(",", $host)); ?>
|
|
||||||
<div class="row dhcp-static-lease-row js-dhcp-static-lease-row">
|
|
||||||
<div class="col-md-5 col-xs-5">
|
|
||||||
<input type="text" name="static_leases[mac][]" value="<?php echo htmlspecialchars($mac, ENT_QUOTES) ?>" placeholder="<?php echo _("MAC address") ?>" class="form-control">
|
|
||||||
</div>
|
|
||||||
<div class="col-md-5 col-xs-4">
|
|
||||||
<input type="text" name="static_leases[ip][]" value="<?php echo htmlspecialchars($ip, ENT_QUOTES) ?>" placeholder="<?php echo _("IP address") ?>" class="form-control">
|
|
||||||
</div>
|
|
||||||
<div class="col-md-2 col-xs-3">
|
|
||||||
<button type="button" class="btn btn-danger js-remove-dhcp-static-lease"><?php echo _("Remove") ?></button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<?php endforeach ?>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<h4 class="mt-3 mb-3"><?php echo _("Add static DHCP lease") ?></h4>
|
|
||||||
<div class="row dhcp-static-lease-row js-new-dhcp-static-lease">
|
|
||||||
<div class="col-md-5 col-xs-5">
|
|
||||||
<input type="text" name="mac" value="" placeholder="<?php echo _("MAC address") ?>" class="form-control" autofocus="autofocus">
|
|
||||||
</div>
|
|
||||||
<div class="col-md-5 col-xs-4">
|
|
||||||
<input type="text" name="ip" value="" placeholder="<?php echo _("IP address") ?>" class="form-control">
|
|
||||||
</div>
|
|
||||||
<div class="col-md-2 col-xs-3">
|
|
||||||
<button type="button" class="btn btn-success js-add-dhcp-static-lease"><?php echo _("Add") ?></button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<template id="js-dhcp-static-lease-row">
|
|
||||||
<div class="row dhcp-static-lease-row js-dhcp-static-lease-row">
|
|
||||||
<div class="col-md-5 col-xs-5">
|
|
||||||
<input type="text" name="static_leases[mac][]" value="{{ mac }}" placeholder="<?php echo _("MAC address") ?>" class="form-control">
|
|
||||||
</div>
|
|
||||||
<div class="col-md-5 col-xs-4">
|
|
||||||
<input type="text" name="static_leases[ip][]" value="{{ ip }}" placeholder="<?php echo _("IP address") ?>" class="form-control">
|
|
||||||
</div>
|
|
||||||
<div class="col-md-2 col-xs-3">
|
|
||||||
<button type="button" class="btn btn-warning js-remove-dhcp-static-lease"><?php echo _("Remove") ?></button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<?php echo $buttons ?>
|
|
||||||
|
|
||||||
</div>
|
|
||||||
|
|
||||||
</div><!-- /.tab-content -->
|
|
||||||
</form>
|
|
||||||
</div><!-- ./ card-body -->
|
|
||||||
<div class="card-footer"> <?php echo _("Information provided by Dnsmasq"); ?></div>
|
|
||||||
</div><!-- /.card -->
|
|
||||||
</div><!-- /.col-lg-12 -->
|
|
||||||
</div><!-- /.row -->
|
</div><!-- /.row -->
|
||||||
|
63
templates/dhcp/advanced.php
Normal file
63
templates/dhcp/advanced.php
Normal file
@ -0,0 +1,63 @@
|
|||||||
|
<!-- advanced tab -->
|
||||||
|
<div class="tab-pane" id="advanced">
|
||||||
|
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-md-6">
|
||||||
|
<h5><?php echo _("Upstream DNS servers") ?></h5>
|
||||||
|
|
||||||
|
<div class="input-group">
|
||||||
|
<input type="hidden" name="no-resolv" value="0">
|
||||||
|
<div class="custom-control custom-switch">
|
||||||
|
<input class="custom-control-input" id="no-resolv" type="checkbox" name="no-resolv" value="1" <?php echo $conf['no-resolv'] ? ' checked="checked"' : "" ?> aria-describedby="no-resolv-description">
|
||||||
|
<label class="custom-control-label" for="no-resolv"><?php echo _("Only ever query DNS servers configured below") ?></label>
|
||||||
|
</div>
|
||||||
|
<p id="no-resolv-description">
|
||||||
|
<small><?php echo _("Enable this option if you want RaspAP to <b>send DNS queries to the servers configured below exclusively</b>. By default RaspAP also uses its upstream DHCP server's name servers.") ?></small>
|
||||||
|
<br><small class="text-muted"><?php echo _("This option adds <code>no-resolv</code> to the dnsmasq configuration.") ?></small>
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="js-dhcp-upstream-servers">
|
||||||
|
<?php foreach ($upstreamServers as $server): ?>
|
||||||
|
<div class="form-group input-group input-group-sm js-dhcp-upstream-server">
|
||||||
|
<input type="text" class="form-control" name="server[]" value="<?php echo $server ?>">
|
||||||
|
<div class="input-group-append">
|
||||||
|
<button class="btn btn-outline-secondary js-remove-dhcp-upstream-server" type="button"><i class="fas fa-minus"></i></button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<?php endforeach ?>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="form-group">
|
||||||
|
<label for="add-dhcp-upstream-server-field"><?php echo _("Add upstream DNS server") ?></label>
|
||||||
|
<div class="input-group">
|
||||||
|
<input type="text" class="form-control" id="add-dhcp-upstream-server-field" aria-describedby="new-dhcp-upstream-server" placeholder="<?php printf(_("e.g. %s"), "208.67.222.222") ?>">
|
||||||
|
<div class="input-group-append">
|
||||||
|
<button type="button" class="btn btn-outline-secondary js-add-dhcp-upstream-server"><i class="fas fa-plus"></i></button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<p id="new-dhcp-upstream-server" class="form-text text-muted">
|
||||||
|
<small>
|
||||||
|
<?php echo _("Format: ") ?>
|
||||||
|
<code class="text-muted"><?php echo htmlspecialchars("[/[<domain>]/[domain/]][<ipaddr>[#<port>][@<source-ip>|<interface>[#<port>]]"); ?></code>
|
||||||
|
</small>
|
||||||
|
</p>
|
||||||
|
<select class="custom-select custom-select-sm js-field-preset" data-field-preset-target="#add-dhcp-upstream-server-field">
|
||||||
|
<option value=""><?php echo _("Choose a hosted server") ?></option>
|
||||||
|
<option disabled="disabled"></option>
|
||||||
|
<?php echo optionsForSelect(dnsServers()) ?>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<template id="dhcp-upstream-server">
|
||||||
|
<div class="form-group input-group input-group-sm js-dhcp-upstream-server">
|
||||||
|
<input type="text" class="form-control" name="server[]" value="{{ server }}">
|
||||||
|
<div class="input-group-append">
|
||||||
|
<button class="btn btn-outline-secondary js-remove-dhcp-upstream-server" type="button"><i class="fas fa-minus"></i></button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
</div><!-- /.row -->
|
||||||
|
|
||||||
|
</div><!-- /.tab-pane | advanded tab -->
|
35
templates/dhcp/clients.php
Normal file
35
templates/dhcp/clients.php
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
<div class="tab-pane fade" id="client-list">
|
||||||
|
<h4 class="mt-3 mb-3">Client list</h4>
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-lg-12">
|
||||||
|
<div class="card mb-3">
|
||||||
|
<div class="card-header"><?php echo _("Active DHCP leases"); ?></div>
|
||||||
|
<!-- /.panel-heading -->
|
||||||
|
<div class="card-body">
|
||||||
|
<div class="table-responsive">
|
||||||
|
<table class="table table-hover">
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th><?php echo _("Expire time"); ?></th>
|
||||||
|
<th><?php echo _("MAC Address"); ?></th>
|
||||||
|
<th><?php echo _("IP Address"); ?></th>
|
||||||
|
<th><?php echo _("Host name"); ?></th>
|
||||||
|
<th><?php echo _("Client ID"); ?></th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
<?php foreach ($leases as $lease) : ?>
|
||||||
|
<tr>
|
||||||
|
<?php foreach (explode(' ', $lease) as $prop) : ?>
|
||||||
|
<td><?php echo htmlspecialchars($prop, ENT_QUOTES) ?></td>
|
||||||
|
<?php endforeach ?>
|
||||||
|
</tr>
|
||||||
|
<?php endforeach ?>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div><!-- /.table-responsive -->
|
||||||
|
</div><!-- /.card-body -->
|
||||||
|
</div><!-- /.card -->
|
||||||
|
</div><!-- /.col-lg-12 -->
|
||||||
|
</div><!-- /.row -->
|
||||||
|
</div><!-- /.tab-pane -->
|
59
templates/dhcp/general.php
Normal file
59
templates/dhcp/general.php
Normal file
@ -0,0 +1,59 @@
|
|||||||
|
<div class="tab-pane active" id="server-settings">
|
||||||
|
<h4 class="mt-3">DHCP server settings</h4>
|
||||||
|
<div class="row">
|
||||||
|
<div class="form-group col-md-6">
|
||||||
|
<label for="code">Interface</label>
|
||||||
|
<select class="form-control" name="interface">
|
||||||
|
<?php foreach ($interfaces as $if) : ?>
|
||||||
|
<?php $if_quoted = htmlspecialchars($if, ENT_QUOTES) ?>
|
||||||
|
<?php $selected = $if === $conf['interface'] ? ' selected="selected"' : '' ?>
|
||||||
|
<option value="<?php echo $if_quoted ?>"<?php echo $selected ?>><?php echo $if_quoted ?></option>
|
||||||
|
<?php endforeach ?>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="row">
|
||||||
|
<div class="form-group col-md-6">
|
||||||
|
<label for="code"><?php echo _("Starting IP Address"); ?></label>
|
||||||
|
<input type="text" class="form-control"name="RangeStart" value="<?php echo htmlspecialchars($RangeStart, ENT_QUOTES); ?>" />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="row">
|
||||||
|
<div class="form-group col-md-6">
|
||||||
|
<label for="code"><?php echo _("Ending IP Address"); ?></label>
|
||||||
|
<input type="text" class="form-control" name="RangeEnd" value="<?php echo htmlspecialchars($RangeEnd, ENT_QUOTES); ?>" />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="row">
|
||||||
|
<div class="form-group col-xs-3 col-sm-3">
|
||||||
|
<label for="code"><?php echo _("Lease Time"); ?></label>
|
||||||
|
<input type="text" class="form-control" name="RangeLeaseTime" value="<?php echo htmlspecialchars($arrRangeLeaseTime[1], ENT_QUOTES); ?>" />
|
||||||
|
</div>
|
||||||
|
<div class="col-xs-3 col-sm-3">
|
||||||
|
<label for="code"><?php echo _("Interval"); ?></label>
|
||||||
|
<select name="RangeLeaseTimeUnits" class="form-control" >
|
||||||
|
<option value="m"<?php echo $mselected; ?>><?php echo _("Minute(s)"); ?></option>
|
||||||
|
<option value="h"<?php echo $hselected; ?>><?php echo _("Hour(s)"); ?></option>
|
||||||
|
<option value="d"<?php echo $dselected; ?>><?php echo _("Day(s)"); ?></option>
|
||||||
|
<option value="infinite"<?php echo $infiniteselected; ?>><?php echo _("Infinite"); ?></option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="row">
|
||||||
|
<div class="form-group col-md-6">
|
||||||
|
<label for="code"><?php echo _("DNS Server"); ?> 1</label>
|
||||||
|
<input type="text" class="form-control"name="DNS1" value="<?php echo htmlspecialchars($DNS1, ENT_QUOTES); ?>" />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="row">
|
||||||
|
<div class="form-group col-md-6">
|
||||||
|
<label for="code"><?php echo _("DNS Server"); ?> 2</label>
|
||||||
|
<input type="text" class="form-control" name="DNS2" value="<?php echo htmlspecialchars($DNS2, ENT_QUOTES); ?>" />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div><!-- /.tab-pane -->
|
19
templates/dhcp/logging.php
Normal file
19
templates/dhcp/logging.php
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
<!-- logfile output tab -->
|
||||||
|
<div class="tab-pane fade" id="logging">
|
||||||
|
<h4><?php echo _("Logging") ?></h4>
|
||||||
|
<p><?php echo _("Enable these options to log DHCP server activity.") ?></p>
|
||||||
|
|
||||||
|
<div class="custom-control custom-switch">
|
||||||
|
<input class="custom-control-input" id="log-dhcp" type="checkbox" name="log-dhcp" value="1" <?php echo $conf['log-dhcp'] ? ' checked="checked"' : "" ?> aria-describedby="log-dhcp-requests">
|
||||||
|
<label class="custom-control-label" for="log-dhcp"><?php echo _("Log DHCP requests") ?></label>
|
||||||
|
</div>
|
||||||
|
<div class="custom-control custom-switch">
|
||||||
|
<input class="custom-control-input" id="log-queries" type="checkbox" name="log-queries" value="1" <?php echo $conf['log-queries'] ? ' checked="checked"' : "" ?> aria-describedby="log-dhcp-queries">
|
||||||
|
<label class="custom-control-label" for="log-queries"><?php echo _("Log DNS queries") ?></label>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<?php
|
||||||
|
$log = file_get_contents('/tmp/dnsmasq.log');
|
||||||
|
echo '<textarea class="logoutput my-3">'.htmlspecialchars($log, ENT_QUOTES).'</textarea>';
|
||||||
|
?>
|
||||||
|
</div><!-- /.tab-pane -->
|
48
templates/dhcp/static_leases.php
Normal file
48
templates/dhcp/static_leases.php
Normal file
@ -0,0 +1,48 @@
|
|||||||
|
<!-- static leases tab -->
|
||||||
|
<div class="tab-pane fade" id="static-leases">
|
||||||
|
<h4 class="mt-3 mb-3"><?php echo _("Static leases") ?></h4>
|
||||||
|
|
||||||
|
<div class="dhcp-static-leases js-dhcp-static-lease-container">
|
||||||
|
<?php foreach ($dhcpHost as $host) : ?>
|
||||||
|
<?php list($mac, $ip) = array_map("trim", explode(",", $host)); ?>
|
||||||
|
<div class="row dhcp-static-lease-row js-dhcp-static-lease-row">
|
||||||
|
<div class="col-md-5 col-xs-5">
|
||||||
|
<input type="text" name="static_leases[mac][]" value="<?php echo htmlspecialchars($mac, ENT_QUOTES) ?>" placeholder="<?php echo _("MAC address") ?>" class="form-control">
|
||||||
|
</div>
|
||||||
|
<div class="col-md-5 col-xs-4">
|
||||||
|
<input type="text" name="static_leases[ip][]" value="<?php echo htmlspecialchars($ip, ENT_QUOTES) ?>" placeholder="<?php echo _("IP address") ?>" class="form-control">
|
||||||
|
</div>
|
||||||
|
<div class="col-md-2 col-xs-3">
|
||||||
|
<button type="button" class="btn btn-danger js-remove-dhcp-static-lease"><?php echo _("Remove") ?></button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<?php endforeach ?>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<h5 class="mt-3 mb-3"><?php echo _("Add static DHCP lease") ?></h5>
|
||||||
|
<div class="row dhcp-static-lease-row js-new-dhcp-static-lease">
|
||||||
|
<div class="col-md-5 col-xs-5">
|
||||||
|
<input type="text" name="mac" value="" placeholder="<?php echo _("MAC address") ?>" class="form-control" autofocus="autofocus">
|
||||||
|
</div>
|
||||||
|
<div class="col-md-5 col-xs-4">
|
||||||
|
<input type="text" name="ip" value="" placeholder="<?php echo _("IP address") ?>" class="form-control">
|
||||||
|
</div>
|
||||||
|
<div class="col-md-2 col-xs-3">
|
||||||
|
<button type="button" class="btn btn-success js-add-dhcp-static-lease"><?php echo _("Add") ?></button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<template id="js-dhcp-static-lease-row">
|
||||||
|
<div class="row dhcp-static-lease-row js-dhcp-static-lease-row">
|
||||||
|
<div class="col-md-5 col-xs-5">
|
||||||
|
<input type="text" name="static_leases[mac][]" value="{{ mac }}" placeholder="<?php echo _("MAC address") ?>" class="form-control">
|
||||||
|
</div>
|
||||||
|
<div class="col-md-5 col-xs-4">
|
||||||
|
<input type="text" name="static_leases[ip][]" value="{{ ip }}" placeholder="<?php echo _("IP address") ?>" class="form-control">
|
||||||
|
</div>
|
||||||
|
<div class="col-md-2 col-xs-3">
|
||||||
|
<button type="button" class="btn btn-warning js-remove-dhcp-static-lease"><?php echo _("Remove") ?></button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
</div><!-- /.tab-pane -->
|
Loading…
Reference in New Issue
Block a user