Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add graphs to the dashboard #84

Merged
merged 11 commits into from
Feb 21, 2025
4 changes: 4 additions & 0 deletions appinfo/routes.php
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,10 @@
],
'routes' => [
['name' => 'dashboard#page', 'url' => '/', 'verb' => 'GET'],
['name' => 'dashboard#index', 'url' => '/api/dashboard', 'verb' => 'GET'],
['name' => 'dashboard#getCallStats', 'url' => '/api/dashboard/callstats', 'verb' => 'GET'],
['name' => 'dashboard#getJobStats', 'url' => '/api/dashboard/jobstats', 'verb' => 'GET'],
['name' => 'dashboard#getSyncStats', 'url' => '/api/dashboard/syncstats', 'verb' => 'GET'],
['name' => 'sources#test', 'url' => '/api/source-test/{id}', 'verb' => 'POST'],
['name' => 'sources#logs', 'url' => '/api/sources-logs/{id}', 'verb' => 'GET'],
['name' => 'jobs#run', 'url' => '/api/jobs-test/{id}', 'verb' => 'POST'],
Expand Down
148 changes: 111 additions & 37 deletions lib/Controller/DashboardController.php
Original file line number Diff line number Diff line change
Expand Up @@ -14,62 +14,56 @@
use OCA\OpenConnector\Db\EndpointMapper;
use OCA\OpenConnector\Db\JobMapper;
use OCA\OpenConnector\Db\MappingMapper;
use OCA\OpenConnector\Db\CallLogMapper;
use OCA\OpenConnector\Db\JobLogMapper;
use OCA\OpenConnector\Db\SynchronizationContractLogMapper;

/**
* @package OCA\OpenConnector\Controller
*/
class DashboardController extends Controller
{
private $synchronizationMapper;
private $sourceMapper;
private $synchronizationContractMapper;
private $consumerMapper;
private $endpointMapper;
private $jobMapper;
private $mappingMapper;

public function __construct(
$appName,
IRequest $request,
SynchronizationMapper $synchronizationMapper,
SourceMapper $sourceMapper,
SynchronizationContractMapper $synchronizationContractMapper,
ConsumerMapper $consumerMapper,
EndpointMapper $endpointMapper,
JobMapper $jobMapper,
MappingMapper $mappingMapper
private readonly SynchronizationMapper $synchronizationMapper,
private readonly SourceMapper $sourceMapper,
private readonly SynchronizationContractMapper $synchronizationContractMapper,
private readonly ConsumerMapper $consumerMapper,
private readonly EndpointMapper $endpointMapper,
private readonly JobMapper $jobMapper,
private readonly MappingMapper $mappingMapper,
private readonly CallLogMapper $callLogMapper,
private readonly JobLogMapper $jobLogMapper,
private readonly SynchronizationContractLogMapper $synchronizationContractLogMapper
) {
parent::__construct($appName, $request);
$this->synchronizationMapper = $synchronizationMapper;
$this->sourceMapper = $sourceMapper;
$this->synchronizationContractMapper = $synchronizationContractMapper;
$this->consumerMapper = $consumerMapper;
$this->endpointMapper = $endpointMapper;
$this->jobMapper = $jobMapper;
$this->mappingMapper = $mappingMapper;
}

/**
* @NoAdminRequired
* @NoCSRFRequired
*/
public function page(?string $getParameter)
{
public function page(?string $getParameter): TemplateResponse
{
try {
$response = new TemplateResponse(
$this->appName,
'index',
[]
appName: $this->appName,
templateName: 'index',
params:[]
);

$csp = new ContentSecurityPolicy();
$csp->addAllowedConnectDomain('*');
$csp->addAllowedConnectDomain(domain: '*');
$response->setContentSecurityPolicy($csp);

return $response;
} catch (\Exception $e) {
return new TemplateResponse(
$this->appName,
'error',
['error' => $e->getMessage()],
'500'
appName: $this->appName,
templateName: 'error',
params: ['error' => $e->getMessage()],
renderAs: '500'
);
}
}
Expand All @@ -82,15 +76,95 @@ public function index(): JSONResponse
{
try {
$results = [
"synchronizations" => $this->synchronizationMapper->getTotalCallCount(),
"sources" => $this->sourceMapper->getTotalCallCount(),
"mappings" => $this->mappingMapper->getTotalCallCount(),
"synchronizations" => $this->synchronizationMapper->getTotalCallCount(),
"synchronizationContracts" => $this->synchronizationContractMapper->getTotalCallCount(),
"consumers" => $this->consumerMapper->getTotalCallCount(),
"endpoints" => $this->endpointMapper->getTotalCallCount(),
"jobs" => $this->jobMapper->getTotalCallCount(),
"mappings" => $this->mappingMapper->getTotalCallCount()
"endpoints" => $this->endpointMapper->getTotalCallCount()
];
return new JSONResponse($results);
} catch (\Exception $e) {
return new JSONResponse(data: ['error' => $e->getMessage()], statusCode: 500);
}
}

/**
* Get call statistics for the dashboard
*
* @NoAdminRequired
* @NoCSRFRequired
* @param string|null $from Start date in ISO format
* @param string|null $to End date in ISO format
* @return JSONResponse
*/
public function getCallStats(?string $from = null, ?string $to = null): JSONResponse
{
try {
$fromDate = $from ? new \DateTime($from) : (new \DateTime())->modify('-7 days');
$toDate = $to ? new \DateTime($to) : new \DateTime();

$dailyStats = $this->callLogMapper->getCallStatsByDateRange($fromDate, $toDate);
$hourlyStats = $this->callLogMapper->getCallStatsByHourRange($fromDate, $toDate);

return new JSONResponse([
'daily' => $dailyStats,
'hourly' => $hourlyStats
]);
} catch (\Exception $e) {
return new JSONResponse(['error' => $e->getMessage()], 500);
}
}

/**
* Get job statistics for the dashboard
*
* @NoAdminRequired
* @NoCSRFRequired
* @param string|null $from Start date in ISO format
* @param string|null $to End date in ISO format
* @return JSONResponse
*/
public function getJobStats(?string $from = null, ?string $to = null): JSONResponse
{
try {
$fromDate = $from ? new \DateTime($from) : (new \DateTime())->modify('-7 days');
$toDate = $to ? new \DateTime($to) : new \DateTime();

$dailyStats = $this->jobLogMapper->getJobStatsByDateRange($fromDate, $toDate);
$hourlyStats = $this->jobLogMapper->getJobStatsByHourRange($fromDate, $toDate);

return new JSONResponse([
'daily' => $dailyStats,
'hourly' => $hourlyStats
]);
} catch (\Exception $e) {
return new JSONResponse(['error' => $e->getMessage()], 500);
}
}

/**
* Get synchronization statistics for the dashboard
*
* @NoAdminRequired
* @NoCSRFRequired
* @param string|null $from Start date in ISO format
* @param string|null $to End date in ISO format
* @return JSONResponse
*/
public function getSyncStats(?string $from = null, ?string $to = null): JSONResponse
{
try {
$fromDate = $from ? new \DateTime($from) : (new \DateTime())->modify('-7 days');
$toDate = $to ? new \DateTime($to) : new \DateTime();

$dailyStats = $this->synchronizationContractLogMapper->getSyncStatsByDateRange($fromDate, $toDate);
$hourlyStats = $this->synchronizationContractLogMapper->getSyncStatsByHourRange($fromDate, $toDate);

return new JSONResponse([
'daily' => $dailyStats,
'hourly' => $hourlyStats
]);
} catch (\Exception $e) {
return new JSONResponse(['error' => $e->getMessage()], 500);
}
Expand Down
Loading