Skip to content

Commit

Permalink
Merge pull request #1136 from didoda/feat/modules-count-items
Browse files Browse the repository at this point in the history
Module items count
  • Loading branch information
didoda committed Jun 25, 2024
2 parents f86447d + a204013 commit e46e8f1
Show file tree
Hide file tree
Showing 11 changed files with 199 additions and 6 deletions.
6 changes: 6 additions & 0 deletions resources/styles/_elements.scss
Original file line number Diff line number Diff line change
Expand Up @@ -337,3 +337,9 @@ nav.pagination {
.drop-area-double {
min-height: $gutter * 16;
}

.module-items-counter {
position: absolute;
bottom: 1rem;
background: transparent;
}
17 changes: 17 additions & 0 deletions src/Controller/DashboardController.php
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
*/
namespace App\Controller;

use App\Utility\CacheTools;
use App\Utility\SchemaTrait;
use Cake\Utility\Hash;

Expand Down Expand Up @@ -48,6 +49,22 @@ public function index(): void
'jobsAllow',
(array)Hash::extract($this->getMeta($user), 'resources./async_jobs.hints.allow')
);

// set modules counters
$modules = array_keys((array)$this->viewBuilder()->getVar('modules'));
foreach ($modules as $name) {
if (CacheTools::existsCount($name)) {
continue;
}
$endpoint = $name === 'tags' ? '/model/tags' : $name;
$options = $name === 'tags' ? ['page_size' => 1] : ['limit' => 1, 'page_size' => 1, 'fields' => 'id'];
try {
$response = $this->apiClient->get($endpoint, $options);
CacheTools::setModuleCount($response, $name);
} catch (\Exception $e) {
CacheTools::setModuleCount(['meta' => ['pagination' => ['count' => '-']]], $name);
}
}
}

/**
Expand Down
2 changes: 2 additions & 0 deletions src/Controller/Model/TagsController.php
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
*/
namespace App\Controller\Model;

use App\Utility\CacheTools;
use BEdita\WebTools\ApiClientProvider;
use Cake\Http\Response;
use Cake\Utility\Hash;
Expand Down Expand Up @@ -59,6 +60,7 @@ public function index(): ?Response
$options['sort'] = empty($options['sort']) ? 'name' : $options['sort'];
$response = ApiClientProvider::getApiClient()->get('/model/tags', $options);
$resources = Hash::combine((array)Hash::get($response, 'data'), '{n}.id', '{n}');
CacheTools::setModuleCount((array)$response, 'tags');
$roots = $this->Categories->getAvailableRoots($resources);
$tagsTree = $this->Categories->tree($resources);
$this->set(compact('resources', 'roots', 'tagsTree'));
Expand Down
2 changes: 2 additions & 0 deletions src/Controller/ModulesController.php
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
*/
namespace App\Controller;

use App\Utility\CacheTools;
use App\Utility\PermissionsTrait;
use BEdita\SDK\BEditaClientException;
use Cake\Core\Configure;
Expand Down Expand Up @@ -102,6 +103,7 @@ public function index(): ?Response

try {
$response = $this->apiClient->getObjects($this->objectType, $this->Query->index());
CacheTools::setModuleCount((array)$response, $this->Modules->getConfig('currentModuleName'));
} catch (BEditaClientException $e) {
$this->log($e->getMessage(), LogLevel::ERROR);
$this->Flash->error($e->getMessage(), ['params' => $e]);
Expand Down
2 changes: 2 additions & 0 deletions src/Controller/TrashController.php
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
*/
namespace App\Controller;

use App\Utility\CacheTools;
use BEdita\SDK\BEditaClientException;
use Cake\Event\EventInterface;
use Cake\Http\Response;
Expand Down Expand Up @@ -63,6 +64,7 @@ public function index(): ?Response

try {
$response = $this->apiClient->getObjects('trash', $this->getRequest()->getQueryParams());
CacheTools::setModuleCount($response, 'trash');
} catch (BEditaClientException $e) {
// Error! Back to dashboard.
$this->log($e->getMessage(), LogLevel::ERROR);
Expand Down
46 changes: 46 additions & 0 deletions src/Utility/CacheTools.php
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@
namespace App\Utility;

use BEdita\WebTools\ApiClientProvider;
use Cake\Cache\Cache;
use Cake\Utility\Hash;

/**
* Add cache related utility methods
Expand All @@ -32,4 +34,48 @@ public static function cacheKey(string $name): string

return sprintf('%s_%s', $name, $apiSignature);
}

/**
* Check if module count exists in cache.
*
* @param string $moduleName Module name.
* @return bool
*/
public static function existsCount(string $moduleName): bool
{
$name = sprintf('statistics_%s_count', $moduleName);
$cacheKey = self::cacheKey($name);

return Cache::read($cacheKey) !== null;
}

/**
* Get module count from cache.
*
* @param string $moduleName Module name.
* @return string
*/
public static function getModuleCount(string $moduleName): string
{
$name = sprintf('statistics_%s_count', $moduleName);
$cacheKey = self::cacheKey($name);
$count = Cache::read($cacheKey);

return $count !== false ? (int)$count : '-';
}

/**
* Set module count in cache.
*
* @param array $response API response.
* @param string $moduleName Module name.
* @return void
*/
public static function setModuleCount(array $response, string $moduleName): void
{
$count = Hash::get($response, 'meta.pagination.count', 0);
$name = sprintf('statistics_%s_count', $moduleName);
$cacheKey = self::cacheKey($name);
Cache::write($cacheKey, $count);
}
}
28 changes: 24 additions & 4 deletions src/View/Helper/LayoutHelper.php
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
*/
namespace App\View\Helper;

use App\Utility\CacheTools;
use App\Utility\Translate;
use Cake\Core\Configure;
use Cake\Utility\Hash;
Expand Down Expand Up @@ -129,14 +130,32 @@ public function dashboardModuleLink(string $name, array $module): string
$param = empty($route) ? ['_name' => 'modules:list', 'object_type' => $name, 'plugin' => null] : $route;

return sprintf(
'<a href="%s" class="%s"><span>%s</span>%s</a>',
'<a href="%s" class="%s"><span>%s</span>%s%s</a>',
$this->Url->build($param),
sprintf('dashboard-item has-background-module-%s %s', $name, Hash::get($module, 'class', '')),
$this->tr($label),
$this->moduleIcon($name, $module)
$this->moduleIcon($name, $module),
$this->moduleCount($name)
);
}

