Test/custom admin ui #4
@@ -2,7 +2,7 @@
|
||||
from pathlib import Path
|
||||
import gzip
|
||||
|
||||
ASSETS = Path('/app/themes/2024/assets')
|
||||
ASSETS_ROOT = Path('/app')
|
||||
|
||||
|
||||
def rewrite(path: Path, text: str) -> None:
|
||||
@@ -53,14 +53,75 @@ def patch_clipboard(path: Path) -> bool:
|
||||
return False
|
||||
|
||||
|
||||
def write_detail_collapse_script(theme_dir: Path) -> bool:
|
||||
assets = theme_dir / 'assets'
|
||||
index = theme_dir / 'index.html'
|
||||
if not assets.exists() or not index.exists():
|
||||
return False
|
||||
js_path = assets / 'fcb-detail-collapse.js'
|
||||
js = r'''(() => {
|
||||
const EVENT_RE = /(第\s*\d+\s*次取件|取件\s*[##]\s*\d+|Retrieval\s*#\s*\d+)/i;
|
||||
const LIFE_RE = /(生命周期|Lifecycle)/i;
|
||||
const markRows = () => {
|
||||
document.querySelectorAll('section').forEach(section => {
|
||||
const title = section.querySelector('h1,h2,h3,h4,h5');
|
||||
if (!title || !LIFE_RE.test(title.textContent || '')) return;
|
||||
const rows = [...section.querySelectorAll('div.grid')].filter(row => EVENT_RE.test(row.textContent || ''));
|
||||
if (rows.length <= 3) return;
|
||||
if (section.dataset.fcbxLifecycleReady !== '1') {
|
||||
section.dataset.fcbxLifecycleReady = '1';
|
||||
section.dataset.fcbxLifecycleCollapsed = '1';
|
||||
const btn = document.createElement('button');
|
||||
btn.type = 'button';
|
||||
btn.className = 'fcbx-life-toggle mt-3 rounded-lg border px-3 py-2 text-sm font-medium transition';
|
||||
btn.style.cssText = 'border-color:rgba(148,163,184,.55);display:inline-flex;align-items:center;gap:.35rem;';
|
||||
btn.addEventListener('click', () => {
|
||||
section.dataset.fcbxLifecycleCollapsed = section.dataset.fcbxLifecycleCollapsed === '1' ? '0' : '1';
|
||||
apply(section);
|
||||
});
|
||||
(section.lastElementChild || section).appendChild(btn);
|
||||
}
|
||||
apply(section);
|
||||
});
|
||||
};
|
||||
const apply = section => {
|
||||
const rows = [...section.querySelectorAll('div.grid')].filter(row => EVENT_RE.test(row.textContent || ''));
|
||||
const collapsed = section.dataset.fcbxLifecycleCollapsed !== '0';
|
||||
rows.forEach((row, idx) => { row.style.display = collapsed && idx >= 3 ? 'none' : ''; });
|
||||
const btn = section.querySelector('.fcbx-life-toggle');
|
||||
if (btn) btn.textContent = collapsed ? `展开全部取件记录(共 ${rows.length} 次)` : '收起取件记录';
|
||||
};
|
||||
let timer = 0;
|
||||
const schedule = () => { clearTimeout(timer); timer = setTimeout(markRows, 80); };
|
||||
window.addEventListener('hashchange', schedule);
|
||||
document.addEventListener('DOMContentLoaded', schedule);
|
||||
new MutationObserver(schedule).observe(document.documentElement, { childList: true, subtree: true });
|
||||
schedule();
|
||||
})();'''
|
||||
rewrite(js_path, js)
|
||||
html = index.read_text(encoding='utf-8')
|
||||
tag = '<script src="assets/fcb-detail-collapse.js?v=20260709"></script>'
|
||||
if 'fcb-detail-collapse.js' not in html:
|
||||
html = html.replace('</body>', tag + '\n</body>') if '</body>' in html else html + '\n' + tag + '\n'
|
||||
index.write_text(html, encoding='utf-8')
|
||||
gz = index.with_suffix(index.suffix + '.gz')
|
||||
if gz.exists():
|
||||
with gzip.open(gz, 'wb', compresslevel=9) as fh:
|
||||
fh.write(html.encode('utf-8'))
|
||||
return True
|
||||
|
||||
|
||||
def main() -> None:
|
||||
changed = []
|
||||
for path in ASSETS.glob('FileManageView-*.js'):
|
||||
if patch_file_manage(path):
|
||||
changed.append(path.name)
|
||||
for path in ASSETS.glob('clipboard-*.js'):
|
||||
if patch_clipboard(path):
|
||||
changed.append(path.name)
|
||||
for assets in ASSETS_ROOT.glob('themes/*/assets'):
|
||||
for path in assets.glob('FileManageView-*.js'):
|
||||
if patch_file_manage(path):
|
||||
changed.append(str(path.relative_to(ASSETS_ROOT)))
|
||||
for path in assets.glob('clipboard-*.js'):
|
||||
if patch_clipboard(path):
|
||||
changed.append(str(path.relative_to(ASSETS_ROOT)))
|
||||
if write_detail_collapse_script(assets.parent):
|
||||
changed.append(str((assets / 'fcb-detail-collapse.js').relative_to(ASSETS_ROOT)))
|
||||
if not changed:
|
||||
raise SystemExit('admin timeline/clipboard patch markers not found or already patched')
|
||||
print('patched admin assets:', ', '.join(changed))
|
||||
|
||||
Reference in New Issue
Block a user