From 2f3d94adf332a7edb9e978f971ee153cffa521c4 Mon Sep 17 00:00:00 2001 From: garrettmills Date: Thu, 18 Feb 2021 10:18:57 -0600 Subject: [PATCH] Noded/frontend#86 Store user bookmarks in their preferences --- app/controllers/api/v1/Menu.controller.js | 55 ++++++++++++++++++-- app/controllers/api/v1/Session.controller.js | 5 ++ app/models/auth/User.model.js | 15 ++++++ 3 files changed, 71 insertions(+), 4 deletions(-) diff --git a/app/controllers/api/v1/Menu.controller.js b/app/controllers/api/v1/Menu.controller.js index a13f046..0763fef 100644 --- a/app/controllers/api/v1/Menu.controller.js +++ b/app/controllers/api/v1/Menu.controller.js @@ -26,9 +26,21 @@ class Menu extends Controller { .api() } - const nodes = await this._build_menu_object(root_page, [], page_only) + const nodes = await this._build_menu_object(req.user, root_page, [], page_only) const menu = [] + if ( req.user.preferences?.bookmark_page_ids?.length ) { + menu.push({ + id: 0, + name: 'My Bookmarks', + children: await this.get_bookmarks(req.user), + noDelete: true, + noChildren: true, + virtual: true, + type: PageType.Branch, + }) + } + const virtual_page = { id: root_page.UUID, children: [...(await root_page.get_menu_items(page_only)), ...nodes], @@ -57,9 +69,21 @@ class Menu extends Controller { // Build the "My Tree" option const root_page = await req.user.get_root_page() - const nodes = await this._build_menu_object(root_page, [], page_only) + const nodes = await this._build_menu_object(req.user, root_page, [], page_only) const menu = [] + if ( req.user.preferences?.bookmark_page_ids?.length ) { + menu.push({ + id: 0, + name: 'My Bookmarks', + children: await this.get_bookmarks(req.user), + noDelete: true, + noChildren: true, + virtual: true, + type: PageType.Branch, + }) + } + menu.push({ id: 0, name: 'My Info Tree', @@ -82,6 +106,7 @@ class Menu extends Controller { children: await this._build_secure_menu_object(tree, req.user), level: await tree.access_level_for(req.user), type: tree.PageType || PageType.Note, + bookmark: (req.user.preferences.bookmark_page_ids || []).includes(tree.UUID), }) } @@ -96,6 +121,7 @@ class Menu extends Controller { children: await this._build_secure_menu_object(tree, req.user), level: await tree.access_level_for(req.user), type: tree.PageType || PageType.Note, + bookmark: (req.user.preferences.bookmark_page_ids || []).includes(tree.UUID), }) } @@ -110,6 +136,7 @@ class Menu extends Controller { children: await this._build_secure_menu_object(tree, req.user), level: await tree.access_level_for(req.user), type: tree.PageType || PageType.Note, + bookmark: (req.user.preferences.bookmark_page_ids || []).includes(tree.UUID), }) } @@ -126,6 +153,24 @@ class Menu extends Controller { return res.api(menu) } + async get_bookmarks(user) { + const pages = await user.get_bookmarked_pages() + const items = [] + + for ( const page of pages ) { + items.push({ + id: page.UUID, + name: page.is_shared() ? page.Name + ' ⁽ˢʰᵃʳᵉᵈ⁾' : page.Name, + shared: page.is_shared(), + bookmark: true, + type: page.PageType || PageType.Note, + children: [], + }) + } + + return items + } + async move_node(req, res, next) { const Page = this.models.get('api:Page'); @@ -181,7 +226,7 @@ class Menu extends Controller { return res.api(); } - async _build_menu_object(parent_node, arr= [], page_only = false) { + async _build_menu_object(user, parent_node, arr= [], page_only = false) { const children = await this.models.get('api:Page').find({UUID: {$in: parent_node.ChildPageIds}}) if ( children ) { for ( const child of children ) { @@ -189,8 +234,9 @@ class Menu extends Controller { id: child.UUID, name: child.is_shared() ? child.Name + ' ⁽ˢʰᵃʳᵉᵈ⁾' : child.Name, shared: child.is_shared(), - children: [...(await child.get_menu_items(page_only)), ...(await this._build_menu_object(child, [], page_only))], + children: [...(await child.get_menu_items(page_only)), ...(await this._build_menu_object(user, child, [], page_only))], type: child.PageType || PageType.Note, + bookmark: (user.preferences.bookmark_page_ids || []).includes(child.UUID), }) } } @@ -209,6 +255,7 @@ class Menu extends Controller { children: await this._build_secure_menu_object(child, user), level: await child.access_level_for(user), type: child.PageType || PageType.Note, + bookmark: (user.preferences.bookmark_page_ids || []).includes(child.UUID), }) } } diff --git a/app/controllers/api/v1/Session.controller.js b/app/controllers/api/v1/Session.controller.js index a8c0011..d8b418a 100644 --- a/app/controllers/api/v1/Session.controller.js +++ b/app/controllers/api/v1/Session.controller.js @@ -21,6 +21,10 @@ class SessionController extends Controller { } req.user.preferences.auto_prefetch = !!save_prefs.auto_prefetch + + if ( Array.isArray(save_prefs.bookmark_page_ids) ) { + req.user.preferences.bookmark_page_ids = save_prefs.bookmark_page_ids + } } await req.user.save() @@ -34,6 +38,7 @@ class SessionController extends Controller { username: user.uid, preferences: user.preferences || {}, is_public_user: user.is_public_user(), + bookmark_page_ids: user.preferences.bookmark_page_ids, }, app: { name: this.configs.get('app.name'), diff --git a/app/models/auth/User.model.js b/app/models/auth/User.model.js index 7e12203..ca15672 100644 --- a/app/models/auth/User.model.js +++ b/app/models/auth/User.model.js @@ -18,6 +18,7 @@ class User extends AuthUser { dark_mode: { type: Boolean, default: false }, auto_prefetch: { type: Boolean, default: false }, default_page: String, + bookmark_page_ids: [String], }, }} } @@ -27,6 +28,20 @@ class User extends AuthUser { return Page.findOne({OrgUserId: this._id, ParentId: '0'}) } + async get_bookmarked_pages() { + const Page = this.models.get('api:Page') + const pages = await Page.find({ UUID: { $in: this.preferences.bookmark_page_ids || [] }}) + + const visible = [] + for ( const page of pages ) { + if ( await page.is_accessible_by(this) ) { + visible.push(page) + } + } + + return visible + } + async get_accessible_pages() { const Page = this.models.get('api:Page') const user_page = await this.get_root_page()