diff --git a/config/widgets.php b/config/widgets.php index 25782d12..59a7be49 100644 --- a/config/widgets.php +++ b/config/widgets.php @@ -10,7 +10,7 @@ return [ 'zone' => 'sidebar', 'default_enabled' => true, 'supports_public_home' => true, - 'summary' => 'Startet die persoenlichen Desktop-Einstellungen fuer Skin, Apps, Widgets und Benutzerdaten.', + 'summary' => 'Startet die persoenlichen Desktop-Einstellungen fuer Skin, Apps, Infobereich und Benutzerdaten.', 'content' => 'Oeffnet den zentralen Setup-Bereich mit linker Navigation und lokaler Persistenz pro Benutzer.', 'launch_app_id' => 'user-self-management', 'action_label' => 'Setup oeffnen', @@ -53,6 +53,6 @@ return [ 'default_enabled' => false, 'supports_public_home' => false, 'summary' => 'Platz fuer persoenliche Hinweise und Notizen je Workspace.', - 'content' => 'Dieses Widget ist vorbereitet, aber standardmaessig noch nicht eingeblendet.', + 'content' => 'Dieser Bereich ist vorbereitet, aber standardmaessig noch nicht eingeblendet.', ], ]; diff --git a/partials/desktop/shell.php b/partials/desktop/shell.php index 82b1152b..40fd9b1c 100644 --- a/partials/desktop/shell.php +++ b/partials/desktop/shell.php @@ -112,7 +112,7 @@ $renderStartIcon = static function (array $profile): string {
-

Widgets

+

Infobereich

@@ -132,13 +132,18 @@ $renderStartIcon = static function (array $profile): string {
- + - - Logout -
+ diff --git a/public/assets/apps/user-self-management/app.js b/public/assets/apps/user-self-management/app.js index 2b399b20..8eb5d7ef 100644 --- a/public/assets/apps/user-self-management/app.js +++ b/public/assets/apps/user-self-management/app.js @@ -3,7 +3,7 @@ { id: 'desktop', label: 'Desktop Type' }, { id: 'profile', label: 'Benutzerdaten' }, { id: 'apps', label: 'App-Installation' }, - { id: 'widgets', label: 'Widget-Installation' }, + { id: 'widgets', label: 'Infobereich' }, ]; const escapeHtml = (value) => String(value) @@ -35,7 +35,7 @@ return 'Bestimmt, welche Desktop-Apps fuer diesen Benutzer sichtbar bleiben.'; } - return 'Steuert, welche Widgets in der rechten Leiste des Desktops aktiv sind.'; + return 'Steuert, welche Elemente im rechten Infobereich des Desktops aktiv sind.'; }; const renderSkinChoices = (state) => state.bootstrap.options.skins.map((skin) => { @@ -101,7 +101,7 @@ ${escapeHtml(widget.title)}

${escapeHtml(widget.summary || '')}

- ${widget.default_enabled ? 'Standard-Widget' : 'Optionales Widget'} + ${widget.default_enabled ? 'Standardbereich' : 'Optionaler Bereich'}
`; @@ -177,9 +177,9 @@ return `
-

Widget-Auswahl

-

Aktive Widget-Leiste

-

Widgets bleiben Teil der Desktop-Mechanik und werden hier nur benutzerbezogen ein- oder ausgeblendet.

+

Infobereich

+

Rechter Desktopbereich

+

Diese Inhalte liegen aktuell im rechten Infobereich des Desktops und werden hier benutzerbezogen ein- oder ausgeblendet.

${renderWidgetItems(state)}
@@ -205,7 +205,7 @@

Setup

User Self Management

-

Ein gemeinsamer Setup-Bereich fuer Desktop-Typ, Benutzerdaten, Apps und Widgets.

+

Ein gemeinsamer Setup-Bereich fuer Desktop-Typ, Benutzerdaten, Apps und den rechten Infobereich.

${SECTIONS.map((section) => ` diff --git a/public/assets/desktop/desktop.css b/public/assets/desktop/desktop.css index e027df77..cf4b5eea 100644 --- a/public/assets/desktop/desktop.css +++ b/public/assets/desktop/desktop.css @@ -814,27 +814,6 @@ h1 { white-space: nowrap; } -.tray-skins { - display: flex; - align-items: center; - gap: 6px; -} - -.tray-skin-button { - border: 0; - border-radius: 999px; - padding: 8px 10px; - background: rgba(255, 255, 255, 0.08); - color: inherit; - cursor: pointer; - font-size: 12px; -} - -.tray-skin-button.is-active { - background: var(--accent); - color: #0f172a; -} - .tray-pill { padding: 8px 10px; border-radius: 999px; @@ -842,22 +821,55 @@ h1 { font-size: 13px; } -.tray-action { - display: inline-flex; - align-items: center; - justify-content: center; - padding: 8px 12px; - border-radius: 999px; - background: rgba(255, 255, 255, 0.08); +.tray-pill-button { + border: 0; color: inherit; - font-size: 13px; - text-decoration: none; - transition: background-color 140ms ease, transform 140ms ease; + font: inherit; + cursor: pointer; } -.tray-action:hover { +.tray-pill-button:hover, +.tray-pill-button[aria-expanded="true"] { background: rgba(255, 255, 255, 0.16); - transform: translateY(-1px); +} + +.tray-menu { + position: absolute; + right: 16px; + bottom: calc(100% + 12px); + display: grid; + gap: 8px; + min-width: 220px; + padding: 10px; + border-radius: 18px; + border: 1px solid rgba(255, 255, 255, 0.14); + background: rgba(15, 23, 42, 0.94); + box-shadow: 0 18px 40px rgba(15, 23, 42, 0.24); + backdrop-filter: blur(20px); +} + +.tray-menu[hidden] { + display: none; +} + +.tray-menu-entry { + display: flex; + align-items: center; + width: 100%; + min-height: 40px; + padding: 10px 12px; + border: 0; + border-radius: 12px; + background: transparent; + color: #f8fafc; + font: inherit; + text-align: left; + text-decoration: none; + cursor: pointer; +} + +.tray-menu-entry:hover { + background: rgba(255, 255, 255, 0.12); } .window-content p:last-child { diff --git a/public/assets/desktop/desktop.js b/public/assets/desktop/desktop.js index d3f13b08..d101ab15 100644 --- a/public/assets/desktop/desktop.js +++ b/public/assets/desktop/desktop.js @@ -12,6 +12,7 @@ if (payloadNode) { const startMenuApps = document.getElementById('start-menu-apps'); const startMenuWidgets = document.getElementById('start-menu-widgets'); const startMenuActions = document.getElementById('start-menu-actions'); + const accountMenu = document.getElementById('tray-account-menu'); const clockNode = document.getElementById('clock'); const clockTopNode = document.getElementById('clock-top'); const windows = new Map(); @@ -179,6 +180,17 @@ if (payloadNode) { } }; + const setAccountMenuOpen = (isOpen) => { + const accountButton = document.querySelector('.tray-pill[data-tray-id="account"]'); + + if (!(accountMenu instanceof HTMLElement) || !(accountButton instanceof HTMLElement)) { + return; + } + + accountMenu.hidden = !isOpen; + accountButton.setAttribute('aria-expanded', String(isOpen)); + }; + const findAppById = (appId) => payload.apps.find((app) => app.app_id === appId) || null; const dispatchUserSettingsUpdate = (detail) => { @@ -614,6 +626,14 @@ if (payloadNode) { setStartMenuOpen(false); }; + const openAccountSettings = () => { + const app = findAppById('user-self-management'); + if (app) { + openApp(app); + } + setAccountMenuOpen(false); + }; + const applyWindowLayout = (record) => { const { x, y, width, height } = record.layout; record.node.style.left = `${x}px`; @@ -1275,11 +1295,16 @@ if (payloadNode) { if (!(event.target instanceof Element) || !event.target.closest('.desktop-context-menu')) { closeDesktopContextMenu(); } + + if (!(event.target instanceof Element) || !event.target.closest('.tray-pill[data-tray-id="account"], #tray-account-menu')) { + setAccountMenuOpen(false); + } }); document.addEventListener('keydown', (event) => { if (event.key === 'Escape') { closeDesktopContextMenu(); + setAccountMenuOpen(false); } }); @@ -1291,6 +1316,41 @@ if (payloadNode) { const isClosed = startMenu.hasAttribute('hidden'); setStartMenuOpen(isClosed); + setAccountMenuOpen(false); + }); + + document.querySelector('.tray-pill[data-tray-id="account"]')?.addEventListener('click', () => { + if (!(accountMenu instanceof HTMLElement)) { + return; + } + + setStartMenuOpen(false); + setAccountMenuOpen(accountMenu.hidden); + }); + + accountMenu?.addEventListener('click', (event) => { + const target = event.target instanceof Element ? event.target.closest('[data-account-action]') : null; + + if (!target) { + return; + } + + const action = target.getAttribute('data-account-action'); + + if (action === 'settings') { + event.preventDefault(); + openAccountSettings(); + return; + } + + if (action === 'login') { + event.preventDefault(); + const loginApp = findAppById('desktop-login'); + if (loginApp) { + openApp(loginApp); + } + setAccountMenuOpen(false); + } }); window.addEventListener('desktop:user-settings-updated', (event) => { diff --git a/src/Desktop/DesktopState.php b/src/Desktop/DesktopState.php index 6c82b7bc..ea8bc974 100644 --- a/src/Desktop/DesktopState.php +++ b/src/Desktop/DesktopState.php @@ -33,8 +33,6 @@ final class DesktopState public static function trayItems(): array { return [ - ['id' => 'network', 'label' => 'Netzwerk'], - ['id' => 'widgets', 'label' => 'Widgets'], ['id' => 'account', 'label' => 'Gast'], ]; } @@ -57,8 +55,8 @@ final class DesktopState ], [ 'action_id' => 'toggle-all-widgets', - 'label' => 'Widgets umschalten', - 'description' => 'Blendet alle registrierten Widgets ein oder aus.', + 'label' => 'Infobereich umschalten', + 'description' => 'Blendet den rechten Infobereich des Desktops ein oder aus.', ], ]; }