From e7dddcb0038b25bddbbbd8bc6baa19cd4c936ee8 Mon Sep 17 00:00:00 2001 From: Arthur Schiwon Date: Tue, 5 Mar 2024 16:40:17 +0100 Subject: [PATCH] feat(Contexts): add Contexts to navigation when applicable Signed-off-by: Arthur Schiwon --- lib/AppInfo/Application.php | 8 +- lib/Db/ContextMapper.php | 37 ++++++++ .../BeforeTemplateRenderedListener.php | 91 +++++++++++++++++++ lib/Service/ContextService.php | 4 + 4 files changed, 139 insertions(+), 1 deletion(-) create mode 100644 lib/Listener/BeforeTemplateRenderedListener.php diff --git a/lib/AppInfo/Application.php b/lib/AppInfo/Application.php index c5d12b859..48bd542df 100644 --- a/lib/AppInfo/Application.php +++ b/lib/AppInfo/Application.php @@ -6,6 +6,7 @@ use OCA\Analytics\Datasource\DatasourceEvent; use OCA\Tables\Capabilities; use OCA\Tables\Listener\AnalyticsDatasourceListener; +use OCA\Tables\Listener\BeforeTemplateRenderedListener; use OCA\Tables\Listener\LoadAdditionalListener; use OCA\Tables\Listener\TablesReferenceListener; use OCA\Tables\Listener\UserDeletedListener; @@ -18,6 +19,7 @@ use OCP\AppFramework\Bootstrap\IBootContext; use OCP\AppFramework\Bootstrap\IBootstrap; use OCP\AppFramework\Bootstrap\IRegistrationContext; +use OCP\AppFramework\Http\Events\BeforeTemplateRenderedEvent; use OCP\Collaboration\Reference\RenderReferenceEvent; use OCP\Collaboration\Resources\LoadAdditionalScriptsEvent; use OCP\IConfig; @@ -35,6 +37,10 @@ class Application extends App implements IBootstrap { public const OWNER_TYPE_USER = 0; + public const NAV_ENTRY_MODE_HIDDEN = 0; + public const NAV_ENTRY_MODE_RECIPIENTS = 1; + public const NAV_ENTRY_MODE_ALL = 2; + public function __construct() { parent::__construct(self::APP_ID); } @@ -50,7 +56,7 @@ public function register(IRegistrationContext $context): void { $context->registerEventListener(BeforeUserDeletedEvent::class, UserDeletedListener::class); $context->registerEventListener(DatasourceEvent::class, AnalyticsDatasourceListener::class); $context->registerEventListener(RenderReferenceEvent::class, TablesReferenceListener::class); - + $context->registerEventListener(BeforeTemplateRenderedEvent::class, BeforeTemplateRenderedListener::class); $context->registerEventListener(LoadAdditionalScriptsEvent::class, LoadAdditionalListener::class); $context->registerSearchProvider(SearchTablesProvider::class); diff --git a/lib/Db/ContextMapper.php b/lib/Db/ContextMapper.php index 702af3767..472c6d3d6 100644 --- a/lib/Db/ContextMapper.php +++ b/lib/Db/ContextMapper.php @@ -4,6 +4,7 @@ namespace OCA\Tables\Db; +use OCA\Tables\AppInfo\Application; use OCA\Tables\Errors\NotFoundError; use OCA\Tables\Helper\UserHelper; use OCP\AppFramework\Db\QBMapper; @@ -161,6 +162,42 @@ public function findAll(?string $userId = null): array { return $resultEntities; } + public function findForNavBar(string $userId): array { + $qb = $this->getFindContextBaseQuery($userId); + $qb->andWhere($qb->expr()->andX( + // default + $qb->expr()->gt('n.display_mode', $qb->createNamedParameter(Application::NAV_ENTRY_MODE_HIDDEN, IQueryBuilder::PARAM_INT)), + // user override + $qb->expr()->orX( + $qb->expr()->gt('n2.display_mode', $qb->createNamedParameter(Application::NAV_ENTRY_MODE_HIDDEN, IQueryBuilder::PARAM_INT)), + $qb->expr()->isNull('n2.display_mode'), + ) + )); + + $result = $qb->executeQuery(); + $r = $result->fetchAll(); + + $contextIds = []; + foreach ($r as $row) { + $contextIds[$row['id']] = 1; + } + $contextIds = array_keys($contextIds); + unset($row); + + $resultEntities = []; + foreach ($contextIds as $contextId) { + $workArray = []; + foreach ($r as $row) { + if ($row['id'] === $contextId) { + $workArray[] = $row; + } + } + $resultEntities[] = $this->formatResultRows($workArray, $userId); + } + + return $resultEntities; + } + /** * @throws Exception * @throws NotFoundError diff --git a/lib/Listener/BeforeTemplateRenderedListener.php b/lib/Listener/BeforeTemplateRenderedListener.php new file mode 100644 index 000000000..a592ff3ce --- /dev/null +++ b/lib/Listener/BeforeTemplateRenderedListener.php @@ -0,0 +1,91 @@ + + */ +class BeforeTemplateRenderedListener implements IEventListener { + public function __construct( + protected INavigationManager $navigationManager, + protected IURLGenerator $urlGenerator, + protected IUserSession $userSession, + protected ContextService $contextService, + ) { + } + + /** + * @inheritDoc + */ + public function handle(Event $event): void { + if (!$event instanceof BeforeTemplateRenderedEvent) { + return; + } + + $user = $this->userSession->getUser(); + if ($user === null) { + return; + } + + // temporarily show all + //$contexts = $this->contextService->findForNavigation($user->getUID()); + $contexts = $this->contextService->findAll($user->getUID()); + foreach ($contexts as $context) { + /* temporarily, show all + if ($context->getOwnerType() === Application::OWNER_TYPE_USER + && $context->getOwnerId() === $user->getUID()) { + + + // filter out entries for owners unless it is set to be visible + $skipEntry = true; + foreach ($context->getSharing() as $shareInfo) { + // TODO: integrate into DB query in Mapper + + if (isset($shareInfo['display_mode']) && $shareInfo['display_mode'] === Application::NAV_ENTRY_MODE_ALL) { + // a custom override makes it visible + $skipEntry = false; + break; + } elseif (!isset($shareInfo['display_mode']) && $shareInfo['display_mode_default'] === Application::NAV_ENTRY_MODE_ALL) { + // no custom override, and visible also for owner by default + $skipEntry = false; + break; + } + } + if ($skipEntry) { + continue; + } + } + */ + + $this->navigationManager->add(function () use ($context) { + $iconRelPath = 'material/' . $context->getIcon() . '.svg'; + if (file_exists(__DIR__ . '/../../img/' . $iconRelPath)) { + $iconUrl = $this->urlGenerator->imagePath(Application::APP_ID, $iconRelPath); + } else { + $iconUrl = $this->urlGenerator->imagePath('core', 'places/default-app-icon.svg'); + } + + $contextUrl = $this->urlGenerator->linkToRoute('tables.page.index'); + $contextUrl .= sprintf('#/application/%d', $context->getId()); + + return [ + 'id' => Application::APP_ID . '_application_' . $context->getId(), + 'name' => $context->getName(), + 'href' => $contextUrl, + 'icon' => $iconUrl, + 'order' => 500, + 'type' => 'link', + ]; + }); + } + } +} diff --git a/lib/Service/ContextService.php b/lib/Service/ContextService.php index ee31cc7ad..464a7222f 100644 --- a/lib/Service/ContextService.php +++ b/lib/Service/ContextService.php @@ -77,6 +77,10 @@ public function findAll(?string $userId): array { return $this->contextMapper->findAll($userId); } + public function findForNavigation(string $userId): array { + return $this->contextMapper->findForNavBar($userId); + } + /** * @throws Exception * @throws InternalError