ucentral: development update

* add new maverick theme
* fix sporadic wifi bringup on firstboot

Signed-off-by: John Crispin <john@phrozen.org>
This commit is contained in:
John Crispin
2021-07-28 13:18:48 +02:00
parent 71ae5a9a08
commit a9f3fa7ad4
6 changed files with 247 additions and 75 deletions

View File

@@ -0,0 +1,152 @@
'use strict';
'require baseclass';
'require ui';
return baseclass.extend({
__init__: function() {
ui.menu.load().then(L.bind(this.render, this));
},
render: function(tree) {
var menu = document.querySelector('#mainmenu'),
nav = document.querySelector('#menubar > .navigation'),
node = tree,
url = '';
this.renderModeMenu(node);
if (L.env.dispatchpath.length >= 3) {
for (var i = 0; i < 3 && node; i++) {
node = node.children[L.env.dispatchpath[i]];
url = url + (url ? '/' : '') + L.env.dispatchpath[i];
}
if (node)
this.renderTabMenu(node, url);
}
if (menu.firstElementChild) {
nav.addEventListener('click', ui.createHandlerFn(this, 'handleSidebarToggle'));
nav.style.visibility = 'visible';
}
},
handleMenuExpand: function(ev) {
var a = ev.target, ul1 = a.parentNode.parentNode, ul2 = a.nextElementSibling;
document.querySelectorAll('ul.mainmenu.l1 > li.active').forEach(function(li) {
if (li !== a.parentNode)
li.classList.remove('active');
});
if (!ul2)
return;
if (ul2.parentNode.offsetLeft + ul2.offsetWidth <= ul1.offsetLeft + ul1.offsetWidth)
ul2.classList.add('align-left');
ul1.classList.add('active');
a.parentNode.classList.add('active');
a.blur();
ev.preventDefault();
ev.stopPropagation();
},
renderMainMenu: function(tree, url, level) {
var l = (level || 0) + 1,
ul = E('ul', { 'class': 'mainmenu l%d'.format(l) }),
children = ui.menu.getChildren(tree);
if (children.length == 0 || l > 2)
return E([]);
for (var i = 0; i < children.length; i++) {
var isActive = (L.env.dispatchpath[l] == children[i].name),
isReadonly = children[i].readonly,
activeClass = 'mainmenu-item-%s%s'.format(children[i].name, isActive ? ' selected' : '');
ul.appendChild(E('li', { 'class': activeClass }, [
E('a', {
'href': L.url(url, children[i].name),
'click': (l == 1) ? ui.createHandlerFn(this, 'handleMenuExpand') : null
}, [ _(children[i].title) ]),
this.renderMainMenu(children[i], url + '/' + children[i].name, l)
]));
}
if (l == 1)
document.querySelector('#mainmenu').appendChild(E('div', [ ul ]));
return ul;
},
renderModeMenu: function(tree, root) {
var menu = document.querySelector('#modemenu'),
children = ui.menu.getChildren(tree);
for (var i = 0; i < children.length; i++) {
var isActive = (L.env.requestpath.length ? children[i].name == L.env.requestpath[+!!root] : i == 0),
isUcentral = (!root && children[i].name == 'ucentral');
if (root || children.length > 1)
menu.appendChild(E('div', { 'class': isActive ? 'active' : null }, [
E('a', { 'href': root ? L.url(root, children[i].name) : L.url(children[i].name) }, [ _(children[i].title) ])
]));
if (isUcentral && isActive)
this.renderModeMenu(children[i], children[i].name);
else if (isActive)
this.renderMainMenu(children[i], children[i].name);
}
if (menu.children.length > 1)
menu.style.display = '';
},
renderTabMenu: function(tree, url, level) {
var container = document.querySelector('#tabmenu'),
l = (level || 0) + 1,
ul = E('ul', { 'class': 'cbi-tabmenu' }),
children = ui.menu.getChildren(tree),
activeNode = null;
if (children.length == 0)
return E([]);
for (var i = 0; i < children.length; i++) {
var isActive = (L.env.dispatchpath[l + 2] == children[i].name),
activeClass = isActive ? ' cbi-tab' : '',
className = 'tabmenu-item-%s %s'.format(children[i].name, activeClass);
ul.appendChild(E('li', { 'class': className }, [
E('a', { 'href': L.url(url, children[i].name) }, [ _(children[i].title) ] )
]));
if (isActive)
activeNode = children[i];
}
container.appendChild(ul);
container.style.display = '';
if (activeNode)
container.appendChild(this.renderTabMenu(activeNode, url + '/' + activeNode.name, l));
return ul;
},
handleSidebarToggle: function(ev) {
var btn = ev.currentTarget,
bar = document.querySelector('#mainmenu');
if (btn.classList.contains('active')) {
btn.classList.remove('active');
bar.classList.remove('active');
}
else {
btn.classList.add('active');
bar.classList.add('active');
}
}
});