/**
* Return module count span.
*
* @param string $name The module name
* @param string|null $moduleClass The module class
* @return string
*/
public function moduleCount(string $name, ?string $moduleClass = null): string
{
$count = CacheTools::getModuleCount($name);
$base = 'tag mx-05 module-items-counter';
$defaultModuleClass = sprintf('has-background-module-%s', $name);
$cssClasses = empty($moduleClass) ? sprintf('%s %s', $base, $defaultModuleClass) : sprintf('%s %s', $base, $moduleClass);

return $count === '-' ? '-' : sprintf('<span class="%s">%s</span>', $cssClasses, $count);
}

/**
* Return module icon.
*
Expand Down Expand Up @@ -217,11 +236,12 @@ public function moduleLink(): string
$label = Hash::get($currentModule, 'label', $name);

return sprintf(
'<a href="%s" class="%s"><span class="mr-05">%s</span>%s</a>',
'<a href="%s" class="%s"><span class="mr-05">%s</span>%s%s</a>',
$this->Url->build(['_name' => 'modules:list', 'object_type' => $name]),
sprintf('module-item has-background-module-%s', $name),
$this->tr($label),
$this->moduleIcon($name, $currentModule)
$this->moduleIcon($name, $currentModule),
$this->moduleCount($name)
);
}

Expand Down
2 changes: 2 additions & 0 deletions templates/Pages/Dashboard/index.twig
Original file line number Diff line number Diff line change
Expand Up @@ -22,13 +22,15 @@
{% if modules.trash %}
<a href="{{ Url.build({ '_name': 'trash:list' }) }}" title="{{ __('Trash') }}" class="dashboard-item has-background-black">
<span>{{ __('Trash can') }}</span>
{{ Layout.moduleCount('trash', 'has-background-black')|raw }}
<app-icon icon="carbon:trash-can"></app-icon>
</a>
{% endif %}

{% if modules.users %}
<a href="{{ Url.build({'_name': 'modules:list', 'object_type': 'users'}) }}" title="{{ __('System users') }}" class="dashboard-item has-background-black">
<span>{{ __('System users') }}</span>
{{ Layout.moduleCount('users')|raw }}
<app-icon icon="carbon:user-admin"></app-icon>
</a>
{% endif %}
Expand Down
22 changes: 22 additions & 0 deletions tests/TestCase/Controller/DashboardControllerTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -14,13 +14,15 @@
namespace App\Test\TestCase\Controller;

use App\Controller\DashboardController;
use App\Utility\CacheTools;
use Authentication\AuthenticationService;
use Authentication\AuthenticationServiceInterface;
use Authentication\Identifier\IdentifierInterface;
use Authentication\Identity;
use Authentication\IdentityInterface;
use BEdita\WebTools\ApiClientProvider;
use BEdita\WebTools\Identifier\ApiIdentifier;
use Cake\Cache\Cache;
use Cake\Http\Exception\MethodNotAllowedException;
use Cake\Http\ServerRequest;
use Cake\TestSuite\TestCase;
Expand All @@ -42,6 +44,24 @@ class DashboardControllerTest extends TestCase
*/
public $Dashboard;

/**
* {@inheritDoc}
*/
public function setUp(): void
{
parent::setUp();
Cache::enable();
}

/**
* {@inheritDoc}
*/
public function tearDown(): void
{
parent::tearDown();
Cache::disable();
}

