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

Lets fill in the dashboard #72

Open
wants to merge 14 commits into
base: development
Choose a base branch
from
2 changes: 1 addition & 1 deletion appinfo/info.xml
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ Create a [bug report](https://github.com/OpenRegister/.github/issues/new/choose)

Create a [feature request](https://github.com/OpenRegister/.github/issues/new/choose)
]]></description>
<version>0.1.22</version>
<version>0.1.23</version>
<licence>agpl</licence>
<author mail="info@conduction.nl" homepage="https://www.conduction.nl/">Conduction</author>
<namespace>OpenRegister</namespace>
Expand Down
6 changes: 6 additions & 0 deletions appinfo/routes.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,12 @@
],
'routes' => [
['name' => 'dashboard#page', 'url' => '/', 'verb' => 'GET'],
['name' => 'dashboard#stats', 'url' => '/api/dashboard/stats', 'verb' => 'GET'],
['name' => 'dashboard#auditStats', 'url' => '/api/dashboard/audit-stats', 'verb' => 'GET'],
['name' => 'dashboard#growthStats', 'url' => '/api/dashboard/growth-stats', 'verb' => 'GET'],
['name' => 'dashboard#qualityStats', 'url' => '/api/dashboard/quality-stats', 'verb' => 'GET'],
['name' => 'dashboard#schemaStats', 'url' => '/api/dashboard/schema-stats', 'verb' => 'GET'],
['name' => 'dashboard#accessStats', 'url' => '/api/dashboard/access-stats', 'verb' => 'GET'],
['name' => 'registers#objects', 'url' => '/api/registers-objects/{register}/{schema}', 'verb' => 'GET'],
['name' => 'objects#logs', 'url' => '/api/objects-logs/{id}', 'verb' => 'GET', 'requirements' => ['id' => '[^/]+']],
['name' => 'objects#mappings', 'url' => '/api/objects/mappings', 'verb' => 'GET'],
Expand Down
1 change: 1 addition & 0 deletions lib/Constants/Colors.php
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@

217 changes: 207 additions & 10 deletions lib/Controller/DashboardController.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,23 +7,108 @@
use OCP\AppFramework\Http\JSONResponse;
use OCP\IRequest;
use OCP\AppFramework\Http\ContentSecurityPolicy;
use OCA\OpenRegister\Db\RegisterMapper;
use OCA\OpenRegister\Db\SchemaMapper;
use OCA\OpenRegister\Db\ObjectEntityMapper;
use OCA\OpenRegister\Db\AuditTrailMapper;

class DashboardController extends Controller
{
/**
* Controller for dashboard related operations
*
* Handles dashboard statistics and page rendering
*/
class DashboardController extends Controller {
/** @var RegisterMapper */
private $registerMapper;

/** @var SchemaMapper */
private $schemaMapper;

/** @var ObjectEntityMapper */
private $objectMapper;

/** @var AuditTrailMapper */
private $auditTrailMapper;

public function __construct($appName, IRequest $request)
{
/**
* Constructor for DashboardController
*
* @param string $appName The name of the app
* @param IRequest $request The request object
* @param RegisterMapper $registerMapper Mapper for register operations
* @param SchemaMapper $schemaMapper Mapper for schema operations
* @param ObjectEntityMapper $objectMapper Mapper for object operations
* @param AuditTrailMapper $auditTrailMapper Mapper for audit trail operations
*/
public function __construct(
$appName,
IRequest $request,
RegisterMapper $registerMapper,
SchemaMapper $schemaMapper,
ObjectEntityMapper $objectMapper,
AuditTrailMapper $auditTrailMapper
) {
parent::__construct($appName, $request);
$this->registerMapper = $registerMapper;
$this->schemaMapper = $schemaMapper;
$this->objectMapper = $objectMapper;
$this->auditTrailMapper = $auditTrailMapper;
}

/**
* Get basic statistics about registers, schemas, objects and audit logs
*
* @NoAdminRequired
* @NoCSRFRequired
* @return JSONResponse Statistics data or error message
*/
public function stats(): JSONResponse {
try {
$stats = [
'registers' => $this->registerMapper->count(),
'schemas' => $this->schemaMapper->count(),
'objects' => $this->objectMapper->countAll(),
'auditLogs' => $this->auditTrailMapper->count(),
];
return new JSONResponse($stats);
} catch (\Exception $e) {
return new JSONResponse(['error' => $e->getMessage()], 500);
}
}

/**
* Get audit statistics for a given time period
*
* @NoAdminRequired
* @NoCSRFRequired
* @param string|null $from Start date (defaults to 7 days ago)
* @param string|null $to End date (defaults to today)
* @return JSONResponse Audit statistics or error message
*/
public function page(?string $getParameter)
public function auditStats(?string $from = null, ?string $to = null): JSONResponse {
try {
$fromDate = $from ? new \DateTime($from) : new \DateTime('-7 days');
$toDate = $to ? new \DateTime($to) : new \DateTime();

$stats = $this->auditTrailMapper->getDailyStats($fromDate, $toDate);
return new JSONResponse($stats);
} catch (\Exception $e) {
return new JSONResponse(['error' => $e->getMessage()], 500);
}
}

/**
* Render the dashboard page
*
* @NoAdminRequired
* @NoCSRFRequired
* @param string|null $getParameter Optional GET parameter
* @return TemplateResponse The rendered page
*/
public function page(?string $getParameter = null): TemplateResponse
{
try {
$response =new TemplateResponse(
$response = new TemplateResponse(
$this->appName,
'index',
[]
Expand All @@ -45,14 +130,126 @@ public function page(?string $getParameter)
}

/**
* Get growth statistics for registers and schemas
*
* @NoAdminRequired
* @NoCSRFRequired
* @param string|null $from Start date
* @param string|null $to End date
* @param int|null $schemaId Optional schema ID filter
* @param int|null $registerId Optional register ID filter
* @return JSONResponse Growth statistics or error message
*/
public function index(): JSONResponse
{
public function growthStats(
?string $from = null,
?string $to = null,
?int $schemaId = null,
?int $registerId = null
): JSONResponse {
try {
$fromDate = $from ? new \DateTime($from) : new \DateTime('-7 days');
$toDate = $to ? new \DateTime($to) : new \DateTime();

$registerGrowth = $this->objectMapper->getRegisterGrowth($fromDate, $toDate, $registerId);
$schemaDistribution = $this->objectMapper->getSchemaDistribution($fromDate, $toDate, $schemaId);

return new JSONResponse([
'registerGrowth' => $registerGrowth,
'schemaDistribution' => $schemaDistribution,
]);
} catch (\Exception $e) {
return new JSONResponse(['error' => $e->getMessage()], 500);
}
}

/**
* Get data quality statistics
*
* @NoAdminRequired
* @NoCSRFRequired
* @param string|null $from Start date
* @param string|null $to End date
* @param int|null $schemaId Optional schema ID filter
* @param int|null $registerId Optional register ID filter
* @return JSONResponse Data quality statistics
*/
public function qualityStats(
?string $from = null,
?string $to = null,
?int $schemaId = null,
?int $registerId = null
): JSONResponse {
try {
$results = ["results" => self::TEST_ARRAY];
return new JSONResponse($results);
$fromDate = $from ? new \DateTime($from) : new \DateTime('-7 days');
$toDate = $to ? new \DateTime($to) : new \DateTime();

$validationErrors = $this->objectMapper->getValidationStats($fromDate, $toDate, $schemaId, $registerId);
$completeness = $this->objectMapper->getCompletenessStats($fromDate, $toDate, $schemaId, $registerId);
$revisions = $this->objectMapper->getRevisionStats($fromDate, $toDate, $schemaId, $registerId);

return new JSONResponse([
'validationErrors' => $validationErrors,
'completeness' => $completeness,
'revisions' => $revisions,
]);
} catch (\Exception $e) {
return new JSONResponse(['error' => $e->getMessage()], 500);
}
}

/**
* Get schema analysis statistics
*
* @NoAdminRequired
* @NoCSRFRequired
* @param string|null $from Start date
* @param string|null $to End date
* @param int|null $schemaId Optional schema ID filter
* @param int|null $registerId Optional register ID filter
* @return JSONResponse Schema analysis statistics
*/
public function schemaStats(
?string $from = null,
?string $to = null,
?int $schemaId = null,
?int $registerId = null
): JSONResponse {
try {
$fromDate = $from ? new \DateTime($from) : new \DateTime('-7 days');
$toDate = $to ? new \DateTime($to) : new \DateTime();

$fieldTypes = $this->schemaMapper->getFieldTypeStats($fromDate, $toDate, $schemaId);
$fieldUsage = $this->schemaMapper->getFieldUsageStats($fromDate, $toDate, $schemaId);
$schemaComplexity = $this->schemaMapper->getComplexityStats($fromDate, $toDate, $schemaId);
$versionDistribution = $this->schemaMapper->getVersionDistribution($fromDate, $toDate, $schemaId);

return new JSONResponse([
'fieldTypes' => $fieldTypes,
'fieldUsage' => $fieldUsage,
'complexity' => $schemaComplexity,
'versions' => $versionDistribution,
]);
} catch (\Exception $e) {
return new JSONResponse(['error' => $e->getMessage()], 500);
}
}

/**
* Get access statistics
*
* @NoAdminRequired
* @NoCSRFRequired
* @param string|null $from Start date
* @param string|null $to End date
* @return JSONResponse Access statistics
*/
public function accessStats(?string $from = null, ?string $to = null): JSONResponse {
try {
$fromDate = $from ? new \DateTime($from) : new \DateTime('-7 days');
$toDate = $to ? new \DateTime($to) : new \DateTime();

$stats = $this->auditTrailMapper->getAccessStats($fromDate, $toDate);
return new JSONResponse($stats);
} catch (\Exception $e) {
return new JSONResponse(['error' => $e->getMessage()], 500);
}
Expand Down
Loading
Loading