View File

@@ -1,17 +1,25 @@
:root {
--main-bright-color: #fff;
--main-dark-color: #444;
--secondary-bright-color: #d8dbe0;
--primary-bright-color: #fff;
--secondary-bright-color: #f8f8f8;
--primary-dark-color: #444;
--secondary-dark-color: #000;
--danger-color: #CC1111;
--warning-color: #CC8800;
--success-color: #5CB85C;
--border-primary-color: #d8dbe0;
--highlight-primary-background: #39f;
--highlight-primary-text: #fff;
--highlight-secondary-background: #17d;
--highlight-secondary-text: #fff;
--button-primary-background: #2a1ab9;
--button-primary-border: #2819ae;
--button-primary-text: #fff;
--button-secondary-background: #ebedef;
--button-secondary-border: #d8dbe0;
--button-secondary-text: #768192;
--button-secondary-text: #444;
--button-positive-background: #5CB85C;
--button-positive-border: #3C983C;
--button-positive-text: #fff;
--button-negative-background: #e55353;
--button-negative-border: #a55353;
--button-negative-text: #fff;
@@ -49,11 +57,11 @@ html {
width: 100%;
max-width: 1366px;
margin: 0 auto;
background: var(--main-bright-color);
background: var(--primary-bright-color);
}
body {
background: var(--main-bright-color);
background: #ebedef;
color: var(--secondary-dark-color);
font-size: var(--base-font-size);
cursor: default;
@@ -93,7 +101,7 @@ body {
#indicators > * {
background: var(--button-primary-background);
color: var(--main-bright-color);
color: var(--primary-bright-color);
display: inline-block;
font-size: .85em;
line-height: 1.5em;
@@ -105,7 +113,7 @@ body {
}
#indicators > [data-style="inactive"] {
background: var(--main-bright-color);
background: var(--primary-bright-color);
color: var(--secondary-bright-color);
border: 2px solid var(--secondary-bright-color);
line-height: calc(1.5em - 4px);
@@ -118,21 +126,20 @@ body {
}
#modemenu {
background: var(--main-bright-color);
background: var(--primary-bright-color);
padding: .5rem 1rem;
display: flex;
align-items: center;
color: var(--secondary-dark-color);
border: 1px solid #d8dbe0;
border: 1px solid var(--border-primary-color);
border-radius: .25rem .25rem 0 0;
font-size: 1rem;
flex-wrap: wrap;
width: 100vw;
}
#modemenu > * {
margin: .125rem;
padding-right: .25rem;
margin: .25rem;
padding-right: .5rem;
border-right: 1px solid var(--secondary-dark-color);
}
@@ -149,12 +156,17 @@ body {
flex-direction: row;
display: flex;
flex: 1 0 auto;
background: var(--main-bright-color);
border: 1px solid #d8dbe0;
border-top: none;
background: var(--primary-bright-color);
border: 1px solid var(--border-primary-color);
border-top-width: 0;
border-radius: 0 0 .25rem .25rem;
}
#modemenu:empty + #maincontainer {
border-top-width: 1px;
border-radius: .25rem;
}
#mainmenu {
flex: 1 1 200px;
color: var(--primary-dark-color);
@@ -214,7 +226,7 @@ body > .luci {
font-size: .7em;
padding: .25em;
text-align: right;
background: var(--main-bright-color);
background: var(--primary-bright-color);
color: var(--secondary-bright-color);
margin: 0;
}
@@ -251,7 +263,7 @@ body.modal-overlay-active #modal_overlay {
max-width: 1300px;
width: 80%;
margin: 10% auto 5rem auto;
background: var(--main-bright-color);
background: var(--primary-bright-color);
box-shadow: 0 0 3px 1px #000;
padding: .5em;
border-radius: .25em;
@@ -263,7 +275,7 @@ body.modal-overlay-active #modal_overlay {
padding: .5rem;
margin: -.5rem -.5rem .5rem -.5rem;
color: var(--primary-dark-color);
border-radius: .25rem .25rem 0 0;
border-bottom: 1px solid var(--border-primary-color);
}
.modal > *:first-child:last-child {
@@ -292,7 +304,7 @@ tr.cbi-section-table-titles[data-title]::before {
tr[data-title]::before {
content: attr(data-title);
display: table-cell;
border-top: 1px solid var(--main-dark-color);
border-top: 1px solid var(--border-primary-color);
padding: .5em;
}
@@ -310,7 +322,7 @@ th {
}
td {
border-top: 1px solid var(--main-dark-color);
border-top: 1px solid var(--border-primary-color);
padding: .5em;
vertical-align: middle;
}
@@ -327,11 +339,11 @@ td .control-group {
}
tr.drag-over-above {
box-shadow: 0 -6px 6px var(--main-bright-color);
box-shadow: 0 -6px 6px var(--primary-bright-color);
}
tr.drag-over-below {
box-shadow: 0 6px 6px var(--main-bright-color);
box-shadow: 0 6px 6px var(--primary-bright-color);
}
tr.placeholder {
@@ -599,20 +611,20 @@ p > textarea:last-child {
}
var {
color: var(--main-dark-color);
color: var(--primary-dark-color);
font-weight: bold;
}
code {
font-family: monospace;
color: var(--main-dark-color);
color: var(--primary-dark-color);
}
pre {
font-family: monospace;
margin: 0 0 1em 0;
font-size: .9rem;
box-shadow: inset 0 0 2px var(--main-dark-color);
box-shadow: inset 0 0 2px var(--primary-dark-color);
padding: .25rem;
overflow: auto;
}
@@ -642,7 +654,7 @@ ul > li {
line-height: 1.8em;
padding: 0 .25em;
margin: .25em;
box-shadow: 0px 0px 2px var(--main-dark-color);
box-shadow: 0px 0px 2px var(--primary-dark-color);
font-size: .9em;
border-radius: .5em;
overflow: hidden;
@@ -673,7 +685,7 @@ ul > li {
}
.ifacebox-head {
background: var(--main-bright-color);
background: var(--highlight-primary-background);
width: 100%;
}
@@ -767,13 +779,13 @@ ul > li {
position: relative;
min-width: 20rem;
height: 1.5em;
border: 1px solid var(--main-dark-color);
border: 1px solid var(--border-primary-color);
overflow: hidden;
margin: .125rem 0;
}
.cbi-progressbar > div {
background: #39f;
background: var(--highlight-primary-background);
height: 100%;
transition: width .25s ease-in;
width: 0%;
@@ -796,7 +808,7 @@ ul > li {
padding: 0;
margin: 0 -.5em 1em -.5em;
font-weight: bold;
color: var(--main-dark-color);
color: var(--primary-dark-color);
}
.cbi-tabmenu > li {
@@ -814,7 +826,7 @@ ul > li {
}
.cbi-tabmenu > .cbi-tab > a {
border-bottom: 2px solid var(--main-dark-color);
border-bottom: 2px solid var(--primary-dark-color);
}
[data-tab] {
@@ -845,7 +857,7 @@ ul > li {
}
.alert-message.info {
background: var(--main-bright-color);
background: var(--primary-bright-color);
}
.alert-message.warning {
@@ -893,9 +905,9 @@ ul > li {
*/
button, .btn {
background: var(--button-secondary-border);
background: var(--button-secondary-background);
border: 1px solid var(--button-secondary-border);
color: var(--button-secondary-color);
color: var(--button-secondary-text);
line-height: 1.5em;
border-radius: .25em;
cursor: pointer;
@@ -904,7 +916,7 @@ button, .btn {
}
button:hover, .btn:hover {
box-shadow: 0 0 6px var(--main-bright-color);
box-shadow: 0 0 6px var(--primary-bright-color);
}
button + button, .btn + .btn, button + .btn, .btn + button, select + button {
@@ -923,7 +935,9 @@ button[disabled], button.disabled, .btn[disabled], .btn.disabled {
}
.cbi-button-apply, .cbi-button-positive {
background: var(--main-dark-color);
background: var(--button-positive-background) !important;
border-color: var(--button-positive-border) !important;
color: var(--button-positive-text) !important;
}
.cbi-button-negative, .cbi-button-remove {
@@ -958,7 +972,7 @@ button[disabled], button.disabled, .btn[disabled], .btn.disabled {
content: "\0a";
height: 1em;
width: 1em;
box-shadow: 0 0 2px var(--main-dark-color);
border: 1px solid var(--button-secondary-border);
display: inline-block;
border-radius: .25em;
margin: .15em 0;
@@ -971,9 +985,9 @@ button[disabled], button.disabled, .btn[disabled], .btn.disabled {
content: "\0a";
position: absolute;
display: inline-block;
background: var(--main-dark-color);
top: .35em;
left: .2em;
background: var(--secondary-dark-color);
top: calc(.35em + 1px);
left: calc(.2em + 1px);
width: .6em;
height: .6em;
border-radius: .15em;
@@ -1032,8 +1046,10 @@ input:not([type]) + .btn, input:not([type]) + button,
input[type="text"] + .btn, input[type="text"] + button,
input[type="password"] + .btn, input[type="password"] + button {
margin: 0 0 2px -1px;
background: var(--main-dark-color);
background: var(--button-secondary-background);
border: 1px solid var(--button-secondary-border);
border-radius: 0 .25em .25em 0;
color: var(--button-secondary-text);
}
.control-group > select + .btn, .control-group > select + button {
@@ -1043,7 +1059,7 @@ input[type="password"] + .btn, input[type="password"] + button {
.control-group > input:not([type]) + .btn, .control-group > input:not([type]) + button,
.control-group > input[type="text"] + .btn, .control-group > input[type="text"] + button,
.control-group > input[type="password"] + .btn, .control-group > input[type="password"] + button {
margin: .125em .125em calc(.125em + 2px) calc(-.125em - .25em) !important;
margin: .125em .125em .125em calc(-.125em - .25em) !important;
}
input[type="checkbox"] {
@@ -1059,7 +1075,7 @@ select {
textarea {
width: 100%;
box-shadow: inset 0 0 2px var(--main-dark-color);
box-shadow: inset 0 0 2px var(--primary-dark-color);
font-family: monospace;
font-size: .9rem;
padding: .2rem;
@@ -1142,7 +1158,7 @@ textarea {
}
.cbi-dynlist > .item {
box-shadow: 0 0 2px var(--main-dark-color);
border: 1px solid var(--button-secondary-border);
margin: .3em 0;
padding: .15em 2em .15em .2em;
border-radius: .25em;
@@ -1160,14 +1176,14 @@ textarea {
right: 0;
bottom: 0;
width: 1.6rem;
background: var(--main-bright-color);
background: var(--button-secondary-background);
color: var(--button-secondary-text);
display: flex;
align-items: center;
justify-content: space-around;
position: absolute;
box-shadow: 0 0 2px var(--main-dark-color);
border-left: 1px solid var(--button-secondary-border);
text-align: center;
color: var(--secondary-bright-color);
cursor: pointer;
pointer-events: all;
}
@@ -1177,7 +1193,7 @@ textarea {
}
.cbi-dynlist > .item:hover {
box-shadow: 0 0 2px var(--main-bright-color);
box-shadow: 0 0 2px var(--primary-bright-color);
}
.cbi-dynlist > .add-item {
@@ -1193,7 +1209,7 @@ textarea {
.cbi-dynlist > .add-item > .btn {
flex: 0 0 1.6rem;
margin: 0 0 2px -1px;
margin: 0 0 0 -1px;
width: 1.6rem;
text-align: center;
}
@@ -1206,10 +1222,6 @@ textarea {
padding: 0 !important;
}
.cbi-dropdown:not(.btn):not(.cbi-button) {
box-shadow: inset 0 0 1px var(--main-dark-color);
}
.cbi-dropdown > ul {
margin: 0 !important;
padding: 0;
@@ -1229,7 +1241,7 @@ textarea {
}
.cbi-dropdown.btn > ul.dropdown > li {
color: var(--main-dark-color);
color: var(--primary-dark-color);
}
.cbi-dropdown > ul.preview {
@@ -1315,7 +1327,7 @@ textarea {
.cbi-dropdown[open] > ul.dropdown {
display: block;
background: var(--secondary-bright-color);
box-shadow: 0 0 1px var(--main-dark-color), 0 0 4px rgba(0, 0, 0, .7);
box-shadow: 0 0 1px var(--primary-dark-color), 0 0 4px rgba(0, 0, 0, .7);
position: absolute;
z-index: 1100;
max-width: none;
@@ -1349,12 +1361,13 @@ textarea {
}
.cbi-dropdown[open] > ul.dropdown > li[selected] {
background: var(--main-dark-color);
color: var(--secondary-bright-color);
background: var(--highlight-primary-background);
color: var(--highlight-primary-text);
}
.cbi-dropdown[open] > ul.dropdown > li.focus {
background: var(--main-bright-color);
background: var(--highlight-secondary-background);
color: var(--highlight-secondary-text);
}
.cbi-dropdown[open] > ul.dropdown > li:last-child {
@@ -1378,7 +1391,7 @@ textarea {
.cbi-filebrowser {
max-width: 100%;
width: 1px;
box-shadow: 0 0 2px var(--main-dark-color);
box-shadow: 0 0 2px var(--primary-dark-color);
border-radius: .25rem;
display: flex;
flex-direction: column;
@@ -1403,7 +1416,7 @@ textarea {
padding: 0 0 .25em 0;
margin: .25em .25em 0px .25em;
white-space: nowrap;
border-bottom: 1px solid var(--main-dark-color);
border-bottom: 1px solid var(--primary-dark-color);
}
.cbi-filebrowser .cbi-button-positive {
@@ -1447,7 +1460,7 @@ textarea {
flex-wrap: wrap;
margin: 0 -.125em .25em -.125em;
padding: 0 0 .125em 0px;
border-bottom: 1px solid var(--main-dark-color);
border-bottom: 1px solid var(--primary-dark-color);
}
.cbi-filebrowser .upload > * {
@@ -1554,7 +1567,7 @@ button.spinning::before, .btn.spinning::before {
}
.label {
background: var(--main-bright-color);
background: var(--primary-bright-color);
color: var(--secondary-bright-color);
font-size: .8rem;
padding: 0 .4rem;
@@ -1579,6 +1592,7 @@ ul.errors {
@media only screen and (max-width: 800px) {
body {
padding-top: 70px;
background: var(--primary-bright-color);
}
#page {
@@ -1590,6 +1604,7 @@ ul.errors {
#maincontainer {
width: 100vw;
border: none;
}
#maincontent {
@@ -1598,7 +1613,7 @@ ul.errors {
}
#menubar {
background: var(--main-bright-color) url(logo.svg) no-repeat 50% 0;
background: var(--primary-bright-color) url(logo.svg) no-repeat 50% 0;
padding: 1em .5em;
position: fixed;
top: 0;
@@ -1610,17 +1625,19 @@ ul.errors {
#menubar > h2 {
flex: 0 0 2em;
display: block;
border: 2px solid var(--main-dark-color);
border: 1px solid var(--primary-dark-color);
color: var(--secondary-dark-color);
border-radius: .5em;
cursor: pointer;
font-size: 100%;
margin: 0 1em 0 0;
width: 37px;
height: 37px;
}
#menubar > h2:hover {
border-color: var(--secondary-bright-color);
color: var(--secondary-bright-color);
border-color: var(--highlight-primary-background);
color: var(--highlight-primary-background);
}
#menubar > h2 > * {
@@ -1656,6 +1673,9 @@ ul.errors {
#modemenu {
padding: .125em .25em;
width: 100vw;
border-width: 1px 0;
margin-top: 1px;
}
#mainmenu {
@@ -1667,14 +1687,14 @@ ul.errors {
position: fixed;
z-index: 900;
height: 100%;
background: var(--main-bright-color);
background: var(--primary-bright-color);
}
#mainmenu.active {
max-width: 200px;
padding: 1em 1em calc(1em + 70px) 1em;
overflow-x: visible;
border-right: 1px solid var(--secondary-bright-color);
border-right: 1px solid var(--border-primary-color);
}
#mainmenu > div {
@@ -1696,7 +1716,7 @@ ul.errors {
tr {
display: block;
border-bottom: 1px solid var(--main-dark-color);
border-bottom: 1px solid var(--border-primary-color);
margin-bottom: .5em;
padding-bottom: .5em;
}
@@ -1756,7 +1776,7 @@ ul.errors {
top: 0;
bottom: 0;
display: block;
background: linear-gradient(90deg, rgba(255, 255, 255, 0), var(--main-bright-color) 90%);
background: linear-gradient(90deg, rgba(255, 255, 255, 0), var(--primary-bright-color) 90%);
}
[data-page="admin-status-overview"] .cbi-section:nth-of-type(1) td:first-of-type,

View File

@@ -6,7 +6,7 @@ PKG_RELEASE:=1
PKG_SOURCE_URL=https://github.com/blogic/ucentral-client.git
PKG_SOURCE_PROTO:=git
PKG_SOURCE_DATE:=2021-02-15
PKG_SOURCE_VERSION:=94b39ac3c1201d2cd391edc136e148316d7c4e0a
PKG_SOURCE_VERSION:=4bb62909328b2a7ed7214939b9aa5a7999794024
PKG_LICENSE:=BSD-3-Clause
PKG_MAINTAINER:=John Crispin <john@phrozen.org>

View File

@@ -6,7 +6,7 @@ PKG_RELEASE:=1
PKG_SOURCE_URL=https://github.com/blogic/ucentral-schema.git
PKG_SOURCE_PROTO:=git
PKG_SOURCE_DATE:=2021-02-15
PKG_SOURCE_VERSION:=0e180e4595371bcdbf0bd0cff2f31734a39c4946
PKG_SOURCE_VERSION:=2ddf79a8269953e8ce6cd9bc1f8b54b7636ad88f
PKG_MAINTAINER:=John Crispin <john@phrozen.org>
PKG_LICENSE:=BSD-3-Clause

View File

@@ -6,7 +6,7 @@ PKG_RELEASE:=1
PKG_SOURCE_URL=https://github.com/blogic/ucentral-wifi.git
PKG_SOURCE_PROTO:=git
PKG_SOURCE_DATE:=2021-04-13
PKG_SOURCE_VERSION:=b1dd63ae6e450f720758019dd8516ceae15c2387
PKG_SOURCE_VERSION:=a7e2f706d37a6e0b996d2af49c3b8663becb3f08
#PKG_MIRROR_HASH:=a8000b3cf43ce9ebfa7305661475fec98ec1dba2dc7b062028c2e17d7c2ec50b
PKG_MAINTAINER:=John Crispin <john@phrozen.org>

View File

@@ -10,7 +10,7 @@ packages:
- lua
- luci-base
- luci-mod-ucentral
- luci-theme-openwrt-2020
- luci-theme-ucentral
- rpcd
- rpcd-mod-file
- rpcd-mod-iwinfo