Development
This commit is contained in:
parent
3b5e9e7eaa
commit
1ed913524f
1 changed files with 87 additions and 5 deletions
|
|
@ -1797,6 +1797,72 @@ def _render_editable_list(item, tokens):
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
_STANDARD_INPUT_TYPES = {'text', 'password', 'number', 'checkbox', 'select', 'textarea'}
|
||||||
|
|
||||||
|
|
||||||
|
def _js_str(value):
|
||||||
|
return json.dumps(str(value))
|
||||||
|
|
||||||
|
|
||||||
|
def _get_worker_id(datasource):
|
||||||
|
for prefix in ('config:', 'live:'):
|
||||||
|
if datasource.startswith(prefix):
|
||||||
|
return datasource[len(prefix):]
|
||||||
|
return ''
|
||||||
|
|
||||||
|
|
||||||
|
def _render_table_worker_script(item, expanded_ra_fields):
|
||||||
|
"""Emit a <script> registering a table worker for any non-standard inline_edit field types.
|
||||||
|
Returns empty string when all fields are standard types."""
|
||||||
|
if not expanded_ra_fields:
|
||||||
|
return ''
|
||||||
|
worker_id = _get_worker_id(item.get('datasource', ''))
|
||||||
|
if not worker_id:
|
||||||
|
return ''
|
||||||
|
nonstandard = set()
|
||||||
|
for fields in expanded_ra_fields.values():
|
||||||
|
for f in fields:
|
||||||
|
it = f.get('input_type', 'text')
|
||||||
|
if it not in _STANDARD_INPUT_TYPES:
|
||||||
|
nonstandard.add(it)
|
||||||
|
if not nonstandard:
|
||||||
|
return ''
|
||||||
|
if nonstandard == {'credentials'}:
|
||||||
|
return (
|
||||||
|
f'<script>registerTableWorker({_js_str(worker_id)}, (function() {{\n'
|
||||||
|
' function _buildCreds(provider, data) {\n'
|
||||||
|
' if (provider === \'noip\') {\n'
|
||||||
|
' return \'<div class="cred-field"><span class="cred-label">U:</span>\' +\n'
|
||||||
|
' \'<input type="text" name="username" value="\' + _htmlEsc(data.username||\'\')'
|
||||||
|
' + \'" class="form-input inline-edit-input"/></div>\' +\n'
|
||||||
|
' \'<div class="cred-field"><span class="cred-label">P:</span>\' +\n'
|
||||||
|
' \'<input type="password" name="password" value="\' + _htmlEsc(data.password||\'\')'
|
||||||
|
' + \'" class="form-input inline-edit-input"/></div>\';\n'
|
||||||
|
' }\n'
|
||||||
|
' return \'<input type="text" name="api_token" value="\' + _htmlEsc(data.api_token||\'\')'
|
||||||
|
' + \'" class="form-input inline-edit-input" placeholder="API Token"/>\';\n'
|
||||||
|
' }\n'
|
||||||
|
' return {\n'
|
||||||
|
' renderCell: function(fDef, td, val, row) {\n'
|
||||||
|
' if (fDef.input_type !== \'credentials\') return false;\n'
|
||||||
|
' td.innerHTML = _buildCreds(row.provider || \'noip\', row);\n'
|
||||||
|
' return true;\n'
|
||||||
|
' },\n'
|
||||||
|
' afterRowOpen: function(tr, row) {\n'
|
||||||
|
' var provSel = tr.querySelector(\'td[data-field="provider"] select\');\n'
|
||||||
|
' var credTd = tr.querySelector(\'td[data-field="credentials"]\');\n'
|
||||||
|
' if (!provSel || !credTd) return;\n'
|
||||||
|
' provSel.addEventListener(\'change\', function() {\n'
|
||||||
|
' credTd.innerHTML = _buildCreds(this.value, row);\n'
|
||||||
|
' });\n'
|
||||||
|
' }\n'
|
||||||
|
' };\n'
|
||||||
|
'}()));</script>\n'
|
||||||
|
)
|
||||||
|
# Unrecognized non-standard types: emit a safe no-op worker
|
||||||
|
return f'<script>registerTableWorker({_js_str(worker_id)}, {{}});</script>\n'
|
||||||
|
|
||||||
|
|
||||||
def _render_table(item, tokens, inherited_req=None):
|
def _render_table(item, tokens, inherited_req=None):
|
||||||
level = _client_level()
|
level = _client_level()
|
||||||
columns = item.get('columns', [])
|
columns = item.get('columns', [])
|
||||||
|
|
@ -1820,6 +1886,12 @@ def _render_table(item, tokens, inherited_req=None):
|
||||||
if row_actions:
|
if row_actions:
|
||||||
thead += '<th></th>'
|
thead += '<th></th>'
|
||||||
|
|
||||||
|
expanded_ra_fields = {
|
||||||
|
i: _expand_fields(ra.get('fields', []), tokens)
|
||||||
|
for i, ra in enumerate(row_actions)
|
||||||
|
if ra.get('method', 'post').lower() == 'inline_edit'
|
||||||
|
}
|
||||||
|
|
||||||
if not rows:
|
if not rows:
|
||||||
colspan = len(columns) + (1 if row_actions else 0)
|
colspan = len(columns) + (1 if row_actions else 0)
|
||||||
tbody = f'<tr><td colspan="{colspan}" class="table-empty">{empty}</td></tr>'
|
tbody = f'<tr><td colspan="{colspan}" class="table-empty">{empty}</td></tr>'
|
||||||
|
|
@ -1845,7 +1917,7 @@ def _render_table(item, tokens, inherited_req=None):
|
||||||
)
|
)
|
||||||
if row_actions:
|
if row_actions:
|
||||||
btns = ''
|
btns = ''
|
||||||
for ra in row_actions:
|
for ra_i, ra in enumerate(row_actions):
|
||||||
req = ra.get('client_requirement', inherited_req)
|
req = ra.get('client_requirement', inherited_req)
|
||||||
if not _passes(req, level):
|
if not _passes(req, level):
|
||||||
continue
|
continue
|
||||||
|
|
@ -1869,29 +1941,39 @@ def _render_table(item, tokens, inherited_req=None):
|
||||||
row_json = e(json.dumps(row))
|
row_json = e(json.dumps(row))
|
||||||
btns += (
|
btns += (
|
||||||
f'<button type="button" class="btn {cls} row-edit-btn"'
|
f'<button type="button" class="btn {cls} row-edit-btn"'
|
||||||
|
f' data-edit-mode="reveal"'
|
||||||
f' data-row-index="{idx}" data-row="{row_json}"'
|
f' data-row-index="{idx}" data-row="{row_json}"'
|
||||||
f' data-target="{target}">{text}</button>'
|
f' data-target="{target}">{text}</button>'
|
||||||
)
|
)
|
||||||
elif method == 'inline_edit':
|
elif method == 'inline_edit':
|
||||||
fields_json = e(json.dumps(_expand_fields(ra.get('fields', []), tokens)))
|
expanded = expanded_ra_fields.get(ra_i, [])
|
||||||
|
fields_json = e(json.dumps(expanded))
|
||||||
row_json = e(json.dumps(row))
|
row_json = e(json.dumps(row))
|
||||||
|
worker_id = _get_worker_id(item.get('datasource', ''))
|
||||||
|
has_nonstandard = any(
|
||||||
|
f.get('input_type', 'text') not in _STANDARD_INPUT_TYPES
|
||||||
|
for f in expanded
|
||||||
|
)
|
||||||
|
worker_attr = f' data-worker-id="{e(worker_id)}"' if has_nonstandard and worker_id else ''
|
||||||
btns += (
|
btns += (
|
||||||
f'<button type="button" class="btn {cls} row-inline-edit-btn"'
|
f'<button type="button" class="btn {cls} row-edit-btn"'
|
||||||
|
f' data-edit-mode="inline"'
|
||||||
f' data-row-index="{idx}" data-row="{row_json}"'
|
f' data-row-index="{idx}" data-row="{row_json}"'
|
||||||
f' data-action="{action}" data-fields="{fields_json}">{text}</button>'
|
f' data-action="{action}" data-fields="{fields_json}"{worker_attr}>{text}</button>'
|
||||||
)
|
)
|
||||||
else:
|
else:
|
||||||
btns += f'<a href="{action}?row_index={idx}" class="btn {cls}">{text}</a>'
|
btns += f'<a href="{action}?row_index={idx}" class="btn {cls}">{text}</a>'
|
||||||
cells += f'<td class="col-actions">{btns}</td>'
|
cells += f'<td class="col-actions">{btns}</td>'
|
||||||
tbody += f'<tr>{cells}</tr>'
|
tbody += f'<tr>{cells}</tr>'
|
||||||
|
|
||||||
|
worker_script = _render_table_worker_script(item, expanded_ra_fields)
|
||||||
return (
|
return (
|
||||||
f'{toolbar_html}'
|
f'{toolbar_html}'
|
||||||
'<div class="table-wrapper">'
|
'<div class="table-wrapper">'
|
||||||
'<table class="data-table">'
|
'<table class="data-table">'
|
||||||
f'<thead><tr>{thead}</tr></thead>'
|
f'<thead><tr>{thead}</tr></thead>'
|
||||||
f'<tbody>{tbody}</tbody>'
|
f'<tbody>{tbody}</tbody>'
|
||||||
'</table></div>'
|
f'</table></div>{worker_script}'
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue