2024-10-30 14:54:09 +00:00
|
|
|
|
2025-01-20 19:17:54 +00:00
|
|
|
<!-- "jilo configuration" -->
|
|
|
|
<div class="container-fluid mt-2">
|
|
|
|
<div class="row mb-4">
|
|
|
|
<div class="col-md-6 mb-5">
|
|
|
|
<h2>Jitsi Meet platforms configuration</h2>
|
|
|
|
</div>
|
|
|
|
<div class="col-md-6 text-end">
|
2025-01-21 14:57:28 +00:00
|
|
|
<button type="button" class="btn btn-primary" onclick="showAddPlatformModal()">
|
2025-01-20 19:17:54 +00:00
|
|
|
<i class="fas fa-plus me-2"></i>Add new platform
|
2025-01-21 14:57:28 +00:00
|
|
|
</button>
|
2025-01-20 19:17:54 +00:00
|
|
|
</div>
|
|
|
|
<div class="row mb-4">
|
|
|
|
<?php if (!empty($platformsAll)): ?>
|
|
|
|
<ul class="nav nav-tabs mb-3" id="platformTabs" role="tablist">
|
|
|
|
<?php foreach ($platformsAll as $index => $platform): ?>
|
|
|
|
<li class="nav-item">
|
|
|
|
<a class="nav-link <?= ($index === 0) ? 'active' : '' ?>"
|
|
|
|
id="platform-<?= htmlspecialchars($platform['id']) ?>-tab"
|
|
|
|
data-toggle="tab"
|
|
|
|
href="#platform-<?= htmlspecialchars($platform['id']) ?>"
|
|
|
|
role="tab"
|
|
|
|
aria-controls="platform-<?= htmlspecialchars($platform['id']) ?>"
|
|
|
|
aria-selected="<?= ($index === 0) ? 'true' : 'false' ?>">
|
|
|
|
<?= htmlspecialchars($platform['name']) ?>
|
|
|
|
</a>
|
|
|
|
</li>
|
|
|
|
<?php endforeach; ?>
|
|
|
|
</ul>
|
|
|
|
|
|
|
|
<div class="tab-content" id="platformTabsContent">
|
|
|
|
<?php foreach ($platformsAll as $index => $platform): ?>
|
|
|
|
<?php
|
|
|
|
$hosts = $hostObject->getHostDetails($platform['id']);
|
|
|
|
$agents = $agentObject->getAgentDetails($platform['id']);
|
|
|
|
?>
|
|
|
|
<div class="tab-pane fade <?= ($index === 0) ? 'show active' : '' ?>"
|
|
|
|
id="platform-<?= htmlspecialchars($platform['id']) ?>"
|
|
|
|
role="tabpanel"
|
|
|
|
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>
|
2024-10-30 14:54:09 +00:00
|
|
|
</div>
|
2025-01-20 19:17:54 +00:00
|
|
|
<div class="btn-group platform-actions" data-platform-id="<?= htmlspecialchars($platform['id']) ?>">
|
2025-01-21 14:57:28 +00:00
|
|
|
<button type="button" class="btn btn-outline-primary edit-platform platform-view-mode">
|
2025-01-20 19:17:54 +00:00
|
|
|
<i class="fas fa-edit me-1"></i>Edit platform
|
|
|
|
</button>
|
2025-01-21 14:57:28 +00:00
|
|
|
<button type="button" class="btn btn-outline-primary save-platform platform-edit-mode" style="display: none;">
|
2025-01-20 19:17:54 +00:00
|
|
|
<i class="fas fa-save me-1"></i>Save
|
|
|
|
</button>
|
2025-01-21 14:57:28 +00:00
|
|
|
<button type="button" class="btn btn-outline-secondary cancel-edit platform-edit-mode" style="display: none;">
|
2025-01-20 19:17:54 +00:00
|
|
|
<i class="fas fa-times me-1"></i>Cancel
|
|
|
|
</button>
|
2025-01-21 14:57:28 +00:00
|
|
|
<?php if ($userObject->hasRight($user_id, 'delete platform')): ?>
|
|
|
|
<button type="button" class="btn btn-outline-danger platform-view-mode" onclick="showDeletePlatformModal(<?= htmlspecialchars($platform['id']) ?>, '<?= htmlspecialchars(addslashes($platform['name'])) ?>', '<?= htmlspecialchars(addslashes($platform['jitsi_url'])) ?>', '<?= htmlspecialchars(addslashes($platform['jilo_database'])) ?>')">
|
2025-01-20 19:17:54 +00:00
|
|
|
<i class="fas fa-trash me-1"></i>Delete platform
|
|
|
|
</button>
|
|
|
|
<?php endif; ?>
|
2024-10-30 14:54:09 +00:00
|
|
|
</div>
|
2025-01-20 19:17:54 +00:00
|
|
|
</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>
|
|
|
|
|
2025-01-21 14:57:28 +00:00
|
|
|
<!-- Hosts section -->
|
2025-01-20 19:17:54 +00:00
|
|
|
<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>
|
2024-10-30 14:54:09 +00:00
|
|
|
</div>
|
2025-01-21 14:57:28 +00:00
|
|
|
<button class="btn btn-primary" onclick="showAddHostModal(<?= htmlspecialchars($platform['id']) ?>)">
|
2025-01-20 19:17:54 +00:00
|
|
|
<i class="fas fa-plus me-2"></i>Add new host
|
2025-01-21 14:57:28 +00:00
|
|
|
</button>
|
2024-10-30 14:54:09 +00:00
|
|
|
</div>
|
2025-01-20 19:17:54 +00:00
|
|
|
|
|
|
|
<?php if (!empty($hosts)): ?>
|
|
|
|
<?php foreach ($hosts as $host): ?>
|
|
|
|
<?php
|
2025-01-22 15:46:08 +00:00
|
|
|
$hostAgents = $agentObject->getAgentDetails($host['id']);
|
2025-01-20 19:17:54 +00:00
|
|
|
?>
|
2025-01-21 14:57:28 +00:00
|
|
|
<div class="card mt-5 host-details" data-host-id="<?= htmlspecialchars($host['id']) ?>">
|
2025-01-20 19:17:54 +00:00
|
|
|
<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">
|
2025-01-20 19:42:22 +00:00
|
|
|
<span class="host-view-mode">
|
2025-01-20 19:17:54 +00:00
|
|
|
<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>
|
2025-01-20 19:42:22 +00:00
|
|
|
<div class="host-edit-mode" style="display: none;">
|
2025-01-20 19:17:54 +00:00
|
|
|
<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']) ?>">
|
2025-01-20 19:42:22 +00:00
|
|
|
<button type="button" class="btn btn-outline-primary btn-sm edit-host host-view-mode">
|
2025-01-20 19:17:54 +00:00
|
|
|
<i class="fas fa-edit me-1"></i>Edit host
|
|
|
|
</button>
|
2025-01-20 19:42:22 +00:00
|
|
|
<button type="button" class="btn btn-outline-primary btn-sm save-host host-edit-mode" style="display: none;">
|
2025-01-20 19:17:54 +00:00
|
|
|
<i class="fas fa-save me-1"></i>Save
|
|
|
|
</button>
|
2025-01-20 19:42:22 +00:00
|
|
|
<button type="button" class="btn btn-outline-secondary btn-sm cancel-host-edit host-edit-mode" style="display: none;">
|
2025-01-20 19:17:54 +00:00
|
|
|
<i class="fas fa-times me-1"></i>Cancel
|
|
|
|
</button>
|
2025-01-21 14:57:28 +00:00
|
|
|
<button type="button" class="btn btn-outline-danger btn-sm host-view-mode" onclick="showDeleteHostModal(<?= htmlspecialchars($platform['id']) ?>, <?= htmlspecialchars($host['id']) ?>, '<?= htmlspecialchars(addslashes($host['name'])) ?>', '<?= htmlspecialchars(addslashes($host['address'])) ?>')">
|
2025-01-20 19:17:54 +00:00
|
|
|
<i class="fas fa-trash me-1"></i>Delete host
|
2025-01-21 14:57:28 +00:00
|
|
|
</button>
|
2025-01-20 19:17:54 +00:00
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
|
|
|
|
<div class="card-body">
|
2025-01-21 14:57:28 +00:00
|
|
|
<!-- Agents section -->
|
2025-01-20 19:17:54 +00:00
|
|
|
<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">
|
2025-01-22 15:46:08 +00:00
|
|
|
<?php
|
|
|
|
$hostAgents = $agentObject->getAgentDetails($host['id']);
|
|
|
|
echo count($hostAgents) . ' ' . (count($hostAgents) === 1 ? 'agent' : 'agents') . ' for host "' . htmlspecialchars($host['name']) . '"';
|
|
|
|
?>
|
2025-01-20 19:17:54 +00:00
|
|
|
</span>
|
|
|
|
</div>
|
2025-01-22 15:46:08 +00:00
|
|
|
<button class="btn btn-primary" onclick="showAddAgentModal(<?= htmlspecialchars($host['id']) ?>)">
|
2025-01-20 19:17:54 +00:00
|
|
|
<i class="fas fa-plus me-2"></i>Add new agent
|
2025-01-21 14:57:28 +00:00
|
|
|
</button>
|
2025-01-20 19:17:54 +00:00
|
|
|
</div>
|
|
|
|
|
|
|
|
<?php if (!empty($hostAgents)): ?>
|
|
|
|
<div class="table-responsive">
|
|
|
|
<table class="table table-hover align-middle mb-0">
|
|
|
|
<thead class="table-light">
|
|
|
|
<tr>
|
2025-01-21 14:57:28 +00:00
|
|
|
<th>Agent type</th>
|
2025-01-20 19:17:54 +00:00
|
|
|
<th>Endpoint URL</th>
|
2025-01-22 15:46:08 +00:00
|
|
|
<th>Check period</th>
|
|
|
|
<th>Actions</th>
|
2025-01-20 19:17:54 +00:00
|
|
|
</tr>
|
|
|
|
</thead>
|
|
|
|
<tbody>
|
|
|
|
<?php foreach ($hostAgents as $agent): ?>
|
2025-01-21 14:57:28 +00:00
|
|
|
<tr class="agent-details" data-agent-id="<?= htmlspecialchars($agent['id']) ?>">
|
2025-01-20 19:17:54 +00:00
|
|
|
<td>
|
|
|
|
<div class="d-flex align-items-center">
|
|
|
|
<i class="fas fa-robot me-2 text-secondary"></i>
|
2025-01-20 19:42:22 +00:00
|
|
|
<span class="agent-view-mode">
|
|
|
|
<?= htmlspecialchars($agent['agent_description']) ?>
|
|
|
|
</span>
|
|
|
|
</div>
|
|
|
|
</td>
|
2025-01-22 15:46:08 +00:00
|
|
|
<td>
|
2025-01-20 19:42:22 +00:00
|
|
|
<span class="agent-view-mode">
|
2025-01-22 15:46:08 +00:00
|
|
|
<?= htmlspecialchars($agent['url']) ?>
|
2025-01-20 19:42:22 +00:00
|
|
|
</span>
|
|
|
|
<div class="agent-edit-mode" style="display: none;">
|
2025-01-22 15:46:08 +00:00
|
|
|
<input type="text" class="form-control" name="url" value="<?= htmlspecialchars($agent['url']) ?>" required>
|
2025-01-20 19:17:54 +00:00
|
|
|
</div>
|
|
|
|
</td>
|
|
|
|
<td>
|
2025-01-20 19:42:22 +00:00
|
|
|
<span class="agent-view-mode">
|
|
|
|
<?php if (isset($agent['check_period']) && $agent['check_period'] !== 0): ?>
|
|
|
|
<?= htmlspecialchars($agent['check_period']) ?> <?= ($agent['check_period'] == 1 ? 'minute' : 'minutes') ?>
|
|
|
|
<?php else: ?>
|
2025-01-22 15:46:08 +00:00
|
|
|
Not monitored
|
2025-01-20 19:42:22 +00:00
|
|
|
<?php endif; ?>
|
|
|
|
</span>
|
|
|
|
<div class="agent-edit-mode" style="display: none;">
|
2025-01-22 15:46:08 +00:00
|
|
|
<input type="number" class="form-control" name="check_period" value="<?= htmlspecialchars($agent['check_period']) ?>" min="0">
|
2025-01-20 19:42:22 +00:00
|
|
|
</div>
|
2025-01-20 19:17:54 +00:00
|
|
|
</td>
|
2025-01-22 15:46:08 +00:00
|
|
|
<td>
|
2025-01-20 19:42:22 +00:00
|
|
|
<div class="btn-group agent-actions" data-agent-id="<?= htmlspecialchars($agent['id']) ?>"
|
|
|
|
data-host-id="<?= htmlspecialchars($host['id']) ?>">
|
|
|
|
<button type="button" class="btn btn-outline-primary btn-sm edit-agent agent-view-mode">
|
2025-01-22 15:46:08 +00:00
|
|
|
<i class="fas fa-edit me-1"></i>Edit agent
|
2025-01-20 19:42:22 +00:00
|
|
|
</button>
|
2025-01-22 15:46:08 +00:00
|
|
|
<button type="button" class="btn btn-outline-danger btn-sm delete-agent agent-view-mode"
|
|
|
|
onclick="showDeleteAgentModal(<?= htmlspecialchars($agent['id']) ?>, '<?= htmlspecialchars($agent['agent_description']) ?>', '<?= htmlspecialchars($agent['url']) ?>')">
|
|
|
|
<i class="fas fa-trash-alt me-1"></i>Delete
|
|
|
|
</button>
|
|
|
|
<button type="button" class="btn btn-outline-success btn-sm save-agent agent-edit-mode" style="display: none;">
|
2025-01-20 19:42:22 +00:00
|
|
|
<i class="fas fa-save me-1"></i>Save
|
|
|
|
</button>
|
|
|
|
<button type="button" class="btn btn-outline-secondary btn-sm cancel-agent-edit agent-edit-mode" style="display: none;">
|
|
|
|
<i class="fas fa-times me-1"></i>Cancel
|
|
|
|
</button>
|
2025-01-20 19:17:54 +00:00
|
|
|
</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; ?>
|
2024-10-30 14:54:09 +00:00
|
|
|
</div>
|
|
|
|
</div>
|
2025-01-20 19:17:54 +00:00
|
|
|
<?php endforeach; ?>
|
|
|
|
</div>
|
|
|
|
<?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.
|
2024-10-30 14:54:09 +00:00
|
|
|
</div>
|
2025-01-20 19:17:54 +00:00
|
|
|
<?php endif; ?>
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
|
2025-01-21 14:57:28 +00:00
|
|
|
<!-- Add platform modal -->
|
|
|
|
<div class="modal" id="addPlatformModal" tabindex="-1" role="dialog">
|
|
|
|
<div class="modal-dialog" role="document">
|
|
|
|
<div class="modal-content">
|
|
|
|
<div class="modal-header">
|
|
|
|
<h5 class="modal-title" id="addPlatformModalLabel">Add new Jitsi platform</h5>
|
|
|
|
<button type="button" class="btn-close" data-dismiss="modal" aria-label="Close"></button>
|
|
|
|
</div>
|
|
|
|
<form method="POST" action="<?= htmlspecialchars($app_root) ?>?page=config" id="addPlatformForm">
|
|
|
|
<input type="hidden" name="item" value="platform">
|
|
|
|
<div class="modal-body">
|
|
|
|
<div class="mb-3">
|
|
|
|
<label for="platformName" class="form-label">Platform name <span class="text-danger">*</span></label>
|
|
|
|
<input type="text" class="form-control" id="platformName" name="name" required>
|
|
|
|
<small class="form-text text-muted">Descriptive name for the platform</small>
|
|
|
|
</div>
|
|
|
|
<div class="mb-3">
|
|
|
|
<label for="platformJitsiUrl" class="form-label">Jitsi URL <span class="text-danger">*</span></label>
|
|
|
|
<input type="url" class="form-control" id="platformJitsiUrl" name="jitsi_url" value="https://" required>
|
|
|
|
<small class="form-text text-muted">URL of the Jitsi Meet (used for checks and for loading config.js)</small>
|
|
|
|
</div>
|
|
|
|
<div class="mb-3">
|
|
|
|
<label for="platformDatabase" class="form-label">Jilo database <span class="text-danger">*</span></label>
|
|
|
|
<input type="text" class="form-control" id="platformDatabase" name="jilo_database" required>
|
|
|
|
<small class="form-text text-muted">Path to Jilo database file</small>
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
<div class="modal-footer">
|
|
|
|
<button type="button" class="btn btn-secondary" data-dismiss="modal">Cancel</button>
|
|
|
|
<button type="submit" class="btn btn-primary">Add platform</button>
|
|
|
|
</div>
|
|
|
|
</form>
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
|
|
|
|
<!-- Add host modal -->
|
|
|
|
<div class="modal" id="addHostModal" tabindex="-1" role="dialog">
|
|
|
|
<div class="modal-dialog" role="document">
|
|
|
|
<div class="modal-content">
|
|
|
|
<div class="modal-header">
|
|
|
|
<h5 class="modal-title" id="addHostModalLabel">Add new host</h5>
|
|
|
|
<button type="button" class="btn-close" data-dismiss="modal" aria-label="Close"></button>
|
|
|
|
</div>
|
|
|
|
<form method="POST" action="<?= htmlspecialchars($app_root) ?>?page=config" id="addHostForm">
|
|
|
|
<input type="hidden" name="item" value="host">
|
|
|
|
<input type="hidden" name="platform" id="hostPlatformId">
|
|
|
|
<div class="modal-body">
|
|
|
|
<div class="mb-3">
|
|
|
|
<label for="hostAddress" class="form-label">Address <span class="text-danger">*</span></label>
|
|
|
|
<input type="text" class="form-control" id="hostAddress" name="address" required>
|
|
|
|
<small class="form-text text-muted">DNS name or IP address of the machine</small>
|
|
|
|
</div>
|
|
|
|
<div class="mb-3">
|
|
|
|
<label for="hostName" class="form-label">Name</label>
|
|
|
|
<input type="text" class="form-control" id="hostName" name="name">
|
|
|
|
<small class="form-text text-muted">Description or name of the host (optional)</small>
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
<div class="modal-footer">
|
|
|
|
<button type="button" class="btn btn-secondary" data-dismiss="modal">Cancel</button>
|
|
|
|
<button type="submit" class="btn btn-primary">Add host</button>
|
|
|
|
</div>
|
|
|
|
</form>
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
|
|
|
|
<!-- Add agent modal -->
|
|
|
|
<div class="modal" id="addAgentModal" tabindex="-1" role="dialog">
|
|
|
|
<div class="modal-dialog" role="document">
|
|
|
|
<div class="modal-content">
|
|
|
|
<div class="modal-header">
|
|
|
|
<h5 class="modal-title" id="addAgentModalLabel">Add new Jilo agent</h5>
|
|
|
|
<button type="button" class="btn-close" data-dismiss="modal" aria-label="Close"></button>
|
|
|
|
</div>
|
|
|
|
<form method="POST" action="<?= htmlspecialchars($app_root) ?>?page=config" id="addAgentForm">
|
|
|
|
<input type="hidden" name="item" value="agent">
|
|
|
|
<input type="hidden" name="platform" id="agentPlatformId">
|
|
|
|
<input type="hidden" name="host" id="agentHostId">
|
|
|
|
<input type="hidden" name="new" value="true">
|
|
|
|
<div class="modal-body">
|
|
|
|
<div class="mb-3">
|
|
|
|
<label for="agentType" class="form-label">Agent type <span class="text-danger">*</span></label>
|
|
|
|
<select class="form-select form-control" id="agentType" name="type" required>
|
|
|
|
<option value="">Select agent type</option>
|
|
|
|
<?php foreach ($jilo_agent_types as $type): ?>
|
|
|
|
<option value="<?= htmlspecialchars($type['id']) ?>"><?= htmlspecialchars($type['description']) ?></option>
|
|
|
|
<?php endforeach; ?>
|
|
|
|
</select>
|
|
|
|
</div>
|
|
|
|
<div class="mb-3">
|
|
|
|
<label for="agentUrl" class="form-label">URL <span class="text-danger">*</span></label>
|
|
|
|
<input type="text" class="form-control" id="agentUrl" name="url" required>
|
|
|
|
</div>
|
|
|
|
<div class="mb-3">
|
|
|
|
<label for="agentSecretKey" class="form-label">Secret key <span class="text-danger">*</span></label>
|
|
|
|
<input type="text" class="form-control" id="agentSecretKey" name="secret_key" required>
|
|
|
|
</div>
|
|
|
|
<div class="mb-3">
|
|
|
|
<label for="agentCheckPeriod" class="form-label">Check period (minutes) <span class="text-danger">*</span></label>
|
|
|
|
<input type="number" class="form-control" id="agentCheckPeriod" name="check_period" min="1" required>
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
<div class="modal-footer">
|
|
|
|
<button type="button" class="btn btn-secondary" data-dismiss="modal">Cancel</button>
|
|
|
|
<button type="submit" class="btn btn-primary">Add agent</button>
|
|
|
|
</div>
|
|
|
|
</form>
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
|
|
|
|
<!-- Delete platform modal -->
|
|
|
|
<div class="modal fade" id="deletePlatformModal" tabindex="-1" role="dialog" aria-labelledby="deletePlatformModalLabel" aria-hidden="true">
|
|
|
|
<div class="modal-dialog" role="document">
|
|
|
|
<div class="modal-content">
|
|
|
|
<div class="modal-header">
|
|
|
|
<h5 class="modal-title" id="deletePlatformModalLabel">Delete platform</h5>
|
|
|
|
<button type="button" class="btn-close" data-dismiss="modal" aria-label="Close"></button>
|
|
|
|
</div>
|
|
|
|
<form method="POST" action="<?= htmlspecialchars($app_root) ?>?page=config" id="deletePlatformForm">
|
|
|
|
<input type="hidden" name="item" value="platform">
|
|
|
|
<input type="hidden" name="platform" id="deletePlatformId">
|
|
|
|
<input type="hidden" name="delete" value="true">
|
|
|
|
<div class="modal-body">
|
|
|
|
<div class="alert alert-danger">
|
|
|
|
<h6>Are you sure you want to delete this platform?</h6>
|
|
|
|
<div id="deletePlatformWarning"></div>
|
|
|
|
</div>
|
|
|
|
<div class="mb-3">
|
|
|
|
<label class="form-label">Platform name</label>
|
|
|
|
<div id="deletePlatformName" class="form-control-plaintext"></div>
|
|
|
|
</div>
|
|
|
|
<div class="mb-3">
|
|
|
|
<label class="form-label">Jitsi URL</label>
|
|
|
|
<div id="deletePlatformUrl" class="form-control-plaintext"></div>
|
|
|
|
</div>
|
|
|
|
<div class="mb-3">
|
|
|
|
<label class="form-label">Database</label>
|
|
|
|
<div id="deletePlatformDatabase" class="form-control-plaintext"></div>
|
|
|
|
</div>
|
|
|
|
<div class="mb-3">
|
|
|
|
<label class="form-label">Type 'delete' to confirm</label>
|
|
|
|
<input type="text" class="form-control" id="deletePlatformConfirm" placeholder="delete">
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
<div class="modal-footer">
|
|
|
|
<button type="button" class="btn btn-secondary" data-dismiss="modal">Cancel</button>
|
|
|
|
<button type="submit" class="btn btn-danger" id="deletePlatformButton" disabled>Delete platform</button>
|
|
|
|
</div>
|
|
|
|
</form>
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
|
|
|
|
<!-- Delete host modal -->
|
|
|
|
<div class="modal fade" id="deleteHostModal" tabindex="-1" role="dialog" aria-labelledby="deleteHostModalLabel" aria-hidden="true">
|
|
|
|
<div class="modal-dialog" role="document">
|
|
|
|
<div class="modal-content">
|
|
|
|
<div class="modal-header">
|
|
|
|
<h5 class="modal-title" id="deleteHostModalLabel">Delete host</h5>
|
|
|
|
<button type="button" class="btn-close" data-dismiss="modal" aria-label="Close"></button>
|
|
|
|
</div>
|
|
|
|
<form method="POST" action="<?= htmlspecialchars($app_root) ?>?page=config" id="deleteHostForm">
|
|
|
|
<input type="hidden" name="item" value="host">
|
|
|
|
<input type="hidden" name="platform" id="deleteHostPlatformId">
|
|
|
|
<input type="hidden" name="host" id="deleteHostId">
|
|
|
|
<input type="hidden" name="delete" value="true">
|
|
|
|
<div class="modal-body">
|
|
|
|
<div class="alert alert-danger">
|
|
|
|
<h6>Are you sure you want to delete this host?</h6>
|
|
|
|
<div id="deleteHostWarning"></div>
|
|
|
|
</div>
|
|
|
|
<div class="mb-3">
|
2025-01-22 15:46:08 +00:00
|
|
|
<label class="form-label small text-muted">Host name</label>
|
2025-01-21 14:57:28 +00:00
|
|
|
<div id="deleteHostName" class="form-control-plaintext"></div>
|
|
|
|
</div>
|
|
|
|
<div class="mb-3">
|
2025-01-22 15:46:08 +00:00
|
|
|
<label class="form-label small text-muted">Address</label>
|
2025-01-21 14:57:28 +00:00
|
|
|
<div id="deleteHostAddress" class="form-control-plaintext"></div>
|
|
|
|
</div>
|
|
|
|
<div class="mb-3">
|
|
|
|
<label class="form-label">Type 'delete' to confirm</label>
|
|
|
|
<input type="text" class="form-control" id="deleteHostConfirm" placeholder="delete">
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
<div class="modal-footer">
|
|
|
|
<button type="button" class="btn btn-secondary" data-dismiss="modal">Cancel</button>
|
|
|
|
<button type="submit" class="btn btn-danger" id="deleteHostButton" disabled>Delete host</button>
|
|
|
|
</div>
|
|
|
|
</form>
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
|
|
|
|
<!-- Delete agent modal -->
|
|
|
|
<div class="modal fade" id="deleteAgentModal" tabindex="-1" role="dialog" aria-labelledby="deleteAgentModalLabel" aria-hidden="true">
|
|
|
|
<div class="modal-dialog" role="document">
|
|
|
|
<div class="modal-content">
|
|
|
|
<div class="modal-header">
|
|
|
|
<h5 class="modal-title" id="deleteAgentModalLabel">Delete agent</h5>
|
|
|
|
<button type="button" class="btn-close" data-dismiss="modal" aria-label="Close"></button>
|
|
|
|
</div>
|
|
|
|
<form method="POST" action="<?= htmlspecialchars($app_root) ?>?page=config" id="deleteAgentForm">
|
|
|
|
<input type="hidden" name="item" value="agent">
|
|
|
|
<input type="hidden" name="platform" id="deleteAgentPlatformId">
|
|
|
|
<input type="hidden" name="host" id="deleteAgentHostId">
|
|
|
|
<input type="hidden" name="agent" id="deleteAgentId">
|
|
|
|
<input type="hidden" name="delete" value="true">
|
|
|
|
<div class="modal-body">
|
|
|
|
<div class="alert alert-danger">
|
|
|
|
<h6>Are you sure you want to delete this agent?</h6>
|
|
|
|
</div>
|
|
|
|
<div class="mb-3">
|
|
|
|
<label class="form-label">Agent type</label>
|
|
|
|
<div id="deleteAgentType" class="form-control-plaintext"></div>
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
<div class="modal-footer">
|
|
|
|
<button type="button" class="btn btn-secondary" data-dismiss="modal">Cancel</button>
|
|
|
|
<button type="submit" class="btn btn-danger">Delete agent</button>
|
|
|
|
</div>
|
|
|
|
</form>
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
|
2025-01-20 19:17:54 +00:00
|
|
|
<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}"]`);
|
2025-01-21 14:57:28 +00:00
|
|
|
|
2025-01-20 19:17:54 +00:00
|
|
|
// Show edit mode
|
|
|
|
platformTable.find('.view-mode').hide();
|
|
|
|
platformTable.find('.edit-mode').show();
|
2025-01-21 14:57:28 +00:00
|
|
|
|
2025-01-20 19:17:54 +00:00
|
|
|
// Toggle buttons
|
|
|
|
const actions = $(this).closest('.platform-actions');
|
2025-01-21 14:57:28 +00:00
|
|
|
actions.find('.platform-view-mode').hide();
|
|
|
|
actions.find('.platform-edit-mode').show();
|
2025-01-20 19:17:54 +00:00
|
|
|
});
|
|
|
|
|
2025-01-21 14:57:28 +00:00
|
|
|
// Cancel platform edit
|
2025-01-20 19:17:54 +00:00
|
|
|
$('.cancel-edit').click(function() {
|
|
|
|
const platformId = $(this).closest('.platform-actions').data('platform-id');
|
|
|
|
const platformTable = $(`.platform-details[data-platform-id="${platformId}"]`);
|
2025-01-21 14:57:28 +00:00
|
|
|
|
2025-01-20 19:17:54 +00:00
|
|
|
// Show view mode
|
|
|
|
platformTable.find('.view-mode').show();
|
|
|
|
platformTable.find('.edit-mode').hide();
|
2025-01-21 14:57:28 +00:00
|
|
|
|
2025-01-20 19:17:54 +00:00
|
|
|
// Toggle buttons
|
|
|
|
const actions = $(this).closest('.platform-actions');
|
2025-01-21 14:57:28 +00:00
|
|
|
actions.find('.platform-view-mode').show();
|
|
|
|
actions.find('.platform-edit-mode').hide();
|
2025-01-20 19:17:54 +00:00
|
|
|
});
|
|
|
|
|
|
|
|
// Save platform
|
|
|
|
$('.save-platform').click(function() {
|
|
|
|
const platformId = $(this).closest('.platform-actions').data('platform-id');
|
|
|
|
const platformTable = $(`.platform-details[data-platform-id="${platformId}"]`);
|
2025-01-21 14:57:28 +00:00
|
|
|
|
2025-01-20 19:17:54 +00:00
|
|
|
// 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());
|
|
|
|
});
|
2025-01-21 14:57:28 +00:00
|
|
|
|
2025-01-20 19:17:54 +00:00
|
|
|
// 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);
|
|
|
|
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);
|
|
|
|
}
|
|
|
|
});
|
2025-01-21 14:57:28 +00:00
|
|
|
|
2025-01-20 19:17:54 +00:00
|
|
|
// Switch back to view mode
|
|
|
|
platformTable.find('.view-mode').show();
|
|
|
|
platformTable.find('.edit-mode').hide();
|
2025-01-21 14:57:28 +00:00
|
|
|
|
2025-01-20 19:17:54 +00:00
|
|
|
// Toggle buttons
|
|
|
|
const actions = $(this).closest('.platform-actions');
|
2025-01-21 14:57:28 +00:00
|
|
|
actions.find('.platform-view-mode').show();
|
|
|
|
actions.find('.platform-edit-mode').hide();
|
2025-01-20 19:17:54 +00:00
|
|
|
|
|
|
|
// 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);
|
|
|
|
}
|
|
|
|
});
|
2025-01-21 14:57:28 +00:00
|
|
|
|
2025-01-20 19:17:54 +00:00
|
|
|
// Switch back to view mode
|
|
|
|
platformTable.find('.view-mode').show();
|
|
|
|
platformTable.find('.edit-mode').hide();
|
2025-01-21 14:57:28 +00:00
|
|
|
|
2025-01-20 19:17:54 +00:00
|
|
|
// Toggle buttons
|
|
|
|
const actions = $(this).closest('.platform-actions');
|
2025-01-21 14:57:28 +00:00
|
|
|
actions.find('.platform-view-mode').show();
|
|
|
|
actions.find('.platform-edit-mode').hide();
|
2025-01-20 19:17:54 +00:00
|
|
|
|
|
|
|
// 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;
|
|
|
|
}
|
2025-01-21 14:57:28 +00:00
|
|
|
|
2025-01-20 19:17:54 +00:00
|
|
|
const platformId = $(this).closest('.platform-actions').data('platform-id');
|
2025-01-21 14:57:28 +00:00
|
|
|
|
2025-01-20 19:17:54 +00:00
|
|
|
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 card = hostActions.closest('.card');
|
2025-01-21 14:57:28 +00:00
|
|
|
|
2025-01-20 19:17:54 +00:00
|
|
|
// Show edit mode
|
2025-01-20 19:42:22 +00:00
|
|
|
card.find('.host-view-mode:not(.btn)').hide();
|
|
|
|
card.find('.host-edit-mode').show();
|
2025-01-21 14:57:28 +00:00
|
|
|
|
2025-01-20 19:17:54 +00:00
|
|
|
// Toggle buttons
|
2025-01-20 19:42:22 +00:00
|
|
|
hostActions.find('.host-view-mode').hide();
|
|
|
|
hostActions.find('.host-edit-mode').show();
|
2025-01-20 19:17:54 +00:00
|
|
|
});
|
|
|
|
|
|
|
|
// Cancel host edit
|
|
|
|
$('.cancel-host-edit').click(function() {
|
|
|
|
const hostActions = $(this).closest('.host-actions');
|
|
|
|
const card = hostActions.closest('.card');
|
2025-01-21 14:57:28 +00:00
|
|
|
|
2025-01-20 19:17:54 +00:00
|
|
|
// Show view mode
|
2025-01-20 19:42:22 +00:00
|
|
|
card.find('.host-view-mode:not(.btn)').show();
|
|
|
|
card.find('.host-edit-mode').hide();
|
2025-01-21 14:57:28 +00:00
|
|
|
|
2025-01-20 19:17:54 +00:00
|
|
|
// Toggle buttons
|
2025-01-20 19:42:22 +00:00
|
|
|
hostActions.find('.host-view-mode').show();
|
|
|
|
hostActions.find('.host-edit-mode').hide();
|
2025-01-20 19:17:54 +00:00
|
|
|
});
|
|
|
|
|
|
|
|
// 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');
|
2025-01-21 14:57:28 +00:00
|
|
|
|
2025-01-20 19:17:54 +00:00
|
|
|
// Collect form data
|
|
|
|
const formData = new FormData();
|
2025-01-20 19:42:22 +00:00
|
|
|
formData.append('item', 'host');
|
2025-01-20 19:17:54 +00:00
|
|
|
formData.append('host', hostId);
|
|
|
|
formData.append('platform', platformId);
|
2025-01-21 14:57:28 +00:00
|
|
|
|
2025-01-20 19:42:22 +00:00
|
|
|
card.find('.host-edit-mode input').each(function() {
|
2025-01-20 19:17:54 +00:00
|
|
|
formData.append($(this).attr('name'), $(this).val());
|
|
|
|
});
|
2025-01-21 14:57:28 +00:00
|
|
|
|
2025-01-20 19:17:54 +00:00
|
|
|
// 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
|
2025-01-20 19:42:22 +00:00
|
|
|
const name = card.find('input[name="name"]').val() || '(no description)';
|
2025-01-20 19:17:54 +00:00
|
|
|
const address = card.find('input[name="address"]').val();
|
2025-01-20 19:42:22 +00:00
|
|
|
const viewContent = card.find('.host-view-mode:not(.btn)').first();
|
|
|
|
viewContent.html(
|
2025-01-20 19:17:54 +00:00
|
|
|
`<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>`
|
|
|
|
);
|
2025-01-21 14:57:28 +00:00
|
|
|
|
2025-01-20 19:17:54 +00:00
|
|
|
// Switch back to view mode
|
2025-01-20 19:42:22 +00:00
|
|
|
card.find('.host-view-mode:not(.btn)').show();
|
|
|
|
card.find('.host-edit-mode').hide();
|
2025-01-21 14:57:28 +00:00
|
|
|
|
2025-01-20 19:17:54 +00:00
|
|
|
// Toggle buttons
|
2025-01-20 19:42:22 +00:00
|
|
|
hostActions.find('.host-view-mode').show();
|
|
|
|
hostActions.find('.host-edit-mode').hide();
|
2025-01-20 19:17:54 +00:00
|
|
|
} 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
|
2025-01-20 19:42:22 +00:00
|
|
|
const name = card.find('input[name="name"]').val() || '(no description)';
|
2025-01-20 19:17:54 +00:00
|
|
|
const address = card.find('input[name="address"]').val();
|
2025-01-20 19:42:22 +00:00
|
|
|
const viewContent = card.find('.host-view-mode:not(.btn)').first();
|
|
|
|
viewContent.html(
|
2025-01-20 19:17:54 +00:00
|
|
|
`<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>`
|
|
|
|
);
|
2025-01-21 14:57:28 +00:00
|
|
|
|
2025-01-20 19:17:54 +00:00
|
|
|
// Switch back to view mode
|
2025-01-20 19:42:22 +00:00
|
|
|
card.find('.host-view-mode:not(.btn)').show();
|
|
|
|
card.find('.host-edit-mode').hide();
|
2025-01-21 14:57:28 +00:00
|
|
|
|
2025-01-20 19:17:54 +00:00
|
|
|
// Toggle buttons
|
2025-01-20 19:42:22 +00:00
|
|
|
hostActions.find('.host-view-mode').show();
|
|
|
|
hostActions.find('.host-edit-mode').hide();
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
|
|
|
// Agent editing functionality
|
|
|
|
$('.edit-agent').click(function() {
|
|
|
|
const agentActions = $(this).closest('.agent-actions');
|
|
|
|
const row = agentActions.closest('tr');
|
2025-01-21 14:57:28 +00:00
|
|
|
|
2025-01-20 19:42:22 +00:00
|
|
|
// Show edit mode
|
|
|
|
row.find('.agent-view-mode').hide();
|
|
|
|
row.find('.agent-edit-mode').show();
|
|
|
|
});
|
|
|
|
|
|
|
|
// Cancel agent edit
|
|
|
|
$('.cancel-agent-edit').click(function() {
|
|
|
|
const agentActions = $(this).closest('.agent-actions');
|
|
|
|
const row = agentActions.closest('tr');
|
2025-01-21 14:57:28 +00:00
|
|
|
|
2025-01-20 19:42:22 +00:00
|
|
|
// Show view mode
|
|
|
|
row.find('.agent-view-mode').show();
|
|
|
|
row.find('.agent-edit-mode').hide();
|
|
|
|
});
|
|
|
|
|
|
|
|
// Save agent
|
|
|
|
$('.save-agent').click(function() {
|
|
|
|
const agentActions = $(this).closest('.agent-actions');
|
|
|
|
const agentId = agentActions.data('agent-id');
|
|
|
|
const platformId = agentActions.data('platform-id');
|
|
|
|
const hostId = agentActions.data('host-id');
|
|
|
|
const row = agentActions.closest('tr');
|
2025-01-21 14:57:28 +00:00
|
|
|
|
2025-01-20 19:42:22 +00:00
|
|
|
// Collect form data
|
|
|
|
const formData = new FormData();
|
|
|
|
formData.append('item', 'agent');
|
|
|
|
formData.append('agent', agentId);
|
|
|
|
formData.append('platform', platformId);
|
|
|
|
formData.append('host', hostId);
|
2025-01-21 14:57:28 +00:00
|
|
|
|
2025-01-20 19:42:22 +00:00
|
|
|
row.find('.agent-edit-mode input, .agent-edit-mode select').each(function() {
|
|
|
|
formData.append($(this).attr('name'), $(this).val());
|
|
|
|
});
|
2025-01-21 14:57:28 +00:00
|
|
|
|
2025-01-20 19:42:22 +00:00
|
|
|
// Save via AJAX
|
|
|
|
fetch('<?= htmlspecialchars($app_root) ?>?page=config&item=agent&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 type = row.find('select[name="agent_type_id"] option:selected').text();
|
|
|
|
const url = row.find('input[name="url"]').val();
|
|
|
|
const endpoint = row.find('select[name="agent_type_id"] option:selected').data('endpoint');
|
|
|
|
const checkPeriod = row.find('input[name="check_period"]').val();
|
2025-01-21 14:57:28 +00:00
|
|
|
|
2025-01-20 19:42:22 +00:00
|
|
|
row.find('td:first-child .agent-view-mode').text(type);
|
|
|
|
row.find('td:nth-child(2) .agent-view-mode').text(url + endpoint);
|
|
|
|
row.find('td:nth-child(3) .agent-view-mode').text(
|
|
|
|
checkPeriod > 0 ?
|
|
|
|
`${checkPeriod} ${checkPeriod == 1 ? 'minute' : 'minutes'}` :
|
|
|
|
'-'
|
|
|
|
);
|
2025-01-21 14:57:28 +00:00
|
|
|
|
2025-01-20 19:42:22 +00:00
|
|
|
// Switch back to view mode
|
|
|
|
row.find('.agent-view-mode').show();
|
|
|
|
row.find('.agent-edit-mode').hide();
|
|
|
|
} else {
|
|
|
|
alert('Error saving agent: ' + (data.message || 'Unknown error'));
|
|
|
|
}
|
|
|
|
})
|
|
|
|
.catch(error => {
|
|
|
|
console.error('Error:', error);
|
|
|
|
alert('Error saving agent. Please try again.');
|
2025-01-20 19:17:54 +00:00
|
|
|
});
|
|
|
|
});
|
|
|
|
|
2025-01-22 15:46:08 +00:00
|
|
|
// Run the delete platform modal
|
2025-01-21 14:57:28 +00:00
|
|
|
function showDeletePlatformModal(platformId, name, url, database) {
|
|
|
|
document.getElementById('deletePlatformId').value = platformId;
|
|
|
|
document.getElementById('deletePlatformName').textContent = name;
|
|
|
|
document.getElementById('deletePlatformUrl').textContent = url;
|
|
|
|
document.getElementById('deletePlatformDatabase').textContent = database;
|
|
|
|
|
|
|
|
// Get hosts and agents for this platform
|
|
|
|
const platformPane = document.getElementById(`platform-${platformId}`);
|
|
|
|
if (!platformPane) {
|
|
|
|
document.getElementById('deletePlatformWarning').innerHTML = '<p class="mb-0">Error: Platform not found.</p>';
|
|
|
|
$('#deletePlatformModal').modal();
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
const hosts = platformPane.querySelectorAll('.host-details');
|
|
|
|
let warningText = '<p>This will delete the following items:</p>';
|
|
|
|
|
|
|
|
if (hosts.length > 0) {
|
|
|
|
warningText += '<ul class="mb-0">';
|
|
|
|
hosts.forEach(host => {
|
|
|
|
const hostNameEl = host.querySelector('.card-header h6');
|
|
|
|
const hostName = hostNameEl ? hostNameEl.textContent.trim() : 'Unknown host';
|
|
|
|
const agents = host.querySelectorAll('.agent-details');
|
|
|
|
warningText += `<li>Host: ${hostName}`;
|
|
|
|
|
|
|
|
if (agents.length > 0) {
|
|
|
|
warningText += '<ul>';
|
|
|
|
agents.forEach(agent => {
|
|
|
|
const agentType = agent.querySelector('td:first-child span');
|
|
|
|
const agentName = agentType ? agentType.textContent.trim() : 'Unknown agent';
|
|
|
|
warningText += `<li>Agent: ${agentName}</li>`;
|
|
|
|
});
|
|
|
|
warningText += '</ul>';
|
|
|
|
}
|
|
|
|
warningText += '</li>';
|
|
|
|
});
|
|
|
|
warningText += '</ul>';
|
|
|
|
} else {
|
|
|
|
warningText = '<p class="mb-0">This platform has no hosts or agents.</p>';
|
|
|
|
}
|
|
|
|
|
|
|
|
document.getElementById('deletePlatformWarning').innerHTML = warningText;
|
|
|
|
$('#deletePlatformModal').modal();
|
|
|
|
}
|
|
|
|
|
2025-01-22 15:46:08 +00:00
|
|
|
// run the delete host modal
|
2025-01-21 14:57:28 +00:00
|
|
|
function showDeleteHostModal(platformId, hostId, name, address) {
|
|
|
|
document.getElementById('deleteHostPlatformId').value = platformId;
|
|
|
|
document.getElementById('deleteHostId').value = hostId;
|
|
|
|
document.getElementById('deleteHostName').textContent = name || '(no description)';
|
|
|
|
document.getElementById('deleteHostAddress').textContent = address;
|
|
|
|
|
|
|
|
// Get agents for this host
|
|
|
|
const platformPane = document.getElementById(`platform-${platformId}`);
|
|
|
|
if (!platformPane) {
|
|
|
|
document.getElementById('deleteHostWarning').innerHTML = '<p class="mb-0">Error: Platform not found.</p>';
|
|
|
|
$('#deleteHostModal').modal();
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
const hostCard = platformPane.querySelector(`.host-details[data-host-id="${hostId}"]`);
|
|
|
|
let warningText = '<p>This will delete the following items:</p>';
|
|
|
|
|
|
|
|
if (hostCard) {
|
|
|
|
const agents = hostCard.querySelectorAll('.agent-details');
|
|
|
|
if (agents.length > 0) {
|
|
|
|
warningText += '<ul class="mb-0">';
|
|
|
|
agents.forEach(agent => {
|
|
|
|
const agentType = agent.querySelector('td:first-child span');
|
|
|
|
const agentName = agentType ? agentType.textContent.trim() : 'Unknown agent';
|
|
|
|
warningText += `<li>Agent: ${agentName}</li>`;
|
|
|
|
});
|
|
|
|
warningText += '</ul>';
|
|
|
|
} else {
|
|
|
|
warningText = '<p class="mb-0">This host has no agents.</p>';
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
warningText = '<p class="mb-0">Error: Host not found.</p>';
|
|
|
|
}
|
|
|
|
|
|
|
|
document.getElementById('deleteHostWarning').innerHTML = warningText;
|
|
|
|
$('#deleteHostModal').modal();
|
|
|
|
}
|
|
|
|
|
2025-01-22 15:46:08 +00:00
|
|
|
// Run the delete agent modal
|
2025-01-21 14:57:28 +00:00
|
|
|
function showDeleteAgentModal(platformId, hostId, agentId, type) {
|
|
|
|
document.getElementById('deleteAgentPlatformId').value = platformId;
|
|
|
|
document.getElementById('deleteAgentHostId').value = hostId;
|
|
|
|
document.getElementById('deleteAgentId').value = agentId;
|
|
|
|
document.getElementById('deleteAgentType').textContent = type;
|
|
|
|
$('#deleteAgentModal').modal();
|
|
|
|
}
|
|
|
|
|
|
|
|
// Handle confirmation inputs
|
|
|
|
$('#deletePlatformConfirm').on('input', function() {
|
|
|
|
document.getElementById('deletePlatformButton').disabled = this.value !== 'delete';
|
|
|
|
});
|
|
|
|
|
|
|
|
$('#deleteHostConfirm').on('input', function() {
|
|
|
|
document.getElementById('deleteHostButton').disabled = this.value !== 'delete';
|
|
|
|
});
|
|
|
|
|
|
|
|
// Reset confirmation on modal close
|
|
|
|
$('#deletePlatformModal').on('hidden.bs.modal', function() {
|
|
|
|
document.getElementById('deletePlatformConfirm').value = '';
|
|
|
|
document.getElementById('deletePlatformButton').disabled = true;
|
|
|
|
});
|
|
|
|
|
|
|
|
$('#deleteHostModal').on('hidden.bs.modal', function() {
|
|
|
|
document.getElementById('deleteHostConfirm').value = '';
|
|
|
|
document.getElementById('deleteHostButton').disabled = true;
|
|
|
|
});
|
|
|
|
|
|
|
|
// Make functions globally available
|
|
|
|
window.showDeletePlatformModal = showDeletePlatformModal;
|
|
|
|
window.showDeleteHostModal = showDeleteHostModal;
|
|
|
|
window.showDeleteAgentModal = showDeleteAgentModal;
|
|
|
|
|
2025-01-20 19:17:54 +00:00
|
|
|
// Initialize tooltips
|
|
|
|
$('[data-toggle="tooltip"]').tooltip();
|
|
|
|
});
|
2025-01-21 14:57:28 +00:00
|
|
|
|
2025-01-22 15:46:08 +00:00
|
|
|
// Show add platform modal
|
2025-01-21 14:57:28 +00:00
|
|
|
function showAddPlatformModal() {
|
|
|
|
$('#addPlatformModal').modal('show');
|
|
|
|
}
|
|
|
|
|
2025-01-22 15:46:08 +00:00
|
|
|
// Show add host modal
|
2025-01-21 14:57:28 +00:00
|
|
|
function showAddHostModal(platformId) {
|
|
|
|
document.getElementById('hostPlatformId').value = platformId;
|
|
|
|
document.getElementById('addHostModalLabel').textContent = 'Add new host to platform #' + platformId;
|
|
|
|
$('#addHostModal').modal('show');
|
|
|
|
}
|
|
|
|
|
2025-01-22 15:46:08 +00:00
|
|
|
// Show add agent modal
|
|
|
|
function showAddAgentModal(hostId) {
|
2025-01-21 14:57:28 +00:00
|
|
|
document.getElementById('agentHostId').value = hostId;
|
|
|
|
document.getElementById('addAgentModalLabel').textContent = 'Add new agent to host #' + hostId;
|
|
|
|
|
|
|
|
// Filter agent types that are not yet in this host
|
|
|
|
const existingTypes = Array.from(document.querySelectorAll(`[data-host-id="${hostId}"] [data-agent-type-id]`))
|
|
|
|
.map(el => el.dataset.agentTypeId);
|
|
|
|
|
|
|
|
const agentTypeSelect = document.getElementById('agentType');
|
|
|
|
Array.from(agentTypeSelect.options).forEach(option => {
|
|
|
|
if (option.value && existingTypes.includes(option.value)) {
|
|
|
|
option.disabled = true;
|
|
|
|
} else {
|
|
|
|
option.disabled = false;
|
|
|
|
}
|
|
|
|
});
|
|
|
|
|
|
|
|
$('#addAgentModal').modal('show');
|
|
|
|
}
|
|
|
|
|
|
|
|
// Remove the old platform button creation since we have it in the HTML now
|
|
|
|
document.addEventListener('DOMContentLoaded', function() {
|
|
|
|
// Add Host buttons for each platform
|
|
|
|
document.querySelectorAll('.platform-card').forEach(card => {
|
|
|
|
const platformId = card.dataset.platformId;
|
|
|
|
const addHostBtn = document.createElement('button');
|
|
|
|
addHostBtn.className = 'btn btn-outline-primary btn-sm ms-2';
|
|
|
|
addHostBtn.innerHTML = '<i class="fas fa-plus me-1"></i>Add host';
|
|
|
|
addHostBtn.onclick = () => showAddHostModal(platformId);
|
|
|
|
card.querySelector('.card-header').appendChild(addHostBtn);
|
|
|
|
});
|
|
|
|
|
|
|
|
// Add Agent buttons for each host
|
|
|
|
document.querySelectorAll('.host-card').forEach(card => {
|
|
|
|
const hostId = card.dataset.hostId;
|
|
|
|
const addAgentBtn = document.createElement('button');
|
|
|
|
addAgentBtn.className = 'btn btn-outline-primary btn-sm ms-2';
|
|
|
|
addAgentBtn.innerHTML = '<i class="fas fa-plus me-1"></i>Add agent';
|
2025-01-22 15:46:08 +00:00
|
|
|
addAgentBtn.onclick = () => showAddAgentModal(hostId);
|
2025-01-21 14:57:28 +00:00
|
|
|
card.querySelector('.card-header').appendChild(addAgentBtn);
|
|
|
|
});
|
|
|
|
});
|
2025-01-20 19:17:54 +00:00
|
|
|
</script>
|
2025-01-21 14:57:28 +00:00
|
|
|
|
2025-01-20 19:17:54 +00:00
|
|
|
<!-- "jilo configuration" -->
|