diff --git a/src/app/app.component.ts b/src/app/app.component.ts index b451fa3..b5b423a 100644 --- a/src/app/app.component.ts +++ b/src/app/app.component.ts @@ -22,6 +22,7 @@ import {SearchComponent} from './components/search/Search.component'; import {NodeTypeIcons} from './structures/node-types'; import {NavigationService} from './service/navigation.service'; import {DatabaseService} from './service/db/database.service'; +import {EditorService} from './service/editor.service'; @Component({ selector: 'app-root', @@ -97,6 +98,7 @@ export class AppComponent implements OnInit { protected navService: NavigationService, protected toasts: ToastController, protected db: DatabaseService, + protected editor: EditorService, ) { this.initializeApp(); } @@ -303,7 +305,7 @@ export class AppComponent implements OnInit { { text: 'Create', handler: async args => { - const page = await this.api.createPage(args.name); + const page = await this.editor.createPage(args.name); this.reloadMenuItems().subscribe(); await this.router.navigate(['/editor', { id: page.UUID }]); } diff --git a/src/app/service/api.service.ts b/src/app/service/api.service.ts index 46c7bcf..1fedbd9 100644 --- a/src/app/service/api.service.ts +++ b/src/app/service/api.service.ts @@ -870,101 +870,4 @@ export class ApiService { }); }); } - - public createPage(name: string): Promise { - return new Promise(async (res, rej) => { - // If we're offline, create a stub page to be saved later - if ( this.isOffline ) { - const page = new Page( - Page.getUUID(), - 'New Page', - 'OrgUserId', - true, - true, - '0', - [], - String(new Date()), - String(new Date()), - true, - 'create user id', - 'update user id', - [], - false, - false, - true - ); - - const firstNode = new PageNode( - PageNode.getUUID(), - 'paragraph', - JSON.stringify({ Value: 'Click to edit...' }), - page.UUID, - String(new Date()), - String(new Date()), - 'create user id', - 'update user id', - true - ); - - await firstNode.save(); - - page.NodeIds.push(firstNode.UUID); - await page.save(); - - // Because we're offline, we need to manually create the menu item node - const topLevelItem = await this.db.menuItems.where({ - serverId: 0, - name: 'My Info Tree', - }).first() as MenuItem; - - if ( topLevelItem ) { - const newItem = new MenuItem( - page.Name, - MenuItem.getUUID(), - [], - false, - false, - false, - 'page', - false, - true - ); - - await newItem.save(); - - topLevelItem.childIds.push(newItem.serverId); - await topLevelItem.save(); - } - - return res(page.getSaveRecord()); - } - - // If we're online, the server will handle all of that mess... - this.post('/page/create', { name }).subscribe({ - next: async result => { - const page = new Page( - result.data.UUID, - result.data.Name, - result.data.OrgUserId, - result.data.IsPublic, - result.data.IsVisibleInMenu, - result.data.ParentId, - result.data.NodeIds, - result.data.CreatedAt, - result.data.UpdatedAt, - true, - result.data.CreatedUserId, - result.data.UpdateUserId, - result.data.ChildPageIds, - result.data.noDelete, - result.data.virtual - ); - - await page.save(); - return res(result.data); - }, - error: rej, - }); - }); - } } diff --git a/src/app/service/editor.service.ts b/src/app/service/editor.service.ts index 76c4a51..0bcfafc 100644 --- a/src/app/service/editor.service.ts +++ b/src/app/service/editor.service.ts @@ -8,6 +8,9 @@ import {NavigationService} from './navigation.service'; import {DatabaseService} from './db/database.service'; import {Page} from './db/Page'; import {PageNode} from './db/PageNode'; +import {MenuItem} from './db/MenuItem'; +import {SessionService} from './session.service'; +import {debounce} from '../utility'; export class NoPageLoadedError extends Error { constructor(msg = 'There is no page open for editing.') { @@ -15,17 +18,6 @@ export class NoPageLoadedError extends Error { } } -export function debounce(func: (...args: any[]) => any, timeout?: number) { - let timer: number | undefined; - return (...args: any[]) => { - const next = () => func(...args); - if (timer) { - clearTimeout(timer); - } - timer = setTimeout(next, timeout > 0 ? timeout : 300); - }; -} - @Injectable({ providedIn: 'root' }) @@ -90,6 +82,7 @@ export class EditorService { protected api: ApiService, protected nav: NavigationService, protected db: DatabaseService, + protected session: SessionService, ) { } async startEditing(pageId: string) { @@ -175,6 +168,7 @@ export class EditorService { } async savePage(page: PageRecord): Promise { + console.log('saving page', page); await new Promise(async (res, rej) => { const existingLocalPage = await this.db.pages.where({ UUID: page.UUID }).first() as Page; const saveData = page.toSave(); @@ -343,8 +337,12 @@ export class EditorService { return rej(new ResourceNotAvailableOfflineError()); } + if ( !nodeData.UUID ) { + nodeData.UUID = PageNode.getUUID(); + } + const newLocalNode = new PageNode( - nodeData.UUID || PageNode.getUUID(), + nodeData.UUID, nodeData.Type, JSON.stringify(nodeData.Value), nodeData.PageId, @@ -448,6 +446,7 @@ export class EditorService { baseHost.PageId = this.currentPage.UUID; const host = await this.saveNodeToPage(this.currentPage, baseHost); + console.log('added node to page', host) let placed = false; if ( position === 'before' && positionNodeId ) { @@ -530,7 +529,7 @@ export class EditorService { // If we're offline, return the local record, or throw an error. if ( this.api.isOffline ) { if ( existingLocalPage ) { - return res(existingLocalPage.getSaveRecord()); + return res(new PageRecord(existingLocalPage.getSaveRecord())); } else { return rej(new ResourceNotAvailableOfflineError()); } @@ -618,4 +617,106 @@ export class EditorService { }); }); } + + public createPage(name: string): Promise { + return new Promise(async (res, rej) => { + const userId = this.session.get('user.id'); + if ( !userId ) { + throw new ResourceNotAvailableOfflineError(); + } + + // If we're offline, create a stub page to be saved later + if ( this.api.isOffline ) { + const page = new Page( + Page.getUUID(), + name, + userId, + true, + true, + '0', + [], + String(new Date()), + String(new Date()), + true, + userId, + userId, + [], + false, + false, + true + ); + + const firstNode = new PageNode( + PageNode.getUUID(), + 'paragraph', + JSON.stringify({ Value: 'Click to edit...' }), + page.UUID, + String(new Date()), + String(new Date()), + userId, + userId, + true + ); + + await firstNode.save(); + + page.NodeIds.push(firstNode.UUID); + await page.save(); + + // Because we're offline, we need to manually create the menu item node + const topLevelItem = await this.db.menuItems.where({ + serverId: 0, + name: 'My Info Tree', + }).first() as MenuItem; + + if ( topLevelItem ) { + const newItem = new MenuItem( + page.Name, + page.UUID, + [], + false, + false, + false, + 'page', + false, + true + ); + + await newItem.save(); + + topLevelItem.childIds.push(newItem.serverId); + await topLevelItem.save(); + } + + return res(page.getSaveRecord()); + } + + // If we're online, the server will handle all of that mess... + this.api.post('/page/create', { name }).subscribe({ + next: async result => { + const page = new Page( + result.data.UUID, + result.data.Name, + result.data.OrgUserId, + result.data.IsPublic, + result.data.IsVisibleInMenu, + result.data.ParentId, + result.data.NodeIds, + result.data.CreatedAt, + result.data.UpdatedAt, + true, + result.data.CreatedUserId, + result.data.UpdateUserId, + result.data.ChildPageIds, + result.data.noDelete, + result.data.virtual + ); + + await page.save(); + return res(result.data); + }, + error: rej, + }); + }); + } } diff --git a/src/app/service/session.service.ts b/src/app/service/session.service.ts index 2d466c7..ab98b29 100644 --- a/src/app/service/session.service.ts +++ b/src/app/service/session.service.ts @@ -1,6 +1,6 @@ import { Injectable } from '@angular/core'; import {ApiService} from './api.service'; -import {debounce} from './editor.service'; +import {debounce} from '../utility'; @Injectable({ providedIn: 'root' diff --git a/src/app/utility.ts b/src/app/utility.ts index 1d3de37..9fdc206 100644 --- a/src/app/utility.ts +++ b/src/app/utility.ts @@ -6,3 +6,14 @@ export function uuid_v4() { (c ^ crypto.getRandomValues(new Uint8Array(1))[0] & 15 >> c / 4).toString(16) ); } + +export function debounce(func: (...args: any[]) => any, timeout?: number) { + let timer: number | undefined; + return (...args: any[]) => { + const next = () => func(...args); + if (timer) { + clearTimeout(timer); + } + timer = setTimeout(next, timeout > 0 ? timeout : 300); + }; +}