From bfbf606fe0de8ce7d06295f911b1c33c3b900b42 Mon Sep 17 00:00:00 2001 From: Thomas Citharel Date: Fri, 4 Oct 2024 16:05:19 +0200 Subject: [PATCH] feat(active users): add more active user statistics intervals and improve presentation Signed-off-by: Thomas Citharel --- css/style.css | 32 +++++++++++++ lib/SessionStatistics.php | 10 ++++ templates/settings-admin.php | 45 ++++++++++++------ tests/lib/SessionStatisticsTest.php | 71 ++++++++++++++++------------- 4 files changed, 113 insertions(+), 45 deletions(-) diff --git a/css/style.css b/css/style.css index 6d0bf6ea..2d4f4f0a 100644 --- a/css/style.css +++ b/css/style.css @@ -259,3 +259,35 @@ align-items: center; height: 24px; } + +.active-users-wrapper { + flex: 1; + display: flex; + gap: 0 1rem; + flex-wrap: wrap; + align-items: center; + justify-content: center; +} + +.active-users-box { + padding: 0.25rem 1rem; + flex: 1; + min-width: 150px; + border-left: 2px solid var(--color-border); +} + +@media (width <= 1280px) { + .active-users-box { + padding: 1rem 0.5rem; + border: none; + text-align: center; + } +} + +.active-users-box:first-child { + border: none; +} + +.active-users-box .info { + font-size: 2rem; +} diff --git a/lib/SessionStatistics.php b/lib/SessionStatistics.php index 6f5e56dc..2402b487 100644 --- a/lib/SessionStatistics.php +++ b/lib/SessionStatistics.php @@ -25,6 +25,11 @@ class SessionStatistics { private const OFFSET_5MIN = 300; private const OFFSET_1HOUR = 3600; private const OFFSET_1DAY = 86400; + private const OFFSET_7DAYS = 604800; + private const OFFSET_1MONTH = 2592000; + private const OFFSET_3MONTHS = 7776000; + private const OFFSET_6MONTHS = 15552000; + private const OFFSET_1YEAR = 31536000; private IDBConnection $connection; private ITimeFactory $timeFactory; @@ -39,6 +44,11 @@ public function getSessionStatistics(): array { 'last5minutes' => $this->getNumberOfActiveUsers(self::OFFSET_5MIN), 'last1hour' => $this->getNumberOfActiveUsers(self::OFFSET_1HOUR), 'last24hours' => $this->getNumberOfActiveUsers(self::OFFSET_1DAY), + 'last7days' => $this->getNumberOfActiveUsers(self::OFFSET_7DAYS), + 'last1month' => $this->getNumberOfActiveUsers(self::OFFSET_1MONTH), + 'last3months' => $this->getNumberOfActiveUsers(self::OFFSET_3MONTHS), + 'last6months' => $this->getNumberOfActiveUsers(self::OFFSET_6MONTHS), + 'lastyear' => $this->getNumberOfActiveUsers(self::OFFSET_1YEAR), ]; } diff --git a/templates/settings-admin.php b/templates/settings-admin.php index 79b7d1be..8f375c4c 100644 --- a/templates/settings-admin.php +++ b/templates/settings-admin.php @@ -227,27 +227,46 @@ function FormatMegabytes(int $byte): string {
-
+
-
- 0) : ?> - t('Total users:')); ?> -
+
+ 0) : ?> +
+ t('1 Hour Active Users')); ?>
+
+ t('%s%% of all users', [round($_['activeUsers']['last1hour'] * 100 / $_['storage']['num_users'], 1)])) ?> +
0) : ?> - t('24 hours:')); ?> -
+
+ t('1 Day Active Users')); ?>
+
+ t('%s%% of all users', [round($_['activeUsers']['last24hours'] * 100 / $_['storage']['num_users'], 1)])) ?> +
- 0) : ?> - t('1 hour:')); ?> -
+ 0) : ?> +
+ t('7 Day Active Users')); ?>
+
+ t('%s%% of all users', [round($_['activeUsers']['last7days'] * 100 / $_['storage']['num_users'], 1)])) ?> +
+ + + 0) : ?> +
+ t('1 Month Active Users')); ?>
+
+ t('%s%% of all users', [round($_['activeUsers']['last1month'] * 100 / $_['storage']['num_users'], 1)])) ?> +
- 0) : ?> - t('5 mins:')); ?> -
+ 0) : ?> +
+ t('Total users')); ?>
+
+
diff --git a/tests/lib/SessionStatisticsTest.php b/tests/lib/SessionStatisticsTest.php index 0eb2d958..8179a88a 100644 --- a/tests/lib/SessionStatisticsTest.php +++ b/tests/lib/SessionStatisticsTest.php @@ -13,6 +13,8 @@ use OCA\ServerInfo\SessionStatistics; use OCP\AppFramework\Utility\ITimeFactory; use OCP\IDBConnection; +use OCP\Server; +use PHPUnit\Framework\MockObject\MockObject; use Test\TestCase; /** @@ -22,43 +24,43 @@ * @package OCA\ServerInfo\Tests */ class SessionStatisticsTest extends TestCase { - /** @var ITimeFactory | \PHPUnit_Framework_MockObject_MockObject */ - private $timeFactory; + private ITimeFactory&MockObject $timeFactory; + private IDBConnection $connection; + private SessionStatistics $instance; + private string $table = 'authtoken'; + private const OFFSET_5MIN = 300; + private const OFFSET_1HOUR = 3600; + private const OFFSET_1DAY = 86400; + private const OFFSET_7DAYS = 604800; + private const OFFSET_1MONTH = 2592000; + private const OFFSET_3MONTHS = 7776000; + private const OFFSET_6MONTHS = 15552000; + private const OFFSET_1YEAR = 31536000; + private const CURRENT_TIME = 100000; - /** @var IDBConnection */ - private $connection; - - /** @var SessionStatistics */ - private $instance; - - private $table = 'authtoken'; - - private $offset5Minutes = 300; - - private $offset1Hour = 3600; - - private $offset1Day = 86400; - - private $currentTime = 100000; protected function setUp(): void { parent::setUp(); - $this->timeFactory = $this->getMockBuilder('OCP\AppFramework\Utility\ITimeFactory') - ->disableOriginalConstructor()->getMock(); + $this->timeFactory = $this->createMock(ITimeFactory::class); - $this->connection = \OC::$server->getDatabaseConnection(); + $this->connection = Server::get(IDBConnection::class); $this->instance = new SessionStatistics($this->connection, $this->timeFactory); } - private function addDummyValues() { - $this->addDummyValuesWithLastLogin($this->currentTime - $this->offset5Minutes + 1, 10); - $this->addDummyValuesWithLastLogin($this->currentTime - $this->offset1Hour + 1, 20); - $this->addDummyValuesWithLastLogin($this->currentTime - $this->offset1Day + 1, 30); + private function addDummyValues(): void { + $this->addDummyValuesWithLastLogin(self::CURRENT_TIME - self::OFFSET_5MIN + 1, 10); + $this->addDummyValuesWithLastLogin(self::CURRENT_TIME - self::OFFSET_1HOUR + 1, 20); + $this->addDummyValuesWithLastLogin(self::CURRENT_TIME - self::OFFSET_1DAY + 1, 30); + $this->addDummyValuesWithLastLogin(self::CURRENT_TIME - self::OFFSET_7DAYS + 1, 40); + $this->addDummyValuesWithLastLogin(self::CURRENT_TIME - self::OFFSET_1MONTH + 1, 50); + $this->addDummyValuesWithLastLogin(self::CURRENT_TIME - self::OFFSET_3MONTHS + 1, 60); + $this->addDummyValuesWithLastLogin(self::CURRENT_TIME - self::OFFSET_6MONTHS + 1, 70); + $this->addDummyValuesWithLastLogin(self::CURRENT_TIME - self::OFFSET_1YEAR + 1, 80); } - private function addDummyValuesWithLastLogin($lastActivity, $numOfEntries) { + private function addDummyValuesWithLastLogin($lastActivity, $numOfEntries): void { for ($i = 0; $i < $numOfEntries; $i++) { $query = $this->connection->getQueryBuilder(); $query->insert($this->table) @@ -68,26 +70,31 @@ private function addDummyValuesWithLastLogin($lastActivity, $numOfEntries) { 'login_name' => $query->createNamedParameter('user-' . ($numOfEntries + $i % 2)), 'password' => $query->createNamedParameter('password'), 'name' => $query->createNamedParameter('user agent'), - 'token' => $query->createNamedParameter('token-' . ($i + $numOfEntries * 10)), + 'token' => $query->createNamedParameter('token-' . $this->getUniqueID()), 'type' => $query->createNamedParameter(0), 'last_activity' => $query->createNamedParameter($lastActivity), 'last_check' => $query->createNamedParameter($lastActivity), ] ); - $query->execute(); + $query->executeStatement(); } } public function testGetSessionStatistics() { $this->addDummyValues(); $this->timeFactory->expects($this->any())->method('getTime') - ->willReturn($this->currentTime); + ->willReturn(self::CURRENT_TIME); $result = $this->instance->getSessionStatistics(); - $this->assertSame(3, count($result)); - $this->assertSame(2, $result['last5minutes']); - $this->assertSame(4, $result['last1hour']); - $this->assertSame(6, $result['last24hours']); + $this->assertSame(8, count($result)); + $this->assertSame(3, $result['last5minutes']); + $this->assertSame(5, $result['last1hour']); + $this->assertSame(7, $result['last24hours']); + $this->assertSame(9, $result['last7days']); + $this->assertSame(11, $result['last1month']); + $this->assertSame(13, $result['last3months']); + $this->assertSame(15, $result['last6months']); + $this->assertSame(17, $result['lastyear']); } }