Separate panel settings from services
This commit is contained in:
@@ -34,3 +34,4 @@ Updated: 2026-04-02
|
||||
18. Restored panel language/theme preferences in Settings with `localStorage`, merged service `Command/Protocol` into a single `Type`, and removed the legacy `admin` service path from managed panel state.
|
||||
19. Added service-removal confirmation with linked-user warnings, backend cascade deletion for removed services, and migration that strips persisted legacy `admin` services from stored state.
|
||||
20. Made `npm run dev` start both the Vite client and Express backend, added a Vite API proxy for local development, and restored `system` as the default panel theme so the login screen follows OS appearance.
|
||||
21. Re-separated the Settings tab into distinct panel-settings and services cards so panel preferences no longer appear inside the Services section.
|
||||
|
||||
@@ -24,7 +24,7 @@ Updated: 2026-04-02
|
||||
|
||||
- `src/main.tsx`: application bootstrap
|
||||
- `src/App.tsx`: authenticated panel shell with API-backed login, `sessionStorage` token persistence, localized labels, early theme application, and protected panel mutations
|
||||
- `src/SystemTab.tsx`: Settings tab with panel language/style preferences, unified service type editing, remove confirmation, and generated config preview
|
||||
- `src/SystemTab.tsx`: Settings tab with separate panel-settings and services cards, unified service type editing, remove confirmation, and generated config preview
|
||||
- `src/App.test.tsx`: login-gate, preferences persistence, modal interaction, pause/resume, delete-confirm, and settings-save UI tests
|
||||
- `src/app.css`: full panel styling
|
||||
- `src/data/mockDashboard.ts`: default panel state and frontend fallback snapshot
|
||||
|
||||
@@ -149,7 +149,8 @@ describe('App login gate', () => {
|
||||
await loginIntoPanel(user);
|
||||
await user.click(screen.getByRole('button', { name: /settings/i }));
|
||||
|
||||
expect(screen.queryByText(/panel settings/i)).not.toBeInTheDocument();
|
||||
expect(screen.getByRole('heading', { name: /panel settings/i })).toBeInTheDocument();
|
||||
expect(screen.getByRole('heading', { name: /^services$/i })).toBeInTheDocument();
|
||||
expect(screen.queryByLabelText(/public host/i)).not.toBeInTheDocument();
|
||||
expect(screen.queryByLabelText(/command/i)).not.toBeInTheDocument();
|
||||
expect(screen.queryByLabelText(/protocol/i)).not.toBeInTheDocument();
|
||||
|
||||
@@ -73,7 +73,8 @@ export default function SystemTab({
|
||||
<section className="page-grid single-column system-grid">
|
||||
<article className="panel-card">
|
||||
<div className="card-header">
|
||||
<h2>{text.settings.title}</h2>
|
||||
<h2>{text.settings.panelTitle}</h2>
|
||||
</div>
|
||||
<div className="settings-toolbar">
|
||||
<label className="field-group compact-field">
|
||||
<span>{text.common.language}</span>
|
||||
@@ -106,6 +107,12 @@ export default function SystemTab({
|
||||
<option value="system">{getThemeLabel(preferences.language, 'system')}</option>
|
||||
</select>
|
||||
</label>
|
||||
</div>
|
||||
</article>
|
||||
|
||||
<article className="panel-card">
|
||||
<div className="card-header">
|
||||
<h2>{text.settings.title}</h2>
|
||||
<button
|
||||
type="button"
|
||||
className="button-secondary"
|
||||
@@ -119,7 +126,6 @@ export default function SystemTab({
|
||||
{text.common.addService}
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<div className="service-editor-list">
|
||||
{draft.services.map((service, index) => (
|
||||
<section key={service.id} className="service-editor-row">
|
||||
|
||||
@@ -92,6 +92,7 @@ const text = {
|
||||
deleteAction: 'Delete user',
|
||||
},
|
||||
settings: {
|
||||
panelTitle: 'Panel settings',
|
||||
title: 'Services',
|
||||
generatedConfig: 'Generated config',
|
||||
serviceLabel: 'Service',
|
||||
@@ -207,6 +208,7 @@ const text = {
|
||||
deleteAction: 'Удалить пользователя',
|
||||
},
|
||||
settings: {
|
||||
panelTitle: 'Настройки панели',
|
||||
title: 'Сервисы',
|
||||
generatedConfig: 'Сгенерированный конфиг',
|
||||
serviceLabel: 'Сервис',
|
||||
|
||||
Reference in New Issue
Block a user