Skip to content

Commit

Permalink
Add button to load unsaved edits from localstorage
Browse files Browse the repository at this point in the history
  • Loading branch information
minottic authored Jan 26, 2024
1 parent 870c0f8 commit fa0dacb
Show file tree
Hide file tree
Showing 3 changed files with 86 additions and 25 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,9 @@ <h2 mat-dialog-title>{{ dialogTitle }}</h2>
<!-- apparently, this can also be achieved by using [(ngModel)]="postData.content" debounce="300" -->
<tag-editor [tagIn]="tag" (tagsUpdate)="updateTags($event)" [config]="config" [syncAtStart]="false"></tag-editor>
</mat-dialog-content>
<button (click)="loadLastUnsavedEdit()" [disabled]="noUnsavedEditTooltip()" matTooltip="{{ noUnsavedEditTooltip() }}">
Load last unsaved edit
</button>
<mat-dialog-actions align="end">
<button mat-button mat-dialog-close *ngIf="!liveFeedback">Cancel</button>
<button mat-button [mat-dialog-close]="true" (click)="addContent($event)">{{ addButtonLabel }}</button>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ describe('AddContentComponent', () => {
{ provide: MAT_DIALOG_DATA, useValue: {} },
{ provide: MatDialogRef, useValue: {} },
{ provide: AddContentService, useClass: AddContentServiceMock },
{ provide: AppConfigService, useValue: { getConfig } }
{ provide: AppConfigService, useValue: { getConfig } },
],
declarations: [AddContentComponent]
})
Expand Down Expand Up @@ -118,14 +118,18 @@ describe('AddContentComponent', () => {
expect(component.liveFeedback).toBe(false);
expect(component.addButtonLabel).toBe("Done");
expect(component.sendMessage).toHaveBeenCalledTimes(1);
expect(component.editStorageKey).toEqual('6061d9a13587f37b851694d6LastEdit');
});

it('should get data from editor before sending', () => {
component.setupComponent();
component.editor = jasmine.createSpyObj("component.editor", ["getData"])
const localStorageSpy = spyOn(localStorage, 'removeItem');
component.editStorageKey = '123LastEdit';
component.addContent("");
expect(component.editor.getData).toHaveBeenCalled();
})
expect(localStorageSpy).toHaveBeenCalledOnceWith('123LastEdit');
});

it('should get edit data from editor before sending', () => {
component.setupComponent();
Expand All @@ -135,7 +139,8 @@ describe('AddContentComponent', () => {
component.addContent("");
expect(component.editor.getData).toHaveBeenCalled();
expect(component.notification.snippetType).toEqual('paragraph');
})
expect(component.editStorageKey).toEqual(undefined);
});

it('should prepare quote', () => {
let quoted_snippet = {
Expand Down Expand Up @@ -188,7 +193,7 @@ describe('AddContentComponent', () => {
expect(component.metadataPanelExpanded).toBe(false);
component.toggleMetadataPanel();
expect(component.metadataPanelExpanded).toBe(true);
})
});

it('should update tags', () => {
spyOn(component, 'changeChain')
Expand All @@ -197,13 +202,13 @@ describe('AddContentComponent', () => {
expect(component.contentChanged).toBe(true);
expect(component.tag).toEqual(defaultTags);
expect(component.changeChain).toHaveBeenCalledTimes(1);
})
});

it('should send message', () => {
spyOn(component['dataService'], 'changeMessage');
component.sendMessage();
expect(component['dataService'].changeMessage).toHaveBeenCalledWith(component.notification);
})
});

it('should adjust figure HTML content for ckeditor', () => {
let figureMockNoSize = '<figure class="image"><img src="source" title="d3cc95ad-45d5-48c4-ba0e-db6fcfd252ce"></figure>';
Expand All @@ -223,8 +228,7 @@ describe('AddContentComponent', () => {
component.data = figureMockSizeBefore;
component.adjustContentForEditor();
expect(component.data).toBe(figureMockSizeAfter);

})
});


