mirror of
https://github.com/UNITRONIX/BetterDesk.git
synced 2026-09-11 13:49:03 +00:00
2e01955f6c
- Introduced server URL validation via `GET /api/bd/server-info` and `probe_server_url`. - Added LAN discovery capabilities using UDP and optional mDNS for local network panel detection. - Implemented a local settings window for managing URL, TLS settings, and user preferences. - Enhanced dashboard with a unified sidebar and improved scrolling behavior. - Updated documentation and pre-release checklist to reflect new features and requirements.
171 lines
9.8 KiB
HTML
171 lines
9.8 KiB
HTML
<%- include('layouts/remote-desk', {
|
|
title: typeof title !== 'undefined' ? title : _('remote_dashboard.title'),
|
|
pageStyles: ['remote-dashboard'],
|
|
pageScripts: ['remote-dashboard'],
|
|
body: `
|
|
<div class="rd-desk-app" id="rd-desk-app">
|
|
<header class="rd-desk-header">
|
|
<div class="rd-desk-brand">
|
|
<div class="rd-desk-logo" id="rd-desk-logo"></div>
|
|
<div class="rd-desk-brand-text">
|
|
<h1 class="rd-desk-title">${_('remote_dashboard.title')}</h1>
|
|
<p class="rd-desk-subtitle">${_('remote_dashboard.subtitle')}</p>
|
|
</div>
|
|
</div>
|
|
<div class="rd-desk-header-actions">
|
|
<select id="rd-desk-lang" class="rd-desk-lang-select" data-language-select aria-label="${_('settings.language')}"></select>
|
|
<button type="button" class="rd-desk-icon-btn" id="rd-desk-settings" title="${_('rdclient_settings.open') || 'Settings'}" style="display:none;">
|
|
<span class="material-icons">settings</span>
|
|
</button>
|
|
<span class="rd-desk-user" id="rd-desk-user"></span>
|
|
<button type="button" class="rd-desk-icon-btn" id="rd-desk-refresh" title="${_('remote_dashboard.sync_now')}">
|
|
<span class="material-icons">sync</span>
|
|
</button>
|
|
<a href="/devices" class="rd-desk-btn rd-desk-btn-ghost" target="_blank" rel="noopener noreferrer">
|
|
<span class="material-icons">dashboard</span>
|
|
${_('remote_dashboard.open_panel')}
|
|
</a>
|
|
</div>
|
|
</header>
|
|
|
|
<section class="rd-desk-quick-connect">
|
|
<div class="rd-desk-quick-connect-inner">
|
|
<span class="material-icons rd-desk-quick-icon">connected_tv</span>
|
|
<label class="rd-desk-quick-label" for="rd-desk-quick-id">${_('remote_dashboard.quick_connect')}</label>
|
|
<input type="text" id="rd-desk-quick-id" class="rd-desk-quick-input"
|
|
placeholder="${_('remote_dashboard.quick_connect_placeholder')}" autocomplete="off" spellcheck="false">
|
|
<button type="button" class="rd-desk-btn" id="rd-desk-quick-btn">
|
|
<span class="material-icons">play_arrow</span>
|
|
${_('remote_dashboard.connect')}
|
|
</button>
|
|
</div>
|
|
</section>
|
|
|
|
<div class="rd-desk-workspace">
|
|
<aside class="rd-desk-sidebar" id="rd-desk-sidebar">
|
|
<div class="rd-desk-sidebar-scroll" id="rd-desk-sidebar-scroll">
|
|
<nav class="rd-desk-nav-section" data-collapsible="folders">
|
|
<button type="button" class="rd-desk-nav-heading rd-desk-nav-heading-btn" id="rd-desk-nav-folders-toggle" aria-expanded="true">
|
|
<span>${_('remote_dashboard.nav_folders')}</span>
|
|
<span class="material-icons rd-desk-nav-chevron" aria-hidden="true">expand_more</span>
|
|
</button>
|
|
<div class="rd-desk-nav-body" id="rd-desk-nav-folders-body">
|
|
<ul class="rd-desk-nav-list" id="rd-desk-folders">
|
|
<li><button type="button" class="rd-desk-nav-item active" data-nav="folder" data-id="all">
|
|
<span class="material-icons">devices</span>
|
|
<span class="rd-desk-nav-label">${_('remote_dashboard.filter_all')}</span>
|
|
<span class="rd-desk-nav-count" id="rd-count-all">0</span>
|
|
</button></li>
|
|
<li><button type="button" class="rd-desk-nav-item" data-nav="folder" data-id="unassigned">
|
|
<span class="material-icons">folder_off</span>
|
|
<span class="rd-desk-nav-label">${_('remote_dashboard.unassigned')}</span>
|
|
<span class="rd-desk-nav-count" id="rd-count-unassigned">0</span>
|
|
</button></li>
|
|
</ul>
|
|
<ul class="rd-desk-nav-list rd-desk-nav-custom" id="rd-desk-folders-custom"></ul>
|
|
</div>
|
|
</nav>
|
|
|
|
<nav class="rd-desk-nav-section" data-collapsible="groups">
|
|
<button type="button" class="rd-desk-nav-heading rd-desk-nav-heading-btn" id="rd-desk-nav-groups-toggle" aria-expanded="true">
|
|
<span>${_('remote_dashboard.nav_groups')}</span>
|
|
<span class="material-icons rd-desk-nav-chevron" aria-hidden="true">expand_more</span>
|
|
</button>
|
|
<div class="rd-desk-nav-body" id="rd-desk-nav-groups-body">
|
|
<ul class="rd-desk-nav-list" id="rd-desk-groups">
|
|
<li class="rd-desk-nav-empty hidden" id="rd-desk-groups-empty">${_('remote_dashboard.no_groups')}</li>
|
|
</ul>
|
|
</div>
|
|
</nav>
|
|
|
|
<nav class="rd-desk-nav-section" data-collapsible="tags">
|
|
<button type="button" class="rd-desk-nav-heading rd-desk-nav-heading-btn" id="rd-desk-nav-tags-toggle" aria-expanded="true">
|
|
<span>${_('remote_dashboard.nav_tags')}</span>
|
|
<span class="material-icons rd-desk-nav-chevron" aria-hidden="true">expand_more</span>
|
|
</button>
|
|
<div class="rd-desk-nav-body" id="rd-desk-nav-tags-body">
|
|
<ul class="rd-desk-nav-list rd-desk-nav-tags" id="rd-desk-tags">
|
|
<li class="rd-desk-nav-empty hidden" id="rd-desk-tags-empty">${_('remote_dashboard.no_tags')}</li>
|
|
</ul>
|
|
</div>
|
|
</nav>
|
|
</div>
|
|
</aside>
|
|
|
|
<div class="rd-desk-content">
|
|
<div class="rd-desk-toolbar">
|
|
<div class="rd-desk-toolbar-left">
|
|
<button type="button" class="rd-desk-icon-btn rd-desk-panel-toggle" id="rd-desk-devices-toggle"
|
|
title="${_('remote_dashboard.collapse_devices')}" aria-expanded="true" aria-controls="rd-desk-devices-scroll">
|
|
<span class="material-icons" id="rd-desk-devices-toggle-icon">expand_more</span>
|
|
</button>
|
|
<span class="rd-desk-section-title" id="rd-desk-section-title">${_('remote_dashboard.nav_address_book')}</span>
|
|
</div>
|
|
<div class="rd-desk-search-wrap">
|
|
<span class="material-icons rd-desk-search-icon">search</span>
|
|
<input type="search" id="rd-desk-search" class="rd-desk-search"
|
|
placeholder="${_('remote_dashboard.search_placeholder')}" autocomplete="off">
|
|
</div>
|
|
<div class="rd-desk-filters" role="tablist">
|
|
<button type="button" class="rd-desk-filter active" data-filter="all">${_('remote_dashboard.filter_all')}</button>
|
|
<button type="button" class="rd-desk-filter" data-filter="online">${_('remote_dashboard.filter_online')}</button>
|
|
<button type="button" class="rd-desk-filter" data-filter="offline">${_('remote_dashboard.filter_offline')}</button>
|
|
</div>
|
|
<div class="rd-desk-view-toggle" role="group">
|
|
<button type="button" class="rd-desk-icon-btn active" id="rd-view-grid" title="${_('remote_dashboard.view_grid')}">
|
|
<span class="material-icons">grid_view</span>
|
|
</button>
|
|
<button type="button" class="rd-desk-icon-btn" id="rd-view-list" title="${_('remote_dashboard.view_list')}">
|
|
<span class="material-icons">view_list</span>
|
|
</button>
|
|
</div>
|
|
<span class="rd-desk-count" id="rd-desk-count"></span>
|
|
</div>
|
|
|
|
<main class="rd-desk-main">
|
|
<div class="rd-desk-devices-panel" id="rd-desk-devices-panel">
|
|
<div class="rd-desk-devices-scroll" id="rd-desk-devices-scroll">
|
|
<div class="rd-desk-loading" id="rd-desk-loading">
|
|
<span class="material-icons rd-desk-spin">sync</span>
|
|
<span>${_('remote_dashboard.loading')}</span>
|
|
</div>
|
|
<div class="rd-desk-error hidden" id="rd-desk-error">
|
|
<span class="material-icons">error_outline</span>
|
|
<span id="rd-desk-error-text">${_('remote_dashboard.error_load')}</span>
|
|
<button type="button" class="rd-desk-btn" id="rd-desk-retry">${_('remote_dashboard.retry')}</button>
|
|
</div>
|
|
<div class="rd-desk-empty hidden" id="rd-desk-empty">
|
|
<span class="material-icons">devices_other</span>
|
|
<p>${_('remote_dashboard.empty')}</p>
|
|
</div>
|
|
<div class="rd-desk-grid hidden" id="rd-desk-grid"></div>
|
|
<div class="rd-desk-table-wrap hidden" id="rd-desk-table-wrap">
|
|
<table class="rd-desk-table">
|
|
<thead>
|
|
<tr>
|
|
<th>${_('remote_dashboard.col_status')}</th>
|
|
<th>${_('remote_dashboard.col_id')}</th>
|
|
<th>${_('remote_dashboard.col_hostname')}</th>
|
|
<th>${_('remote_dashboard.col_platform')}</th>
|
|
<th>${_('remote_dashboard.col_last_seen')}</th>
|
|
<th></th>
|
|
</tr>
|
|
</thead>
|
|
<tbody id="rd-desk-tbody"></tbody>
|
|
</table>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</main>
|
|
</div>
|
|
</div>
|
|
|
|
<footer class="rd-desk-footer">
|
|
<span class="rd-desk-status-dot online" id="rd-desk-status-dot"></span>
|
|
<span id="rd-desk-status-text">${_('remote_dashboard.status_ready')}</span>
|
|
<span class="rd-desk-sync-time" id="rd-desk-sync-time"></span>
|
|
</footer>
|
|
</div>
|
|
`
|
|
}) %>
|