/**
* Setup controller to test with request config
*
Expand Down Expand Up @@ -184,6 +204,8 @@ public function testIndex($expected, $method): void

$this->setupControllerAndLogin($requestConfig);

$this->Dashboard->set('modules', ['abcde' => [], 'wrong' => [], 'documents' => [], 'images' => [], 'media' => [], 'objects' => [], 'tags' => [], 'trash' => [], 'users' => []]);
CacheTools::setModuleCount(['meta' => ['pagination' => ['count' => 0]]], 'abcde');
$this->Dashboard->index();
$response = $this->Dashboard->getResponse();

Expand Down
45 changes: 45 additions & 0 deletions tests/TestCase/Utility/CacheToolsTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@

use App\Utility\CacheTools;
use BEdita\WebTools\ApiClientProvider;
use Cake\Cache\Cache;
use Cake\TestSuite\TestCase;

/**
Expand All @@ -23,6 +24,24 @@
*/
class CacheToolsTest extends TestCase
{
/**
* @inheritDoc
*/
public function setUp(): void
{
parent::setUp();
Cache::enable();
}

/**
* @inheritDoc
*/
public function tearDown(): void
{
parent::tearDown();
Cache::disable();
}

/**
* Test `cacheKey` method.
*
Expand All @@ -36,4 +55,30 @@ public function testCacheKey(): void
$actual = CacheTools::cacheKey('test');
static::assertEquals($expected, $actual);
}

/**
* Test `getModuleCount` and `setModuleCount` methods.
*
* @return void
* @covers ::existsCount()
* @covers ::setModuleCount()
* @covers ::getModuleCount()
*/
public function testGetSetModuleCount(): void
{
$moduleName = 'test';
$response = [
'meta' => [
'pagination' => [
'count' => 42,
],
],
];
$exists = CacheTools::existsCount($moduleName);
static::assertFalse($exists);
CacheTools::setModuleCount($response, $moduleName);
$expected = 42;
$actual = CacheTools::getModuleCount($moduleName);
static::assertEquals($expected, $actual);
}
}
33 changes: 31 additions & 2 deletions tests/TestCase/View/Helper/LayoutHelperTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,12 @@

namespace App\Test\TestCase\View\Helper;

use App\Utility\CacheTools;
use App\View\Helper\EditorsHelper;
use App\View\Helper\LayoutHelper;
use App\View\Helper\PermsHelper;
use App\View\Helper\SystemHelper;
use Cake\Cache\Cache;
use Cake\Core\Configure;
use Cake\Http\Cookie\Cookie;
use Cake\Http\Cookie\CookieCollection;
Expand Down Expand Up @@ -242,7 +244,7 @@ public function moduleLinkProvider(): array
],
],
'objects' => [
'<a href="/objects" class="module-item has-background-module-objects"><span class="mr-05">Objects</span></a>',
'<a href="/objects" class="module-item has-background-module-objects"><span class="mr-05">Objects</span><span class="tag mx-05 module-items-counter has-background-module-objects">0</span></a>',
'Module',
[
'currentModule' => ['name' => 'objects'],
Expand Down Expand Up @@ -733,7 +735,7 @@ public function dashboardModuleLinkProvider(): array
'documents' => [
'documents',
[],
'<a href="/documents" class="dashboard-item has-background-module-documents "><span>Documents</span><app-icon icon="carbon:document"></app-icon></a>',
'<a href="/documents" class="dashboard-item has-background-module-documents "><span>Documents</span><app-icon icon="carbon:document"></app-icon><span class="tag mx-05 module-items-counter has-background-module-documents">0</span></a>',
],
];
}
Expand Down Expand Up @@ -822,4 +824,31 @@ public function testModuleIcon(string $name, array $module, string $expected): v
$actual = $layout->moduleIcon($name, $module);
static::assertEquals($expected, $actual);
}

/**
* Test `moduleCount` method.
*
* @return void
* @covers ::moduleCount()
*/
public function testModuleCount(): void
{
$moduleName = 'test';
$viewVars = [];
$request = new ServerRequest();
$view = new View($request, null, null, compact('viewVars'));
$layout = new LayoutHelper($view);
$actual = $layout->moduleCount($moduleName);
static::assertEquals('<span class="tag mx-05 module-items-counter has-background-module-test">0</span>', $actual);

Cache::enable();
$count = 42;
CacheTools::setModuleCount(['meta' => ['pagination' => ['count' => $count]]], $moduleName);
$expected = sprintf('<span class="tag mx-05 module-items-counter has-background-module-test">%s</span>', $count);
$actual = $layout->moduleCount($moduleName);
static::assertEquals($expected, $actual);
$actual = $layout->moduleCount($moduleName, 'my-dummy-css-class');
$expected = sprintf('<span class="tag mx-05 module-items-counter my-dummy-css-class">%s</span>', $count);
Cache::disable();
}
}

0 comments on commit e46e8f1

Please sign in to comment.