it('should adjust figure HTML content with links for ckeditor ', () => {
Expand All @@ -239,8 +243,7 @@ describe('AddContentComponent', () => {
component.data = figureMockSizeBefore;
component.adjustContentForEditor();
expect(component.data).toBe(figureMockSizeAfter);

})
});

it('should extract notification with new files', () => {
let figureMock = '<figure class="image image_resized" style="width:79%;"><img src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAEjgAAA2oCAIAAACtz6bAAAAACXBIWXMAAHsIAAB7CAF"></figure>"';
Expand All @@ -254,8 +257,7 @@ describe('AddContentComponent', () => {
expect(message.files[0].fileHash).toBeTruthy();
combineHtmlFigureHash(figureMockNoSrc, message.files[0].fileHash)
expect(message.textcontent).toEqual(combineHtmlFigureHash(figureMockNoSrc, message.files[0].fileHash));

})
});

it('should extract notification without files', () => {
let figureMock = '<figure class="image image_resized" style="width:79%;"><img src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAEjgAAA2oCAIAAACtz6bAAAAACXBIWXMAAHsIAAB7CAF"></figure>"'
Expand All @@ -268,18 +270,16 @@ describe('AddContentComponent', () => {
expect(message.files[0].fileHash).toBeTruthy();
combineHtmlFigureHash(figureMockNoSrc, message.files[0].fileHash)
expect(message.textcontent).toEqual(combineHtmlFigureHash(figureMockNoSrc, message.files[0].fileHash));

})
});

it('should extract links', () => {
let linkMock = '<p><a class="fileLink" href="file:myHash">myFile.pdf</a></p>'
let linkStorageMock = [{ fileHash: "myHash" }];
let message = extractNotificationMessage(linkMock, linkStorageMock);
expect(message.files[0].fileHash).toEqual("myHash")
})
});

it('should prepare subsnippets container for quotes', () => {

component.notification = notificationMock;
component.prepareSubsnippetsQuoteContainer();
expect(component.notification.subsnippets[0].id).toBeFalsy();
Expand All @@ -291,48 +291,86 @@ describe('AddContentComponent', () => {
expect(component.notification.subsnippets[0].defaultOrder).toBeFalsy();
expect(component.notification.subsnippets[0].subsnippets).toBeFalsy();
expect(component.notification.subsnippets[0].linkType).toBe(LinkType.QUOTE);

})
});

it('should send a message if notification is edit', () => {
spyOn(component, 'sendMessage');
component.notification.snippetType = 'edit';
component.changeChain(notificationMock);
expect(component.sendMessage).toHaveBeenCalledTimes(1);
})
});

it('should not send messages if notification is not edit', () => {
spyOn(component, 'sendMessage');
component.changeChain(notificationMock);
expect(component.sendMessage).toHaveBeenCalledTimes(0);
})
});

it('should mark for deletion and send message', () => {
spyOn(component, 'sendMessage');
component.dialogTitle = 'Modify data snippet';
component['sendEditDelitionMessage']();
expect(component.sendMessage).toHaveBeenCalledTimes(1);
expect(component.notification.toDelete).toEqual(true);
})
});

it('should not mark for deletion and send message', () => {
spyOn(component, 'sendMessage');
component.sendEditDelitionMessage();
expect(component.sendMessage).toHaveBeenCalledTimes(0);
})
});


it('should unset the logbook on unload', () => {
spyOn(component, 'sendEditDelitionMessage');
const unloadEvent = new Event('unload');
window.dispatchEvent(unloadEvent);
expect(component.sendEditDelitionMessage).toHaveBeenCalledTimes(1);
})
});

it('should unset the logbook on destroy', () => {
spyOn(component, 'sendEditDelitionMessage');
component.ngOnDestroy();
expect(component.sendEditDelitionMessage).toHaveBeenCalledTimes(1);
})
});

[
{input: undefined, output: 'No unsaved edit in current session'},
{input: 'sameData', output: 'No unsaved edit in current session'},
{input: 'edit', output: undefined},
].forEach((t, i) => {
it(`should test noUnsavedEditTooltip ${i}`, () => {
component.lastEdit = t.input;
if (t.input === 'sameData') component.data = t.input;
expect(component.noUnsavedEditTooltip()).toEqual(t.output);
});
});

