Files
ledgrab/server/src/wled_controller/templates/modals/device-settings.html
T
alexei.dolgolyov 294d704eb0 Add CSPT entity, processed CSS source type, reverse filter, and UI improvements
- Add Color Strip Processing Template (CSPT) entity: reusable filter chains
  for 1D LED strip postprocessing (backend, storage, API, frontend CRUD)
- Add "processed" color strip source type that wraps another CSS source and
  applies a CSPT filter chain (dataclass, stream, schema, modal, cards)
- Add Reverse filter for strip LED order reversal
- Add CSPT and processed CSS nodes/edges to visual graph editor
- Add CSPT test preview WS endpoint with input source selection
- Add device settings CSPT template selector (add + edit modals with hints)
- Use icon grids for palette quantization preset selector in filter lists
- Use EntitySelect for template references and test modal source selectors
- Fix filters.css_filter_template.desc missing localization
- Fix icon grid cell height inequality (grid-auto-rows: 1fr)
- Rename "Processed" subtab to "Processing Templates"
- Localize all new strings (en/ru/zh)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-15 02:16:59 +03:00

188 lines
14 KiB
HTML

<!-- General Settings Modal -->
<div id="device-settings-modal" class="modal" role="dialog" aria-modal="true" aria-labelledby="device-settings-modal-title">
<div class="modal-content">
<div class="modal-header">
<h2 id="device-settings-modal-title"><svg class="icon" viewBox="0 0 24 24"><path d="M9.671 4.136a2.34 2.34 0 0 1 4.659 0 2.34 2.34 0 0 0 3.319 1.915 2.34 2.34 0 0 1 2.33 4.033 2.34 2.34 0 0 0 0 3.831 2.34 2.34 0 0 1-2.33 4.033 2.34 2.34 0 0 0-3.319 1.915 2.34 2.34 0 0 1-4.659 0 2.34 2.34 0 0 0-3.32-1.915 2.34 2.34 0 0 1-2.33-4.033 2.34 2.34 0 0 0 0-3.831A2.34 2.34 0 0 1 6.35 6.051a2.34 2.34 0 0 0 3.319-1.915"/><circle cx="12" cy="12" r="3"/></svg> <span data-i18n="settings.general.title">General Settings</span></h2>
<button class="modal-close-btn" onclick="closeDeviceSettingsModal()" title="Close" data-i18n-aria-label="aria.close">&#x2715;</button>
</div>
<div class="modal-body">
<form id="device-settings-form">
<input type="hidden" id="settings-device-id">
<div class="form-group">
<label for="settings-device-name" data-i18n="device.name">Device Name:</label>
<input type="text" id="settings-device-name" data-i18n-placeholder="device.name.placeholder" placeholder="Living Room TV" required>
<div id="device-tags-container"></div>
</div>
<div class="form-group" id="settings-url-group">
<div class="label-row">
<label for="settings-device-url" data-i18n="device.url">URL:</label>
<button type="button" class="hint-toggle" onclick="toggleHint(this)" title="?">?</button>
</div>
<small class="input-hint" style="display:none" data-i18n="settings.url.hint">IP address or hostname of the device</small>
<input type="text" id="settings-device-url" data-i18n-placeholder="device.url.placeholder" placeholder="http://192.168.1.100" required>
</div>
<div class="form-group" id="settings-serial-port-group" style="display: none;">
<div class="label-row">
<label for="settings-serial-port" data-i18n="device.serial_port">Serial Port:</label>
<button type="button" class="hint-toggle" onclick="toggleHint(this)" title="?">?</button>
</div>
<small class="input-hint" style="display:none" data-i18n="device.serial_port.hint">Select the COM port of the Adalight device</small>
<select id="settings-serial-port"></select>
</div>
<div class="form-group" id="settings-zone-group" style="display: none;">
<div class="label-row">
<label data-i18n="device.openrgb.zone">Zones:</label>
<button type="button" class="hint-toggle" onclick="toggleHint(this)" title="?">?</button>
</div>
<small class="input-hint" style="display:none" data-i18n="device.openrgb.zone.hint">Select which LED zones to control (leave all unchecked for all zones)</small>
<div id="settings-zone-list" class="zone-checkbox-list"></div>
</div>
<div class="form-group" id="settings-zone-mode-group" style="display: none;">
<div class="label-row">
<label data-i18n="device.openrgb.mode">Zone mode:</label>
<button type="button" class="hint-toggle" onclick="toggleHint(this)" title="?">?</button>
</div>
<small class="input-hint" style="display:none" data-i18n="device.openrgb.mode.hint">Combined treats all zones as one continuous LED strip. Separate renders each zone independently with the full effect.</small>
<div class="zone-mode-radios">
<label class="zone-mode-option">
<input type="radio" name="settings-zone-mode" value="combined" checked>
<span data-i18n="device.openrgb.mode.combined">Combined strip</span>
</label>
<label class="zone-mode-option">
<input type="radio" name="settings-zone-mode" value="separate">
<span data-i18n="device.openrgb.mode.separate">Independent zones</span>
</label>
</div>
</div>
<div class="form-group" id="settings-led-count-group" style="display: none;">
<div class="label-row">
<label for="settings-led-count" data-i18n="device.led_count">LED Count:</label>
<button type="button" class="hint-toggle" onclick="toggleHint(this)" title="?">?</button>
</div>
<small class="input-hint" style="display:none" data-i18n="device.led_count_manual.hint">Number of LEDs on the strip (must match your Arduino sketch)</small>
<input type="number" id="settings-led-count" min="1" max="10000" oninput="updateSettingsBaudFpsHint()">
</div>
<div class="form-group" id="settings-baud-rate-group" style="display: none;">
<div class="label-row">
<label for="settings-baud-rate" data-i18n="device.baud_rate">Baud Rate:</label>
<button type="button" class="hint-toggle" onclick="toggleHint(this)" title="?">?</button>
</div>
<small class="input-hint" style="display:none" data-i18n="device.baud_rate.hint">Serial communication speed. Higher = more FPS but requires matching Arduino sketch.</small>
<select id="settings-baud-rate" onchange="updateSettingsBaudFpsHint()">
<option value="115200">115200</option>
<option value="230400">230400</option>
<option value="460800">460800</option>
<option value="500000">500000</option>
<option value="921600">921600</option>
<option value="1000000">1000000</option>
<option value="1500000">1500000</option>
<option value="2000000">2000000</option>
</select>
<small id="settings-baud-fps-hint" class="fps-hint" style="display:none"></small>
</div>
<div class="form-group" id="settings-led-type-group" style="display: none;">
<div class="label-row">
<label for="settings-led-type" data-i18n="device.led_type">LED Type:</label>
<button type="button" class="hint-toggle" onclick="toggleHint(this)" title="?">?</button>
</div>
<small class="input-hint" style="display:none" data-i18n="device.led_type.hint">RGB (3 channels) or RGBW (4 channels with dedicated white)</small>
<select id="settings-led-type">
<option value="rgb">RGB</option>
<option value="rgbw">RGBW</option>
</select>
</div>
<div class="form-group" id="settings-send-latency-group" style="display: none;">
<div class="label-row">
<label for="settings-send-latency" data-i18n="device.send_latency">Send Latency (ms):</label>
<button type="button" class="hint-toggle" onclick="toggleHint(this)" title="?">?</button>
</div>
<small class="input-hint" style="display:none" data-i18n="device.send_latency.hint">Simulated network/serial delay per frame in milliseconds</small>
<input type="number" id="settings-send-latency" min="0" max="5000" value="0">
</div>
<div class="form-group" id="settings-dmx-protocol-group" style="display: none;">
<div class="label-row">
<label for="settings-dmx-protocol" data-i18n="device.dmx_protocol">DMX Protocol:</label>
<button type="button" class="hint-toggle" onclick="toggleHint(this)" title="?">?</button>
</div>
<small class="input-hint" style="display:none" data-i18n="device.dmx_protocol.hint">Art-Net uses UDP port 6454, sACN (E1.31) uses UDP port 5568</small>
<select id="settings-dmx-protocol">
<option value="artnet">Art-Net</option>
<option value="sacn">sACN (E1.31)</option>
</select>
</div>
<div class="form-group" id="settings-dmx-start-universe-group" style="display: none;">
<div class="label-row">
<label for="settings-dmx-start-universe" data-i18n="device.dmx_start_universe">Start Universe:</label>
<button type="button" class="hint-toggle" onclick="toggleHint(this)" title="?">?</button>
</div>
<small class="input-hint" style="display:none" data-i18n="device.dmx_start_universe.hint">First DMX universe (0-32767). Multiple universes are used automatically for >170 LEDs.</small>
<input type="number" id="settings-dmx-start-universe" min="0" max="32767" value="0">
</div>
<div class="form-group" id="settings-dmx-start-channel-group" style="display: none;">
<div class="label-row">
<label for="settings-dmx-start-channel" data-i18n="device.dmx_start_channel">Start Channel:</label>
<button type="button" class="hint-toggle" onclick="toggleHint(this)" title="?">?</button>
</div>
<small class="input-hint" style="display:none" data-i18n="device.dmx_start_channel.hint">First DMX channel within the universe (1-512)</small>
<input type="number" id="settings-dmx-start-channel" min="1" max="512" value="1">
</div>
<div class="form-group" id="settings-health-interval-group">
<div class="label-row">
<label for="settings-health-interval" data-i18n="settings.health_interval">Health Check Interval (s):</label>
<button type="button" class="hint-toggle" onclick="toggleHint(this)" title="?">?</button>
</div>
<small class="input-hint" style="display:none" data-i18n="settings.health_interval.hint">How often to check the device status (5-600 seconds)</small>
<input type="number" id="settings-health-interval" min="5" max="600" value="30">
</div>
<div class="form-group settings-toggle-group" id="settings-auto-shutdown-group">
<div class="label-row">
<label data-i18n="settings.auto_shutdown">Auto Restore:</label>
<button type="button" class="hint-toggle" onclick="toggleHint(this)" title="?">?</button>
</div>
<small class="input-hint" style="display:none" data-i18n="settings.auto_shutdown.hint">Restore device to idle state when targets stop or server shuts down</small>
<label class="settings-toggle">
<input type="checkbox" id="settings-auto-shutdown">
<span class="settings-toggle-slider"></span>
</label>
</div>
<div class="form-group" id="settings-ws-url-group" style="display: none;">
<div class="label-row">
<label for="settings-ws-url" data-i18n="device.ws_url">Connection URL:</label>
<button type="button" class="hint-toggle" onclick="toggleHint(this)" title="?">?</button>
</div>
<small class="input-hint" style="display:none" data-i18n="device.ws_url.hint">WebSocket URL for clients to connect and receive LED data</small>
<div class="ws-url-row">
<input type="text" id="settings-ws-url" readonly>
<button type="button" class="btn btn-sm btn-secondary" onclick="copyWsUrl()" title="Copy">&#x1F4CB;</button>
</div>
</div>
<div class="form-group" id="settings-cspt-group">
<div class="label-row">
<label for="settings-css-processing-template" data-i18n="device.css_processing_template">Strip Processing Template:</label>
<button type="button" class="hint-toggle" onclick="toggleHint(this)" title="?">?</button>
</div>
<small class="input-hint" style="display:none" data-i18n="device.css_processing_template.hint">Default processing template applied to all color strip outputs on this device</small>
<select id="settings-css-processing-template">
<option value=""></option>
</select>
</div>
<div id="device-settings-error" class="error-message" style="display: none;"></div>
</form>
</div>
<div class="modal-footer">
<button class="btn btn-icon btn-secondary" onclick="closeDeviceSettingsModal()" title="Cancel" data-i18n-aria-label="aria.cancel">&#x2715;</button>
<button class="btn btn-icon btn-primary" onclick="saveDeviceSettings()" title="Save" data-i18n-aria-label="aria.save">&#x2713;</button>
</div>
</div>
</div>