Cache pages and page nodes offline
All checks were successful
continuous-integration/drone/push Build is passing
All checks were successful
continuous-integration/drone/push Build is passing
This commit is contained in:
parent
8f5ad697b3
commit
6bcb4bf455
@ -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 }]);
|
||||
}
|
||||
|
@ -870,101 +870,4 @@ export class ApiService {
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
public createPage(name: string): Promise<any> {
|
||||
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,
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
|
@ -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<void> {
|
||||
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<any> {
|
||||
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,
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
|
@ -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'
|
||||
|
@ -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);
|
||||
};
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user