Development
This commit is contained in:
parent
263639eb95
commit
aff93abf5f
2 changed files with 69 additions and 5 deletions
|
|
@ -343,6 +343,61 @@ def build_table_picker(name, label, value, rows, headers, summary_config, action
|
||||||
])
|
])
|
||||||
summary_attr = f' data-summary="{e(summary_json)}"'
|
summary_attr = f' data-summary="{e(summary_json)}"'
|
||||||
|
|
||||||
|
script = (
|
||||||
|
'<script>(function(){'
|
||||||
|
'var _fg=document.currentScript.previousElementSibling;'
|
||||||
|
'var _pk=_fg.querySelector(\'.table-picker\');'
|
||||||
|
'var _btn=_pk.querySelector(\'.table-picker-btn\');'
|
||||||
|
'var _hdr=_pk.querySelector(\'.table-picker-header\');'
|
||||||
|
'var _dd=_pk.querySelector(\'.table-picker-dropdown\');'
|
||||||
|
'var _hid=_pk.querySelector(\'input[type="hidden"]\');'
|
||||||
|
'var _sc=JSON.parse(_pk.dataset.summary||\'[]\');'
|
||||||
|
'function _apply(key){'
|
||||||
|
'var row=_dd.querySelector(\'.table-picker-row[data-key="\'+key+\'"]\');'
|
||||||
|
'if(!row)return;'
|
||||||
|
'_btn.querySelector(\'.table-picker-name\').textContent=row.dataset.label||key;'
|
||||||
|
'var badge=_btn.querySelector(\'.table-picker-badge\');'
|
||||||
|
'if(row.dataset.badgeClass){'
|
||||||
|
'if(!badge){badge=document.createElement(\'span\');_btn.appendChild(badge);}'
|
||||||
|
'badge.className=\'badge \'+row.dataset.badgeClass+\' table-picker-badge\';'
|
||||||
|
'badge.textContent=row.dataset.badgeLabel||\'\';'
|
||||||
|
'}else if(badge){badge.remove();}'
|
||||||
|
'if(_sc.length){'
|
||||||
|
'var stats=_hdr.querySelector(\'.table-picker-stats\');'
|
||||||
|
'if(!stats){'
|
||||||
|
'stats=document.createElement(\'table\');'
|
||||||
|
'stats.className=\'table-picker-stats\';'
|
||||||
|
'var hc=_sc.map(function(c){return\'<th>\'+htmlEsc(c.label)+\'</th>\';}).join(\'\');'
|
||||||
|
'stats.innerHTML=\'<thead><tr>\'+hc+\'</tr></thead><tbody><tr></tr></tbody>\';'
|
||||||
|
'_hdr.appendChild(stats);'
|
||||||
|
'}'
|
||||||
|
'var dc=_sc.map(function(c){'
|
||||||
|
'var v=row.dataset[c.field]!==undefined?row.dataset[c.field]:\'-\';'
|
||||||
|
'return\'<td\'+(c.mono?\' class="col-mono"\':\'\')+\'>\'+htmlEsc(v)+\'</td>\';'
|
||||||
|
'}).join(\'\');'
|
||||||
|
'stats.querySelector(\'tbody tr\').innerHTML=dc;'
|
||||||
|
'}'
|
||||||
|
'_dd.querySelectorAll(\'.table-picker-row\').forEach(function(r){'
|
||||||
|
'r.classList.toggle(\'selected\',r===row);'
|
||||||
|
'});'
|
||||||
|
'}'
|
||||||
|
'_hid.addEventListener(\'change\',function(){_apply(_hid.value);});'
|
||||||
|
'_btn.addEventListener(\'click\',function(e){'
|
||||||
|
'e.stopPropagation();'
|
||||||
|
'var wasOpen=_dd.classList.contains(\'open\');'
|
||||||
|
'tablePickerCloseAll();'
|
||||||
|
'if(!wasOpen)_dd.classList.add(\'open\');'
|
||||||
|
'});'
|
||||||
|
'_dd.addEventListener(\'click\',function(e){e.stopPropagation();});'
|
||||||
|
'_dd.querySelectorAll(\'.table-picker-row\').forEach(function(row){'
|
||||||
|
'row.addEventListener(\'click\',function(){'
|
||||||
|
'_hid.value=this.dataset.key;'
|
||||||
|
'tablePickerCloseAll();'
|
||||||
|
'_hid.dispatchEvent(new Event(\'change\',{bubbles:true}));'
|
||||||
|
'});'
|
||||||
|
'});'
|
||||||
|
'})();</script>'
|
||||||
|
)
|
||||||
return (
|
return (
|
||||||
'<div class="form-group">'
|
'<div class="form-group">'
|
||||||
f'<label class="form-label">{e(label)}</label>'
|
f'<label class="form-label">{e(label)}</label>'
|
||||||
|
|
@ -356,6 +411,7 @@ def build_table_picker(name, label, value, rows, headers, summary_config, action
|
||||||
f'<div class="table-picker-dropdown">{table_html}</div>'
|
f'<div class="table-picker-dropdown">{table_html}</div>'
|
||||||
'</div>'
|
'</div>'
|
||||||
'</div>'
|
'</div>'
|
||||||
|
f'{script}'
|
||||||
)
|
)
|
||||||
|
|
||||||
# Field renderer ======================================================
|
# Field renderer ======================================================
|
||||||
|
|
|
||||||
|
|
@ -884,7 +884,7 @@ def collect_tokens():
|
||||||
|
|
||||||
# Layout renderer ===================================================
|
# Layout renderer ===================================================
|
||||||
|
|
||||||
def render_layout(view_id, content_html, tokens):
|
def render_layout(view_id, content_html, tokens, page_name=None):
|
||||||
css = _load_css()
|
css = _load_css()
|
||||||
level = client_level()
|
level = client_level()
|
||||||
has_pending_alert = not _apply_changes_immediately() and bool(get_dashboard_pending())
|
has_pending_alert = not _apply_changes_immediately() and bool(get_dashboard_pending())
|
||||||
|
|
@ -1008,7 +1008,7 @@ def render_layout(view_id, content_html, tokens):
|
||||||
f'<main class="main-content">\n{pending_bar}{problem_bars}{other_bars}{content_html}\n</main>\n'
|
f'<main class="main-content">\n{pending_bar}{problem_bars}{other_bars}{content_html}\n</main>\n'
|
||||||
f'{footer_html}\n'
|
f'{footer_html}\n'
|
||||||
f'<script>var CONFIG_HASH="{page_hash}";var LAN_IFACE="{lan_iface}";var VPN_VLAN_COUNT={vpn_count};var APPLY_UUID={json.dumps(my_uuid)};</script>\n'
|
f'<script>var CONFIG_HASH="{page_hash}";var LAN_IFACE="{lan_iface}";var VPN_VLAN_COUNT={vpn_count};var APPLY_UUID={json.dumps(my_uuid)};</script>\n'
|
||||||
f'<script>{_inline_js()}</script>\n'
|
f'<script>{_inline_js(page_name)}</script>\n'
|
||||||
'</body>\n</html>'
|
'</body>\n</html>'
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
@ -1076,7 +1076,7 @@ def build_nav_item(item, active_view, level, in_dropdown=False, inherited_req=No
|
||||||
|
|
||||||
# Inline JavaScript =================================================
|
# Inline JavaScript =================================================
|
||||||
|
|
||||||
def _inline_js():
|
def _inline_js(page_name=None):
|
||||||
try:
|
try:
|
||||||
with open(VALIDATION_FILE) as f:
|
with open(VALIDATION_FILE) as f:
|
||||||
val_js = f.read()
|
val_js = f.read()
|
||||||
|
|
@ -1087,7 +1087,15 @@ def _inline_js():
|
||||||
app_js = f.read()
|
app_js = f.read()
|
||||||
except Exception:
|
except Exception:
|
||||||
app_js = ''
|
app_js = ''
|
||||||
return val_js + '\n' + app_js
|
page_js = ''
|
||||||
|
if page_name:
|
||||||
|
page_js_path = os.path.join(PAGES_DIR, page_name, 'page.js')
|
||||||
|
try:
|
||||||
|
with open(page_js_path) as f:
|
||||||
|
page_js = f.read()
|
||||||
|
except Exception:
|
||||||
|
pass
|
||||||
|
return val_js + '\n' + app_js + ('\n' + page_js if page_js else '')
|
||||||
|
|
||||||
|
|
||||||
# Routes ============================================================
|
# Routes ============================================================
|
||||||
|
|
@ -1121,4 +1129,4 @@ def serve_view(page_name):
|
||||||
flash_html += f'<div class="info-bar info-bar-{variant} info-bar-flash"><span>{msg_html}</span></div>'
|
flash_html += f'<div class="info-bar info-bar-{variant} info-bar-flash"><span>{msg_html}</span></div>'
|
||||||
|
|
||||||
content_html = flash_html + build_items(view_def.get('items', []), tokens, view_req)
|
content_html = flash_html + build_items(view_def.get('items', []), tokens, view_req)
|
||||||
return render_layout(page_name, content_html, tokens)
|
return render_layout(page_name, content_html, tokens, page_name=page_name)
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue