Development
This commit is contained in:
parent
7e39b077d1
commit
275ccd0bac
2 changed files with 41 additions and 33 deletions
|
|
@ -325,10 +325,12 @@ def _config_datasource(name):
|
|||
row = dict(p)
|
||||
ptype = p.get('provider', '').lower()
|
||||
if ptype == 'noip':
|
||||
row['credentials'] = f'<b>U:</b> {e(p.get("username", "-"))}<br><b>P:</b> •••'
|
||||
row['credentials'] = (f'<div style="line-height:1.3">'
|
||||
f'<b>U:</b> {e(p.get("username", "-"))}<br/>'
|
||||
f'<b>P:</b> •••</div>')
|
||||
elif ptype in ('cloudflare', 'duckdns'):
|
||||
tok = p.get('api_token', '')
|
||||
row['credentials'] = f'API Token: {tok[:8]}...' if tok else '(not set)'
|
||||
row['credentials'] = f'<b>API Token:</b> {e(tok[:16])}...' if tok else '(not set)'
|
||||
else:
|
||||
row['credentials'] = '-'
|
||||
row['hostnames'] = json.dumps(p.get('hostnames', p.get('subdomains', [])))
|
||||
|
|
@ -628,7 +630,7 @@ def collect_tokens():
|
|||
f'<tbody>{rows}</tbody>'
|
||||
'</table>'
|
||||
'<form method="post" action="/action/general_cardpendingchanges_applyselected">'
|
||||
f'<input type="hidden" name="config_hash" value="{e(core_hash())}">'
|
||||
f'<input type="hidden" name="config_hash" value="{e(core_hash())}"/>'
|
||||
'<div class="button-row">'
|
||||
'<button type="submit" class="btn btn-primary">Apply Now</button>'
|
||||
'</div></form>'
|
||||
|
|
@ -915,13 +917,13 @@ def _render_item(item, tokens, inherited_req=None):
|
|||
f'<div class="credential-fields" data-provider-select="{psel}">'
|
||||
f'<div class="cred-group-token" style="display:none">'
|
||||
f'<div class="form-group"><label class="form-label">API Token</label>'
|
||||
f'<input type="text" name="api_token" class="form-input"></div>'
|
||||
f'<input type="text" name="api_token" class="form-input"/></div>'
|
||||
f'</div>'
|
||||
f'<div class="cred-group-noip" style="display:none">'
|
||||
f'<div class="form-group"><label class="form-label">Username</label>'
|
||||
f'<input type="text" name="username" class="form-input"></div>'
|
||||
f'<input type="text" name="username" class="form-input"/></div>'
|
||||
f'<div class="form-group"><label class="form-label">Password</label>'
|
||||
f'<input type="password" name="password" class="form-input"></div>'
|
||||
f'<input type="password" name="password" class="form-input"/></div>'
|
||||
f'</div>'
|
||||
f'</div>'
|
||||
)
|
||||
|
|
@ -943,15 +945,15 @@ def _render_item(item, tokens, inherited_req=None):
|
|||
action = e(apply_tokens(item.get('action', ''), tokens))
|
||||
method = e(item.get('method', 'post'))
|
||||
inner = render_items(item.get('items', []), tokens, req)
|
||||
hash_field = f'<input type="hidden" name="config_hash" value="{e(core_hash())}">'
|
||||
hash_field = f'<input type="hidden" name="config_hash" value="{e(core_hash())}"/>'
|
||||
originals = json.dumps(_collect_form_originals(item.get('items', []), tokens))
|
||||
orig_field = f'<input type="hidden" name="original_values" value="{e(originals)}">'
|
||||
orig_field = f'<input type="hidden" name="original_values" value="{e(originals)}"/>'
|
||||
return f'<form action="{action}" method="{method}">{hash_field}{orig_field}{inner}</form>'
|
||||
|
||||
if t == 'hidden':
|
||||
name = e(item.get('name', ''))
|
||||
value = e(apply_tokens(item.get('value', ''), tokens))
|
||||
return f'<input type="hidden" name="{name}" value="{value}">'
|
||||
return f'<input type="hidden" name="{name}" value="{value}"/>'
|
||||
|
||||
if t == 'field':
|
||||
return _render_field(item, tokens)
|
||||
|
|
@ -978,9 +980,9 @@ def _render_item(item, tokens, inherited_req=None):
|
|||
f'<div class="form-group">'
|
||||
f'<label class="form-label">Subnet</label>'
|
||||
f'<div class="subnet-row-wrap">'
|
||||
f'<input type="text" name="{subnet_name}" value="{e(subnet_val)}" placeholder="{subnet_ph}" class="form-input">'
|
||||
f'<input type="text" name="{subnet_name}" value="{e(subnet_val)}" placeholder="{subnet_ph}" class="form-input"/>'
|
||||
f'<span class="subnet-sep">/</span>'
|
||||
f'<input type="number" name="{prefix_name}" value="{pf}" min="1" max="30" class="form-input subnet-prefix-input">'
|
||||
f'<input type="number" name="{prefix_name}" value="{pf}" min="1" max="30" class="form-input subnet-prefix-input"/>'
|
||||
f'<span class="subnet-dotted">{e(dotted)}</span>'
|
||||
f'</div>'
|
||||
f'<p class="form-hint field-dyn-hint" style="display:none"></p>'
|
||||
|
|
@ -1022,7 +1024,7 @@ def _render_field(item, tokens):
|
|||
readonly = ' readonly' if item.get('readonly') else ''
|
||||
|
||||
if input_type == 'hidden':
|
||||
return f'<input type="hidden" name="{name}" value="{e(value)}">'
|
||||
return f'<input type="hidden" name="{name}" value="{e(value)}"/>'
|
||||
|
||||
if input_type == 'checkbox':
|
||||
checked = 'checked' if value.lower() in ('true', '1', 'yes') else ''
|
||||
|
|
@ -1031,12 +1033,12 @@ def _render_field(item, tokens):
|
|||
return (f'<div class="form-group">'
|
||||
f'<label class="form-label">{label}</label>'
|
||||
f'<label class="form-checkbox-row">'
|
||||
f'<input type="checkbox" name="{name}" {checked} class="form-checkbox">'
|
||||
f'<input type="checkbox" name="{name}" {checked} class="form-checkbox"/>'
|
||||
f' <span class="form-checkbox-label">{e(cb_label)}</span>'
|
||||
f'</label>{hint_html}</div>')
|
||||
return (f'<div class="form-group">'
|
||||
f'<label class="form-label">'
|
||||
f'<input type="checkbox" name="{name}" {checked} class="form-checkbox"> {label}'
|
||||
f'<input type="checkbox" name="{name}" {checked} class="form-checkbox"/> {label}'
|
||||
f'</label>{hint_html}</div>')
|
||||
|
||||
if input_type == 'checkbox_group':
|
||||
|
|
@ -1048,7 +1050,7 @@ def _render_field(item, tokens):
|
|||
boxes = ''.join(
|
||||
f'<label class="checkbox-group-item">'
|
||||
f'<input type="checkbox" name="{name}" value="{e(o.get("value",""))}"'
|
||||
f'{"checked" if o.get("value") in selected else ""}> {e(o.get("label",""))}'
|
||||
f'{"checked" if o.get("value") in selected else ""}/> {e(o.get("label",""))}'
|
||||
f'</label>'
|
||||
for o in opts
|
||||
)
|
||||
|
|
@ -1075,7 +1077,7 @@ def _render_field(item, tokens):
|
|||
min_attr = f' min="{item["min"]}"' if 'min' in item else ''
|
||||
max_attr = f' max="{item["max"]}"' if 'max' in item else ''
|
||||
return (f'<div class="form-group"><label class="form-label">{label}</label>'
|
||||
f'<input type="number" name="{name}" value="{e(value)}"{min_attr}{max_attr} class="form-input{extra_cls}"{readonly}>'
|
||||
f'<input type="number" name="{name}" value="{e(value)}"{min_attr}{max_attr} class="form-input{extra_cls}"{readonly}/>'
|
||||
f'{hint_html}</div>')
|
||||
|
||||
if input_type == 'textarea':
|
||||
|
|
@ -1175,7 +1177,7 @@ def _render_field(item, tokens):
|
|||
return (f'<div class="form-group">'
|
||||
f'<label class="form-label">{label}</label>'
|
||||
f'<div class="iface-picker">'
|
||||
f'<input type="hidden" name="{name}" value="{e(current)}">'
|
||||
f'<input type="hidden" name="{name}" value="{e(current)}"/>'
|
||||
f'<div class="iface-picker-header">'
|
||||
f'<button type="button" class="iface-picker-btn">{btn_label}{btn_badge}</button>'
|
||||
f'{ext_meta}'
|
||||
|
|
@ -1190,7 +1192,7 @@ def _render_field(item, tokens):
|
|||
dyn_hint = '<p class="form-hint field-dyn-hint" style="display:none"></p>' if (item.get('readonly') or item.get('dyn_hint') or validate) else ''
|
||||
return (f'<div class="form-group"><label class="form-label">{label}</label>'
|
||||
f'<input type="{e(input_type)}" name="{name}" value="{e(value)}"'
|
||||
f' placeholder="{placeholder}" class="form-input{extra_cls}"{readonly}{validate_attr}>{hint_html}{dyn_hint}</div>')
|
||||
f' placeholder="{placeholder}" class="form-input{extra_cls}"{readonly}{validate_attr}/>{hint_html}{dyn_hint}</div>')
|
||||
|
||||
|
||||
def _collect_form_originals(items, tokens):
|
||||
|
|
@ -1249,7 +1251,7 @@ def _render_editable_list(item, tokens):
|
|||
|
||||
rows = ''.join(
|
||||
f'<div class="editable-list-item">'
|
||||
f'<input type="text" name="{name}" value="{e(v)}" class="form-input">'
|
||||
f'<input type="text" name="{name}" value="{e(v)}" class="form-input"/>'
|
||||
f'<button type="button" class="btn btn-ghost btn-sm editable-list-remove">Remove</button>'
|
||||
f'</div>'
|
||||
for v in items_list
|
||||
|
|
@ -1323,8 +1325,8 @@ def _render_table(item, tokens, inherited_req=None):
|
|||
btns += f'<button type="button" class="btn {cls}" disabled>{text}</button>'
|
||||
continue
|
||||
btns += (f'<form method="post" action="{action}" style="display:inline">'
|
||||
f'<input type="hidden" name="row_index" value="{idx}">'
|
||||
f'<input type="hidden" name="config_hash" value="{e(hash_val)}">'
|
||||
f'<input type="hidden" name="row_index" value="{idx}"/>'
|
||||
f'<input type="hidden" name="config_hash" value="{e(hash_val)}"/>'
|
||||
f'<button type="submit" class="btn {cls}">{text}</button></form>')
|
||||
elif method == 'js_edit':
|
||||
target = e(ra.get('target', 'edit-form'))
|
||||
|
|
@ -1377,7 +1379,7 @@ def _render_table_cell(value, render_fn, col_class='', field='', row_idx=None,
|
|||
label = 'Disabled'; badge_cls = 'badge-disabled'
|
||||
if toggle_action and row_idx is not None and toggle_allowed:
|
||||
inner = (f'<form method="post" action="{e(toggle_action)}" style="display:inline">'
|
||||
f'<input type="hidden" name="row_index" value="{row_idx}">'
|
||||
f'<input type="hidden" name="row_index" value="{row_idx}"/>'
|
||||
f'<button type="submit" class="btn-badge">'
|
||||
f'<span class="badge {badge_cls}">{label}</span></button></form>')
|
||||
else:
|
||||
|
|
@ -1497,8 +1499,8 @@ def render_layout(view_id, content_html, tokens):
|
|||
pass
|
||||
|
||||
return (f'<!DOCTYPE html>\n<html lang="en">\n<head>\n'
|
||||
f' <meta charset="UTF-8">\n'
|
||||
f' <meta name="viewport" content="width=device-width, initial-scale=1.0">\n'
|
||||
f' <meta charset="UTF-8"/>\n'
|
||||
f' <meta name="viewport" content="width=device-width, initial-scale=1.0"/>\n'
|
||||
f' <title>{PRODUCT_DISPLAY_NAME}</title>\n'
|
||||
f' <style>{css}</style>\n'
|
||||
f'</head>\n<body>\n'
|
||||
|
|
@ -1950,13 +1952,13 @@ document.addEventListener('click', function(e) {
|
|||
if (provider === 'noip') {
|
||||
return '<div class="cred-field"><span class="cred-label">U:</span>' +
|
||||
'<input type="text" name="username" value="' + esc(data.username||'') +
|
||||
'" class="form-input inline-edit-input"></div>' +
|
||||
'" class="form-input inline-edit-input"/></div>' +
|
||||
'<div class="cred-field"><span class="cred-label">P:</span>' +
|
||||
'<input type="password" name="password" value="' + esc(data.password||'') +
|
||||
'" class="form-input inline-edit-input"></div>';
|
||||
'" class="form-input inline-edit-input"/></div>';
|
||||
} else {
|
||||
return '<input type="text" name="api_token" value="' + esc(data.api_token||'') +
|
||||
'" class="form-input inline-edit-input" placeholder="API Token">';
|
||||
'" class="form-input inline-edit-input" placeholder="API Token"/>';
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1971,7 +1973,7 @@ document.addEventListener('click', function(e) {
|
|||
if (inputType === 'checkbox') {
|
||||
var checked = (val === true || val === 'true' || val === 1 || val === '1');
|
||||
td.innerHTML = '<input type="checkbox" name="' + field + '"' +
|
||||
(checked ? ' checked' : '') + ' class="inline-edit-checkbox">';
|
||||
(checked ? ' checked' : '') + ' class="inline-edit-checkbox"/>';
|
||||
} else if (inputType === 'checkbox_multi') {
|
||||
var opts = fDef.options || [];
|
||||
var checked = [];
|
||||
|
|
@ -1981,7 +1983,7 @@ document.addEventListener('click', function(e) {
|
|||
var isChecked = checked.indexOf(o.value) !== -1;
|
||||
cbHtml += '<label class="checkbox-multi-item">' +
|
||||
'<input type="checkbox" name="' + field + '" value="' + esc(o.value) + '"' +
|
||||
(isChecked ? ' checked' : '') + ' class="inline-edit-checkbox-multi"> ' + esc(o.label) + '</label>';
|
||||
(isChecked ? ' checked' : '') + ' class="inline-edit-checkbox-multi"/> ' + esc(o.label) + '</label>';
|
||||
});
|
||||
cbHtml += '</div>';
|
||||
td.innerHTML = cbHtml;
|
||||
|
|
@ -1998,7 +2000,7 @@ document.addEventListener('click', function(e) {
|
|||
var minAttr = fDef.min !== undefined ? ' min="' + esc(String(fDef.min)) + '"' : '';
|
||||
var maxAttr = fDef.max !== undefined ? ' max="' + esc(String(fDef.max)) + '"' : '';
|
||||
td.innerHTML = '<input type="number" name="' + field + '" value="' + esc(String(val)) +
|
||||
'"' + minAttr + maxAttr + ' class="form-input inline-edit-input">';
|
||||
'"' + minAttr + maxAttr + ' class="form-input inline-edit-input"/>';
|
||||
} else if (inputType === 'textarea') {
|
||||
var textVal;
|
||||
try { var arr = JSON.parse(val); textVal = Array.isArray(arr) ? arr.join('\n') : String(val||''); }
|
||||
|
|
@ -2011,7 +2013,7 @@ document.addEventListener('click', function(e) {
|
|||
var validateAttr = fDef.validate ? ' data-validate="' + esc(fDef.validate) + '"' : '';
|
||||
var hintHtml = fDef.validate ? '<p class="form-hint field-dyn-hint" style="display:none"></p>' : '';
|
||||
td.innerHTML = '<input type="' + inputType + '" name="' + field +
|
||||
'" value="' + esc(String(val)) + '" class="form-input inline-edit-input"' + validateAttr + '>' + hintHtml;
|
||||
'" value="' + esc(String(val)) + '" class="form-input inline-edit-input"' + validateAttr + '/>' + hintHtml;
|
||||
if (fDef.validate && typeof validateEl === 'function') validateEl(td.querySelector('input'));
|
||||
}
|
||||
});
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue