asdasd
This commit is contained in:
39
public/api/system/deploy-status/index.php
Normal file
39
public/api/system/deploy-status/index.php
Normal 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;
|
||||
}
|
||||
@@ -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;
|
||||
|
||||
@@ -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();
|
||||
|
||||
Reference in New Issue
Block a user