it('should test setLocalStorage', () => {
component.message = {id: 123};
const localStorageSpy = spyOn(localStorage, 'getItem');
component['setLocalStorage']();
expect(localStorageSpy).toHaveBeenCalledOnceWith('123LastEdit');
});

[undefined, 'edit'].forEach((t, i) => {
it(`should test loadLastUnsavedEdit ${i}`, () => {
component.lastEdit = t;
component.editor = jasmine.createSpyObj("component.editor", ["setData"]);
component.loadLastUnsavedEdit();
expect(component.editor.setData).toHaveBeenCalledTimes(t? 1: 0);
if (t)
expect(component.editor.setData).toHaveBeenCalledOnceWith(t);
});
});

it('should test onChange', () => {
component.editStorageKey = '123LastEdit';
const editor = {getData: () => 'edit'};
const localStorageSpy = spyOn(localStorage, 'setItem');
component.onChange({editor: editor});
expect(localStorageSpy).toHaveBeenCalledOnceWith('123LastEdit', 'edit');
});

function combineHtmlFigureHash(figureMock: string[], hash: string) {
return (figureMock[0] + ' title="' + hash + '"' + figureMock[1]);
Expand Down
22 changes: 21 additions & 1 deletion scilog/src/app/logbook/core/add-content/add-content.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,8 @@ export class AddContentComponent implements OnInit {
prel_fileStorage: any[] = [];
config: any = [];
editor: any;
editStorageKey: string;
lastEdit: string;

constructor(
private dataService: AddContentService,
Expand Down Expand Up @@ -102,6 +104,7 @@ export class AddContentComponent implements OnInit {

if (this.message.id) {
this.notification = this.message;
this.setLocalStorage();
this.notification.snippetType = 'edit';
this.notification.toDelete = false;
this.liveFeedback = false;
Expand Down Expand Up @@ -130,6 +133,11 @@ export class AddContentComponent implements OnInit {
return;
}

private setLocalStorage() {
this.editStorageKey = `${this.message.id}LastEdit`;
this.lastEdit = localStorage.getItem(this.editStorageKey);
}

onEditorReady(editor: any) {
console.log(Array.from(editor.ui.componentFactory.names()));
editor.ui.getEditableElement().parentElement.insertBefore(
Expand All @@ -154,11 +162,13 @@ export class AddContentComponent implements OnInit {
}
if (this.notification.snippetType === 'edit' && this.contentChanged)
this.notification.snippetType = 'paragraph';
localStorage.removeItem(this.editStorageKey);
this.prepareMessage(this.data);
this.sendMessage();
};

onChange({ editor }: ChangeEvent) {
localStorage.setItem(this.editStorageKey, editor.getData());
// this.editorChange(editor);
this.contentChanged = true;
}
Expand All @@ -168,7 +178,6 @@ export class AddContentComponent implements OnInit {
if (typeof editor != "undefined") {
const data = editor.getData();
this.prel_fileStorage = editor['prel_fileStorage'];
this.contentChanged = false;
this.changeChain(data);
}
}
Expand Down Expand Up @@ -240,6 +249,11 @@ export class AddContentComponent implements OnInit {

}

loadLastUnsavedEdit() {
if (this.lastEdit)
this.editor.setData(this.lastEdit);
}

updateTags(tags: string[]) {
this.tag = tags;
this.contentChanged = true;
Expand All @@ -250,6 +264,11 @@ export class AddContentComponent implements OnInit {
this.metadataPanelExpanded = !this.metadataPanelExpanded;
}

noUnsavedEditTooltip() {
if (!this.lastEdit || this.lastEdit === this.data)
return 'No unsaved edit in current session';
}

ngOnDestroy(): void {
this.sendEditDelitionMessage();
console.log("deleting add-content subscriptions")
Expand All @@ -265,6 +284,7 @@ export class AddContentComponent implements OnInit {
}
}

@HostListener('window:beforeunload')
@HostListener('window:unload')
onUnload() {
this.sendEditDelitionMessage();
Expand Down

0 comments on commit fa0dacb

Please sign in to comment.