Development
This commit is contained in:
parent
113328c566
commit
01a636e842
16 changed files with 388 additions and 502 deletions
|
|
@ -4,7 +4,7 @@ import json, re, subprocess, os, sys
|
|||
import sanitize
|
||||
import validation as validate
|
||||
from datetime import datetime, timezone
|
||||
from config_utils import config_hash, get_pending_entries, get_dashboard_pending, get_dashboard_done, load_snapshot_for_uuid, load_all_snapshots, get_done_timestamps, queue_command, _find_cmd_in_queues, _entry_ts_from_queue, _apply_changes_immediately, _seconds_until_next_run, _format_timing, _is_locked, _lock_mtime, WEB_APP_DISPLAY_NAME, CONFIGS_DIR, DATA_DIR, WWW_DIR, ACCOUNTS_FILE, APP_DIR
|
||||
from config_utils import config_hash, get_pending_entries, get_dashboard_pending, get_dashboard_done, load_all_groups, revert_group, get_done_timestamps, queue_command, _find_cmd_in_queues, _entry_ts_from_queue, _apply_changes_immediately, _seconds_until_next_run, _format_timing, _is_locked, _lock_mtime, WEB_APP_DISPLAY_NAME, CONFIGS_DIR, DATA_DIR, WWW_DIR, ACCOUNTS_FILE, APP_DIR
|
||||
import factory
|
||||
from factory import LEVEL_RANK, e, client_level, passes, build_items, build_snap_val, snap_expand_row
|
||||
PAGES_DIR = os.path.join(APP_DIR, 'pages')
|
||||
|
|
@ -634,19 +634,18 @@ def collect_tokens():
|
|||
except Exception:
|
||||
pass
|
||||
|
||||
all_snaps = load_all_snapshots()
|
||||
_snap_uuid_set = {s.get('uuid') for s in all_snaps}
|
||||
all_groups = load_all_groups() # [(group_dict, [change_dicts])]
|
||||
_group_uuid_set = {g['uuid'] for g, _ in all_groups}
|
||||
pending_items = get_dashboard_pending()
|
||||
if pending_items:
|
||||
# Group by command; each group = one row in the Pending Actions table.
|
||||
from collections import defaultdict
|
||||
groups = defaultdict(list)
|
||||
_pgroups = defaultdict(list)
|
||||
for _uuid, _ts, cmd, user in pending_items:
|
||||
groups[cmd].append((_uuid, user))
|
||||
_pgroups[cmd].append((_uuid, user))
|
||||
rows = ''
|
||||
for cmd, entries in groups.items():
|
||||
for cmd, entries in _pgroups.items():
|
||||
users = ', '.join(sorted({u for _, u in entries if u and u != 'unknown'}))
|
||||
snap_uuids = [_uuid for _uuid, _ in entries if _uuid in _snap_uuid_set]
|
||||
snap_uuids = [_uuid for _uuid, _ in entries if _uuid in _group_uuid_set]
|
||||
if snap_uuids:
|
||||
req_tags = ''.join(
|
||||
f'<span class="tag" data-tooltip="{_uuid}" data-uuid="{_uuid}">'
|
||||
|
|
@ -690,27 +689,33 @@ def collect_tokens():
|
|||
if pending_items else ''
|
||||
)
|
||||
done_ts_map = get_done_timestamps()
|
||||
if all_snaps:
|
||||
# UUIDs that cannot be reverted: revert entries themselves, and entries
|
||||
# that have already been reverted (referenced in another snap's 'reverts').
|
||||
if all_groups:
|
||||
_no_revert = set()
|
||||
for _s in all_snaps:
|
||||
if _s.get('operation') == 'revert':
|
||||
_no_revert.add(_s.get('uuid', ''))
|
||||
if _s.get('reverts'):
|
||||
_no_revert.add(_s['reverts'])
|
||||
for g, _ in all_groups:
|
||||
if g['reverts_group']:
|
||||
_no_revert.add(g['uuid'])
|
||||
_no_revert.add(g['reverts_group'])
|
||||
hist_rows = ''
|
||||
_hist_onclick = (
|
||||
'onclick="if(event.target.type!==\'checkbox\')'
|
||||
'this.nextElementSibling.hidden=!this.nextElementSibling.hidden"'
|
||||
)
|
||||
for snap in all_snaps:
|
||||
_uuid = snap.get('uuid', '')
|
||||
for g, changes in all_groups:
|
||||
_uuid = g['uuid']
|
||||
applied_ts = done_ts_map.get(_uuid)
|
||||
dt_str = datetime.fromtimestamp(applied_ts).strftime('%Y-%m-%d %H:%M') if applied_ts else '-'
|
||||
snap_desc = e(snap.get('description', ''))
|
||||
before_val = snap.get('before')
|
||||
after_val = snap.get('after')
|
||||
all_before_null = all(c['before'] is None for c in changes)
|
||||
all_after_null = all(c['after'] is None for c in changes)
|
||||
if g['reverts_group']:
|
||||
verb = 'Reverted'
|
||||
elif all_before_null:
|
||||
verb = 'Added'
|
||||
elif all_after_null:
|
||||
verb = 'Deleted'
|
||||
else:
|
||||
verb = 'Edited'
|
||||
item = g.get('item_value') or ''
|
||||
summary = f'{verb} {g["parent_path"]}: {item}' if item else f'{verb} {g["parent_path"]}'
|
||||
snap_tag = (
|
||||
f'<div class="tag-list"><span class="tag" data-tooltip="{e(_uuid)}" data-uuid="{e(_uuid)}">'
|
||||
f'<span class="tl-full">{e(_uuid[:8])}</span>'
|
||||
|
|
@ -718,19 +723,18 @@ def collect_tokens():
|
|||
f'<span class="tl-min">{e(_uuid[:8])}</span>'
|
||||
'</span></div>'
|
||||
)
|
||||
snap_user = e(snap.get('user', ''))
|
||||
snap_user = e(g.get('user', ''))
|
||||
_cb_attrs = 'disabled title="Cannot revert"' if _uuid in _no_revert else ''
|
||||
hist_rows += (
|
||||
f'<tr class="row-expandable" data-uuid="{e(_uuid)}" {_hist_onclick}>'
|
||||
f'<td class="table-cell"><input type="checkbox" name="selected_uuids" value="{e(_uuid)}" {_cb_attrs}/></td>'
|
||||
f'<td class="table-cell">{e(dt_str)}</td>'
|
||||
f'<td class="table-cell">{snap_desc}</td>'
|
||||
f'<td class="table-cell">{build_snap_val(before_val)}</td>'
|
||||
f'<td class="table-cell">{build_snap_val(after_val)}</td>'
|
||||
f'<td class="table-cell">{e(summary)}</td>'
|
||||
f'<td class="table-cell">{build_snap_val(changes)}</td>'
|
||||
f'<td class="table-cell">{snap_tag}</td>'
|
||||
f'<td class="table-cell">{snap_user}</td>'
|
||||
'</tr>'
|
||||
f'{snap_expand_row(before_val, after_val, 7)}'
|
||||
f'{snap_expand_row(changes, 6)}'
|
||||
)
|
||||
select_all = (
|
||||
'<input type="checkbox" '
|
||||
|
|
@ -741,10 +745,9 @@ def collect_tokens():
|
|||
'<thead><tr>'
|
||||
f'<th class="table-header">{select_all}</th>'
|
||||
'<th class="table-header">Applied</th>'
|
||||
'<th class="table-header">Description</th>'
|
||||
'<th class="table-header">Before</th>'
|
||||
'<th class="table-header">After</th>'
|
||||
'<th class="table-header">Snapshot</th>'
|
||||
'<th class="table-header">Change</th>'
|
||||
'<th class="table-header">Fields</th>'
|
||||
'<th class="table-header">Group</th>'
|
||||
'<th class="table-header">User</th>'
|
||||
'</tr></thead>'
|
||||
f'<tbody>{hist_rows}</tbody>'
|
||||
|
|
@ -754,7 +757,7 @@ def collect_tokens():
|
|||
history_html = '<p class="text-muted">No change history.</p>'
|
||||
|
||||
tokens['CHANGE_HISTORY_HTML'] = history_html
|
||||
tokens['NO_HISTORY'] = 'true' if not all_snaps else ''
|
||||
tokens['NO_HISTORY'] = 'true' if not all_groups else ''
|
||||
|
||||
servers = dns.get('upstream_servers', [])
|
||||
tokens['DNS_STRICT_ORDER'] = 'true' if dns.get('strict_order') else 'false'
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue