Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

SF-3083 Resolve icon should change when editing resolved note #2964

Merged
merged 1 commit into from
Jan 23, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -367,15 +367,63 @@ describe('BiblicalTermsComponent', () => {
env.setupProjectData('en');
env.wait();

// SUT
env.biblicalTermsNotesButton.click();
env.wait();
env.mockNoteDialogRef.close({ status: NoteStatus.Resolved });
env.wait();

verify(mockedMatDialog.open(NoteDialogComponent, anything())).once();
const noteThread: NoteThread = env.getNoteThreadDoc(projectId, 'threadId01').data!;
expect(noteThread.status).toEqual(NoteStatus.Resolved);
expect(noteThread.status).toBe(NoteStatus.Resolved);
expect(noteThread.notes[1].content).toBeUndefined();
expect(noteThread.notes[1].status).toBe(NoteStatus.Resolved);
}));

it('can resolve and edit a note for a biblical term', fakeAsync(async () => {
const projectId = 'project01';
const newContent = 'Updated Note Content';
const env = new TestEnvironment(projectId, 1, 1);
env.setupProjectData('en');
env.wait();

// Make the note editable
const noteThreadDoc: NoteThreadDoc = env.getNoteThreadDoc(projectId, 'threadId01');
await noteThreadDoc.submitJson0Op(op => op.set(nt => nt.notes[0].editable, true));

// SUT
env.biblicalTermsNotesButton.click();
env.wait();
env.mockNoteDialogRef.close({ status: NoteStatus.Resolved, noteContent: newContent, noteDataId: 'note01' });
env.wait();

verify(mockedMatDialog.open(NoteDialogComponent, anything())).once();
const noteThread: NoteThread = env.getNoteThreadDoc(projectId, 'threadId01').data!;
expect(noteThread.status).toBe(NoteStatus.Resolved);
expect(noteThread.notes[0].content).toBe(newContent);
expect(noteThread.notes[0].status).toBe(NoteStatus.Resolved);
}));

it('cannot resolve a non-editable note for a biblical term', fakeAsync(() => {
const projectId = 'project01';
const env = new TestEnvironment(projectId, 1, 1);
env.setupProjectData('en');
env.wait();

// Stub the error message display
const dialogMessage = spyOn((env.component as any).dialogService, 'message').and.stub();

// SUT
env.biblicalTermsNotesButton.click();
env.wait();
env.mockNoteDialogRef.close({ status: NoteStatus.Resolved, noteDataId: 'note01' });
env.wait();

verify(mockedMatDialog.open(NoteDialogComponent, anything())).once();
const noteThread: NoteThread = env.getNoteThreadDoc(projectId, 'threadId01').data!;
expect(noteThread.status).toEqual(NoteStatus.Todo);
expect(noteThread.notes.length).toBe(1);
expect(dialogMessage).toHaveBeenCalledTimes(1);
}));

