Compare commits
15 Commits
Author | SHA1 | Date |
---|---|---|
Yasen Pramatarov | d45ba62805 | |
Yasen Pramatarov | 5321942da8 | |
Yasen Pramatarov | 405f58124d | |
Yasen Pramatarov | 1e4ebae652 | |
Yasen Pramatarov | e932e4899c | |
Yasen Pramatarov | 7c8335d3e7 | |
Yasen Pramatarov | 81287a2c95 | |
Yasen Pramatarov | 9c3964da20 | |
Yasen Pramatarov | 3c9cce2c8b | |
Yasen Pramatarov | 35020a0108 | |
Yasen Pramatarov | e85292b58f | |
Yasen Pramatarov | 9fd2af6538 | |
Yasen Pramatarov | 949ce27f63 | |
Yasen Pramatarov | 81b66db3c6 | |
Yasen Pramatarov | b2fcaf6793 |
16
CHANGELOG.md
16
CHANGELOG.md
|
@ -4,6 +4,22 @@ All notable changes to this project will be documented in this file.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
## Unreleased
|
||||||
|
|
||||||
|
#### Links
|
||||||
|
- upstream: https://code.lindeas.com/lindeas/jilo-web/compare/v0.3...HEAD
|
||||||
|
- codeberg: https://codeberg.org/lindeas/jilo-web/compare/v0.3...HEAD
|
||||||
|
- github: https://github.com/lindeas/jilo-web/compare/v0.3...HEAD
|
||||||
|
- gitlab: https://gitlab.com/lindeas/jilo-web/-/compare/v0.3...HEAD
|
||||||
|
|
||||||
|
### Added
|
||||||
|
|
||||||
|
### Changed
|
||||||
|
|
||||||
|
### Fixed
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
## 0.3 - 2025-01-15
|
## 0.3 - 2025-01-15
|
||||||
|
|
||||||
#### Links
|
#### Links
|
||||||
|
|
|
@ -34,7 +34,6 @@ class Host {
|
||||||
$sql = 'SELECT
|
$sql = 'SELECT
|
||||||
id,
|
id,
|
||||||
address,
|
address,
|
||||||
port,
|
|
||||||
platform_id,
|
platform_id,
|
||||||
name
|
name
|
||||||
FROM
|
FROM
|
||||||
|
@ -73,14 +72,13 @@ class Host {
|
||||||
public function addHost($newHost) {
|
public function addHost($newHost) {
|
||||||
try {
|
try {
|
||||||
$sql = 'INSERT INTO hosts
|
$sql = 'INSERT INTO hosts
|
||||||
(address, port, platform_id, name)
|
(address, platform_id, name)
|
||||||
VALUES
|
VALUES
|
||||||
(:address, :port, :platform_id, :name)';
|
(:address, :platform_id, :name)';
|
||||||
|
|
||||||
$query = $this->db->prepare($sql);
|
$query = $this->db->prepare($sql);
|
||||||
$query->execute([
|
$query->execute([
|
||||||
':address' => $newHost['address'],
|
':address' => $newHost['address'],
|
||||||
':port' => $newHost['port'],
|
|
||||||
':platform_id' => $newHost['platform_id'],
|
':platform_id' => $newHost['platform_id'],
|
||||||
':name' => $newHost['name'],
|
':name' => $newHost['name'],
|
||||||
]);
|
]);
|
||||||
|
@ -99,25 +97,28 @@ class Host {
|
||||||
* @param string $platform_id The platform ID to which the host belongs.
|
* @param string $platform_id The platform ID to which the host belongs.
|
||||||
* @param array $updatedHost An associative array containing the updated details of the host.
|
* @param array $updatedHost An associative array containing the updated details of the host.
|
||||||
*
|
*
|
||||||
* @return bool True if the host was updated successfully, otherwise false.
|
* @return bool|string True if the host was updated successfully, otherwise error message.
|
||||||
*/
|
*/
|
||||||
public function editHost($platform_id, $updatedHost) {
|
public function editHost($platform_id, $updatedHost) {
|
||||||
try {
|
try {
|
||||||
$sql = 'UPDATE hosts SET
|
$sql = 'UPDATE hosts SET
|
||||||
address = :address,
|
address = :address,
|
||||||
port = :port,
|
|
||||||
name = :name
|
name = :name
|
||||||
WHERE
|
WHERE
|
||||||
id = :id';
|
id = :id AND platform_id = :platform_id';
|
||||||
|
|
||||||
$query = $this->db->prepare($sql);
|
$query = $this->db->prepare($sql);
|
||||||
$query->execute([
|
$query->execute([
|
||||||
':id' => $updatedHost['id'],
|
':id' => $updatedHost['id'],
|
||||||
':address' => $updatedHost['address'],
|
':platform_id' => $platform_id,
|
||||||
':port' => $updatedHost['port'],
|
':address' => $updatedHost['address'],
|
||||||
':name' => $updatedHost['name'],
|
':name' => $updatedHost['name']
|
||||||
]);
|
]);
|
||||||
|
|
||||||
|
if ($query->rowCount() === 0) {
|
||||||
|
return "No host found with ID {$updatedHost['id']} in platform $platform_id";
|
||||||
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
} catch (Exception $e) {
|
} catch (Exception $e) {
|
||||||
|
|
|
@ -21,7 +21,6 @@ class Log {
|
||||||
$this->db = $database->getConnection();
|
$this->db = $database->getConnection();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Insert a log event into the database.
|
* Insert a log event into the database.
|
||||||
*
|
*
|
||||||
|
@ -40,9 +39,9 @@ class Log {
|
||||||
|
|
||||||
$query = $this->db->prepare($sql);
|
$query = $this->db->prepare($sql);
|
||||||
$query->execute([
|
$query->execute([
|
||||||
':user_id' => $user_id,
|
':user_id' => $user_id,
|
||||||
':scope' => $scope,
|
':scope' => $scope,
|
||||||
':message' => $message,
|
':message' => $message,
|
||||||
]);
|
]);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
@ -52,7 +51,6 @@ class Log {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Retrieve log entries from the database.
|
* Retrieve log entries from the database.
|
||||||
*
|
*
|
||||||
|
@ -60,36 +58,67 @@ class Log {
|
||||||
* @param string $scope The scope of the logs ('user' or 'system').
|
* @param string $scope The scope of the logs ('user' or 'system').
|
||||||
* @param int $offset The offset for pagination. Default is 0.
|
* @param int $offset The offset for pagination. Default is 0.
|
||||||
* @param int $items_per_page The number of log entries to retrieve per page. Default is no limit.
|
* @param int $items_per_page The number of log entries to retrieve per page. Default is no limit.
|
||||||
|
* @param array $filters Optional array of filters (from_time, until_time, message, id)
|
||||||
*
|
*
|
||||||
* @return array An array of log entries.
|
* @return array An array of log entries.
|
||||||
*/
|
*/
|
||||||
public function readLog($user_id, $scope, $offset=0, $items_per_page='') {
|
public function readLog($user_id, $scope, $offset=0, $items_per_page='', $filters=[]) {
|
||||||
|
$params = [];
|
||||||
|
$where_clauses = [];
|
||||||
|
|
||||||
|
// Base query with user join
|
||||||
|
$base_sql = 'SELECT l.*, u.username
|
||||||
|
FROM logs l
|
||||||
|
LEFT JOIN users u ON l.user_id = u.id';
|
||||||
|
|
||||||
|
// Add scope condition
|
||||||
if ($scope === 'user') {
|
if ($scope === 'user') {
|
||||||
$sql = 'SELECT * FROM logs WHERE user_id = :user_id ORDER BY time DESC';
|
$where_clauses[] = 'l.user_id = :user_id';
|
||||||
if ($items_per_page) {
|
$params[':user_id'] = $user_id;
|
||||||
$items_per_page = (int)$items_per_page;
|
|
||||||
$sql .= ' LIMIT ' . $offset . ',' . $items_per_page;
|
|
||||||
}
|
|
||||||
|
|
||||||
$query = $this->db->prepare($sql);
|
|
||||||
$query->execute([
|
|
||||||
':user_id' => $user_id,
|
|
||||||
]);
|
|
||||||
}
|
}
|
||||||
if ($scope === 'system') {
|
|
||||||
$sql = 'SELECT * FROM logs ORDER BY time DESC';
|
|
||||||
if ($items_per_page) {
|
|
||||||
$items_per_page = (int)$items_per_page;
|
|
||||||
$sql .= ' LIMIT ' . $offset . ',' . $items_per_page;
|
|
||||||
}
|
|
||||||
|
|
||||||
$query = $this->db->prepare($sql);
|
// Add time range filters if specified
|
||||||
$query->execute();
|
if (!empty($filters['from_time'])) {
|
||||||
|
$where_clauses[] = 'l.time >= :from_time';
|
||||||
|
$params[':from_time'] = $filters['from_time'] . ' 00:00:00';
|
||||||
}
|
}
|
||||||
|
if (!empty($filters['until_time'])) {
|
||||||
|
$where_clauses[] = 'l.time <= :until_time';
|
||||||
|
$params[':until_time'] = $filters['until_time'] . ' 23:59:59';
|
||||||
|
}
|
||||||
|
|
||||||
|
// Add message search if specified
|
||||||
|
if (!empty($filters['message'])) {
|
||||||
|
$where_clauses[] = 'l.message LIKE :message';
|
||||||
|
$params[':message'] = '%' . $filters['message'] . '%';
|
||||||
|
}
|
||||||
|
|
||||||
|
// Add user ID search if specified
|
||||||
|
if (!empty($filters['id'])) {
|
||||||
|
$where_clauses[] = 'l.user_id = :search_user_id';
|
||||||
|
$params[':search_user_id'] = $filters['id'];
|
||||||
|
}
|
||||||
|
|
||||||
|
// Combine WHERE clauses
|
||||||
|
$sql = $base_sql;
|
||||||
|
if (!empty($where_clauses)) {
|
||||||
|
$sql .= ' WHERE ' . implode(' AND ', $where_clauses);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Add ordering
|
||||||
|
$sql .= ' ORDER BY l.time DESC';
|
||||||
|
|
||||||
|
// Add pagination
|
||||||
|
if ($items_per_page) {
|
||||||
|
$items_per_page = (int)$items_per_page;
|
||||||
|
$sql .= ' LIMIT ' . $offset . ',' . $items_per_page;
|
||||||
|
}
|
||||||
|
|
||||||
|
$query = $this->db->prepare($sql);
|
||||||
|
$query->execute($params);
|
||||||
|
|
||||||
return $query->fetchAll(PDO::FETCH_ASSOC);
|
return $query->fetchAll(PDO::FETCH_ASSOC);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
?>
|
?>
|
||||||
|
|
|
@ -115,51 +115,122 @@ 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
|
||||||
} elseif (isset($_POST['agent'])) {
|
} elseif (isset($_POST['item']) && $_POST['item'] === 'agent') {
|
||||||
|
$agent_id = $_POST['agent'];
|
||||||
|
$platform_id = $_POST['platform'];
|
||||||
$updatedAgent = [
|
$updatedAgent = [
|
||||||
'id' => $agent,
|
'id' => $agent_id,
|
||||||
'agent_type_id' => $type,
|
'agent_type_id' => $_POST['agent_type_id'],
|
||||||
'url' => $url,
|
'url' => $_POST['url'],
|
||||||
'secret_key' => $secret_key,
|
'secret_key' => $_POST['secret_key'],
|
||||||
'check_period' => $check_period,
|
'check_period' => $_POST['check_period']
|
||||||
];
|
];
|
||||||
$result = $agentObject->editAgent($platform_id, $updatedAgent);
|
$result = $agentObject->editAgent($platform_id, $updatedAgent);
|
||||||
if ($result === true) {
|
|
||||||
$_SESSION['notice'] = "Agent id \"{$_REQUEST['agent']}\" 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 agent failed. Error: $result"
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
exit();
|
||||||
} else {
|
} else {
|
||||||
$_SESSION['error'] = "Editing the agent failed. Error: $result";
|
// Regular form submission
|
||||||
|
if ($result === true) {
|
||||||
|
$_SESSION['notice'] = "Agent edited.";
|
||||||
|
} else {
|
||||||
|
$_SESSION['error'] = "Editing the agent failed. Error: $result";
|
||||||
|
}
|
||||||
|
header("Location: $app_root?page=config&item=$item");
|
||||||
|
exit();
|
||||||
}
|
}
|
||||||
|
|
||||||
// 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
|
||||||
|
@ -209,30 +280,39 @@ if ($_SERVER['REQUEST_METHOD'] == 'POST') {
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'endpoint':
|
case 'agent':
|
||||||
// TODO ad here endpoints options
|
if (isset($action) && $action === 'add') {
|
||||||
echo 'under construction';
|
$jilo_agent_types = $agentObject->getAgentTypes();
|
||||||
// switch ($action) {
|
$platform_id = $_REQUEST['platform'] ?? '';
|
||||||
// case 'add-agent':
|
if (!empty($platform_id)) {
|
||||||
// $jilo_agent_types = $agentObject->getAgentTypes();
|
$jilo_agents_in_platform = $agentObject->getPlatformAgentTypes($platform_id);
|
||||||
// $jilo_agents_in_platform = $agentObject->getPlatformAgentTypes($platform_id);
|
$jilo_agent_types_in_platform = array_column($jilo_agents_in_platform, 'agent_type_id');
|
||||||
// $jilo_agent_types_in_platform = array_column($jilo_agents_in_platform, 'agent_type_id');
|
include '../app/templates/config-agent-add.php';
|
||||||
// include '../app/templates/config-add-agent.php';
|
} else {
|
||||||
// break;
|
$_SESSION['error'] = "Platform ID is required to add an agent.";
|
||||||
// case 'edit':
|
header("Location: $app_root?page=config&item=agent");
|
||||||
// if (isset($_GET['agent'])) {
|
exit();
|
||||||
// $agentDetails = $agentObject->getAgentDetails($platform_id, $agent);
|
}
|
||||||
// $jilo_agent_types = $agentObject->getAgentTypes();
|
} elseif (isset($action) && $action === 'edit') {
|
||||||
// include '../app/templates/config-edit-agent.php';
|
if (isset($_REQUEST['agent'])) {
|
||||||
// }
|
$platform_id = $_REQUEST['platform'] ?? '';
|
||||||
// break;
|
$agentDetails = $agentObject->getAgentDetails($platform_id, $agent)['0'];
|
||||||
// case 'delete':
|
$jilo_agent_types = $agentObject->getAgentTypes();
|
||||||
// if (isset($_GET['agent'])) {
|
include '../app/templates/config-agent-edit.php';
|
||||||
// $agentDetails = $agentObject->getAgentDetails($platform_id, $agent);
|
}
|
||||||
// include '../app/templates/config-delete-agent.php';
|
} elseif (isset($action) && $action === 'delete') {
|
||||||
// }
|
if (isset($_REQUEST['agent'])) {
|
||||||
// break;
|
$platform_id = $_REQUEST['platform'] ?? '';
|
||||||
// }
|
$agentDetails = $agentObject->getAgentDetails($platform_id, $agent)['0'];
|
||||||
|
include '../app/templates/config-agent-delete.php';
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if ($userObject->hasRight($user_id, 'view config file')) {
|
||||||
|
include '../app/templates/config-agent.php';
|
||||||
|
} else {
|
||||||
|
include '../app/templates/error-unauthorized.php';
|
||||||
|
}
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'config_file':
|
case 'config_file':
|
||||||
|
|
|
@ -12,49 +12,89 @@ include '../app/includes/messages.php';
|
||||||
include '../app/includes/messages-show.php';
|
include '../app/includes/messages-show.php';
|
||||||
|
|
||||||
// Check for rights; user or system
|
// Check for rights; user or system
|
||||||
if (($userObject->hasRight($user_id, 'superuser') ||
|
$has_system_access = ($userObject->hasRight($user_id, 'superuser') ||
|
||||||
$userObject->hasRight($user_id, 'view app logs'))) {
|
$userObject->hasRight($user_id, 'view app logs'));
|
||||||
$scope = 'system';
|
|
||||||
} else {
|
// Get current page for pagination
|
||||||
$scope = 'user';
|
$currentPage = $_REQUEST['page_num'] ?? 1;
|
||||||
|
$currentPage = (int)$currentPage;
|
||||||
|
|
||||||
|
// Get selected tab
|
||||||
|
$selected_tab = $_REQUEST['tab'] ?? 'user';
|
||||||
|
if ($selected_tab === 'system' && !$has_system_access) {
|
||||||
|
$selected_tab = 'user';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Set scope based on selected tab
|
||||||
|
$scope = ($selected_tab === 'system') ? 'system' : 'user';
|
||||||
|
|
||||||
// specify time range
|
// specify time range
|
||||||
include '../app/helpers/time_range.php';
|
include '../app/helpers/time_range.php';
|
||||||
|
|
||||||
|
// Prepare search filters
|
||||||
|
$filters = [];
|
||||||
|
if (isset($_REQUEST['from_time']) && !empty($_REQUEST['from_time'])) {
|
||||||
|
$filters['from_time'] = $_REQUEST['from_time'];
|
||||||
|
}
|
||||||
|
if (isset($_REQUEST['until_time']) && !empty($_REQUEST['until_time'])) {
|
||||||
|
$filters['until_time'] = $_REQUEST['until_time'];
|
||||||
|
}
|
||||||
|
if (isset($_REQUEST['message']) && !empty($_REQUEST['message'])) {
|
||||||
|
$filters['message'] = $_REQUEST['message'];
|
||||||
|
}
|
||||||
|
if ($scope === 'system' && isset($_REQUEST['id']) && !empty($_REQUEST['id'])) {
|
||||||
|
$filters['id'] = $_REQUEST['id'];
|
||||||
|
}
|
||||||
|
|
||||||
// pagination variables
|
// pagination variables
|
||||||
$items_per_page = 15;
|
$items_per_page = 15;
|
||||||
$browse_page = $_REQUEST['p'] ?? 1;
|
$offset = ($currentPage - 1) * $items_per_page;
|
||||||
$browse_page = (int)$browse_page;
|
|
||||||
$offset = ($browse_page -1) * $items_per_page;
|
// Build params for pagination
|
||||||
|
$params = '';
|
||||||
|
if (!empty($_REQUEST['from_time'])) {
|
||||||
|
$params .= '&from_time=' . urlencode($_REQUEST['from_time']);
|
||||||
|
}
|
||||||
|
if (!empty($_REQUEST['until_time'])) {
|
||||||
|
$params .= '&until_time=' . urlencode($_REQUEST['until_time']);
|
||||||
|
}
|
||||||
|
if (!empty($_REQUEST['message'])) {
|
||||||
|
$params .= '&message=' . urlencode($_REQUEST['message']);
|
||||||
|
}
|
||||||
|
if (!empty($_REQUEST['id'])) {
|
||||||
|
$params .= '&id=' . urlencode($_REQUEST['id']);
|
||||||
|
}
|
||||||
|
if (isset($_REQUEST['tab'])) {
|
||||||
|
$params .= '&tab=' . urlencode($_REQUEST['tab']);
|
||||||
|
}
|
||||||
|
|
||||||
// prepare the result
|
// prepare the result
|
||||||
$search = $logObject->readLog($user_id, $scope, $offset, $items_per_page);
|
$search = $logObject->readLog($user_id, $scope, $offset, $items_per_page, $filters);
|
||||||
$search_all = $logObject->readLog($user_id, $scope);
|
$search_all = $logObject->readLog($user_id, $scope, '', '', $filters);
|
||||||
|
|
||||||
if (!empty($search)) {
|
if (!empty($search)) {
|
||||||
// we get total items and number of pages
|
// we get total items and number of pages
|
||||||
$item_count = count($search_all);
|
$item_count = count($search_all);
|
||||||
$page_count = ceil($item_count / $items_per_page);
|
$totalPages = ceil($item_count / $items_per_page);
|
||||||
|
|
||||||
$logs = array();
|
$logs = array();
|
||||||
$logs['records'] = array();
|
$logs['records'] = array();
|
||||||
|
|
||||||
foreach ($search as $item) {
|
foreach ($search as $item) {
|
||||||
|
|
||||||
// when we show only user's logs, omit user_id column
|
// when we show only user's logs, omit user_id column
|
||||||
if ($scope === 'user') {
|
if ($scope === 'user') {
|
||||||
$log_record = array(
|
$log_record = array(
|
||||||
// assign title to the field in the array record
|
// assign title to the field in the array record
|
||||||
'time' => $item['time'],
|
'time' => $item['time'],
|
||||||
'log message' => $item['message']
|
'log message' => $item['message']
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
$log_record = array(
|
$log_record = array(
|
||||||
// assign title to the field in the array record
|
// assign title to the field in the array record
|
||||||
'userID' => $item['user_id'],
|
'userID' => $item['user_id'],
|
||||||
'time' => $item['time'],
|
'username' => $item['username'],
|
||||||
'log message' => $item['message']
|
'time' => $item['time'],
|
||||||
|
'log message' => $item['message']
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -65,14 +105,15 @@ if (!empty($search)) {
|
||||||
|
|
||||||
// prepare the widget
|
// prepare the widget
|
||||||
$widget['full'] = false;
|
$widget['full'] = false;
|
||||||
$widget['collapsible'] = false;
|
|
||||||
$widget['name'] = 'Logs';
|
$widget['name'] = 'Logs';
|
||||||
$username = $userObject->getUserDetails($user_id)[0]['username'];
|
$username = $userObject->getUserDetails($user_id)[0]['username'];
|
||||||
$widget['title'] = "Log events for user \"$username\"";
|
$widget['title'] = "Log events";
|
||||||
$widget['filter'] = true;
|
$widget['filter'] = true;
|
||||||
|
$widget['scope'] = $scope;
|
||||||
|
$widget['has_system_access'] = $has_system_access;
|
||||||
|
|
||||||
if (!empty($logs['records'])) {
|
if (!empty($logs['records'])) {
|
||||||
$widget['full'] = true;
|
$widget['full'] = true;
|
||||||
$widget['table_headers'] = array_keys($logs['records'][0]);
|
|
||||||
$widget['table_records'] = $logs['records'];
|
$widget['table_records'] = $logs['records'];
|
||||||
}
|
}
|
||||||
$widget['pagination'] = true;
|
$widget['pagination'] = true;
|
||||||
|
|
|
@ -23,9 +23,9 @@ foreach ($platformsAll as $platform) {
|
||||||
// check if we can connect to the jilo database
|
// check if we can connect to the jilo database
|
||||||
$response = connectDB($config, 'jilo', $platform['jilo_database'], $platform['id']);
|
$response = connectDB($config, 'jilo', $platform['jilo_database'], $platform['id']);
|
||||||
if ($response['error'] !== null) {
|
if ($response['error'] !== null) {
|
||||||
$jilo_database_status = '<span class="text-danger">' . htmlspecialchars($response['error']) . '</span>';
|
$jilo_database_status = $response['error'];
|
||||||
} else {
|
} else {
|
||||||
$jilo_database_status = '<span class="text-success">OK</span>';
|
$jilo_database_status = 'OK';
|
||||||
}
|
}
|
||||||
|
|
||||||
include '../app/templates/status-platform.php';
|
include '../app/templates/status-platform.php';
|
||||||
|
@ -44,19 +44,19 @@ foreach ($platformsAll as $platform) {
|
||||||
|
|
||||||
// determine agent availability based on response data
|
// determine agent availability based on response data
|
||||||
if (json_last_error() === JSON_ERROR_NONE) {
|
if (json_last_error() === JSON_ERROR_NONE) {
|
||||||
$agent_availability = '<span class="text-warning">unknown</span>';
|
$agent_availability = 'unknown';
|
||||||
foreach ($agent_data as $key => $value) {
|
foreach ($agent_data as $key => $value) {
|
||||||
if ($key === 'error') {
|
if ($key === 'error') {
|
||||||
$agent_availability = '<span class="text-danger">' . htmlspecialchars($value) . '</span>';
|
$agent_availability = $value;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (preg_match('/_state$/', $key)) {
|
if (preg_match('/_state$/', $key)) {
|
||||||
if ($value === 'error') {
|
if ($value === 'error') {
|
||||||
$agent_availability = '<span class="text-danger">not running</span>';
|
$agent_availability = 'not running';
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if ($value === 'running') {
|
if ($value === 'running') {
|
||||||
$agent_availability = '<span class="text-success">running</span>';
|
$agent_availability = 'running';
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -67,6 +67,7 @@ foreach ($platformsAll as $platform) {
|
||||||
|
|
||||||
include '../app/templates/status-agent.php';
|
include '../app/templates/status-agent.php';
|
||||||
}
|
}
|
||||||
|
echo '</div>';
|
||||||
|
echo '</div>';
|
||||||
}
|
}
|
||||||
|
|
||||||
?>
|
?>
|
||||||
|
|
|
@ -0,0 +1,59 @@
|
||||||
|
<?php
|
||||||
|
// Get available agent types that are not yet in the platform
|
||||||
|
$available_agent_types = array_filter($jilo_agent_types, function($type) use ($jilo_agent_types_in_platform) {
|
||||||
|
return !in_array($type['id'], $jilo_agent_types_in_platform);
|
||||||
|
});
|
||||||
|
?>
|
||||||
|
|
||||||
|
<div class="card text-center w-75 mx-lef">
|
||||||
|
<p class="h4 card-header">Add new Jilo agent</p>
|
||||||
|
<div class="card-body">
|
||||||
|
<form method="post" action="<?= htmlspecialchars($app_root) ?>">
|
||||||
|
<input type="hidden" name="platform" value="<?= htmlspecialchars($platform_id) ?>">
|
||||||
|
<input type="hidden" name="item" value="agent">
|
||||||
|
<input type="hidden" name="new" value="true">
|
||||||
|
|
||||||
|
<div class="mb-3 row">
|
||||||
|
<label for="type" class="col-sm-2 col-form-label">Agent Type:</label>
|
||||||
|
<div class="col-sm-10">
|
||||||
|
<select class="form-select" id="type" name="type" required>
|
||||||
|
<option value="">Select agent type</option>
|
||||||
|
<?php foreach ($available_agent_types as $type): ?>
|
||||||
|
<option value="<?= htmlspecialchars($type['id']) ?>">
|
||||||
|
<?= htmlspecialchars($type['description']) ?>
|
||||||
|
</option>
|
||||||
|
<?php endforeach; ?>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="mb-3 row">
|
||||||
|
<label for="url" class="col-sm-2 col-form-label">URL:</label>
|
||||||
|
<div class="col-sm-10">
|
||||||
|
<input type="text" class="form-control" id="url" name="url" required>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="mb-3 row">
|
||||||
|
<label for="secret_key" class="col-sm-2 col-form-label">Secret Key:</label>
|
||||||
|
<div class="col-sm-10">
|
||||||
|
<input type="text" class="form-control" id="secret_key" name="secret_key" required>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="mb-3 row">
|
||||||
|
<label for="check_period" class="col-sm-2 col-form-label">Check Period (minutes):</label>
|
||||||
|
<div class="col-sm-10">
|
||||||
|
<input type="number" class="form-control" id="check_period" name="check_period" min="1" required>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="mb-3 row">
|
||||||
|
<div class="col-sm-10 offset-sm-2">
|
||||||
|
<button type="submit" class="btn btn-primary">Add Agent</button>
|
||||||
|
<a href="<?= htmlspecialchars($app_root) ?>?page=config&item=agent" class="btn btn-secondary">Cancel</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
</div>
|
|
@ -0,0 +1,31 @@
|
||||||
|
<?php if (!empty($agentDetails)): ?>
|
||||||
|
<div class="card text-center w-75 mx-lef">
|
||||||
|
<p class="h4 card-header">Delete Jilo agent</p>
|
||||||
|
<div class="card-body">
|
||||||
|
<p class="card-text">Are you sure you want to delete this agent?</p>
|
||||||
|
|
||||||
|
<div class="mb-3">
|
||||||
|
<strong>Agent ID:</strong> <?= htmlspecialchars($agentDetails['id']) ?><br>
|
||||||
|
<strong>Type:</strong> <?= htmlspecialchars($agentDetails['agent_description']) ?><br>
|
||||||
|
<strong>URL:</strong> <?= htmlspecialchars($agentDetails['url']) ?><br>
|
||||||
|
<strong>Check Period:</strong> <?= htmlspecialchars($agentDetails['check_period']) ?> <?= ($agentDetails['check_period'] == 1 ? 'minute' : 'minutes') ?>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<form method="post" action="<?= htmlspecialchars($app_root) ?>">
|
||||||
|
<input type="hidden" name="platform" value="<?= htmlspecialchars($platform_id) ?>">
|
||||||
|
<input type="hidden" name="agent" value="<?= htmlspecialchars($agentDetails['id']) ?>">
|
||||||
|
<input type="hidden" name="item" value="agent">
|
||||||
|
<input type="hidden" name="delete" value="true">
|
||||||
|
|
||||||
|
<div class="mb-3">
|
||||||
|
<button type="submit" class="btn btn-danger">Delete Agent</button>
|
||||||
|
<a href="<?= htmlspecialchars($app_root) ?>?page=config&item=agent" class="btn btn-secondary">Cancel</a>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<?php else: ?>
|
||||||
|
<div class="alert alert-danger">
|
||||||
|
Agent not found.
|
||||||
|
</div>
|
||||||
|
<?php endif; ?>
|
|
@ -0,0 +1,57 @@
|
||||||
|
<?php if (!empty($agentDetails)): ?>
|
||||||
|
<div class="card text-center w-75 mx-lef">
|
||||||
|
<p class="h4 card-header">Edit Jilo agent</p>
|
||||||
|
<div class="card-body">
|
||||||
|
<form method="post" action="<?= htmlspecialchars($app_root . '?page=' . $page) ?>">
|
||||||
|
<input type="hidden" name="platform" value="<?= htmlspecialchars($platform_id) ?>">
|
||||||
|
<input type="hidden" name="agent" value="<?= htmlspecialchars($agentDetails['id']) ?>">
|
||||||
|
<input type="hidden" name="item" value="agent">
|
||||||
|
|
||||||
|
<div class="mb-3 row">
|
||||||
|
<label for="type" class="col-sm-2 col-form-label">Agent Type:</label>
|
||||||
|
<div class="col-sm-10">
|
||||||
|
<select class="form-select" id="type" name="type" required>
|
||||||
|
<?php foreach ($jilo_agent_types as $type): ?>
|
||||||
|
<option value="<?= htmlspecialchars($type['id']) ?>" <?= $type['id'] == $agentDetails['agent_type_id'] ? 'selected' : '' ?>>
|
||||||
|
<?= htmlspecialchars($type['description']) ?>
|
||||||
|
</option>
|
||||||
|
<?php endforeach; ?>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="mb-3 row">
|
||||||
|
<label for="url" class="col-sm-2 col-form-label">URL:</label>
|
||||||
|
<div class="col-sm-10">
|
||||||
|
<input type="text" class="form-control" id="url" name="url" value="<?= htmlspecialchars($agentDetails['url']) ?>" required>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="mb-3 row">
|
||||||
|
<label for="secret_key" class="col-sm-2 col-form-label">Secret Key:</label>
|
||||||
|
<div class="col-sm-10">
|
||||||
|
<input type="text" class="form-control" id="secret_key" name="secret_key" value="<?= htmlspecialchars($agentDetails['secret_key']) ?>" required>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="mb-3 row">
|
||||||
|
<label for="check_period" class="col-sm-2 col-form-label">Check Period (minutes):</label>
|
||||||
|
<div class="col-sm-10">
|
||||||
|
<input type="number" class="form-control" id="check_period" name="check_period" value="<?= htmlspecialchars($agentDetails['check_period']) ?>" min="1" required>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="mb-3 row">
|
||||||
|
<div class="col-sm-10 offset-sm-2">
|
||||||
|
<button type="submit" class="btn btn-primary">Save Changes</button>
|
||||||
|
<a href="<?= htmlspecialchars($app_root) ?>?page=config&item=agent" class="btn btn-secondary">Cancel</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<?php else: ?>
|
||||||
|
<div class="alert alert-danger">
|
||||||
|
Agent not found.
|
||||||
|
</div>
|
||||||
|
<?php endif; ?>
|
|
@ -1,52 +0,0 @@
|
||||||
|
|
||||||
<!-- widget "hosts" -->
|
|
||||||
<div class="card text-center w-50 mx-lef">
|
|
||||||
<p class="h4 card-header">Jilo configuration for Jitsi platform <strong>"<?= htmlspecialchars($platformDetails[0]['name']) ?>"</strong></p>
|
|
||||||
<div class="card-body">
|
|
||||||
<p class="card-text">edit host details:</p>
|
|
||||||
<form method="POST" action="<?= htmlspecialchars($app_root) ?>?page=config&item=host">
|
|
||||||
|
|
||||||
<div class="row mb-3">
|
|
||||||
<div class="col-md-4 text-end">
|
|
||||||
<label for="address" class="form-label">address</label>
|
|
||||||
<span class="text-danger" style="margin-right: -12px;">*</span>
|
|
||||||
</div>
|
|
||||||
<div class="col-md-8">
|
|
||||||
<input class="form-control" type="text" name="address" value="<?= htmlspecialchars($hostDetails[0]['address'] ?? '') ?>" required autofocus />
|
|
||||||
<p class="text-start"><small>DNS name or IP address of the machine</small></p>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="row mb-3">
|
|
||||||
<div class="col-md-4 text-end">
|
|
||||||
<label for="port" class="form-label">port</label>
|
|
||||||
<span class="text-danger" style="margin-right: -12px;">*</span>
|
|
||||||
</div>
|
|
||||||
<div class="col-md-8">
|
|
||||||
<input class="form-control" type="text" name="port" value="<?= htmlspecialchars($hostDetails[0]['port'] ?? '') ?>" required />
|
|
||||||
<p class="text-start"><small>port on which the Jilo Agent is listening</small></p>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="row mb-3">
|
|
||||||
<div class="col-md-4 text-end">
|
|
||||||
<label for="name" class="form-label">name</label>
|
|
||||||
</div>
|
|
||||||
<div class="col-md-8">
|
|
||||||
<input class="form-control" type="text" name="name" value="<?= htmlspecialchars($hostDetails[0]['name'] ?? '') ?>" />
|
|
||||||
<p class="text-start"><small>description or name of the host (optional)</small></p>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<input type="hidden" name="platform" value="<?= htmlspecialchars($platform_id) ?>" />
|
|
||||||
<input type="hidden" name="item" value="host" />
|
|
||||||
<input type="hidden" name="host" value="<?= htmlspecialchars($hostDetails[0]['id']) ?>" />
|
|
||||||
|
|
||||||
<br />
|
|
||||||
<a class="btn btn-outline-secondary btn-sm" href="<?= htmlspecialchars($app_root) ?>?page=config&item=host&platform=<?= htmlspecialchars($platform_id) ?>&host=<?= htmlspecialchars($host) ?>#platform<?= htmlspecialchars($platform_id) ?>host<?= htmlspecialchars($host) ?>" />Cancel</a>
|
|
||||||
|
|
||||||
<input type="submit" class="btn btn-primary btn-sm" value="Save" />
|
|
||||||
</form>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<!-- /widget "hosts" -->
|
|
|
@ -1,39 +0,0 @@
|
||||||
|
|
||||||
<!-- widget "hosts" -->
|
|
||||||
<div class="card text-center w-75 mx-lef">
|
|
||||||
<p class="h4 card-header">Jilo configuration :: Jitsi Meet hosts</p>
|
|
||||||
<div class="card-body">
|
|
||||||
<p class="card-text">Jitsi hosts configuration
|
|
||||||
</p>
|
|
||||||
<?php foreach ($platformsAll as $platform_array) {
|
|
||||||
$hosts = $hostObject->getHostDetails($platform_array['id']);
|
|
||||||
?>
|
|
||||||
<a name="platform<?= htmlspecialchars($platform_array['id']) ?>"></a>
|
|
||||||
<div class="row mb-1 border <?= isset($_REQUEST['platform']) && (int)$platform_array['id'] === (int)$_REQUEST['platform'] ? 'rounded bg-light' : '' ?>" style="padding: 20px; padding-bottom: 0px;">
|
|
||||||
<p class="text-start">
|
|
||||||
platform <strong><?= htmlspecialchars($platform_array['name']) ?></strong>
|
|
||||||
</p>
|
|
||||||
<ul class="text-start" style="padding-left: 50px;">
|
|
||||||
<?php foreach ($hosts as $host_array) { ?>
|
|
||||||
<li style="padding-bottom: 10px;">
|
|
||||||
<a name="platform<?= htmlspecialchars($platform_array['id']) ?>host<?= htmlspecialchars($host_array['id']) ?>"></a>
|
|
||||||
<span class="<?= isset($_REQUEST['platform']) && (int)$platform_array['id'] === (int)$_REQUEST['platform'] && isset($_REQUEST['host']) && (int)$host_array['id'] === (int)$_REQUEST['host'] ? 'border rounded bg-light' : '' ?>" style="padding: 10px;">
|
|
||||||
<?= htmlspecialchars($host_array['address']) ?>:<?= htmlspecialchars($host_array['port']) ?>
|
|
||||||
|
|
||||||
<a class="btn btn-outline-secondary btn-sm" href="<?= htmlspecialchars($app_root) ?>?page=config&item=host&platform=<?= htmlspecialchars($host_array['platform_id']) ?>&host=<?= htmlspecialchars($host_array['id']) ?>&action=edit">edit host</a>
|
|
||||||
<a class="btn btn-outline-danger btn-sm" href="<?= htmlspecialchars($app_root) ?>?page=config&item=host&platform=<?= htmlspecialchars($host_array['platform_id']) ?>&host=<?= htmlspecialchars($host_array['id']) ?>&action=delete">delete host</a>
|
|
||||||
</span>
|
|
||||||
</li>
|
|
||||||
<?php } ?>
|
|
||||||
</ul>
|
|
||||||
<p class="text-start" style="padding-left: 50px;">
|
|
||||||
total <?= htmlspecialchars(count($hosts)) ?> jilo <?= htmlspecialchars(count($hosts)) === '1' ? 'host' : 'hosts' ?>
|
|
||||||
|
|
||||||
<a class="btn btn-outline-secondary btn-sm" href="<?= htmlspecialchars($app_root) ?>?page=config&item=host&platform=<?= htmlspecialchars($platform_array['id']) ?>&action=add">add new</a>
|
|
||||||
</p>
|
|
||||||
|
|
||||||
</div>
|
|
||||||
<?php } ?>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<!-- /widget "hosts" -->
|
|
|
@ -1,36 +0,0 @@
|
||||||
|
|
||||||
<!-- widget "platforms" -->
|
|
||||||
<div class="card text-center w-50 mx-lef">
|
|
||||||
<p class="h4 card-header">Jilo configuration for Jitsi platform <strong>"<?= htmlspecialchars($platformDetails[0]['name']) ?>"</strong> :: edit</p>
|
|
||||||
<div class="card-body">
|
|
||||||
<form method="POST" action="<?= htmlspecialchars($app_root) ?>?platform=<?= htmlspecialchars($platform_id) ?>&page=config&item=platform">
|
|
||||||
<?php
|
|
||||||
foreach ($platformDetails[0] as $key => $value) {
|
|
||||||
if ($key === 'id') continue;
|
|
||||||
?>
|
|
||||||
<div class="row mb-3">
|
|
||||||
<div class="col-md-4 text-end">
|
|
||||||
<label for="<?= htmlspecialchars($config_item) ?>" class="form-label"><?= htmlspecialchars($key) ?></label>
|
|
||||||
<span class="text-danger" style="margin-right: -12px;">*</span>
|
|
||||||
</div>
|
|
||||||
<div class="col-md-8">
|
|
||||||
<input class="form-control" type="text" name="<?= htmlspecialchars($key) ?>" value="<?= htmlspecialchars($value ?? '') ?>" required autofocus />
|
|
||||||
<?php if ($key === 'name') { ?>
|
|
||||||
<p class="text-start"><small>descriptive name for the platform</small></p>
|
|
||||||
<?php } elseif ($key === 'jitsi_url') { ?>
|
|
||||||
<p class="text-start"><small>URL of the Jitsi Meet (used for checks and for loading config.js)</small></p>
|
|
||||||
<?php } elseif ($key === 'jilo_database') { ?>
|
|
||||||
<p class="text-start"><small>path to the database file (relative to the app root)</small></p>
|
|
||||||
<?php } ?>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<?php } ?>
|
|
||||||
<br />
|
|
||||||
<input type="hidden" name="platform" value="<?= htmlspecialchars($platform_id) ?>" />
|
|
||||||
<a class="btn btn-outline-secondary btn-sm" href="<?= htmlspecialchars($app_root) ?>?page=config&item=platform&platform=<?= htmlspecialchars($platform_id) ?>#platform<?= htmlspecialchars($platform_id) ?>" />Cancel</a>
|
|
||||||
|
|
||||||
<input type="submit" class="btn btn-primary btn-sm" value="Save" />
|
|
||||||
</form>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<!-- /widget "platforms" -->
|
|
|
@ -1,60 +1,697 @@
|
||||||
|
|
||||||
<!-- 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="host-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="host-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 host-view-mode">
|
||||||
|
<i class="fas fa-edit me-1"></i>Edit host
|
||||||
|
</button>
|
||||||
|
<button type="button" class="btn btn-outline-primary btn-sm save-host host-edit-mode" 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 host-edit-mode" 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 host-view-mode">
|
||||||
|
<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>
|
||||||
|
<span class="agent-view-mode">
|
||||||
|
<?= htmlspecialchars($agent['agent_description']) ?>
|
||||||
|
</span>
|
||||||
|
<div class="agent-edit-mode" style="display: none;">
|
||||||
|
<select class="form-select form-select-sm" name="agent_type_id" required>
|
||||||
|
<?php foreach ($agentObject->getAgentTypes() as $type): ?>
|
||||||
|
<option value="<?= htmlspecialchars($type['id']) ?>"
|
||||||
|
data-endpoint="<?= htmlspecialchars($type['endpoint']) ?>"
|
||||||
|
<?= $type['id'] === $agent['agent_type_id'] ? 'selected' : '' ?>>
|
||||||
|
<?= htmlspecialchars($type['description']) ?>
|
||||||
|
</option>
|
||||||
|
<?php endforeach; ?>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</td>
|
||||||
|
<td class="text-break">
|
||||||
|
<span class="agent-view-mode">
|
||||||
|
<?= htmlspecialchars($agent['url'].$agent['agent_endpoint']) ?>
|
||||||
|
</span>
|
||||||
|
<div class="agent-edit-mode" style="display: none;">
|
||||||
|
<label class="form-label small text-muted">URL</label>
|
||||||
|
<input type="text" class="form-control form-control-sm text-break mb-2" name="url"
|
||||||
|
value="<?= htmlspecialchars($agent['url']) ?>"
|
||||||
|
placeholder="e.g., http://localhost:8080" required>
|
||||||
|
<label class="form-label small text-muted">Secret Key</label>
|
||||||
|
<input type="text" class="form-control form-control-sm text-break" name="secret_key"
|
||||||
|
value="<?= htmlspecialchars($agent['secret_key']) ?>"
|
||||||
|
placeholder="Secret key for authentication" required>
|
||||||
|
</div>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<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: ?>
|
||||||
|
<span class="text-muted">-</span>
|
||||||
|
<?php endif; ?>
|
||||||
|
</span>
|
||||||
|
<div class="agent-edit-mode" style="display: none;">
|
||||||
|
<input type="number" class="form-control form-control-sm" name="check_period"
|
||||||
|
value="<?= htmlspecialchars($agent['check_period']) ?>"
|
||||||
|
min="0" placeholder="Check interval in minutes">
|
||||||
|
</div>
|
||||||
|
</td>
|
||||||
|
<td class="text-end">
|
||||||
|
<div class="btn-group agent-actions" data-agent-id="<?= htmlspecialchars($agent['id']) ?>"
|
||||||
|
data-platform-id="<?= htmlspecialchars($platform['id']) ?>"
|
||||||
|
data-host-id="<?= htmlspecialchars($host['id']) ?>">
|
||||||
|
<button type="button" class="btn btn-outline-primary btn-sm edit-agent agent-view-mode">
|
||||||
|
<i class="fas fa-edit me-1"></i>Edit
|
||||||
|
</button>
|
||||||
|
<button type="button" class="btn btn-outline-primary btn-sm save-agent agent-edit-mode" style="display: none;">
|
||||||
|
<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>
|
||||||
|
<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-outline-danger btn-sm agent-view-mode">
|
||||||
|
<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 card = hostActions.closest('.card');
|
||||||
|
|
||||||
|
// Show edit mode
|
||||||
|
card.find('.host-view-mode:not(.btn)').hide();
|
||||||
|
card.find('.host-edit-mode').show();
|
||||||
|
|
||||||
|
// Toggle buttons
|
||||||
|
hostActions.find('.host-view-mode').hide();
|
||||||
|
hostActions.find('.host-edit-mode').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('.host-view-mode:not(.btn)').show();
|
||||||
|
card.find('.host-edit-mode').hide();
|
||||||
|
|
||||||
|
// Toggle buttons
|
||||||
|
hostActions.find('.host-view-mode').show();
|
||||||
|
hostActions.find('.host-edit-mode').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('item', 'host');
|
||||||
|
formData.append('host', hostId);
|
||||||
|
formData.append('platform', platformId);
|
||||||
|
|
||||||
|
card.find('.host-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() || '(no description)';
|
||||||
|
const address = card.find('input[name="address"]').val();
|
||||||
|
const viewContent = card.find('.host-view-mode:not(.btn)').first();
|
||||||
|
viewContent.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('.host-view-mode:not(.btn)').show();
|
||||||
|
card.find('.host-edit-mode').hide();
|
||||||
|
|
||||||
|
// Toggle buttons
|
||||||
|
hostActions.find('.host-view-mode').show();
|
||||||
|
hostActions.find('.host-edit-mode').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() || '(no description)';
|
||||||
|
const address = card.find('input[name="address"]').val();
|
||||||
|
const viewContent = card.find('.host-view-mode:not(.btn)').first();
|
||||||
|
viewContent.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('.host-view-mode:not(.btn)').show();
|
||||||
|
card.find('.host-edit-mode').hide();
|
||||||
|
|
||||||
|
// Toggle buttons
|
||||||
|
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');
|
||||||
|
|
||||||
|
// 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');
|
||||||
|
|
||||||
|
// 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');
|
||||||
|
|
||||||
|
// Collect form data
|
||||||
|
const formData = new FormData();
|
||||||
|
formData.append('item', 'agent');
|
||||||
|
formData.append('agent', agentId);
|
||||||
|
formData.append('platform', platformId);
|
||||||
|
formData.append('host', hostId);
|
||||||
|
|
||||||
|
row.find('.agent-edit-mode input, .agent-edit-mode select').each(function() {
|
||||||
|
formData.append($(this).attr('name'), $(this).val());
|
||||||
|
});
|
||||||
|
|
||||||
|
// 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();
|
||||||
|
|
||||||
|
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'}` :
|
||||||
|
'-'
|
||||||
|
);
|
||||||
|
|
||||||
|
// 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.');
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
// Initialize tooltips
|
||||||
|
$('[data-toggle="tooltip"]').tooltip();
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
<!-- "jilo configuration" -->
|
||||||
|
|
|
@ -1,26 +1,41 @@
|
||||||
|
|
||||||
<!-- Logs filter -->
|
<!-- Logs filter -->
|
||||||
<div class="card w-auto bg-light border-light card-body text-right" style="text-align: right;">
|
<div class="card mb-3">
|
||||||
<form method="POST" id="filter_form" class="filter-results" action="?page=logs">
|
<div class="card-body">
|
||||||
<label for="from_time">from</label>
|
<form method="get" action="" class="row g-3 align-items-end">
|
||||||
<input type="date" id="from_time" name="from_time"<?php if (isset($_REQUEST['from_time'])) echo " value=\"" . htmlspecialchars($from_time) . "\"" ?> />
|
<input type="hidden" name="page" value="logs">
|
||||||
<label for="until_time">until</label>
|
<input type="hidden" name="tab" value="<?= htmlspecialchars($widget['scope']) ?>">
|
||||||
<input type="date" id="until_time" name="until_time"<?php if (isset($_REQUEST['until_time'])) echo " value=\"" . htmlspecialchars($until_time) . "\"" ?> />
|
|
||||||
<input type="text" name="id" placeholder="user ID"<?php if (isset($_REQUEST['id'])) echo " value=\"" . htmlspecialchars($_REQUEST['id']) . "\"" ?> />
|
<div class="col-md-3">
|
||||||
<input type="text" name="message" placeholder="message"<?php if (isset($_REQUEST['message'])) echo " value=\"" . htmlspecialchars($_REQUEST['message']) . "\"" ?> />
|
<label for="from_time" class="form-label">From date</label>
|
||||||
<input type="button" onclick="clearFilter()" value="clear" />
|
<input type="date" class="form-control" id="from_time" name="from_time" value="<?= htmlspecialchars($_REQUEST['from_time'] ?? '') ?>">
|
||||||
<input type="submit" value="search" />
|
</div>
|
||||||
</form>
|
|
||||||
<script>
|
<div class="col-md-3">
|
||||||
function clearFilter() {
|
<label for="until_time" class="form-label">Until date</label>
|
||||||
document.getElementById("filter_form").reset();
|
<input type="date" class="form-control" id="until_time" name="until_time" value="<?= htmlspecialchars($_REQUEST['until_time'] ?? '') ?>">
|
||||||
const filterFields = document.querySelectorAll("#filter_form input");
|
</div>
|
||||||
filterFields.forEach(input => {
|
|
||||||
if (input.type === 'text' ||input.type === 'date') {
|
<?php if ($widget['scope'] === 'system') { ?>
|
||||||
input.value = '';
|
<div class="col-md-2">
|
||||||
}
|
<label for="id" class="form-label">User ID</label>
|
||||||
});
|
<input type="text" class="form-control" id="id" name="id" value="<?= htmlspecialchars($_REQUEST['id'] ?? '') ?>" placeholder="Enter user ID">
|
||||||
}
|
</div>
|
||||||
</script>
|
<?php } ?>
|
||||||
|
|
||||||
|
<div class="col-md">
|
||||||
|
<label for="message" class="form-label">Message</label>
|
||||||
|
<input type="text" class="form-control" id="message" name="message" value="<?= htmlspecialchars($_REQUEST['message'] ?? '') ?>" placeholder="Search in log messages">
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="col-md-auto">
|
||||||
|
<button type="submit" class="btn btn-primary me-2">
|
||||||
|
<i class="fas fa-search me-2"></i>Search
|
||||||
|
</button>
|
||||||
|
<a href="?page=logs&tab=<?= htmlspecialchars($widget['scope']) ?>" class="btn btn-outline-secondary">
|
||||||
|
<i class="fas fa-times me-2"></i>Clear
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<!-- /Logs filter -->
|
<!-- /Logs filter -->
|
||||||
|
|
|
@ -1,57 +1,73 @@
|
||||||
|
<!-- log events -->
|
||||||
<div class="row">
|
<div class="container-fluid mt-2">
|
||||||
<?php if ($widget['collapsible'] === true) { ?>
|
<div class="row mb-4">
|
||||||
<a style="text-decoration: none;" data-toggle="collapse" href="#collapse<?= htmlspecialchars($widget['name']) ?>" role="button" aria-expanded="true" aria-controls="collapse<?= htmlspecialchars($widget['name']) ?>">
|
<div class="col">
|
||||||
<div class="card w-auto bg-light card-body" style="flex-direction: row;"><?= htmlspecialchars($widget['title']) ?></div>
|
<h2 class="mb-3"><?= htmlspecialchars($widget['title']) ?></h2>
|
||||||
<?php } else { ?>
|
<ul class="nav nav-tabs mb-3">
|
||||||
<div class="card w-auto bg-light border-light card-body" style="flex-direction: row;"><?= htmlspecialchars($widget['title']) ?></div>
|
<li class="nav-item">
|
||||||
<?php } ?>
|
<a class="nav-link <?= $widget['scope'] === 'user' ? 'active' : '' ?>" href="?page=logs&tab=user">
|
||||||
<?php if ($widget['filter'] === true) {
|
Logs for current user
|
||||||
include '../app/templates/logs-filter.php'; } ?>
|
|
||||||
<?php if ($widget['collapsible'] === true) { ?>
|
|
||||||
</a>
|
</a>
|
||||||
|
</li>
|
||||||
|
<?php if ($widget['has_system_access']) { ?>
|
||||||
|
<li class="nav-item">
|
||||||
|
<a class="nav-link <?= $widget['scope'] === 'system' ? 'active' : '' ?>" href="?page=logs&tab=system">
|
||||||
|
Logs for all users
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
<?php } ?>
|
<?php } ?>
|
||||||
</div>
|
</ul>
|
||||||
|
|
||||||
<!-- widget "<?= htmlspecialchars($widget['name']) ?>" -->
|
<?php if ($widget['filter'] === true) {
|
||||||
<div class="collapse show" id="collapse<?= htmlspecialchars($widget['name']) ?>">
|
include '../app/templates/logs-filter.php';
|
||||||
|
} ?>
|
||||||
|
|
||||||
|
<!-- widget "<?= htmlspecialchars($widget['name']) ?>" -->
|
||||||
|
<div class="collapse show" id="collapse<?= htmlspecialchars($widget['name']) ?>">
|
||||||
<?php if ($time_range_specified) { ?>
|
<?php if ($time_range_specified) { ?>
|
||||||
<p class="m-3">time period: <strong><?= htmlspecialchars($from_time) ?> - <?= htmlspecialchars($until_time) ?></strong></p>
|
<div class="alert alert-info m-3">
|
||||||
|
<i class="fas fa-calendar-alt me-2"></i>Time period: <strong><?= htmlspecialchars($from_time) ?> - <?= htmlspecialchars($until_time) ?></strong>
|
||||||
|
</div>
|
||||||
<?php } ?>
|
<?php } ?>
|
||||||
<div class="mb-5">
|
<div class="mb-5">
|
||||||
<?php if ($widget['full'] === true) { ?>
|
<?php if ($widget['full'] === true) { ?>
|
||||||
<table class="table table-results table-striped table-hover table-bordered">
|
<div class="table-responsive">
|
||||||
<thead class="thead-dark">
|
<table class="table table-hover align-middle mb-0">
|
||||||
|
<thead class="table-light">
|
||||||
<tr>
|
<tr>
|
||||||
<?php foreach ($widget['table_headers'] as $header) { ?>
|
<?php if ($widget['scope'] === 'system') { ?>
|
||||||
<th scope="col" class="th-<?= htmlspecialchars($header) ?>"><?= htmlspecialchars($header) ?></th>
|
<th>Username (id)</th>
|
||||||
<?php } ?>
|
<?php } ?>
|
||||||
|
<th>Time</th>
|
||||||
|
<th>Log message</th>
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
<tbody>
|
<tbody>
|
||||||
<?php foreach ($widget['table_records'] as $row) { ?>
|
<?php foreach ($widget['table_records'] as $row) { ?>
|
||||||
<tr>
|
<tr>
|
||||||
<?php
|
<?php if ($widget['scope'] === 'system') { ?>
|
||||||
foreach ($row as $key => $column) {
|
<td><strong><?= htmlspecialchars($row['username']) ?> (<?= htmlspecialchars($row['userID']) ?>)</strong></td>
|
||||||
if ($key === 'user ID' && isset($user_id) && $user_id === $column) { ?>
|
<?php } ?>
|
||||||
<td><strong><?= htmlspecialchars($column ?? '') ?></strong></td>
|
<td><span class="text-muted"><?= date('d M Y H:i', strtotime($row['time'])) ?></span></td>
|
||||||
<?php } else { ?>
|
<td><?= htmlspecialchars($row['log message']) ?></td>
|
||||||
<td><?= htmlspecialchars($column ?? '') ?></td>
|
|
||||||
<?php }
|
|
||||||
} ?>
|
|
||||||
</tr>
|
</tr>
|
||||||
<?php } ?>
|
<?php } ?>
|
||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
|
</div>
|
||||||
<?php
|
<?php
|
||||||
if ($widget['pagination'] && $item_count > $items_per_page) {
|
if ($widget['pagination'] === true) {
|
||||||
$url = "$app_root?platform=$platform_id&page=$page";
|
include '../app/templates/pagination.php';
|
||||||
include '../app/helpers/pagination.php';
|
|
||||||
}
|
}
|
||||||
?>
|
?>
|
||||||
<?php } else { ?>
|
<?php } else { ?>
|
||||||
<p class="m-3">No matching records found.</p>
|
<div class="alert alert-info m-3">
|
||||||
<?php } ?>
|
<i class="fas fa-info-circle me-2"></i>No log entries found for the specified criteria.
|
||||||
</div>
|
</div>
|
||||||
|
<?php } ?>
|
||||||
</div>
|
</div>
|
||||||
<!-- /widget "<?= htmlspecialchars($widget['name']) ?>" -->
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<!-- /log events -->
|
||||||
|
|
|
@ -7,7 +7,7 @@
|
||||||
|
|
||||||
<?php } ?>
|
<?php } ?>
|
||||||
<!-- Footer -->
|
<!-- Footer -->
|
||||||
<div id="footer">Jilo Web <?= htmlspecialchars($config['version']) ?> ©2024 - web interface for <a href="https://lindeas.com/jilo">Jilo</a></div>
|
<div id="footer">Jilo Web <?= htmlspecialchars($config['version']) ?> ©2024-<?= date('Y') ?> - web interface for <a href="https://lindeas.com/jilo">Jilo</a></div>
|
||||||
<!-- /Footer -->
|
<!-- /Footer -->
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -2,13 +2,12 @@
|
||||||
|
|
||||||
<!-- Sidebar -->
|
<!-- Sidebar -->
|
||||||
<div class="col-md-3 mb-5 sidebar-wrapper bg-light" id="sidebar">
|
<div class="col-md-3 mb-5 sidebar-wrapper bg-light" id="sidebar">
|
||||||
<div class="text-center" style="border: 1px solid #0dcaf0; height: 22px;" id="time_now">
|
<div class="text-center" style="border: 1px solid #0dcaf0; height: 22px;" id="time_now">
|
||||||
<?php
|
<?php
|
||||||
$timeNow = new DateTime('now', new DateTimeZone($userTimezone));
|
$timeNow = new DateTime('now', new DateTimeZone($userTimezone));
|
||||||
?>
|
?>
|
||||||
<!--span style="vertical-align: top; font-size: 12px;"><?= htmlspecialchars($timeNow->format('d M Y H:i')) ?> <?= htmlspecialchars($userTimezone) ?></span-->
|
<span style="vertical-align: top; font-size: 12px;"><?= htmlspecialchars($timeNow->format('H:i')) ?> <?= htmlspecialchars($userTimezone) ?></span>
|
||||||
<span style="vertical-align: top; font-size: 12px;"><?= htmlspecialchars($timeNow->format('H:i')) ?> <?= htmlspecialchars($userTimezone) ?></span>
|
</div>
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="col-4"><button class="btn btn-sm btn-info toggle-sidebar-button" type="button" id="toggleSidebarButton" value=">>"></button></div>
|
<div class="col-4"><button class="btn btn-sm btn-info toggle-sidebar-button" type="button" id="toggleSidebarButton" value=">>"></button></div>
|
||||||
<div class="sidebar-content card ml-3 mt-3">
|
<div class="sidebar-content card ml-3 mt-3">
|
||||||
|
@ -70,17 +69,17 @@ $timeNow = new DateTime('now', new DateTimeZone($userTimezone));
|
||||||
|
|
||||||
<a href="<?= htmlspecialchars($app_root) ?>?page=config&item=platform">
|
<a href="<?= htmlspecialchars($app_root) ?>?page=config&item=platform">
|
||||||
<li class="list-group-item<?php if ($page === 'config' && $item === 'platform') echo ' list-group-item-secondary'; else echo ' list-group-item-action'; ?>">
|
<li class="list-group-item<?php if ($page === 'config' && $item === 'platform') echo ' list-group-item-secondary'; else echo ' list-group-item-action'; ?>">
|
||||||
<i class="fas fa-sitemap" data-toggle="tooltip" data-placement="right" data-offset="30.0" title="configuration"></i>platforms
|
<i class="fas fa-sitemap" data-toggle="tooltip" data-placement="right" data-offset="30.0" title="platforms config"></i>platforms
|
||||||
</li>
|
</li>
|
||||||
</a>
|
</a>
|
||||||
<a href="<?= htmlspecialchars($app_root) ?>?page=config&item=host">
|
<a href="<?= htmlspecialchars($app_root) ?>?page=config&item=host">
|
||||||
<li class="list-group-item<?php if ($page === 'config' && $item === 'host') echo ' list-group-item-secondary'; else echo ' list-group-item-action'; ?>">
|
<li class="list-group-item<?php if ($page === 'config' && $item === 'host') echo ' list-group-item-secondary'; else echo ' list-group-item-action'; ?>">
|
||||||
<i class="fas fa-laptop" data-toggle="tooltip" data-placement="right" data-offset="30.0" title="configuration"></i>hosts
|
<i class="fas fa-laptop" data-toggle="tooltip" data-placement="right" data-offset="30.0" title="hosts config"></i>hosts
|
||||||
</li>
|
</li>
|
||||||
</a>
|
</a>
|
||||||
<a href="<?= htmlspecialchars($app_root) ?>?page=config&item=endpoint">
|
<a href="<?= htmlspecialchars($app_root) ?>?page=config&item=agent">
|
||||||
<li class="list-group-item<?php if ($page === 'config' && $item === 'endpoint') echo ' list-group-item-secondary'; else echo ' list-group-item-action'; ?>">
|
<li class="list-group-item<?php if ($page === 'config' && $item === 'agent') echo ' list-group-item-secondary'; else echo ' list-group-item-action'; ?>">
|
||||||
<i class="fas fa-stethoscope" data-toggle="tooltip" data-placement="right" data-offset="30.0" title="configuration"></i>endpoints
|
<i class="fas fa-stethoscope" data-toggle="tooltip" data-placement="right" data-offset="30.0" title="agents config"></i>agents
|
||||||
</li>
|
</li>
|
||||||
</a>
|
</a>
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,85 @@
|
||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* Reusable pagination view/template component
|
||||||
|
* Required variables:
|
||||||
|
* $currentPage - Current page number
|
||||||
|
* $totalPages - Total number of pages
|
||||||
|
*/
|
||||||
|
|
||||||
|
// Ensure required variables are set
|
||||||
|
if (!isset($currentPage) || !isset($totalPages)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Number of page links to show before and after current page
|
||||||
|
$range = 2;
|
||||||
|
?>
|
||||||
|
|
||||||
|
<?php if ($totalPages > 1): ?>
|
||||||
|
<nav aria-label="Page navigation" class="mt-4">
|
||||||
|
<ul class="pagination justify-content-center d-flex flex-row gap-1">
|
||||||
|
|
||||||
|
<!-- First page -->
|
||||||
|
<?php if ($currentPage > 1): ?>
|
||||||
|
<li class="page-item">
|
||||||
|
<a class="page-link" href="<?= htmlspecialchars($app_root . '?page=' . $page . $params) ?>">First</a>
|
||||||
|
</li>
|
||||||
|
<li class="page-item">
|
||||||
|
<a class="page-link" href="<?= htmlspecialchars($app_root . '?page=' . $page . ($currentPage > 1 ? '&page_num=' . ($currentPage - 1) : '') . $params) ?>">«</a>
|
||||||
|
</li>
|
||||||
|
<?php else: ?>
|
||||||
|
<li class="page-item disabled">
|
||||||
|
<span class="page-link">First</span>
|
||||||
|
</li>
|
||||||
|
<li class="page-item disabled">
|
||||||
|
<span class="page-link">«</span>
|
||||||
|
</li>
|
||||||
|
<?php endif; ?>
|
||||||
|
|
||||||
|
<!-- Page numbers -->
|
||||||
|
<?php
|
||||||
|
for ($i = 1; $i <= $totalPages; $i++) {
|
||||||
|
// Show first, last, current page, 2 pages before and after current, and step pages (10, 20, etc.)
|
||||||
|
if ($i === 1 ||
|
||||||
|
$i === $totalPages ||
|
||||||
|
$i === $currentPage ||
|
||||||
|
$i === $currentPage - 1 ||
|
||||||
|
$i === $currentPage + 1 ||
|
||||||
|
$i === $currentPage - 2 ||
|
||||||
|
$i === $currentPage + 2 ||
|
||||||
|
($i % 10 === 0 && $i > 10)
|
||||||
|
) { ?>
|
||||||
|
<li class="page-item <?= $i === (int)$currentPage ? 'active' : '' ?>">
|
||||||
|
<a class="page-link" href="<?= htmlspecialchars($app_root . '?page=' . $page . ($i > 1 ? '&page_num=' . $i : '') . $params) ?>">
|
||||||
|
<?= $i ?>
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
<?php
|
||||||
|
} elseif ($i === $currentPage - 3 || $i === $currentPage + 3) {
|
||||||
|
?>
|
||||||
|
<li class="page-item disabled">
|
||||||
|
<span class="page-link">...</span>
|
||||||
|
</li>
|
||||||
|
<?php
|
||||||
|
}
|
||||||
|
} ?>
|
||||||
|
|
||||||
|
<!-- Last page -->
|
||||||
|
<?php if ($currentPage < $totalPages): ?>
|
||||||
|
<li class="page-item">
|
||||||
|
<a class="page-link" href="<?= htmlspecialchars($app_root . '?page=' . $page . '&page_num=' . ($currentPage + 1) . $params) ?>">»</a>
|
||||||
|
</li>
|
||||||
|
<li class="page-item">
|
||||||
|
<a class="page-link" href="<?= htmlspecialchars($app_root . '?page=' . $page . '&page_num=' . $totalPages . $params) ?>">Last</a>
|
||||||
|
</li>
|
||||||
|
<?php else: ?>
|
||||||
|
<li class="page-item disabled">
|
||||||
|
<span class="page-link">»</span>
|
||||||
|
</li>
|
||||||
|
<li class="page-item disabled">
|
||||||
|
<span class="page-link">Last</span>
|
||||||
|
</li>
|
||||||
|
<?php endif; ?>
|
||||||
|
</ul>
|
||||||
|
</nav>
|
||||||
|
<?php endif; ?>
|
|
@ -1,22 +1,22 @@
|
||||||
<!-- Security Settings -->
|
<!-- security settings -->
|
||||||
<div class="container">
|
<div class="container-fluid mt-2">
|
||||||
<div class="row mb-4">
|
<div class="row mb-4">
|
||||||
<div class="col">
|
<div class="col">
|
||||||
<h2>Security Settings</h2>
|
<h2>Security settings</h2>
|
||||||
<ul class="nav nav-tabs">
|
<ul class="nav nav-tabs mt-5">
|
||||||
<?php if ($userObject->hasRight($user_id, 'superuser') || $userObject->hasRight($user_id, 'edit whitelist')) { ?>
|
<?php if ($userObject->hasRight($user_id, 'superuser') || $userObject->hasRight($user_id, 'edit whitelist')) { ?>
|
||||||
<li class="nav-item">
|
<li class="nav-item">
|
||||||
<a class="nav-link <?= $section === 'whitelist' ? 'active' : '' ?>" href="?page=security§ion=whitelist">IP Whitelist</a>
|
<a class="nav-link <?= $section === 'whitelist' ? 'active' : '' ?>" href="?page=security§ion=whitelist">IP whitelist</a>
|
||||||
</li>
|
</li>
|
||||||
<?php } ?>
|
<?php } ?>
|
||||||
<?php if ($userObject->hasRight($user_id, 'superuser') || $userObject->hasRight($user_id, 'edit blacklist')) { ?>
|
<?php if ($userObject->hasRight($user_id, 'superuser') || $userObject->hasRight($user_id, 'edit blacklist')) { ?>
|
||||||
<li class="nav-item">
|
<li class="nav-item">
|
||||||
<a class="nav-link <?= $section === 'blacklist' ? 'active' : '' ?>" href="?page=security§ion=blacklist">IP Blacklist</a>
|
<a class="nav-link <?= $section === 'blacklist' ? 'active' : '' ?>" href="?page=security§ion=blacklist">IP blacklist</a>
|
||||||
</li>
|
</li>
|
||||||
<?php } ?>
|
<?php } ?>
|
||||||
<?php if ($userObject->hasRight($user_id, 'superuser') || $userObject->hasRight($user_id, 'edit ratelimiting')) { ?>
|
<?php if ($userObject->hasRight($user_id, 'superuser') || $userObject->hasRight($user_id, 'edit ratelimiting')) { ?>
|
||||||
<li class="nav-item">
|
<li class="nav-item">
|
||||||
<a class="nav-link <?= $section === 'ratelimit' ? 'active' : '' ?>" href="?page=security§ion=ratelimit">Rate Limiting</a>
|
<a class="nav-link <?= $section === 'ratelimit' ? 'active' : '' ?>" href="?page=security§ion=ratelimit">Rate limiting</a>
|
||||||
</li>
|
</li>
|
||||||
<?php } ?>
|
<?php } ?>
|
||||||
</ul>
|
</ul>
|
||||||
|
@ -24,12 +24,12 @@
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<?php if ($section === 'whitelist' && ($userObject->hasRight($user_id, 'superuser') || $userObject->hasRight($user_id, 'edit whitelist'))) { ?>
|
<?php if ($section === 'whitelist' && ($userObject->hasRight($user_id, 'superuser') || $userObject->hasRight($user_id, 'edit whitelist'))) { ?>
|
||||||
<!-- Whitelist Section -->
|
<!-- whitelist section -->
|
||||||
<div class="row mb-4">
|
<div class="row mb-4">
|
||||||
<div class="col">
|
<div class="col">
|
||||||
<div class="card">
|
<div class="card">
|
||||||
<div class="card-header">
|
<div class="card-header">
|
||||||
<h3>IP Whitelist</h3>
|
<h3>IP whitelist</h3>
|
||||||
IP addresses and networks that will always bypass the ratelimiting login checks.
|
IP addresses and networks that will always bypass the ratelimiting login checks.
|
||||||
</div>
|
</div>
|
||||||
<div class="card-body">
|
<div class="card-body">
|
||||||
|
@ -37,7 +37,7 @@
|
||||||
<input type="hidden" name="action" value="add_whitelist">
|
<input type="hidden" name="action" value="add_whitelist">
|
||||||
<div class="row g-3">
|
<div class="row g-3">
|
||||||
<div class="col-md-4">
|
<div class="col-md-4">
|
||||||
<input type="text" class="form-control" name="ip_address" placeholder="IP Address or CIDR" required>
|
<input type="text" class="form-control" name="ip_address" placeholder="IP address or CIDR" required>
|
||||||
</div>
|
</div>
|
||||||
<div class="col-md-4">
|
<div class="col-md-4">
|
||||||
<input type="text" class="form-control" name="description" placeholder="Description">
|
<input type="text" class="form-control" name="description" placeholder="Description">
|
||||||
|
@ -45,11 +45,11 @@
|
||||||
<div class="col-md-2">
|
<div class="col-md-2">
|
||||||
<div class="form-check">
|
<div class="form-check">
|
||||||
<input type="checkbox" class="form-check-input" name="is_network" id="is_network_white">
|
<input type="checkbox" class="form-check-input" name="is_network" id="is_network_white">
|
||||||
<label class="form-check-label" for="is_network_white">Is Network</label>
|
<label class="form-check-label" for="is_network_white">is network</label>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="col-md-2">
|
<div class="col-md-2">
|
||||||
<button type="submit" class="btn btn-primary">Add to Whitelist</button>
|
<button type="submit" class="btn btn-primary">Add to whitelist</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
|
@ -57,11 +57,11 @@
|
||||||
<table class="table">
|
<table class="table">
|
||||||
<thead>
|
<thead>
|
||||||
<tr>
|
<tr>
|
||||||
<th>IP Address</th>
|
<th>IP address</th>
|
||||||
<th>Network</th>
|
<th>Network</th>
|
||||||
<th>Description</th>
|
<th>Description</th>
|
||||||
<th>Added By</th>
|
<th>Added by</th>
|
||||||
<th>Added On</th>
|
<th>Added on</th>
|
||||||
<th>Actions</th>
|
<th>Actions</th>
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
|
@ -91,12 +91,12 @@
|
||||||
<?php } ?>
|
<?php } ?>
|
||||||
|
|
||||||
<?php if ($section === 'blacklist' && ($userObject->hasRight($user_id, 'superuser') || $userObject->hasRight($user_id, 'edit blacklist'))) { ?>
|
<?php if ($section === 'blacklist' && ($userObject->hasRight($user_id, 'superuser') || $userObject->hasRight($user_id, 'edit blacklist'))) { ?>
|
||||||
<!-- Blacklist Section -->
|
<!-- blacklist section -->
|
||||||
<div class="row mb-4">
|
<div class="row mb-4">
|
||||||
<div class="col">
|
<div class="col">
|
||||||
<div class="card">
|
<div class="card">
|
||||||
<div class="card-header">
|
<div class="card-header">
|
||||||
<h3>IP Blacklist</h3>
|
<h3>IP blacklist</h3>
|
||||||
IP addresses and networks that will always get blocked at login.
|
IP addresses and networks that will always get blocked at login.
|
||||||
</div>
|
</div>
|
||||||
<div class="card-body">
|
<div class="card-body">
|
||||||
|
@ -104,7 +104,7 @@
|
||||||
<input type="hidden" name="action" value="add_blacklist">
|
<input type="hidden" name="action" value="add_blacklist">
|
||||||
<div class="row g-3">
|
<div class="row g-3">
|
||||||
<div class="col-md-3">
|
<div class="col-md-3">
|
||||||
<input type="text" class="form-control" name="ip_address" placeholder="IP Address or CIDR" required>
|
<input type="text" class="form-control" name="ip_address" placeholder="IP address or CIDR" required>
|
||||||
</div>
|
</div>
|
||||||
<div class="col-md-3">
|
<div class="col-md-3">
|
||||||
<input type="text" class="form-control" name="reason" placeholder="Reason">
|
<input type="text" class="form-control" name="reason" placeholder="Reason">
|
||||||
|
@ -115,11 +115,11 @@
|
||||||
<div class="col-md-2">
|
<div class="col-md-2">
|
||||||
<div class="form-check">
|
<div class="form-check">
|
||||||
<input type="checkbox" class="form-check-input" name="is_network" id="is_network_black">
|
<input type="checkbox" class="form-check-input" name="is_network" id="is_network_black">
|
||||||
<label class="form-check-label" for="is_network_black">Is Network</label>
|
<label class="form-check-label" for="is_network_black">is network</label>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="col-md-2">
|
<div class="col-md-2">
|
||||||
<button type="submit" class="btn btn-primary">Add to Blacklist</button>
|
<button type="submit" class="btn btn-primary">Add to blacklist</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
|
@ -127,11 +127,11 @@
|
||||||
<table class="table">
|
<table class="table">
|
||||||
<thead>
|
<thead>
|
||||||
<tr>
|
<tr>
|
||||||
<th>IP Address</th>
|
<th>IP address</th>
|
||||||
<th>Network</th>
|
<th>Network</th>
|
||||||
<th>Reason</th>
|
<th>Reason</th>
|
||||||
<th>Added By</th>
|
<th>Added by</th>
|
||||||
<th>Added On</th>
|
<th>Added on</th>
|
||||||
<th>Expires</th>
|
<th>Expires</th>
|
||||||
<th>Actions</th>
|
<th>Actions</th>
|
||||||
</tr>
|
</tr>
|
||||||
|
@ -163,17 +163,17 @@
|
||||||
<?php } ?>
|
<?php } ?>
|
||||||
|
|
||||||
<?php if ($section === 'ratelimit' && ($userObject->hasRight($user_id, 'superuser') || $userObject->hasRight($user_id, 'edit ratelimiting'))) { ?>
|
<?php if ($section === 'ratelimit' && ($userObject->hasRight($user_id, 'superuser') || $userObject->hasRight($user_id, 'edit ratelimiting'))) { ?>
|
||||||
<!-- Rate Limiting Section -->
|
<!-- rate limiting section -->
|
||||||
<div class="row mb-4">
|
<div class="row mb-4">
|
||||||
<div class="col">
|
<div class="col">
|
||||||
<div class="card">
|
<div class="card">
|
||||||
<div class="card-header">
|
<div class="card-header">
|
||||||
<h3>Rate Limiting Settings</h3>
|
<h3>Rate limiting settings</h3>
|
||||||
Rate limiting settings control how many failed login attempts are allowed before blocking an IP address.
|
Rate limiting settings control how many failed login attempts are allowed before blocking an IP address.
|
||||||
</div>
|
</div>
|
||||||
<div class="card-body">
|
<div class="card-body">
|
||||||
<div class="alert alert-info">
|
<div class="alert alert-info">
|
||||||
<h4>Current Settings</h4>
|
<h4>Current settings</h4>
|
||||||
<ul>
|
<ul>
|
||||||
<li>Maximum login attempts: <?= $rateLimiter->maxAttempts ?></li>
|
<li>Maximum login attempts: <?= $rateLimiter->maxAttempts ?></li>
|
||||||
<li>Time window: <?= $rateLimiter->decayMinutes ?> minutes</li>
|
<li>Time window: <?= $rateLimiter->decayMinutes ?> minutes</li>
|
||||||
|
@ -185,13 +185,13 @@
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<h4>Recent Failed Login Attempts</h4>
|
<h4>Recent failed login attempts</h4>
|
||||||
<table class="table">
|
<table class="table">
|
||||||
<thead>
|
<thead>
|
||||||
<tr>
|
<tr>
|
||||||
<th>IP Address</th>
|
<th>IP sddress</th>
|
||||||
<th>Username</th>
|
<th>Username</th>
|
||||||
<th>Attempted At</th>
|
<th>Attempted at</th>
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
<tbody>
|
<tbody>
|
||||||
|
@ -220,4 +220,4 @@
|
||||||
</div>
|
</div>
|
||||||
<?php } ?>
|
<?php } ?>
|
||||||
</div>
|
</div>
|
||||||
<!-- /Security Settings -->
|
<!-- /security settings -->
|
||||||
|
|
|
@ -1,14 +1,19 @@
|
||||||
|
|
||||||
<!-- jilo agent status -->
|
<!-- jilo agent status -->
|
||||||
<div class="card text-center w-75 mx-lef" style="padding-left: 80px;">
|
<div class="d-flex align-items-center flex-wrap border-top p-3">
|
||||||
<div class="card-body">
|
<div class="d-flex align-items-center me-4">
|
||||||
<p class="card-text text-left" style="text-align: left;">
|
<span class="me-2">Jilo agent
|
||||||
Jilo Agent <a href="<?= htmlspecialchars($app_root) ?>?page=config#platform<?= htmlspecialchars($platform['id']) ?>agent<?= htmlspecialchars($agent['id']) ?>"><?= htmlspecialchars($agent['agent_description']) ?></a>:
|
<a href="<?= htmlspecialchars($app_root) ?>?page=config#platform<?= htmlspecialchars($platform['id']) ?>agent<?= htmlspecialchars($agent['id']) ?>" class="text-decoration-none">
|
||||||
<strong><?= $agent_availability ?></strong>
|
<?= htmlspecialchars($agent['agent_description']) ?>
|
||||||
<br />
|
</a>:
|
||||||
host: <strong><?= htmlspecialchars($agent_host) ?></strong>,
|
</span>
|
||||||
port: <strong><?= htmlspecialchars($agent_port) ?></strong>,
|
<span class="badge <?= $agent_availability === 'running' ? 'bg-success' : 'bg-danger' ?>" title="<?= $agent_availability !== 'running' ? htmlspecialchars($agent_availability) : '' ?>" data-toggle="tooltip" data-placement="right" data-offset="30.0">
|
||||||
endpoint: <strong><?= htmlspecialchars($agent['agent_endpoint']) ?></strong>
|
<?= $agent_availability === 'running' ? 'Running' : 'Error' ?>
|
||||||
</p>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
<div class="d-flex align-items-center me-4">
|
||||||
|
<span class="me-4">Host: <strong><?= htmlspecialchars($agent_host) ?></strong></span>
|
||||||
|
<span class="me-4">Port: <strong><?= htmlspecialchars($agent_port) ?></strong></span>
|
||||||
|
<span>Endpoint: <strong><?= htmlspecialchars($agent['agent_endpoint']) ?></strong></span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
|
@ -1,13 +1,21 @@
|
||||||
|
|
||||||
<!-- jitsi platform status -->
|
<!-- jitsi platform status -->
|
||||||
<br />
|
<div class="card mt-3 mb-3">
|
||||||
<div class="card text-center w-75 mx-lef" style="padding-left: 40px;">
|
<div class="card-header">
|
||||||
<div class="card-body">
|
<h4>
|
||||||
<p class="card-text text-left" style="text-align: left;">
|
<a href="<?= htmlspecialchars($app_root) ?>?page=config#platform<?= htmlspecialchars($platform['id']) ?>" class="text-decoration-none">
|
||||||
Jitsi Meet platform: <a href="<?= htmlspecialchars($app_root) ?>?page=config#platform<?= htmlspecialchars($platform['id']) ?>"><?= htmlspecialchars($platform['name']) ?></a>
|
Jitsi platform "<?= htmlspecialchars($platform['name']) ?>"
|
||||||
<br />
|
</a>
|
||||||
jilo database: <strong><?= htmlspecialchars($platform['jilo_database']) ?></strong>,
|
</h4>
|
||||||
status: <strong><?= $jilo_database_status ?></strong>
|
<small class="text-muted">Remote Jitsi Meet installation with its database and agents here.</small>
|
||||||
</p>
|
</div>
|
||||||
|
<div class="card-body p-0">
|
||||||
|
<div class="card-body">
|
||||||
|
<div class="d-flex align-items-center flex-wrap">
|
||||||
|
<span class="me-4">Jilo database: <strong><?= htmlspecialchars($platform['jilo_database']) ?></strong></span>
|
||||||
|
<div class="d-flex align-items-center">
|
||||||
|
<span class="me-2">Status:</span>
|
||||||
|
<span class="badge <?= $jilo_database_status === 'OK' ? 'bg-success' : 'bg-danger' ?>"><?= htmlspecialchars($jilo_database_status) ?></span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
</div>
|
||||||
|
|
|
@ -1,19 +1,26 @@
|
||||||
|
<!-- jilo status -->
|
||||||
|
<div class="container-fluid mt-2">
|
||||||
|
<div class="row mb-5">
|
||||||
|
<div class="col">
|
||||||
|
<h2>Jilo status</h2>
|
||||||
|
|
||||||
<!-- jilo status -->
|
<!-- jilo status -->
|
||||||
<div class="card text-center w-75 mx-lef">
|
<div class="card mt-3">
|
||||||
<p class="h4 card-header">Jilo platform status</p>
|
<div class="card-header">
|
||||||
<div class="card-body">
|
<h4>Jilo server</h4>
|
||||||
<p class="card-text text-left" style="text-align: left;">
|
<small class="text-muted">Responsible for periodic checks of remote agents and storing received data.</small>
|
||||||
Jilo Server:
|
</div>
|
||||||
<?php if ($server_status) { ?>
|
<div class="card-body">
|
||||||
<strong><span class="text-success">running</span></strong>
|
<div class="d-flex align-items-center flex-wrap">
|
||||||
<?php } else { ?>
|
<div class="d-flex align-items-center me-4">
|
||||||
<strong><span class="text-danger">not running</span></strong>
|
<span class="me-2">Jilo server:</span>
|
||||||
<?php } ?>
|
<span class="badge <?= $server_status ? 'bg-success' : 'bg-danger' ?>">
|
||||||
<br />
|
<?= $server_status ? 'Running' : 'Not running' ?>
|
||||||
host: <strong><?= htmlspecialchars($server_host) ?></strong>,
|
</span>
|
||||||
port: <strong><?= htmlspecialchars($server_port) ?></strong>,
|
</div>
|
||||||
endpoint: <strong><?= htmlspecialchars($server_endpoint) ?></strong>
|
<span class="me-4">Host: <strong><?= htmlspecialchars($server_host) ?></strong></span>
|
||||||
</p>
|
<span class="me-4">Port: <strong><?= htmlspecialchars($server_port) ?></strong></span>
|
||||||
|
<span>Endpoint: <strong><?= htmlspecialchars($server_endpoint) ?></strong></span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
</div>
|
||||||
|
|
|
@ -86,7 +86,6 @@ CREATE TABLE IF NOT EXISTS "jilo_agents" (
|
||||||
CREATE TABLE IF NOT EXISTS "hosts" (
|
CREATE TABLE IF NOT EXISTS "hosts" (
|
||||||
"id" INTEGER NOT NULL,
|
"id" INTEGER NOT NULL,
|
||||||
"address" TEXT NOT NULL,
|
"address" TEXT NOT NULL,
|
||||||
"port" INTEGER NOT NULL,
|
|
||||||
"platform_id" INTEGER NOT NULL,
|
"platform_id" INTEGER NOT NULL,
|
||||||
"name" TEXT,
|
"name" TEXT,
|
||||||
PRIMARY KEY("id" AUTOINCREMENT),
|
PRIMARY KEY("id" AUTOINCREMENT),
|
||||||
|
|
|
@ -23,5 +23,6 @@ INSERT INTO jilo_agents VALUES(4,1,2,'https://meet.lindeas.com:8081','mysecretke
|
||||||
INSERT INTO jilo_agents VALUES(7,1,3,'http://meet.lindeas.com:8081','mysecretkey',5);
|
INSERT INTO jilo_agents VALUES(7,1,3,'http://meet.lindeas.com:8081','mysecretkey',5);
|
||||||
INSERT INTO jilo_agents VALUES(8,1,4,'http://meet.lindeas.com:8081','mysecretkey',5);
|
INSERT INTO jilo_agents VALUES(8,1,4,'http://meet.lindeas.com:8081','mysecretkey',5);
|
||||||
|
|
||||||
INSERT INTO hosts VALUES(1,'meet.lindeas.com',8888,2,'main machine');
|
INSERT INTO hosts VALUES(1,'meet.lindeas.com',2,'main machine');
|
||||||
INSERT INTO hosts VALUES(2,'meet.example.com',9191,2,'test');
|
INSERT INTO hosts VALUES(2,'meet.example.com',2,'test');
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue