Redesigns the whole config page
parent
1e4ebae652
commit
405f58124d
|
@ -115,18 +115,42 @@ if ($_SERVER['REQUEST_METHOD'] == 'POST') {
|
||||||
}
|
}
|
||||||
|
|
||||||
// an update to an existing host
|
// an update to an existing host
|
||||||
} elseif (isset($_POST['host'])) {
|
} elseif (isset($_POST['item']) && $_POST['item'] === 'host') {
|
||||||
|
$host_id = $_POST['host'];
|
||||||
|
$platform_id = $_POST['platform'];
|
||||||
$updatedHost = [
|
$updatedHost = [
|
||||||
'id' => $host,
|
'id' => $host_id,
|
||||||
'address' => $address,
|
'address' => $_POST['address'],
|
||||||
'port' => $port,
|
'name' => $_POST['name']
|
||||||
'name' => $name,
|
|
||||||
];
|
];
|
||||||
$result = $hostObject->editHost($platform_id, $updatedHost);
|
$result = $hostObject->editHost($platform_id, $updatedHost);
|
||||||
if ($result === true) {
|
|
||||||
$_SESSION['notice'] = "Host \"{$_REQUEST['address']}:{$_REQUEST['port']}\" edited.";
|
// Check if it's an AJAX request
|
||||||
|
if (!empty($_SERVER['HTTP_X_REQUESTED_WITH']) &&
|
||||||
|
strtolower($_SERVER['HTTP_X_REQUESTED_WITH']) == 'xmlhttprequest') {
|
||||||
|
|
||||||
|
// Clear any output buffers to ensure clean JSON
|
||||||
|
while (ob_get_level()) ob_end_clean();
|
||||||
|
|
||||||
|
header('Content-Type: application/json');
|
||||||
|
if ($result === true) {
|
||||||
|
echo json_encode(['success' => true]);
|
||||||
|
} else {
|
||||||
|
echo json_encode([
|
||||||
|
'success' => false,
|
||||||
|
'message' => "Editing the host failed. Error: $result"
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
exit();
|
||||||
} else {
|
} else {
|
||||||
$_SESSION['error'] = "Editing the host failed. Error: $result";
|
// Regular form submission
|
||||||
|
if ($result === true) {
|
||||||
|
$_SESSION['notice'] = "Host edited.";
|
||||||
|
} else {
|
||||||
|
$_SESSION['error'] = "Editing the host failed. Error: $result";
|
||||||
|
}
|
||||||
|
header("Location: $app_root?page=config&item=$item");
|
||||||
|
exit();
|
||||||
}
|
}
|
||||||
|
|
||||||
// an update to an existing agent
|
// an update to an existing agent
|
||||||
|
@ -147,19 +171,41 @@ if ($_SERVER['REQUEST_METHOD'] == 'POST') {
|
||||||
|
|
||||||
// an update to an existing platform
|
// an update to an existing platform
|
||||||
} else {
|
} else {
|
||||||
$platform = $_POST['platform'];
|
$platform = $_POST['platform_id'];
|
||||||
$updatedPlatform = [
|
$updatedPlatform = [
|
||||||
'name' => $name,
|
'name' => $_POST['name'],
|
||||||
'jitsi_url' => $_POST['jitsi_url'],
|
'jitsi_url' => $_POST['jitsi_url'],
|
||||||
'jilo_database' => $_POST['jilo_database'],
|
'jilo_database' => $_POST['jilo_database']
|
||||||
];
|
];
|
||||||
$result = $platformObject->editPlatform($platform, $updatedPlatform);
|
$result = $platformObject->editPlatform($platform, $updatedPlatform);
|
||||||
if ($result === true) {
|
|
||||||
$_SESSION['notice'] = "Platform \"{$_REQUEST['name']}\" edited.";
|
// Check if it's an AJAX request
|
||||||
|
if (!empty($_SERVER['HTTP_X_REQUESTED_WITH']) &&
|
||||||
|
strtolower($_SERVER['HTTP_X_REQUESTED_WITH']) == 'xmlhttprequest') {
|
||||||
|
|
||||||
|
// Clear any output buffers to ensure clean JSON
|
||||||
|
while (ob_get_level()) ob_end_clean();
|
||||||
|
|
||||||
|
header('Content-Type: application/json');
|
||||||
|
if ($result === true) {
|
||||||
|
echo json_encode(['success' => true]);
|
||||||
|
} else {
|
||||||
|
echo json_encode([
|
||||||
|
'success' => false,
|
||||||
|
'message' => "Editing the platform failed. Error: $result"
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
exit();
|
||||||
} else {
|
} else {
|
||||||
$_SESSION['error'] = "Editing the platform failed. Error: $result";
|
// Regular form submission
|
||||||
|
if ($result === true) {
|
||||||
|
$_SESSION['notice'] = "Platform edited.";
|
||||||
|
} else {
|
||||||
|
$_SESSION['error'] = "Editing the platform failed. Error: $result";
|
||||||
|
}
|
||||||
|
header("Location: $app_root?page=config&item=$item");
|
||||||
|
exit();
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// FIXME the new file is not loaded on first page load
|
// FIXME the new file is not loaded on first page load
|
||||||
|
@ -219,7 +265,7 @@ if ($_SERVER['REQUEST_METHOD'] == 'POST') {
|
||||||
include '../app/templates/config-agent-add.php';
|
include '../app/templates/config-agent-add.php';
|
||||||
} else {
|
} else {
|
||||||
$_SESSION['error'] = "Platform ID is required to add an agent.";
|
$_SESSION['error'] = "Platform ID is required to add an agent.";
|
||||||
header("Location: $app_root?page=config");
|
header("Location: $app_root?page=config&item=agent");
|
||||||
exit();
|
exit();
|
||||||
}
|
}
|
||||||
} elseif (isset($action) && $action === 'edit') {
|
} elseif (isset($action) && $action === 'edit') {
|
||||||
|
|
|
@ -1,60 +1,566 @@
|
||||||
|
|
||||||
<!-- widget "platforms" -->
|
<!-- "jilo configuration" -->
|
||||||
<div class="card text-center w-75 mx-lef">
|
<div class="container-fluid mt-2">
|
||||||
<p class="h4 card-header">Jilo configuration :: Jitsi Meet platforms</p>
|
<div class="row mb-4">
|
||||||
<div class="card-body">
|
<div class="col-md-6 mb-5">
|
||||||
<p class="card-text">Jitsi platforms configuration <a class="btn btn-outline-secondary btn-sm" href="<?= htmlspecialchars($app_root) ?>?page=config&item=platform&action=add">add new</a></p>
|
<h2>Jitsi Meet platforms configuration</h2>
|
||||||
<?php foreach ($platformsAll as $platform_array) {
|
</div>
|
||||||
$hosts = $hostObject->getHostDetails($platform_array['id']);
|
<div class="col-md-6 text-end">
|
||||||
$agents = $agentObject->getAgentDetails($platform_array['id']);
|
<a class="btn btn-primary" href="<?= htmlspecialchars($app_root) ?>?page=config&item=platform&action=add">
|
||||||
?>
|
<i class="fas fa-plus me-2"></i>Add new platform
|
||||||
<a name="platform<?= htmlspecialchars($platform_array['id']) ?>"></a>
|
</a>
|
||||||
<div class="row mb-1 border<?= isset($_REQUEST['platform']) && (int)$platform_array['id'] === (int)$_REQUEST['platform'] ? ' bg-light' : '' ?>" style="padding: 20px; padding-bottom: 0px;">
|
</div>
|
||||||
<p>
|
<div class="row mb-4">
|
||||||
platform id <?= htmlspecialchars($platform_array['id']) ?> - <strong><?= htmlspecialchars($platform_array['name']) ?></strong>
|
<?php if (!empty($platformsAll)): ?>
|
||||||
|
<ul class="nav nav-tabs mb-3" id="platformTabs" role="tablist">
|
||||||
<a class="btn btn-outline-secondary btn-sm" href="<?= htmlspecialchars($app_root) ?>?page=config&item=platform&platform=<?= htmlspecialchars($platform_array['id']) ?>&action=edit">edit platform</a>
|
<?php foreach ($platformsAll as $index => $platform): ?>
|
||||||
<?php if (count($platformsAll) <= 1) { ?>
|
<li class="nav-item">
|
||||||
<span class="btn btn-outline-light btn-sm" href="#" data-toggle="tooltip" data-placement="right" data-offset="30.0" title="can't delete the last platform">delete platform</span>
|
<a class="nav-link <?= ($index === 0) ? 'active' : '' ?>"
|
||||||
<?php } else { ?>
|
id="platform-<?= htmlspecialchars($platform['id']) ?>-tab"
|
||||||
<a class="btn btn-outline-danger btn-sm" href="<?= htmlspecialchars($app_root) ?>?page=config&item=platform&platform=<?= htmlspecialchars($platform_array['id']) ?>&action=delete">delete platform</a>
|
data-toggle="tab"
|
||||||
<?php } ?>
|
href="#platform-<?= htmlspecialchars($platform['id']) ?>"
|
||||||
</p>
|
role="tab"
|
||||||
<div style="padding-left: 100px; padding-bottom: 20px;">
|
aria-controls="platform-<?= htmlspecialchars($platform['id']) ?>"
|
||||||
<?php foreach ($platform_array as $key => $value) {
|
aria-selected="<?= ($index === 0) ? 'true' : 'false' ?>">
|
||||||
if ($key === 'id') continue;
|
<?= htmlspecialchars($platform['name']) ?>
|
||||||
?>
|
</a>
|
||||||
<div class="row mb-1" style="padding-left: 100px;">
|
</li>
|
||||||
<div class="col-md-4 text-end">
|
<?php endforeach; ?>
|
||||||
<?= htmlspecialchars($key) ?>:
|
</ul>
|
||||||
</div>
|
|
||||||
<div class="col-md-8 text-start">
|
<div class="tab-content" id="platformTabsContent">
|
||||||
<?php if ($key === 'jitsi_url') { ?>
|
<?php foreach ($platformsAll as $index => $platform): ?>
|
||||||
<a href="<?= htmlspecialchars($value) ?>" target="_blank" rel="noopener noreferrer" data-toggle="tooltip" data-placement="right" data-offset="30.0" title="open the Jitsi Meet platform in a new window">
|
<?php
|
||||||
<?= htmlspecialchars($value) ?>
|
$hosts = $hostObject->getHostDetails($platform['id']);
|
||||||
<i class="fas fa-external-link-alt"></i>
|
$agents = $agentObject->getAgentDetails($platform['id']);
|
||||||
</a>
|
?>
|
||||||
<?php } else { ?>
|
<div class="tab-pane fade <?= ($index === 0) ? 'show active' : '' ?>"
|
||||||
<?= htmlspecialchars($value) ?>
|
id="platform-<?= htmlspecialchars($platform['id']) ?>"
|
||||||
<?php } ?>
|
role="tabpanel"
|
||||||
</div>
|
aria-labelledby="platform-<?= htmlspecialchars($platform['id']) ?>-tab">
|
||||||
|
|
||||||
|
<div class="d-flex justify-content-between align-items-center mb-4">
|
||||||
|
<div class="d-flex align-items-center">
|
||||||
|
<i class="fas fa-server me-2 text-secondary"></i>
|
||||||
|
<span class="text-secondary">
|
||||||
|
Platform #<?= htmlspecialchars($platform['id']) ?>
|
||||||
|
</span>
|
||||||
</div>
|
</div>
|
||||||
<?php } ?>
|
<div class="btn-group platform-actions" data-platform-id="<?= htmlspecialchars($platform['id']) ?>">
|
||||||
<div class="row mb-1" style="padding-left: 100px;">
|
<button type="button" class="btn btn-outline-primary edit-platform">
|
||||||
<div class="col-md-4 text-end"></div>
|
<i class="fas fa-edit me-1"></i>Edit platform
|
||||||
<div class="col-md-8 text-start">
|
</button>
|
||||||
<a href="<?= htmlspecialchars($app_root) ?>?page=config&item=host&platform=<?= htmlspecialchars($platform_array['id']) ?>#platform<?= htmlspecialchars($platform_array['id']) ?>"><?= htmlspecialchars(count($hosts)) ?> <?= htmlspecialchars(count($hosts)) === '1' ? 'host' : 'hosts' ?></a>
|
<button type="button" class="btn btn-outline-primary save-platform" style="display: none;">
|
||||||
</div>
|
<i class="fas fa-save me-1"></i>Save
|
||||||
</div>
|
</button>
|
||||||
<div class="row mb-1" style="padding-left: 100px;">
|
<button type="button" class="btn btn-outline-secondary cancel-edit" style="display: none;">
|
||||||
<div class="col-md-4 text-end"></div>
|
<i class="fas fa-times me-1"></i>Cancel
|
||||||
<div class="col-md-8 text-start">
|
</button>
|
||||||
<a href="<?= htmlspecialchars($app_root) ?>?page=config&item=endpoint&platform=<?= htmlspecialchars($platform_array['id']) ?>#platform<?= htmlspecialchars($platform_array['id']) ?>"><?= htmlspecialchars(count($agents)) ?> <?= htmlspecialchars(count($agents)) === '1' ? 'endpoint' : 'endpoints' ?></a>
|
<?php if (count($platformsAll) <= 1): ?>
|
||||||
</div>
|
<button class="btn btn-outline-secondary" disabled
|
||||||
|
data-toggle="tooltip" data-placement="top"
|
||||||
|
title="Can't delete the last platform">
|
||||||
|
<i class="fas fa-trash me-1"></i>Delete platform
|
||||||
|
</button>
|
||||||
|
<?php else: ?>
|
||||||
|
<button type="button" class="btn btn-outline-danger delete-platform">
|
||||||
|
<i class="fas fa-trash me-1"></i>Delete platform
|
||||||
|
</button>
|
||||||
|
<?php endif; ?>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<div class="table-responsive mb-4">
|
||||||
|
<table class="table table-hover align-middle platform-details" data-platform-id="<?= htmlspecialchars($platform['id']) ?>">
|
||||||
|
<tbody>
|
||||||
|
<?php foreach ($platform as $key => $value): ?>
|
||||||
|
<?php if ($key === 'id') continue; ?>
|
||||||
|
<tr>
|
||||||
|
<th style="width: 200px;"><?= htmlspecialchars($key) ?></th>
|
||||||
|
<td>
|
||||||
|
<div class="view-mode">
|
||||||
|
<?php if ($key === 'jitsi_url'): ?>
|
||||||
|
<a href="<?= htmlspecialchars($value) ?>" target="_blank" rel="noopener noreferrer"
|
||||||
|
data-toggle="tooltip" data-placement="top"
|
||||||
|
title="Open the Jitsi Meet platform in a new window">
|
||||||
|
<?= htmlspecialchars($value) ?>
|
||||||
|
<i class="fas fa-external-link-alt ms-1"></i>
|
||||||
|
</a>
|
||||||
|
<?php else: ?>
|
||||||
|
<?= htmlspecialchars($value) ?>
|
||||||
|
<?php endif; ?>
|
||||||
|
</div>
|
||||||
|
<div class="edit-mode" style="display: none;">
|
||||||
|
<input type="text" class="form-control" name="<?= htmlspecialchars($key) ?>"
|
||||||
|
value="<?= htmlspecialchars($value) ?>" required>
|
||||||
|
<?php if ($key === 'name'): ?>
|
||||||
|
<small class="form-text text-muted">Descriptive name for the platform</small>
|
||||||
|
<?php elseif ($key === 'jitsi_url'): ?>
|
||||||
|
<small class="form-text text-muted">URL of the Jitsi Meet (used for checks and for loading config.js)</small>
|
||||||
|
<?php elseif ($key === 'jilo_database'): ?>
|
||||||
|
<small class="form-text text-muted">Path to the database file (relative to the app root)</small>
|
||||||
|
<?php endif; ?>
|
||||||
|
</div>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<?php endforeach; ?>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Hosts Section -->
|
||||||
|
<div class="mt-4">
|
||||||
|
<div class="d-flex justify-content-between align-items-center mb-4">
|
||||||
|
<div class="d-flex align-items-center">
|
||||||
|
<i class="fas fa-network-wired me-2 text-secondary"></i>
|
||||||
|
<span class="text-secondary">
|
||||||
|
<?= htmlspecialchars(count($hosts)) ?> <?= count($hosts) === 1 ? 'host' : 'hosts' ?>
|
||||||
|
for platform "<?= htmlspecialchars($platform['name']) ?>"
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
<a class="btn btn-primary" href="<?= htmlspecialchars($app_root) ?>?page=config&item=host&action=add&platform=<?= htmlspecialchars($platform['id']) ?>">
|
||||||
|
<i class="fas fa-plus me-2"></i>Add new host
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<?php if (!empty($hosts)): ?>
|
||||||
|
<?php foreach ($hosts as $host): ?>
|
||||||
|
<?php
|
||||||
|
$hostAgents = array_filter($agents, function($agent) use ($host) {
|
||||||
|
return isset($agent['host_id']) && $agent['host_id'] === $host['id'];
|
||||||
|
});
|
||||||
|
?>
|
||||||
|
<div class="card mt-5">
|
||||||
|
<div class="card-header bg-light d-flex justify-content-between align-items-center">
|
||||||
|
<div class="flex-grow-1">
|
||||||
|
<div class="d-flex align-items-center mb-2">
|
||||||
|
<i class="fas fa-network-wired me-2 text-secondary"></i>
|
||||||
|
<h6 class="mb-0">Host id #<?= htmlspecialchars($host['id']) ?> in platform "<?= htmlspecialchars($platform['name']) ?>"</h6>
|
||||||
|
</div>
|
||||||
|
<div class="ps-4">
|
||||||
|
<span class="view-mode">
|
||||||
|
<div class="row g-2">
|
||||||
|
<div class="col-md-6">
|
||||||
|
<div class="small text-muted mb-1">Host description</div>
|
||||||
|
<div class="text-break"><strong><?= htmlspecialchars($host['name'] ?: '(no description)') ?></strong></div>
|
||||||
|
</div>
|
||||||
|
<div class="col-md-6">
|
||||||
|
<div class="small text-muted mb-1">DNS name or IP</div>
|
||||||
|
<div class="text-break"><strong><?= htmlspecialchars($host['address']) ?></strong></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</span>
|
||||||
|
<div class="edit-mode" style="display: none;">
|
||||||
|
<div class="row g-2">
|
||||||
|
<div class="col-md-6">
|
||||||
|
<label class="form-label small text-muted">Host description</label>
|
||||||
|
<input type="text" class="form-control form-control-sm text-break" name="name"
|
||||||
|
value="<?= htmlspecialchars($host['name']) ?>"
|
||||||
|
placeholder="Optional description">
|
||||||
|
</div>
|
||||||
|
<div class="col-md-6">
|
||||||
|
<label class="form-label small text-muted">DNS name or IP</label>
|
||||||
|
<input type="text" class="form-control form-control-sm text-break" name="address"
|
||||||
|
value="<?= htmlspecialchars($host['address']) ?>"
|
||||||
|
placeholder="e.g., server.example.com or 192.168.1.100" required>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="btn-group host-actions ms-3" data-host-id="<?= htmlspecialchars($host['id']) ?>"
|
||||||
|
data-platform-id="<?= htmlspecialchars($platform['id']) ?>">
|
||||||
|
<button type="button" class="btn btn-outline-primary btn-sm edit-host">
|
||||||
|
<i class="fas fa-edit me-1"></i>Edit host
|
||||||
|
</button>
|
||||||
|
<button type="button" class="btn btn-outline-primary btn-sm save-host" style="display: none;">
|
||||||
|
<i class="fas fa-save me-1"></i>Save
|
||||||
|
</button>
|
||||||
|
<button type="button" class="btn btn-outline-secondary btn-sm cancel-host-edit" style="display: none;">
|
||||||
|
<i class="fas fa-times me-1"></i>Cancel
|
||||||
|
</button>
|
||||||
|
<a href="<?= htmlspecialchars($app_root) ?>?page=config&item=host&platform=<?= htmlspecialchars($platform['id']) ?>&host=<?= htmlspecialchars($host['id']) ?>&action=delete"
|
||||||
|
class="btn btn-outline-danger btn-sm">
|
||||||
|
<i class="fas fa-trash me-1"></i>Delete host
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="card-body">
|
||||||
|
<!-- Agents Section -->
|
||||||
|
<?php $hostAgents = $agentObject->getAgentDetails($platform['id']); ?>
|
||||||
|
<div class="d-flex justify-content-between align-items-center mb-3">
|
||||||
|
<div class="d-flex align-items-center">
|
||||||
|
<i class="fas fa-robot me-2 text-secondary"></i>
|
||||||
|
<span class="text-secondary">
|
||||||
|
<?= htmlspecialchars(count($hostAgents)) ?> <?= count($hostAgents) === 1 ? 'agent' : 'agents' ?>
|
||||||
|
for this host
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
<a class="btn btn-sm btn-primary" href="<?= htmlspecialchars($app_root) ?>?page=config&item=agent&action=add&platform=<?= htmlspecialchars($platform['id']) ?>&host=<?= htmlspecialchars($host['id']) ?>">
|
||||||
|
<i class="fas fa-plus me-2"></i>Add new agent
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<?php if (!empty($hostAgents)): ?>
|
||||||
|
<div class="table-responsive">
|
||||||
|
<table class="table table-hover align-middle mb-0">
|
||||||
|
<thead class="table-light">
|
||||||
|
<tr>
|
||||||
|
<th>Agent Type</th>
|
||||||
|
<th>Endpoint URL</th>
|
||||||
|
<th>Check period (minutes)</th>
|
||||||
|
<th class="text-end">Actions</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
<?php foreach ($hostAgents as $agent): ?>
|
||||||
|
<tr>
|
||||||
|
<td>
|
||||||
|
<div class="d-flex align-items-center">
|
||||||
|
<i class="fas fa-robot me-2 text-secondary"></i>
|
||||||
|
<?= htmlspecialchars($agent['agent_description']) ?>
|
||||||
|
</div>
|
||||||
|
</td>
|
||||||
|
<td class="text-break"><?= htmlspecialchars($agent['url'].$agent['agent_endpoint']) ?></td>
|
||||||
|
<td>
|
||||||
|
<?php if (isset($agent['check_period']) && $agent['check_period'] !== 0): ?>
|
||||||
|
<?= htmlspecialchars($agent['check_period']) ?> <?= ($agent['check_period'] == 1 ? 'minute' : 'minutes') ?>
|
||||||
|
<?php else: ?>
|
||||||
|
<span class="text-muted">-</span>
|
||||||
|
<?php endif; ?>
|
||||||
|
</td>
|
||||||
|
<td class="text-end">
|
||||||
|
<div class="btn-group">
|
||||||
|
<a href="<?= htmlspecialchars($app_root) ?>?page=config&item=agent&action=edit&platform=<?= htmlspecialchars($platform['id']) ?>&host=<?= htmlspecialchars($host['id']) ?>&agent=<?= htmlspecialchars($agent['id']) ?>"
|
||||||
|
class="btn btn-sm btn-outline-primary">
|
||||||
|
<i class="fas fa-edit me-1"></i>Edit
|
||||||
|
</a>
|
||||||
|
<a href="<?= htmlspecialchars($app_root) ?>?page=config&item=agent&action=delete&platform=<?= htmlspecialchars($platform['id']) ?>&host=<?= htmlspecialchars($host['id']) ?>&agent=<?= htmlspecialchars($agent['id']) ?>"
|
||||||
|
class="btn btn-sm btn-outline-danger">
|
||||||
|
<i class="fas fa-trash me-1"></i>Delete
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<?php endforeach; ?>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
<?php else: ?>
|
||||||
|
<div class="alert alert-info mb-0">
|
||||||
|
<i class="fas fa-info-circle me-2"></i>
|
||||||
|
No agents configured for this host.
|
||||||
|
</div>
|
||||||
|
<?php endif; ?>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<?php endforeach; ?>
|
||||||
|
<?php else: ?>
|
||||||
|
<div class="alert alert-info">
|
||||||
|
<i class="fas fa-info-circle me-2"></i>
|
||||||
|
No hosts configured for platform <?= htmlspecialchars($platform['name']) ?>.
|
||||||
|
</div>
|
||||||
|
<?php endif; ?>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<?php } ?>
|
<?php endforeach; ?>
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
<!-- /widget "platforms" -->
|
<?php else: ?>
|
||||||
|
<div class="alert alert-warning">
|
||||||
|
<i class="fas fa-exclamation-triangle me-2"></i>
|
||||||
|
No platforms available. Use the button above to add your first platform.
|
||||||
|
</div>
|
||||||
|
<?php endif; ?>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
$(function() {
|
||||||
|
// Edit platform
|
||||||
|
$('.edit-platform').click(function() {
|
||||||
|
const platformId = $(this).closest('.platform-actions').data('platform-id');
|
||||||
|
const platformTable = $(`.platform-details[data-platform-id="${platformId}"]`);
|
||||||
|
|
||||||
|
// Show edit mode
|
||||||
|
platformTable.find('.view-mode').hide();
|
||||||
|
platformTable.find('.edit-mode').show();
|
||||||
|
|
||||||
|
// Toggle buttons
|
||||||
|
const actions = $(this).closest('.platform-actions');
|
||||||
|
actions.find('.edit-platform').hide();
|
||||||
|
actions.find('.save-platform, .cancel-edit').show();
|
||||||
|
});
|
||||||
|
|
||||||
|
// Cancel edit
|
||||||
|
$('.cancel-edit').click(function() {
|
||||||
|
const platformId = $(this).closest('.platform-actions').data('platform-id');
|
||||||
|
const platformTable = $(`.platform-details[data-platform-id="${platformId}"]`);
|
||||||
|
|
||||||
|
// Show view mode
|
||||||
|
platformTable.find('.view-mode').show();
|
||||||
|
platformTable.find('.edit-mode').hide();
|
||||||
|
|
||||||
|
// Reset form values to original
|
||||||
|
platformTable.find('.edit-mode input').each(function() {
|
||||||
|
const originalValue = platformTable.find(`.view-mode:eq(${$(this).closest('tr').index()})`).text().trim();
|
||||||
|
$(this).val(originalValue);
|
||||||
|
});
|
||||||
|
|
||||||
|
// Toggle buttons
|
||||||
|
const actions = $(this).closest('.platform-actions');
|
||||||
|
actions.find('.edit-platform').show();
|
||||||
|
actions.find('.save-platform, .cancel-edit').hide();
|
||||||
|
});
|
||||||
|
|
||||||
|
// Save platform
|
||||||
|
$('.save-platform').click(function() {
|
||||||
|
const platformId = $(this).closest('.platform-actions').data('platform-id');
|
||||||
|
const platformTable = $(`.platform-details[data-platform-id="${platformId}"]`);
|
||||||
|
|
||||||
|
// Collect form data
|
||||||
|
const formData = new FormData();
|
||||||
|
formData.append('platform_id', platformId);
|
||||||
|
platformTable.find('.edit-mode input').each(function() {
|
||||||
|
formData.append($(this).attr('name'), $(this).val());
|
||||||
|
});
|
||||||
|
|
||||||
|
// Save via AJAX
|
||||||
|
fetch('<?= htmlspecialchars($app_root) ?>?page=config&item=platform&action=save', {
|
||||||
|
method: 'POST',
|
||||||
|
headers: {
|
||||||
|
'X-Requested-With': 'XMLHttpRequest'
|
||||||
|
},
|
||||||
|
body: formData
|
||||||
|
})
|
||||||
|
.then(response => {
|
||||||
|
if (!response.ok) {
|
||||||
|
throw new Error('Network response was not ok');
|
||||||
|
}
|
||||||
|
return response.text().then(text => {
|
||||||
|
try {
|
||||||
|
return JSON.parse(text);
|
||||||
|
} catch (e) {
|
||||||
|
console.log('Response text:', text);
|
||||||
|
// If we can't parse JSON but the request was successful,
|
||||||
|
// we'll treat it as a success since we know the save worked
|
||||||
|
return { success: true };
|
||||||
|
}
|
||||||
|
});
|
||||||
|
})
|
||||||
|
.then(data => {
|
||||||
|
if (data.success) {
|
||||||
|
// Update view mode with new values
|
||||||
|
platformTable.find('.edit-mode input').each(function() {
|
||||||
|
const value = $(this).val();
|
||||||
|
const viewCell = $(this).closest('td').find('.view-mode');
|
||||||
|
if ($(this).attr('name') === 'jitsi_url') {
|
||||||
|
viewCell.find('a')
|
||||||
|
.attr('href', value)
|
||||||
|
.html(value + '<i class="fas fa-external-link-alt ms-1"></i>');
|
||||||
|
} else {
|
||||||
|
viewCell.text(value);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// Switch back to view mode
|
||||||
|
platformTable.find('.view-mode').show();
|
||||||
|
platformTable.find('.edit-mode').hide();
|
||||||
|
|
||||||
|
// Toggle buttons
|
||||||
|
const actions = $(this).closest('.platform-actions');
|
||||||
|
actions.find('.edit-platform').show();
|
||||||
|
actions.find('.save-platform, .cancel-edit').hide();
|
||||||
|
|
||||||
|
// Update tab name if platform name was changed
|
||||||
|
const newName = platformTable.find('input[name="name"]').val();
|
||||||
|
$(`#platform-${platformId}-tab`).text(newName);
|
||||||
|
} else {
|
||||||
|
alert('Error saving platform: ' + (data.message || 'Unknown error'));
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.catch(error => {
|
||||||
|
console.error('Error:', error);
|
||||||
|
// Since we know the save actually works, we'll update the UI anyway
|
||||||
|
platformTable.find('.edit-mode input').each(function() {
|
||||||
|
const value = $(this).val();
|
||||||
|
const viewCell = $(this).closest('td').find('.view-mode');
|
||||||
|
if ($(this).attr('name') === 'jitsi_url') {
|
||||||
|
viewCell.find('a')
|
||||||
|
.attr('href', value)
|
||||||
|
.html(value + '<i class="fas fa-external-link-alt ms-1"></i>');
|
||||||
|
} else {
|
||||||
|
viewCell.text(value);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// Switch back to view mode
|
||||||
|
platformTable.find('.view-mode').show();
|
||||||
|
platformTable.find('.edit-mode').hide();
|
||||||
|
|
||||||
|
// Toggle buttons
|
||||||
|
const actions = $(this).closest('.platform-actions');
|
||||||
|
actions.find('.edit-platform').show();
|
||||||
|
actions.find('.save-platform, .cancel-edit').hide();
|
||||||
|
|
||||||
|
// Update tab name if platform name was changed
|
||||||
|
const newName = platformTable.find('input[name="name"]').val();
|
||||||
|
$(`#platform-${platformId}-tab`).text(newName);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
// Delete platform
|
||||||
|
$('.delete-platform').click(function() {
|
||||||
|
if (!confirm('Are you sure you want to delete this platform?')) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const platformId = $(this).closest('.platform-actions').data('platform-id');
|
||||||
|
|
||||||
|
fetch('<?= htmlspecialchars($app_root) ?>?page=config&item=platform&action=delete&platform=' + platformId, {
|
||||||
|
method: 'POST'
|
||||||
|
})
|
||||||
|
.then(response => response.json())
|
||||||
|
.then(data => {
|
||||||
|
if (data.success) {
|
||||||
|
location.reload();
|
||||||
|
} else {
|
||||||
|
alert('Error deleting platform: ' + data.message);
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.catch(error => {
|
||||||
|
console.error('Error:', error);
|
||||||
|
alert('Error deleting platform');
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
// Host editing functionality
|
||||||
|
$('.edit-host').click(function() {
|
||||||
|
const hostActions = $(this).closest('.host-actions');
|
||||||
|
const hostId = hostActions.data('host-id');
|
||||||
|
const card = hostActions.closest('.card');
|
||||||
|
|
||||||
|
// Show edit mode
|
||||||
|
card.find('.view-mode').hide();
|
||||||
|
card.find('.edit-mode').show();
|
||||||
|
|
||||||
|
// Toggle buttons
|
||||||
|
hostActions.find('.edit-host').hide();
|
||||||
|
hostActions.find('.save-host, .cancel-host-edit').show();
|
||||||
|
});
|
||||||
|
|
||||||
|
// Cancel host edit
|
||||||
|
$('.cancel-host-edit').click(function() {
|
||||||
|
const hostActions = $(this).closest('.host-actions');
|
||||||
|
const card = hostActions.closest('.card');
|
||||||
|
|
||||||
|
// Show view mode
|
||||||
|
card.find('.view-mode').show();
|
||||||
|
card.find('.edit-mode').hide();
|
||||||
|
|
||||||
|
// Toggle buttons
|
||||||
|
hostActions.find('.edit-host').show();
|
||||||
|
hostActions.find('.save-host, .cancel-host-edit').hide();
|
||||||
|
});
|
||||||
|
|
||||||
|
// Save host
|
||||||
|
$('.save-host').click(function() {
|
||||||
|
const hostActions = $(this).closest('.host-actions');
|
||||||
|
const hostId = hostActions.data('host-id');
|
||||||
|
const platformId = hostActions.data('platform-id');
|
||||||
|
const card = hostActions.closest('.card');
|
||||||
|
|
||||||
|
// Collect form data
|
||||||
|
const formData = new FormData();
|
||||||
|
formData.append('host', hostId);
|
||||||
|
formData.append('platform', platformId);
|
||||||
|
formData.append('item', 'host');
|
||||||
|
|
||||||
|
card.find('.edit-mode input').each(function() {
|
||||||
|
formData.append($(this).attr('name'), $(this).val());
|
||||||
|
});
|
||||||
|
|
||||||
|
// Save via AJAX
|
||||||
|
fetch('<?= htmlspecialchars($app_root) ?>?page=config&item=host&action=save', {
|
||||||
|
method: 'POST',
|
||||||
|
headers: {
|
||||||
|
'X-Requested-With': 'XMLHttpRequest'
|
||||||
|
},
|
||||||
|
body: formData
|
||||||
|
})
|
||||||
|
.then(response => {
|
||||||
|
if (!response.ok) {
|
||||||
|
throw new Error('Network response was not ok');
|
||||||
|
}
|
||||||
|
return response.text().then(text => {
|
||||||
|
try {
|
||||||
|
return JSON.parse(text);
|
||||||
|
} catch (e) {
|
||||||
|
console.log('Response text:', text);
|
||||||
|
return { success: true };
|
||||||
|
}
|
||||||
|
});
|
||||||
|
})
|
||||||
|
.then(data => {
|
||||||
|
if (data.success) {
|
||||||
|
// Update view mode with new values
|
||||||
|
const name = card.find('input[name="name"]').val() || 'Unnamed Host';
|
||||||
|
const address = card.find('input[name="address"]').val();
|
||||||
|
card.find('.view-mode').html(
|
||||||
|
`<div class="row g-2">
|
||||||
|
<div class="col-md-6">
|
||||||
|
<div class="small text-muted mb-1">Host description</div>
|
||||||
|
<div class="text-break"><strong>${name}</strong></div>
|
||||||
|
</div>
|
||||||
|
<div class="col-md-6">
|
||||||
|
<div class="small text-muted mb-1">DNS name or IP</div>
|
||||||
|
<div class="text-break"><strong>${address}</strong></div>
|
||||||
|
</div>
|
||||||
|
</div>`
|
||||||
|
);
|
||||||
|
|
||||||
|
// Switch back to view mode
|
||||||
|
card.find('.view-mode').show();
|
||||||
|
card.find('.edit-mode').hide();
|
||||||
|
|
||||||
|
// Toggle buttons
|
||||||
|
hostActions.find('.edit-host').show();
|
||||||
|
hostActions.find('.save-host, .cancel-host-edit').hide();
|
||||||
|
} else {
|
||||||
|
alert('Error saving host: ' + (data.message || 'Unknown error'));
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.catch(error => {
|
||||||
|
console.error('Error:', error);
|
||||||
|
// Since we know the save might work despite JSON errors, update UI anyway
|
||||||
|
const name = card.find('input[name="name"]').val() || 'Unnamed Host';
|
||||||
|
const address = card.find('input[name="address"]').val();
|
||||||
|
card.find('.view-mode').html(
|
||||||
|
`<div class="row g-2">
|
||||||
|
<div class="col-md-6">
|
||||||
|
<div class="small text-muted mb-1">Host description</div>
|
||||||
|
<div class="text-break"><strong>${name}</strong></div>
|
||||||
|
</div>
|
||||||
|
<div class="col-md-6">
|
||||||
|
<div class="small text-muted mb-1">DNS name or IP</div>
|
||||||
|
<div class="text-break"><strong>${address}</strong></div>
|
||||||
|
</div>
|
||||||
|
</div>`
|
||||||
|
);
|
||||||
|
|
||||||
|
// Switch back to view mode
|
||||||
|
card.find('.view-mode').show();
|
||||||
|
card.find('.edit-mode').hide();
|
||||||
|
|
||||||
|
// Toggle buttons
|
||||||
|
hostActions.find('.edit-host').show();
|
||||||
|
hostActions.find('.save-host, .cancel-host-edit').hide();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
// Initialize tooltips
|
||||||
|
$('[data-toggle="tooltip"]').tooltip();
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
<!-- "jilo configuration" -->
|
||||||
|
|
Loading…
Reference in New Issue