it('should show the not found message if no messages were found', fakeAsync(() => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -550,6 +550,7 @@ export class BiblicalTermsComponent extends DataLoadingComponent implements OnDe
const currentDate: string = new Date().toJSON();
const threadId = `BT_${biblicalTermDoc.data.termId}`;
const noteContent: string | undefined = params.content == null ? undefined : XmlUtils.encodeForXml(params.content);
const noteStatus: NoteStatus = params.status ?? NoteStatus.Todo;
// Configure the note
const note: Note = {
dateCreated: currentDate,
Expand All @@ -561,7 +562,7 @@ export class BiblicalTermsComponent extends DataLoadingComponent implements OnDe
content: noteContent,
conflictType: NoteConflictType.DefaultValue,
type: NoteType.Normal,
status: params.status ?? NoteStatus.Todo,
status: noteStatus,
deleted: false,
editable: true,
versionNumber: 1
Expand Down Expand Up @@ -597,10 +598,18 @@ export class BiblicalTermsComponent extends DataLoadingComponent implements OnDe
);
const noteIndex: number = threadDoc.data!.notes.findIndex(n => n.dataId === params.dataId);
if (noteIndex >= 0) {
await threadDoc!.submitJson0Op(op => {
op.set(t => t.notes[noteIndex].content, noteContent);
op.set(t => t.notes[noteIndex].dateModified, currentDate);
});
// updated the existing note
if (threadDoc.data?.notes[noteIndex].editable === true) {
await threadDoc!.submitJson0Op(op => {
op.set(t => t.notes[noteIndex].content, noteContent);
op.set(t => t.notes[noteIndex].dateModified, currentDate);
op.set(t => t.notes[noteIndex].status, noteStatus);
// also set the status of the thread to be the status of the note
op.set(t => t.status, noteStatus);
});
} else {
this.dialogService.message('biblical_terms.cannot_edit_note_paratext');
}
} else {
note.threadId = threadDoc.data!.threadId;
await threadDoc.submitJson0Op(op => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3025,6 +3025,54 @@ describe('EditorComponent', () => {
env.dispose();
}));

it('allows editing and resolving a note', fakeAsync(async () => {
const projectId: string = 'project01';
const threadDataId: string = 'dataid01';
const content: string = 'This thread is resolved.';
const env = new TestEnvironment();
let noteThread: NoteThreadDoc = env.getNoteThreadDoc(projectId, threadDataId);
expect(noteThread.data!.notes.length).toEqual(3);
// Mark the note as editable
await noteThread.submitJson0Op(op => op.set(nt => nt.notes[0].editable, true));
env.setProjectUserConfig();
env.wait();
let noteThreadIconElem: HTMLElement | null = env.getNoteThreadIconElement('verse_1_1', threadDataId);
noteThreadIconElem!.click();
verify(mockedMatDialog.open(NoteDialogComponent, anything())).once();
env.mockNoteDialogRef.close({ noteContent: content, status: NoteStatus.Resolved, noteDataId: 'thread01_note0' });
env.wait();
noteThread = env.getNoteThreadDoc(projectId, threadDataId);
expect(noteThread.data!.notes.length).toEqual(3);
expect(noteThread.data!.notes[0].content).toEqual(content);
expect(noteThread.data!.notes[0].status).toEqual(NoteStatus.Resolved);

// the icon should be hidden from the editor
noteThreadIconElem = env.getNoteThreadIconElement('verse_1_1', threadDataId);
expect(noteThreadIconElem).toBeNull();
env.dispose();
}));

it('does not allow editing and resolving a non-editable note', fakeAsync(() => {
const projectId: string = 'project01';
const threadDataId: string = 'dataid01';
const content: string = 'This thread is resolved.';
const env = new TestEnvironment();
const dialogMessage = spyOn((env.component as any).dialogService, 'message').and.stub();
let noteThread: NoteThreadDoc = env.getNoteThreadDoc(projectId, threadDataId);
expect(noteThread.data!.notes.length).toEqual(3);
env.setProjectUserConfig();
env.wait();
let noteThreadIconElem: HTMLElement | null = env.getNoteThreadIconElement('verse_1_1', threadDataId);
noteThreadIconElem!.click();
verify(mockedMatDialog.open(NoteDialogComponent, anything())).once();
env.mockNoteDialogRef.close({ noteContent: content, status: NoteStatus.Resolved, noteDataId: 'thread01_note0' });
env.wait();
noteThread = env.getNoteThreadDoc(projectId, threadDataId);
expect(noteThread.data!.notes.length).toEqual(3);
expect(dialogMessage).toHaveBeenCalledTimes(1);
env.dispose();
}));

it('can open dialog of the second note on the verse', fakeAsync(() => {
const env = new TestEnvironment();
env.setProjectUserConfig();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1366,6 +1366,7 @@ export class EditorComponent extends DataLoadingComponent implements OnDestroy,
const tagId: number | undefined =
params.threadDataId == null ? this.projectDoc?.data?.translateConfig.defaultNoteTagId : undefined;
const noteContent: string | undefined = params.content == null ? undefined : XmlUtils.encodeForXml(params.content);
const noteStatus: NoteStatus = params.status ?? NoteStatus.Todo;
// Configure the note
const note: Note = {
dateCreated: currentDate,
Expand All @@ -1377,7 +1378,7 @@ export class EditorComponent extends DataLoadingComponent implements OnDestroy,
content: noteContent,
conflictType: NoteConflictType.DefaultValue,
type: NoteType.Normal,
status: params.status ?? NoteStatus.Todo,
status: noteStatus,
deleted: false,
editable: true,
versionNumber: 1
Expand Down Expand Up @@ -1411,9 +1412,12 @@ export class EditorComponent extends DataLoadingComponent implements OnDestroy,
await threadDoc!.submitJson0Op(op => {
op.set(t => t.notes[noteIndex].content, noteContent);
op.set(t => t.notes[noteIndex].dateModified, currentDate);
op.set(t => t.notes[noteIndex].status, noteStatus);
// also set the status of the thread to be the status of the note
op.set(t => t.status, noteStatus);
});
} else {
this.dialogService.message(this.i18n.translate('editor.cannot_edit_note_paratext'));
this.dialogService.message('editor.cannot_edit_note_paratext');
}
} else {
note.threadId = threadDoc.data!.threadId;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -400,6 +400,27 @@ describe('NoteDialogComponent', () => {
expect(env.dialogResult).toEqual({ noteContent: content, noteDataId: 'note05' });
}));

it('allows user to resolve the last note in the thread', fakeAsync(() => {
env = new TestEnvironment({ noteThread: TestEnvironment.getNoteThread(undefined, undefined, true) });
// note03 is marked as deleted
expect(env.notes.length).toEqual(4);
const noteThread: NoteThreadDoc = env.getNoteThreadDoc('dataid01');
expect(noteThread.data!.notes[4].content).toEqual('note05');
const noteNumbers = [1, 2, 3];
noteNumbers.forEach(n => expect(env.noteHasEditActions(n)).toBe(false));
expect(env.noteHasEditActions(4)).toBe(true);
env.clickEditNote();
expect(env.noteInputElement).toBeTruthy();
expect(env.notes.length).toEqual(3);
noteNumbers.forEach(n => expect(env.noteHasEditActions(n)).toBe(false));
expect(env.component.currentNoteContent).toEqual('note05');
const content = 'note 05 edited content';
env.enterNoteContent(content);
env.selectResolveOption();
env.submit();
expect(env.dialogResult).toEqual({ noteContent: content, noteDataId: 'note05', status: NoteStatus.Resolved });
}));

it('does not allow user to edit the last note in the thread if it is not editable', fakeAsync(() => {
env = new TestEnvironment({ noteThread: TestEnvironment.getNoteThread() });
// note03 is marked as deleted
Expand Down Expand Up @@ -494,7 +515,7 @@ describe('NoteDialogComponent', () => {
env.enterNoteContent(content);
env.selectResolveOption();
env.submit();
expect(env.dialogResult).toEqual({ status: NoteStatus.Resolved, noteContent: content });
expect(env.dialogResult).toEqual({ status: NoteStatus.Resolved, noteContent: content, noteDataId: undefined });
}));

it('allows changing save option', fakeAsync(() => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -359,6 +359,7 @@ export class NoteDialogComponent implements OnInit {
const content: NoteDialogResult = { status: NoteStatus.Resolved };
if (this.currentNoteContent.trim().length > 0) {
content.noteContent = this.currentNoteContent;
content.noteDataId = this.noteIdBeingEdited;
}
this.dialogRef.close(content);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
"all": "All",
"biblical_terms_renderings": "Biblical Terms Renderings",
"blank": "(Blank)",
"cannot_edit_note_paratext": "You cannot edit this note as it has been edited in Paratext.",
"category": "Category",
"current_book": "Current Book",
"current_chapter": "Current Chapter",
Expand Down
Loading