Add header quick links with CRUD management and icon enhancements
- Add LinkConfig model and links field to settings - Add CRUD API endpoints for links (list/create/update/delete) - Add Links management tab in WebUI with add/edit/delete dialogs - Add live icon preview in Link and Script dialog forms - Show MDI icons inline in Quick Actions cards, Scripts table, Links table - Add broadcast_links_changed WebSocket event for live updates - Add EN/RU translations for all links management strings Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
This commit is contained in:
@@ -66,6 +66,7 @@
|
||||
<span class="version-label" id="version-label"></span>
|
||||
</div>
|
||||
<div style="display: flex; align-items: center; gap: 0.5rem;">
|
||||
<div id="headerLinks" class="header-links"></div>
|
||||
<div class="accent-picker">
|
||||
<button class="accent-picker-btn" onclick="toggleAccentPicker()" title="Accent color">
|
||||
<span class="accent-dot" id="accentDot"></span>
|
||||
@@ -121,6 +122,10 @@
|
||||
<svg viewBox="0 0 24 24" width="16" height="16"><path fill="currentColor" d="M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm-2 15l-5-5 1.41-1.41L10 14.17l7.59-7.59L19 8l-9 9z"/></svg>
|
||||
<span data-i18n="tab.callbacks">Callbacks</span>
|
||||
</button>
|
||||
<button class="tab-btn" data-tab="links" onclick="switchTab('links')" role="tab" aria-selected="false" aria-controls="panel-links" tabindex="-1">
|
||||
<svg viewBox="0 0 24 24" width="16" height="16"><path fill="currentColor" d="M3.9 12c0-1.71 1.39-3.1 3.1-3.1h4V7H7c-2.76 0-5 2.24-5 5s2.24 5 5 5h4v-1.9H7c-1.71 0-3.1-1.39-3.1-3.1zM8 13h8v-2H8v2zm9-6h-4v1.9h4c1.71 0 3.1 1.39 3.1 3.1s-1.39 3.1-3.1 3.1h-4V17h4c2.76 0 5-2.24 5-5s-2.24-5-5-5z"/></svg>
|
||||
<span data-i18n="tab.links">Links</span>
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<div class="player-container" data-tab-content="player" role="tabpanel" id="panel-player">
|
||||
@@ -329,6 +334,36 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Links Management Section -->
|
||||
<div class="script-management" data-tab-content="links" role="tabpanel" id="panel-links">
|
||||
<p style="color: var(--text-secondary); font-size: 0.875rem; margin-bottom: 1rem;" data-i18n="links.description">
|
||||
Quick links displayed as icons in the header bar. Click an icon to open the URL in a new tab.
|
||||
</p>
|
||||
<table class="scripts-table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th data-i18n="links.table.name">Name</th>
|
||||
<th data-i18n="links.table.url">URL</th>
|
||||
<th data-i18n="links.table.label">Label</th>
|
||||
<th data-i18n="links.table.actions">Actions</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody id="linksTableBody">
|
||||
<tr>
|
||||
<td colspan="4" class="empty-state">
|
||||
<div class="empty-state-illustration">
|
||||
<svg viewBox="0 0 64 64"><path d="M26 20a10 10 0 010 14l-6 6a10 10 0 01-14-14l6-6a10 10 0 0114 0" fill="none" stroke="currentColor" stroke-width="2"/><path d="M38 44a10 10 0 010-14l6-6a10 10 0 0114 14l-6 6a10 10 0 01-14 0" fill="none" stroke="currentColor" stroke-width="2"/><path d="M24 40l16-16" stroke="currentColor" stroke-width="2"/></svg>
|
||||
<p data-i18n="links.empty">No links configured. Click "Add" to create one.</p>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
<div class="add-card" onclick="showAddLinkDialog()">
|
||||
<span class="add-card-icon">+</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Display Control Section -->
|
||||
<div class="display-container" data-tab-content="display" role="tabpanel" id="panel-display">
|
||||
<div class="display-monitors" id="displayMonitors">
|
||||
@@ -373,7 +408,10 @@
|
||||
|
||||
<label>
|
||||
<span data-i18n="scripts.field.icon">Icon (MDI)</span>
|
||||
<input type="text" id="scriptIcon" data-i18n-placeholder="scripts.placeholder.icon" placeholder="e.g., mdi:power">
|
||||
<div class="icon-input-wrapper">
|
||||
<input type="text" id="scriptIcon" data-i18n-placeholder="scripts.placeholder.icon" placeholder="e.g., mdi:power">
|
||||
<div class="icon-preview" id="scriptIconPreview"></div>
|
||||
</div>
|
||||
</label>
|
||||
|
||||
<label>
|
||||
@@ -437,6 +475,47 @@
|
||||
</form>
|
||||
</dialog>
|
||||
|
||||
<!-- Add/Edit Link Dialog -->
|
||||
<dialog id="linkDialog">
|
||||
<div class="dialog-header">
|
||||
<h3 id="linkDialogTitle" data-i18n="links.dialog.add">Add Link</h3>
|
||||
</div>
|
||||
<form id="linkForm" onsubmit="saveLink(event)">
|
||||
<div class="dialog-body">
|
||||
<input type="hidden" id="linkOriginalName">
|
||||
<input type="hidden" id="linkIsEdit">
|
||||
|
||||
<label>
|
||||
<span data-i18n="links.field.name">Link Name *</span>
|
||||
<input type="text" id="linkName" required pattern="[a-zA-Z0-9_]+"
|
||||
data-i18n-title="links.placeholder.name" title="Only letters, numbers, and underscores allowed" maxlength="64">
|
||||
</label>
|
||||
|
||||
<label>
|
||||
<span data-i18n="links.field.url">URL *</span>
|
||||
<input type="url" id="linkUrl" required data-i18n-placeholder="links.placeholder.url" placeholder="https://example.com">
|
||||
</label>
|
||||
|
||||
<label>
|
||||
<span data-i18n="links.field.icon">Icon (MDI)</span>
|
||||
<div class="icon-input-wrapper">
|
||||
<input type="text" id="linkIcon" data-i18n-placeholder="links.placeholder.icon" placeholder="mdi:link">
|
||||
<div class="icon-preview" id="linkIconPreview"></div>
|
||||
</div>
|
||||
</label>
|
||||
|
||||
<label>
|
||||
<span data-i18n="links.field.label">Label</span>
|
||||
<input type="text" id="linkLabel" data-i18n-placeholder="links.placeholder.label" placeholder="Tooltip text">
|
||||
</label>
|
||||
</div>
|
||||
<div class="dialog-footer">
|
||||
<button type="button" class="btn-secondary" onclick="closeLinkDialog()" data-i18n="links.button.cancel">Cancel</button>
|
||||
<button type="submit" class="btn-primary" data-i18n="links.button.save">Save</button>
|
||||
</div>
|
||||
</form>
|
||||
</dialog>
|
||||
|
||||
<!-- Execution Result Dialog -->
|
||||
<dialog id="executionDialog">
|
||||
<div class="dialog-header">
|
||||
|
||||
Reference in New Issue
Block a user