mirror of
https://github.com/UNITRONIX/BetterDesk.git
synced 2026-09-10 09:35:39 +00:00
a8d3259d43
- Implemented server management service providing resource snapshots, file browser, service control, and audit logging. - Added terminal proxy for WebSocket-backed PTY, allowing browser-based shell access with user authentication and role-based access control. - Created server management view with tabs for overview, terminal, file management, and services, including UI elements for displaying system metrics and managing files/services. Co-authored-by: Copilot <copilot@github.com>
215 lines
12 KiB
HTML
215 lines
12 KiB
HTML
<% var initialTab = (typeof currentTab !== 'undefined' && currentTab) ? currentTab : 'overview'; %>
|
||
<%- include('layouts/main', {
|
||
title: _('server_mgmt.title'),
|
||
pageStyles: ['server-management'],
|
||
pageScripts: ['server-management'],
|
||
currentPage: 'server-management',
|
||
currentTab: initialTab,
|
||
widePage: true,
|
||
breadcrumb: [{ label: _('server_mgmt.title') }],
|
||
body: `
|
||
<div class="server-mgmt-page" id="server-mgmt-page" data-initial-tab="${initialTab}">
|
||
<!-- Header -->
|
||
<div class="page-header server-mgmt-header">
|
||
<div class="page-title">
|
||
<h1>
|
||
<span class="material-icons">dns</span>
|
||
${_('server_mgmt.title')}
|
||
<span class="beta-badge" title="${_('server_mgmt.beta_tooltip')}">BETA</span>
|
||
</h1>
|
||
</div>
|
||
<p class="page-subtitle">${_('server_mgmt.subtitle')}</p>
|
||
</div>
|
||
|
||
<!-- Beta notice -->
|
||
<div class="server-mgmt-notice">
|
||
<span class="material-icons">info</span>
|
||
<div>
|
||
<strong>${_('server_mgmt.notice_title')}</strong>
|
||
<p>${_('server_mgmt.notice_body')}</p>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="server-mgmt-layout">
|
||
<div class="server-mgmt-content">
|
||
<!-- Overview tab -->
|
||
<section class="sm-tab-panel active" id="sm-panel-overview" role="tabpanel">
|
||
<div class="sm-overview-grid">
|
||
<div class="sm-card">
|
||
<div class="sm-card-header">
|
||
<span class="material-icons">memory</span>
|
||
<h3>${_('server_mgmt.cpu')}</h3>
|
||
</div>
|
||
<div class="sm-gauge" id="sm-cpu-gauge">
|
||
<div class="sm-gauge-bar"><div class="sm-gauge-fill" id="sm-cpu-fill"></div></div>
|
||
<div class="sm-gauge-value" id="sm-cpu-value">0%</div>
|
||
</div>
|
||
<div class="sm-meta" id="sm-cpu-meta"></div>
|
||
</div>
|
||
|
||
<div class="sm-card">
|
||
<div class="sm-card-header">
|
||
<span class="material-icons">developer_board</span>
|
||
<h3>${_('server_mgmt.memory')}</h3>
|
||
</div>
|
||
<div class="sm-gauge">
|
||
<div class="sm-gauge-bar"><div class="sm-gauge-fill" id="sm-mem-fill"></div></div>
|
||
<div class="sm-gauge-value" id="sm-mem-value">0%</div>
|
||
</div>
|
||
<div class="sm-meta" id="sm-mem-meta"></div>
|
||
</div>
|
||
|
||
<div class="sm-card">
|
||
<div class="sm-card-header">
|
||
<span class="material-icons">speed</span>
|
||
<h3>${_('server_mgmt.load')}</h3>
|
||
</div>
|
||
<div class="sm-load-row">
|
||
<div><span class="sm-stat-label">1m</span><span id="sm-load-1">–</span></div>
|
||
<div><span class="sm-stat-label">5m</span><span id="sm-load-5">–</span></div>
|
||
<div><span class="sm-stat-label">15m</span><span id="sm-load-15">–</span></div>
|
||
</div>
|
||
<div class="sm-meta" id="sm-uptime-meta"></div>
|
||
</div>
|
||
|
||
<div class="sm-card sm-card-wide">
|
||
<div class="sm-card-header">
|
||
<span class="material-icons">storage</span>
|
||
<h3>${_('server_mgmt.disks')}</h3>
|
||
</div>
|
||
<div id="sm-disks"></div>
|
||
</div>
|
||
|
||
<div class="sm-card sm-card-wide">
|
||
<div class="sm-card-header">
|
||
<span class="material-icons">timeline</span>
|
||
<h3>${_('server_mgmt.history')}</h3>
|
||
</div>
|
||
<div class="sm-history-wrap">
|
||
<canvas id="sm-history-chart" height="120"></canvas>
|
||
<div class="sm-history-legend">
|
||
<span><span class="dot dot-cpu"></span>${_('server_mgmt.cpu')}</span>
|
||
<span><span class="dot dot-mem"></span>${_('server_mgmt.memory')}</span>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="sm-card sm-card-wide">
|
||
<div class="sm-card-header">
|
||
<span class="material-icons">badge</span>
|
||
<h3>${_('server_mgmt.host_info')}</h3>
|
||
</div>
|
||
<div class="sm-info-grid" id="sm-host-info"></div>
|
||
</div>
|
||
</div>
|
||
</section>
|
||
|
||
<!-- Terminal tab -->
|
||
<section class="sm-tab-panel" id="sm-panel-terminal" role="tabpanel" hidden>
|
||
<div class="sm-terminal-toolbar">
|
||
<button class="btn btn-primary" id="sm-term-connect">
|
||
<span class="material-icons">play_arrow</span>
|
||
${_('server_mgmt.term_connect')}
|
||
</button>
|
||
<button class="btn btn-secondary" id="sm-term-disconnect" disabled>
|
||
<span class="material-icons">stop</span>
|
||
${_('server_mgmt.term_disconnect')}
|
||
</button>
|
||
<button class="btn btn-tertiary" id="sm-term-clear" disabled>
|
||
<span class="material-icons">delete_sweep</span>
|
||
${_('server_mgmt.term_clear')}
|
||
</button>
|
||
<span class="sm-term-status" id="sm-term-status">${_('server_mgmt.term_disconnected')}</span>
|
||
</div>
|
||
<div class="sm-terminal-warning">
|
||
<span class="material-icons">warning</span>
|
||
<span>${_('server_mgmt.term_warning')}</span>
|
||
</div>
|
||
<div class="sm-terminal-host" id="sm-terminal-host"></div>
|
||
<p class="sm-term-hint">${_('server_mgmt.term_hint')}</p>
|
||
</section>
|
||
|
||
<!-- Files tab -->
|
||
<section class="sm-tab-panel" id="sm-panel-files" role="tabpanel" hidden>
|
||
<div class="sm-files-toolbar">
|
||
<button class="btn btn-tertiary" id="sm-files-up" title="${_('server_mgmt.files_up')}">
|
||
<span class="material-icons">arrow_upward</span>
|
||
</button>
|
||
<button class="btn btn-tertiary" id="sm-files-refresh" title="${_('common.refresh')}">
|
||
<span class="material-icons">refresh</span>
|
||
</button>
|
||
<input type="text" class="form-input sm-files-path" id="sm-files-path" value="/" spellcheck="false">
|
||
<button class="btn btn-secondary" id="sm-files-go">${_('server_mgmt.files_go')}</button>
|
||
<span class="spacer"></span>
|
||
<button class="btn btn-tertiary" id="sm-files-mkdir">
|
||
<span class="material-icons">create_new_folder</span>
|
||
${_('server_mgmt.files_mkdir')}
|
||
</button>
|
||
</div>
|
||
<div class="sm-files-table-wrapper">
|
||
<table class="data-table sm-files-table">
|
||
<thead>
|
||
<tr>
|
||
<th style="width:40px"></th>
|
||
<th>${_('server_mgmt.files_name')}</th>
|
||
<th style="width:110px">${_('server_mgmt.files_size')}</th>
|
||
<th style="width:90px">${_('server_mgmt.files_perms')}</th>
|
||
<th style="width:160px">${_('server_mgmt.files_mtime')}</th>
|
||
<th style="width:160px">${_('common.actions')}</th>
|
||
</tr>
|
||
</thead>
|
||
<tbody id="sm-files-body">
|
||
<tr><td colspan="6"><div class="empty-state"><span class="material-icons">folder_off</span><p>${_('common.loading')}…</p></div></td></tr>
|
||
</tbody>
|
||
</table>
|
||
</div>
|
||
|
||
<!-- Inline file editor -->
|
||
<div class="sm-file-editor" id="sm-file-editor" hidden>
|
||
<div class="sm-file-editor-header">
|
||
<span class="material-icons">edit_document</span>
|
||
<span class="sm-file-editor-path" id="sm-file-editor-path"></span>
|
||
<span class="spacer"></span>
|
||
<button class="btn btn-primary" id="sm-file-save">
|
||
<span class="material-icons">save</span>${_('common.save')}
|
||
</button>
|
||
<button class="btn btn-tertiary" id="sm-file-close">
|
||
<span class="material-icons">close</span>${_('common.cancel')}
|
||
</button>
|
||
</div>
|
||
<textarea class="sm-file-textarea" id="sm-file-textarea" spellcheck="false"></textarea>
|
||
<p class="sm-file-meta" id="sm-file-meta"></p>
|
||
</div>
|
||
</section>
|
||
|
||
<!-- Services tab -->
|
||
<section class="sm-tab-panel" id="sm-panel-services" role="tabpanel" hidden>
|
||
<div class="sm-services-toolbar">
|
||
<input type="search" class="form-input sm-services-search" id="sm-services-search" placeholder="${_('server_mgmt.svc_search_placeholder')}">
|
||
<button class="btn btn-tertiary" id="sm-services-refresh">
|
||
<span class="material-icons">refresh</span>${_('common.refresh')}
|
||
</button>
|
||
<span class="sm-services-count" id="sm-services-count"></span>
|
||
</div>
|
||
<div class="sm-services-table-wrapper">
|
||
<table class="data-table sm-services-table">
|
||
<thead>
|
||
<tr>
|
||
<th>${_('server_mgmt.svc_name')}</th>
|
||
<th style="width:120px">${_('server_mgmt.svc_state')}</th>
|
||
<th>${_('server_mgmt.svc_description')}</th>
|
||
<th style="width:280px">${_('common.actions')}</th>
|
||
</tr>
|
||
</thead>
|
||
<tbody id="sm-services-body">
|
||
<tr><td colspan="4"><div class="empty-state"><span class="material-icons">miscellaneous_services</span><p>${_('common.loading')}…</p></div></td></tr>
|
||
</tbody>
|
||
</table>
|
||
</div>
|
||
</section>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
`
|
||
}) %>
|