asdasd
All checks were successful
Deploy / deploy-staging (push) Successful in 27s
Deploy / deploy-production (push) Has been skipped

This commit is contained in:
2026-06-25 01:00:06 +02:00
parent 487f592ca3
commit bd5cb9364c
10 changed files with 537 additions and 1 deletions

View File

@@ -0,0 +1,39 @@
<?php
declare(strict_types=1);
require_once dirname(__DIR__, 4) . '/src/App/bootstrap.php';
use App\ConfigLoader;
use App\GiteaDeployStatusService;
session_start();
$authUser = is_array($_SESSION['desktop_auth']['user'] ?? null) ? $_SESSION['desktop_auth']['user'] : [];
$groups = array_values(array_map('strval', (array) ($authUser['groups'] ?? [])));
$isAdmin = in_array('administrators', $groups, true);
$projectRoot = dirname(__DIR__, 4);
$service = new GiteaDeployStatusService(ConfigLoader::load($projectRoot, 'gitea'));
if (!$service->shouldShowInTray($isAdmin)) {
respond([
'error' => 'forbidden',
'message' => 'Kein Zugriff auf den Gitea-Deploy-Status.',
], 403);
}
respond([
'data' => $service->status(),
]);
/**
* @param array<string, mixed> $payload
*/
function respond(array $payload, int $statusCode = 200): never
{
http_response_code($statusCode);
header('Content-Type: application/json; charset=utf-8');
echo json_encode($payload, JSON_THROW_ON_ERROR | JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE);
exit;
}

View File

@@ -1400,6 +1400,27 @@ h1 {
box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.18);
}
.tray-pill-status {
min-width: 34px;
padding: 8px 9px;
text-align: center;
font-size: 18px;
line-height: 1;
}
.tray-pill-status--idle {
color: #22c55e;
}
.tray-pill-status--running {
color: #facc15;
}
.tray-pill-status--error,
.tray-pill-status--unconfigured {
color: #f97316;
}
.tray-menu {
position: absolute;
right: 16px;

View File

@@ -40,6 +40,7 @@ if (payloadNode) {
const accountMenu = document.getElementById('tray-account-menu');
const fxTrayMenu = document.getElementById('tray-fx-menu');
const fxTrayStatusNode = document.getElementById('tray-fx-status');
const giteaStatusNode = document.querySelector('.tray-pill[data-tray-id="gitea-deploy-status"]');
const clockNode = document.getElementById('clock');
const clockTopNode = document.getElementById('clock-top');
const debugToggleNode = document.getElementById('debug-toggle');
@@ -71,6 +72,7 @@ if (payloadNode) {
let activeFunctionArea = 'programs';
const windowControlsMode = document.body.dataset.windowControls || 'windows';
let wallpaperImagePromise = null;
let giteaStatusTimer = null;
const loadDebugState = () => {
try {
@@ -469,6 +471,63 @@ if (payloadNode) {
}
};
const updateGiteaTrayUi = (state, message) => {
if (!(giteaStatusNode instanceof HTMLElement)) {
return;
}
giteaStatusNode.classList.remove(
'tray-pill-status--idle',
'tray-pill-status--running',
'tray-pill-status--error',
'tray-pill-status--unconfigured',
);
const normalizedState = typeof state === 'string' && state !== '' ? state : 'idle';
giteaStatusNode.classList.add(`tray-pill-status--${normalizedState}`);
giteaStatusNode.setAttribute('title', typeof message === 'string' && message !== '' ? message : 'Gitea-Deploy-Status');
giteaStatusNode.textContent = '●';
};
const scheduleGiteaStatusPoll = (seconds) => {
if (giteaStatusTimer) {
window.clearTimeout(giteaStatusTimer);
}
const delayMs = Math.max(1, Number(seconds || 5)) * 1000;
giteaStatusTimer = window.setTimeout(() => {
void loadGiteaDeployStatus();
}, delayMs);
};
const loadGiteaDeployStatus = async () => {
if (!(giteaStatusNode instanceof HTMLElement)) {
return null;
}
try {
const response = await fetch('/api/system/deploy-status/index.php', {
credentials: 'same-origin',
headers: { Accept: 'application/json' },
});
const responsePayload = await response.json().catch(() => ({}));
const data = responsePayload && typeof responsePayload === 'object' ? (responsePayload.data || {}) : {};
const state = typeof data.state === 'string' ? data.state : (response.ok ? 'idle' : 'error');
const message = typeof data.message === 'string' && data.message !== ''
? data.message
: 'Gitea-Deploy-Status ist unbekannt.';
const nextPoll = Number(data.poll_seconds || 5);
updateGiteaTrayUi(state, message);
scheduleGiteaStatusPoll(nextPoll);
return data;
} catch (_error) {
updateGiteaTrayUi('error', 'Gitea-Deploy-Status konnte nicht geladen werden.');
scheduleGiteaStatusPoll(5);
return null;
}
};
const runFxTrayRefresh = async (force) => {
if (!(fxTrayStatusNode instanceof HTMLElement)) {
return;
@@ -2042,7 +2101,12 @@ if (payloadNode) {
}
});
giteaStatusNode?.addEventListener('click', () => {
void loadGiteaDeployStatus();
});
void loadFxTrayStatus();
void loadGiteaDeployStatus();
debugToggleNode?.addEventListener('click', () => {
toggleDebugWindow();