diff --git a/appinfo/routes.php b/appinfo/routes.php index 8ab1eda21..d1fcbd0e7 100644 --- a/appinfo/routes.php +++ b/appinfo/routes.php @@ -38,6 +38,8 @@ // collectives userSettings API ['name' => 'collectiveUserSettings#pageOrder', 'url' => '/_api/{id}/_userSettings/pageOrder', 'verb' => 'PUT', 'requirements' => ['id' => '\d+']], + ['name' => 'collectiveUserSettings#showRecentPages', 'url' => '/_api/{id}/_userSettings/showRecentPages', 'verb' => 'PUT', + 'requirements' => ['id' => '\d+']], // pages API ['name' => 'page#index', 'url' => '/_api/{collectiveId}/_pages', diff --git a/cypress/e2e/page-landingpage.spec.js b/cypress/e2e/page-landingpage.spec.js index 178c094bb..c6c1fc25e 100644 --- a/cypress/e2e/page-landingpage.spec.js +++ b/cypress/e2e/page-landingpage.spec.js @@ -45,11 +45,30 @@ describe('Page landing page', function() { }) describe('Displays recent pages', function() { - it('Allows to display/close TOC and switch page modes in between', function() { + it('Allows to toggle recent pages widget', function() { cy.get('.recent-pages-widget .recent-page-tile') .contains('Page 2') + + cy.get('.recent-pages-widget .recent-pages-title') .click() + cy.get('.recent-pages-widget .recent-page-tile') + .should('not.exist') + + cy.reload() + cy.get('.recent-pages-widget .recent-page-tile') + .should('not.exist') + cy.get('.recent-pages-widget .recent-pages-title') + .click() + cy.get('.recent-pages-widget .recent-page-tile') + .contains('Page 2') + .click() + }) + + it('Allows to open page from recent pages widget', function() { + cy.get('.recent-pages-widget .recent-page-tile') + .contains('Page 2') + .click() cy.url().should('include', `/apps/collectives/${encodeURIComponent(collective)}/${encodeURIComponent('Page 2')}`) }) }) diff --git a/lib/Controller/CollectiveUserSettingsController.php b/lib/Controller/CollectiveUserSettingsController.php index d2baac0a5..189539eb0 100644 --- a/lib/Controller/CollectiveUserSettingsController.php +++ b/lib/Controller/CollectiveUserSettingsController.php @@ -65,4 +65,23 @@ public function pageOrder(int $id, int $pageOrder): DataResponse { return []; }); } + + /** + * @NoAdminRequired + * + * @param int $id + * @param bool $showRecentPages + * + * @return DataResponse + */ + public function showRecentPages(int $id, bool $showRecentPages): DataResponse { + return $this->prepareResponse(function () use ($id, $showRecentPages): array { + $this->service->setShowRecentPages( + $id, + $this->getUserId(), + $showRecentPages + ); + return []; + }); + } } diff --git a/lib/Db/Collective.php b/lib/Db/Collective.php index 34ebbb395..6a25dbc1e 100644 --- a/lib/Db/Collective.php +++ b/lib/Db/Collective.php @@ -48,6 +48,8 @@ class Collective extends Entity implements JsonSerializable { ]; /** @var int */ public const defaultPageMode = 0; + /** @var bool */ + public const defaultShowRecentPages = true; protected ?string $circleUniqueId = null; protected int $permissions = self::defaultPermissions; diff --git a/lib/Db/CollectiveUserSettings.php b/lib/Db/CollectiveUserSettings.php index d1d1d97cf..28f4a1370 100644 --- a/lib/Db/CollectiveUserSettings.php +++ b/lib/Db/CollectiveUserSettings.php @@ -24,6 +24,7 @@ class CollectiveUserSettings extends Entity implements JsonSerializable { /** @var array */ public const supportedSettings = [ 'page_order', + 'show_recent_pages', ]; protected ?int $collectiveId = null; @@ -81,6 +82,15 @@ public function setPageOrder(int $pageOrder): void { $this->setSetting('page_order', $pageOrder); } + /** + * @param bool $showRecentPages + * + * @throws NotPermittedException + */ + public function setShowRecentPages(bool $showRecentPages): void { + $this->setSetting('show_recent_pages', $showRecentPages); + } + public function jsonSerialize(): array { return [ 'id' => $this->id, diff --git a/lib/Model/CollectiveInfo.php b/lib/Model/CollectiveInfo.php index 19e546b2e..ddbb2da90 100644 --- a/lib/Model/CollectiveInfo.php +++ b/lib/Model/CollectiveInfo.php @@ -19,6 +19,7 @@ * @method bool getShareEditable() * @method void setShareEditable(bool $shareEditable) * @method int getUserPageOrder() + * @method bool getUserShowRecentPages() */ class CollectiveInfo extends Collective { protected string $name; @@ -26,13 +27,15 @@ class CollectiveInfo extends Collective { protected ?string $shareToken; protected bool $shareEditable; protected ?int $userPageOrder; + protected ?bool $userShowRecentPages; public function __construct(Collective $collective, string $name, int $level = Member::LEVEL_MEMBER, ?string $shareToken = null, bool $shareEditable = false, - ?int $userPageOrder = null) { + ?int $userPageOrder = Collective::defaultPageOrder, + ?bool $userShowRecentPages = Collective::defaultShowRecentPages) { $this->id = $collective->getId(); $this->circleUniqueId = $collective->getCircleId(); $this->emoji = $collective->getEmoji(); @@ -44,6 +47,7 @@ public function __construct(Collective $collective, $this->shareToken = $shareToken; $this->shareEditable = $shareEditable; $this->userPageOrder = $userPageOrder; + $this->userShowRecentPages = $userShowRecentPages; } /** @@ -116,6 +120,13 @@ public function setUserPageOrder(int $userPageOrder): void { $this->userPageOrder = $userPageOrder; } + /** + * @param bool $userShowRecentPages + */ + public function setUserShowRecentPages(bool $userShowRecentPages): void { + $this->userShowRecentPages = $userShowRecentPages; + } + /** * @return array */ @@ -135,6 +146,7 @@ public function jsonSerialize(): array { 'shareToken' => $this->shareToken, 'shareEditable' => $this->canEdit() && $this->shareEditable, 'userPageOrder' => $this->userPageOrder, + 'userShowRecentPages' => $this->userShowRecentPages, ]; } } diff --git a/lib/Service/CollectiveHelper.php b/lib/Service/CollectiveHelper.php index c2fa7eab4..f245459b5 100644 --- a/lib/Service/CollectiveHelper.php +++ b/lib/Service/CollectiveHelper.php @@ -52,17 +52,20 @@ public function getCollectivesForUser(string $userId, bool $getLevel = true, boo $circle = $circles[$cid]; $level = $getLevel ? $circle->getInitiator()->getLevel(): 0; $userPageOrder = null; + $userShowRecentPages = null; if ($getUserSettings) { // TODO: merge queries for collective and user settings into one? $settings = $this->collectiveUserSettingsMapper->findByCollectiveAndUser($c->getId(), $userId); $userPageOrder = ($settings ? $settings->getSetting('page_order') : null) ?? Collective::defaultPageOrder; + $userShowRecentPages = ($settings ? $settings->getSetting('show_recent_pages') : null) ?? Collective::defaultShowRecentPages; } $collectiveInfos[] = new CollectiveInfo($c, $circle->getSanitizedName(), $level, null, false, - $userPageOrder); + $userPageOrder, + $userShowRecentPages); } return $collectiveInfos; } diff --git a/lib/Service/CollectiveService.php b/lib/Service/CollectiveService.php index 6f85432b3..69d273c4f 100644 --- a/lib/Service/CollectiveService.php +++ b/lib/Service/CollectiveService.php @@ -291,7 +291,8 @@ public function updateCollective(int $id, $collectiveInfo->getLevel(), $collectiveInfo->getShareToken(), $collectiveInfo->getShareEditable(), - $collectiveInfo->getUserPageOrder()); + $collectiveInfo->getUserPageOrder(), + $collectiveInfo->getUserShowRecentPages()); } /** @@ -322,7 +323,8 @@ public function setPermissionLevel(int $id, $collectiveInfo->getLevel(), $collectiveInfo->getShareToken(), $collectiveInfo->getShareEditable(), - $collectiveInfo->getUserPageOrder()); + $collectiveInfo->getUserPageOrder(), + $collectiveInfo->getUserShowRecentPages()); } /** @@ -351,7 +353,8 @@ public function setPageMode(int $id, $collectiveInfo->getLevel(), $collectiveInfo->getShareToken(), $collectiveInfo->getShareEditable(), - $collectiveInfo->getUserPageOrder()); + $collectiveInfo->getUserPageOrder(), + $collectiveInfo->getUserShowRecentPages()); } /** @@ -380,7 +383,8 @@ public function trashCollective(int $id, string $userId): CollectiveInfo { $collectiveInfo->getLevel(), $collectiveInfo->getShareToken(), $collectiveInfo->getShareEditable(), - $collectiveInfo->getUserPageOrder()); + $collectiveInfo->getUserPageOrder(), + $collectiveInfo->getUserShowRecentPages()); } /** @@ -433,7 +437,8 @@ public function deleteCollective(int $id, string $userId, bool $deleteCircle): C $collectiveInfo->getLevel(), $collectiveInfo->getShareToken(), $collectiveInfo->getShareEditable(), - $collectiveInfo->getUserPageOrder()); + $collectiveInfo->getUserPageOrder(), + $collectiveInfo->getUserShowRecentPages()); } /** @@ -458,6 +463,7 @@ public function restoreCollective(int $id, string $userId): CollectiveInfo { $collectiveInfo->getLevel(), $collectiveInfo->getShareToken(), $collectiveInfo->getShareEditable(), - $collectiveInfo->getUserPageOrder()); + $collectiveInfo->getUserPageOrder(), + $collectiveInfo->getUserShowRecentPages()); } } diff --git a/lib/Service/CollectiveUserSettingsService.php b/lib/Service/CollectiveUserSettingsService.php index bddffbc3e..a75d9e535 100644 --- a/lib/Service/CollectiveUserSettingsService.php +++ b/lib/Service/CollectiveUserSettingsService.php @@ -27,7 +27,7 @@ public function __construct(CollectiveUserSettingsMapper $collectiveUserSettings * @throws NotFoundException * @throws NotPermittedException */ - private function prepareSettings(int $collectiveId, string $userId): CollectiveUserSettings { + private function initSettings(int $collectiveId, string $userId): CollectiveUserSettings { if (null === $this->collectiveMapper->findByIdAndUser($collectiveId, $userId)) { throw new NotFoundException('Collective not found: ' . $collectiveId); } @@ -50,10 +50,29 @@ private function prepareSettings(int $collectiveId, string $userId): CollectiveU * @throws NotPermittedException */ public function setPageOrder(int $collectiveId, string $userId, int $pageOrder): void { - $settings = $this->prepareSettings($collectiveId, $userId); + $settings = $this->initSettings($collectiveId, $userId); + $settings->setPageOrder($pageOrder); + + try { + $this->collectiveUserSettingsMapper->insertOrUpdate($settings); + } catch (Exception $e) { + throw new NotPermittedException($e->getMessage(), 0, $e); + } + } + + /** + * @param int $collectiveId + * @param string $userId + * @param bool $showRecentPages + * + * @throws NotFoundException + * @throws NotPermittedException + */ + public function setShowRecentPages(int $collectiveId, string $userId, bool $showRecentPages): void { + $settings = $this->initSettings($collectiveId, $userId); + $settings->setShowRecentPages($showRecentPages); try { - $settings->setPageOrder($pageOrder); $this->collectiveUserSettingsMapper->insertOrUpdate($settings); } catch (Exception $e) { throw new NotPermittedException($e->getMessage(), 0, $e); diff --git a/src/components/Page/LandingPageWidgets/RecentPagesWidget.vue b/src/components/Page/LandingPageWidgets/RecentPagesWidget.vue index e1b057fce..505adc8e7 100644 --- a/src/components/Page/LandingPageWidgets/RecentPagesWidget.vue +++ b/src/components/Page/LandingPageWidgets/RecentPagesWidget.vue @@ -7,10 +7,10 @@
+ :class="{ 'collapsed': !showRecentPages }" />
-
+
import debounce from 'debounce' -import { mapGetters } from 'vuex' +import { mapActions, mapGetters } from 'vuex' +import { showError } from '@nextcloud/dialogs' import ChevronDownButton from 'vue-material-design-icons/ChevronDown.vue' import ChevronLeftButton from 'vue-material-design-icons/ChevronLeft.vue' import ChevronRightButton from 'vue-material-design-icons/ChevronRight.vue' import RecentPageTile from './RecentPageTile.vue' import WidgetHeading from './WidgetHeading.vue' +import { SET_COLLECTIVE_USER_SETTING_SHOW_RECENT_PAGES } from '../../../store/actions.js' const SLIDE_OFFSET = 198 @@ -58,17 +60,17 @@ export default { WidgetHeading, }, - data() { - return { - showWidget: true, - } - }, - computed: { ...mapGetters([ + 'currentCollective', + 'isPublic', 'recentPages', ]), + showRecentPages() { + return this.currentCollective.userShowRecentPages ?? true + }, + trimmedRecentPages() { return this.recentPages .slice(0, 10) @@ -87,9 +89,20 @@ export default { }, methods: { + ...mapActions({ + dispatchSetUserShowRecentPages: SET_COLLECTIVE_USER_SETTING_SHOW_RECENT_PAGES, + }), + toggleWidget() { - this.showWidget = !this.showWidget - if (this.showWidget) { + if (!this.isPublic) { + this.dispatchSetUserShowRecentPages({ id: this.currentCollective.id, showRecentPages: !this.showRecentPages }) + .catch((error) => { + console.error(error) + showError(t('collectives', 'Could not save recent pages setting for collective')) + }) + } + + if (this.showRecentPages) { this.updateButtons() } }, diff --git a/src/store/actions.js b/src/store/actions.js index d8fd56923..4ff763689 100644 --- a/src/store/actions.js +++ b/src/store/actions.js @@ -20,6 +20,7 @@ export const UPDATE_COLLECTIVE_EDIT_PERMISSIONS = 'UPDATE_COLLECTIVE_EDIT_PERMIS export const UPDATE_COLLECTIVE_SHARE_PERMISSIONS = 'UPDATE_COLLECTIVE_SHARE_PERMISSIONS' export const UPDATE_COLLECTIVE_PAGE_MODE = 'UPDATE_COLLECTIVE_PAGE_MODE' export const SET_COLLECTIVE_USER_SETTING_PAGE_ORDER = 'SET_COLLECTIVE_USER_SETTING_PAGE_ORDER' +export const SET_COLLECTIVE_USER_SETTING_SHOW_RECENT_PAGES = 'SET_COLLECTIVE_USER_SETTING_SHOW_RECENT_PAGES' export const MARK_COLLECTIVE_DELETED = 'MARK_COLLECTIVE_DELETED' export const UNMARK_COLLECTIVE_DELETED = 'UNMARK_COLLECTIVE_DELETED' export const EXPAND_PARENTS = 'EXPAND_PARENTS' diff --git a/src/store/collectives.js b/src/store/collectives.js index 9e5faa795..5e673d463 100644 --- a/src/store/collectives.js +++ b/src/store/collectives.js @@ -32,6 +32,7 @@ import { UPDATE_COLLECTIVE_SHARE_PERMISSIONS, UPDATE_COLLECTIVE_PAGE_MODE, SET_COLLECTIVE_USER_SETTING_PAGE_ORDER, + SET_COLLECTIVE_USER_SETTING_SHOW_RECENT_PAGES, MARK_COLLECTIVE_DELETED, UNMARK_COLLECTIVE_DELETED, GET_COLLECTIVES_FOLDER, @@ -442,6 +443,14 @@ export default { commit(PATCH_COLLECTIVE_WITH_PROPERTY, { id, property: 'userPageOrder', value: pageOrder }) }, + async [SET_COLLECTIVE_USER_SETTING_SHOW_RECENT_PAGES]({ commit, getters }, { id, showRecentPages }) { + commit(PATCH_COLLECTIVE_WITH_PROPERTY, { id, property: 'userShowRecentPages', value: showRecentPages }) + await axios.put( + generateUrl('/apps/collectives/_api/' + id + '/_userSettings/showRecentPages'), + { showRecentPages }, + ) + }, + [MARK_COLLECTIVE_DELETED]({ commit }, collective) { collective.deleted = true commit(ADD_OR_UPDATE_COLLECTIVE, collective) diff --git a/tests/Unit/Db/CollectiveUserSettingsTest.php b/tests/Unit/Db/CollectiveUserSettingsTest.php index 3a173e250..34f980725 100644 --- a/tests/Unit/Db/CollectiveUserSettingsTest.php +++ b/tests/Unit/Db/CollectiveUserSettingsTest.php @@ -58,4 +58,11 @@ public function testSetPageOrderExceptionMax(): void { $this->expectException(NotPermittedException::class); $settings->setPageOrder(max($pageOrders) + 1); } + + public function testSetShowRecentPages(): void { + $settings = new CollectiveUserSettings(); + self::assertEquals(null, $settings->getSetting('show_recent_pages')); + $settings->setShowRecentPages(true); + self::assertEquals(true, $settings->getSetting('show_recent_pages')); + } } diff --git a/tests/Unit/Service/CollectiveServiceTest.php b/tests/Unit/Service/CollectiveServiceTest.php index dcac95b32..f457621b2 100644 --- a/tests/Unit/Service/CollectiveServiceTest.php +++ b/tests/Unit/Service/CollectiveServiceTest.php @@ -211,7 +211,8 @@ public function testCreate(): void { 'canShare' => true, 'shareToken' => null, 'shareEditable' => false, - 'userPageOrder' => null, + 'userPageOrder' => 0, + 'userShowRecentPages' => true, ], $collective->jsonSerialize()); } }