- Add admin DAV tab (rename from CalDAV/CardDAV) and Pushover tab
- Add per-user Pushover tab (User Key only; App Token stays admin-managed)
- Remove system-wide CalDAV/CardDAV fallback — per-user config only
- Rewrite contacts_tool.py using httpx directly (caldav 2.x dropped AddressBook)
- Fix CardDAV REPORT/PROPFIND using SOGo URL pattern
- Fix CalDAV/CardDAV test endpoints (POST method, URL scheme normalization)
- Fix Show Password button — API now returns actual credential values
- Convert Credentials tab to generic key-value store; dedicated keys
(CalDAV, Pushover, trusted_proxy) excluded via _DEDICATED_CRED_KEYS
139 lines
5.7 KiB
HTML
139 lines
5.7 KiB
HTML
{% extends "base.html" %}
|
|
{% block title %}{{ agent_name }} — Monitors{% endblock %}
|
|
|
|
{% block content %}
|
|
<div class="page" id="monitors-container">
|
|
<div style="display:flex;justify-content:space-between;align-items:center;margin-bottom:24px">
|
|
<h1>Monitors</h1>
|
|
</div>
|
|
|
|
<!-- Tabs -->
|
|
<div style="display:flex;gap:0;border-bottom:1px solid var(--border);margin-bottom:24px">
|
|
<button class="tab-btn active" id="mtab-pages" type="button" onclick="switchMonitorTab('pages')">Page Watchers</button>
|
|
<button class="tab-btn" id="mtab-rss" type="button" onclick="switchMonitorTab('rss')">RSS Feeds</button>
|
|
</div>
|
|
|
|
<!-- ── Page Watchers tab ── -->
|
|
<div id="mpane-pages">
|
|
<div style="display:flex;justify-content:flex-end;margin-bottom:16px">
|
|
<button class="btn btn-primary" onclick="openPageModal(null)">+ Add Page Watcher</button>
|
|
</div>
|
|
<div class="table-wrap">
|
|
<table id="pages-table">
|
|
<thead><tr>
|
|
<th>Name</th>
|
|
<th>URL</th>
|
|
<th>Schedule</th>
|
|
<th>Status</th>
|
|
<th>Last checked</th>
|
|
<th>Last changed</th>
|
|
<th style="text-align:right">Actions</th>
|
|
</tr></thead>
|
|
<tbody id="pages-tbody"><tr><td colspan="7" style="color:var(--text-dim)">Loading…</td></tr></tbody>
|
|
</table>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- ── RSS Feeds tab ── -->
|
|
<div id="mpane-rss" style="display:none">
|
|
<div style="display:flex;justify-content:flex-end;margin-bottom:16px">
|
|
<button class="btn btn-primary" onclick="openFeedModal(null)">+ Add RSS Feed</button>
|
|
</div>
|
|
<div class="table-wrap">
|
|
<table id="feeds-table">
|
|
<thead><tr>
|
|
<th>Name</th>
|
|
<th>URL</th>
|
|
<th>Schedule</th>
|
|
<th>Status</th>
|
|
<th>Last fetched</th>
|
|
<th style="text-align:right">Actions</th>
|
|
</tr></thead>
|
|
<tbody id="feeds-tbody"><tr><td colspan="6" style="color:var(--text-dim)">Loading…</td></tr></tbody>
|
|
</table>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Page watcher modal -->
|
|
<div class="modal-overlay" id="page-modal" style="display:none">
|
|
<div class="modal" style="max-width:540px;width:100%">
|
|
<h3 id="page-modal-title" style="margin-bottom:20px">Add Page Watcher</h3>
|
|
<input type="hidden" id="page-modal-id">
|
|
<div class="form-group">
|
|
<label>Name</label>
|
|
<input type="text" id="page-modal-name" class="form-input" placeholder="e.g. Company homepage" autocomplete="off">
|
|
</div>
|
|
<div class="form-group">
|
|
<label>URL</label>
|
|
<input type="text" id="page-modal-url" class="form-input" placeholder="https://example.com/page">
|
|
</div>
|
|
<div class="form-group">
|
|
<label>CSS selector <span style="color:var(--text-dim)">(optional — extract specific element)</span></label>
|
|
<input type="text" id="page-modal-selector" class="form-input" placeholder="e.g. #main-content or .price">
|
|
</div>
|
|
<div class="form-group">
|
|
<label>Check schedule (cron)</label>
|
|
<input type="text" id="page-modal-schedule" class="form-input" value="0 * * * *" placeholder="0 * * * *">
|
|
<div style="font-size:11px;color:var(--text-dim);margin-top:4px">Default: every hour. Use <a href="https://crontab.guru" target="_blank" style="color:var(--accent)">crontab.guru</a> to build expressions.</div>
|
|
</div>
|
|
<div class="form-group">
|
|
<label>On change: notify via</label>
|
|
<select id="page-modal-mode" class="form-input">
|
|
<option value="agent">Agent</option>
|
|
<option value="pushover">Pushover</option>
|
|
<option value="both">Both</option>
|
|
</select>
|
|
</div>
|
|
<div class="form-group" id="page-modal-agent-group">
|
|
<label>Agent to trigger</label>
|
|
<select id="page-modal-agent" class="form-input"></select>
|
|
</div>
|
|
<div class="modal-buttons" style="margin-top:20px">
|
|
<button type="button" class="btn btn-ghost" onclick="closePageModal()">Cancel</button>
|
|
<button type="button" class="btn btn-primary" onclick="savePage()">Save</button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- RSS feed modal -->
|
|
<div class="modal-overlay" id="feed-modal" style="display:none">
|
|
<div class="modal" style="max-width:540px;width:100%">
|
|
<h3 id="feed-modal-title" style="margin-bottom:20px">Add RSS Feed</h3>
|
|
<input type="hidden" id="feed-modal-id">
|
|
<div class="form-group">
|
|
<label>Name</label>
|
|
<input type="text" id="feed-modal-name" class="form-input" placeholder="e.g. Hacker News" autocomplete="off">
|
|
</div>
|
|
<div class="form-group">
|
|
<label>Feed URL (RSS or Atom)</label>
|
|
<input type="text" id="feed-modal-url" class="form-input" placeholder="https://example.com/feed.xml">
|
|
</div>
|
|
<div class="form-group">
|
|
<label>Fetch schedule (cron)</label>
|
|
<input type="text" id="feed-modal-schedule" class="form-input" value="0 */4 * * *" placeholder="0 */4 * * *">
|
|
</div>
|
|
<div class="form-group">
|
|
<label>Max new items per run</label>
|
|
<input type="number" id="feed-modal-max-items" class="form-input" value="5" min="1" max="50">
|
|
</div>
|
|
<div class="form-group">
|
|
<label>On new items: notify via</label>
|
|
<select id="feed-modal-mode" class="form-input">
|
|
<option value="agent">Agent</option>
|
|
<option value="pushover">Pushover</option>
|
|
<option value="both">Both</option>
|
|
</select>
|
|
</div>
|
|
<div class="form-group" id="feed-modal-agent-group">
|
|
<label>Agent to trigger</label>
|
|
<select id="feed-modal-agent" class="form-input"></select>
|
|
</div>
|
|
<div class="modal-buttons" style="margin-top:20px">
|
|
<button type="button" class="btn btn-ghost" onclick="closeFeedModal()">Cancel</button>
|
|
<button type="button" class="btn btn-primary" onclick="saveFeed()">Save</button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
{% endblock %}
|