From b7bea4ef5d906cc2bdf6ea85aba1063fec5eeb52 Mon Sep 17 00:00:00 2001
From: Eugen Ciur <eugen@papermerge.com>
Date: Fri, 19 Nov 2021 19:47:33 +0100
Subject: [PATCH] pagination and polymorphic models in the store

---
 app/adapters/application.js           |  3 ++-
 app/adapters/folder.js                | 22 ++++++++++++++++++++++
 app/adapters/node.js                  | 24 ++++++++++++++++++------
 app/base/routing.js                   |  7 +++++--
 app/components/commander/index.hbs    |  2 +-
 app/components/nav/sidebar.hbs        |  1 -
 app/models/folder.js                  |  2 +-
 app/models/user.js                    | 14 ++++++++++++--
 app/routes/application.js             |  3 +--
 app/routes/authenticated/index.js     |  4 +---
 app/routes/authenticated/nodes.js     | 22 +++++++++++++++-------
 app/templates/authenticated/nodes.hbs |  1 +
 12 files changed, 79 insertions(+), 26 deletions(-)
 create mode 100644 app/adapters/folder.js

diff --git a/app/adapters/application.js b/app/adapters/application.js
index 962b6b7..a3ebce1 100644
--- a/app/adapters/application.js
+++ b/app/adapters/application.js
@@ -11,7 +11,7 @@ export default class ApplicationAdapter extends JSONAPIAdapter {
   buildURL(...args) {
     return `${super.buildURL(...args)}/`;
   }
-
+  /*
   pathForType(modelName) {
     let ret = super.pathForType(modelName);
 
@@ -26,6 +26,7 @@ export default class ApplicationAdapter extends JSONAPIAdapter {
 
     return ret;
   }
+  */
 
   @computed('session.data.authenticated.token', 'session.isAuthenticated')
   get headers() {
diff --git a/app/adapters/folder.js b/app/adapters/folder.js
new file mode 100644
index 0000000..87cec5b
--- /dev/null
+++ b/app/adapters/folder.js
@@ -0,0 +1,22 @@
+import ApplicationAdapter from './application';
+
+
+export default class FolderAdapter extends ApplicationAdapter {
+
+  findFolder(folder_id) {
+    let url, ret;
+
+    if (!folder_id) {
+      console.log('FolderAdapter: folder_id is empty.');
+      return;
+    }
+
+    url = this.buildURL('folders', folder_id);
+
+    return this.ajax(url, 'GET').then((folder) => {
+      this.store.pushPayload('folder', folder);
+      ret = this.store.peekRecord('folder', folder.data.id);
+      return ret;
+    });
+  }
+}
diff --git a/app/adapters/node.js b/app/adapters/node.js
index bf8dc0a..c030096 100644
--- a/app/adapters/node.js
+++ b/app/adapters/node.js
@@ -1,17 +1,29 @@
 import ApplicationAdapter from './application';
+import { inject as service } from '@ember/service';
 
 
 export default class NodeAdapter extends ApplicationAdapter {
 
-  findNode(node_id) {
-    let url, ret;
+  @service store;
+
+  async getChildren(node_id) {
+    let url, nodes, folders, docs;
 
     url = this.buildURL('nodes', node_id);
 
-    return this.ajax(url, 'GET', {data: {include: 'children'}}).then((node) => {
-      this.store.pushPayload('folder', node);
-      ret = this.store.peekRecord('folder', node.data.id);
-      return ret;
+    nodes = await fetch(url, {
+      method: 'GET',
+      headers: this.headers
+    }).then(response => response.json());
+
+    nodes.data.map(node => {
+      let normalized_node = this.store.normalize('node', node);
+      this.store.push(normalized_node);
     });
+
+    folders = this.store.peekAll('folder').filter(folder => folder.parent.get('id') == node_id);
+    docs = this.store.peekAll('document').filter(folder => folder.parent.get('id') == node_id);
+
+    return folders.concat(docs);
   }
 }
diff --git a/app/base/routing.js b/app/base/routing.js
index 391363c..4deb041 100644
--- a/app/base/routing.js
+++ b/app/base/routing.js
@@ -4,13 +4,16 @@ import { inject as service } from '@ember/service';
 
 export default class BaseRoute extends Route {
   @service session;
+  @service store;
   @service currentUser;
 
   async beforeModel(transition) {
+
     this.session.requireAuthentication(transition, 'login');
     await this.currentUser.loadCurrentUser();
+
     if (this.currentUser.user) {
-      await this.currentUser.user.home_folder;
+      return this.currentUser.user.getHomeFolder();
     }
   }
 
@@ -19,7 +22,7 @@ export default class BaseRoute extends Route {
 
     let app_controller = this.controllerFor('authenticated');
 
-    this.currentUser.user.home_folder.then((home_folder) => {
+    this.currentUser.user.getHomeFolder().then((home_folder) => {
       app_controller.set('home_folder', home_folder);
     });
 
diff --git a/app/components/commander/index.hbs b/app/components/commander/index.hbs
index abde0d3..1bf84e2 100644
--- a/app/components/commander/index.hbs
+++ b/app/components/commander/index.hbs
@@ -37,7 +37,7 @@
     @hint={{@hint}} />
 
   <div class="view-mode-{{this.view_mode}}">
-    {{#each @node.children as |node|}}
+    {{#each @children as |node|}}
       {{#let (component node.nodeType) as |NodeType|}}
         {{! NodeType is either <Folder /> or <Document />}}
         <NodeType
diff --git a/app/components/nav/sidebar.hbs b/app/components/nav/sidebar.hbs
index 01d0dc7..ddb3caf 100644
--- a/app/components/nav/sidebar.hbs
+++ b/app/components/nav/sidebar.hbs
@@ -1,5 +1,4 @@
 <div class="d-flex flex-column flex-shrink-0 p-3 text-white bg-dark sidebar-open" >
-    {{this.args.homeFolder}}
     <LinkTo
         @route="authenticated.nodes"
         @model="{{@home_folder.id}}"
diff --git a/app/models/folder.js b/app/models/folder.js
index d4581d3..6e5d9b0 100644
--- a/app/models/folder.js
+++ b/app/models/folder.js
@@ -1,6 +1,6 @@
-import { attr } from '@ember-data/model';
 import NodeModel from './node';
 
+
 export default class FolderModel extends NodeModel {
 
   get nodeType() {
diff --git a/app/models/user.js b/app/models/user.js
index c5a153a..5fbbbf4 100644
--- a/app/models/user.js
+++ b/app/models/user.js
@@ -1,5 +1,6 @@
 import Model, { attr, belongsTo } from '@ember-data/model';
 
+
 class UserModel extends Model {
   @attr username;
   @attr email;
@@ -12,14 +13,23 @@ class UserModel extends Model {
   @attr created_at;
   @attr updated_at;
   @belongsTo('role') role;
-  @belongsTo('node') home_folder;
-  @belongsTo('node') inbox_folder;
+  @belongsTo('folder') home_folder;
+  @belongsTo('folder') inbox_folder;
 
   changePassword(new_password) {
     const adapter = this.store.adapterFor('user');
 
     return adapter.changePassword(this, new_password);
   }
+
+  async getHomeFolder() {
+    let home_id, folder_adapter;
+
+    home_id = this.home_folder.get('id');
+    folder_adapter = this.store.adapterFor('folder');
+
+    return folder_adapter.findFolder(home_id);
+  }
 }
 
 export default UserModel;
diff --git a/app/routes/application.js b/app/routes/application.js
index 2121fb9..88f2c9d 100644
--- a/app/routes/application.js
+++ b/app/routes/application.js
@@ -7,8 +7,7 @@ export default class ApplicationRoute extends BaseRoute {
 
   async model() {
     if (this.currentUser.isAuthenticated) {
-      console.log("ApplicationRoute: current user is authenticated");
-      return this.currentUser.user.home_folder;
+      return this.currentUser.user.getHomeFolder();
     }
   }
 
diff --git a/app/routes/authenticated/index.js b/app/routes/authenticated/index.js
index 7fb4145..e763300 100644
--- a/app/routes/authenticated/index.js
+++ b/app/routes/authenticated/index.js
@@ -11,11 +11,9 @@ export default class IndexRoute extends Route {
     /* Redirects to user's home folder
     */
     let that = this;
-
     this.session.requireAuthentication(transition, 'login');
     await this.currentUser.loadCurrentUser();
-
-    this.currentUser.user.home_folder.then((home_folder) => {
+    this.currentUser.user.getHomeFolder().then((home_folder) => {
       that.replaceWith("authenticated.nodes", home_folder.id);
     });
   }
diff --git a/app/routes/authenticated/nodes.js b/app/routes/authenticated/nodes.js
index b74453f..7bd0fb2 100644
--- a/app/routes/authenticated/nodes.js
+++ b/app/routes/authenticated/nodes.js
@@ -20,12 +20,17 @@ export default class FolderRoute extends Route {
     let adapter,
       doc_adapter,
       page_adapter,
+      folder_adapter,
       pages,
+      current_node,
       pages_with_url,
-      document_version;
+      document_version,
+      children,
+      home_folder;
 
     adapter = this.store.adapterFor('node');
     page_adapter = this.store.adapterFor('page');
+    folder_adapter = this.store.adapterFor('folder');
     doc_adapter = this.store.adapterFor('document');
 
     await this.currentUser.loadCurrentUser();
@@ -51,13 +56,16 @@ export default class FolderRoute extends Route {
       });
     }
 
-    return RSVP.hash({
-      node: adapter.findNode(params.node_id),
-      home_folder: this.currentUser.user.home_folder
-    });
+    children = await adapter.getChildren(params.node_id);
+    home_folder = await this.currentUser.user.getHomeFolder();
+    current_node = await this.store.findRecord('folder', params.node_id);
+
+    return {current_node, home_folder, children};
+
   }
 
   setupController(controller, model) {
+
     let _controller = this.controllerFor('authenticated.nodes'),
       _auth_controller = this.controllerFor('authenticated');
 
@@ -73,8 +81,8 @@ export default class FolderRoute extends Route {
       _controller.set('dualpanel_mode', false);
       _controller.set('extranode', undefined);
     }
-
-    _controller.set('mainnode', model.node);
+    _controller.set('mainnode', model.current_node);
     _auth_controller.set('home_folder', model.home_folder);
+    _controller.set('children', model.children);
   }
 }
diff --git a/app/templates/authenticated/nodes.hbs b/app/templates/authenticated/nodes.hbs
index 714b27b..88c74b8 100644
--- a/app/templates/authenticated/nodes.hbs
+++ b/app/templates/authenticated/nodes.hbs
@@ -2,6 +2,7 @@
   <Commander
     @node={{this.mainnode}}
     @extranode={{this.extranode}}
+    @children={{this.children}}
     @onPanelToggle={{this.onPanelToggle}}
     @dualPanelMode={{this.dualpanel_mode}}
     @hint="left" />
-- 
GitLab