1 import {Component, OnInit, Input, ViewChild} from '@angular/core';
2 import {Observable, throwError, from, empty} from 'rxjs';
3 import {tap, map, switchMap} from 'rxjs/operators';
4 import {NetService} from '@eg/core/net.service';
5 import {IdlService, IdlObject} from '@eg/core/idl.service';
6 import {EventService} from '@eg/core/event.service';
7 import {ToastService} from '@eg/share/toast/toast.service';
8 import {AuthService} from '@eg/core/auth.service';
9 import {PcrudService} from '@eg/core/pcrud.service';
10 import {OrgService} from '@eg/core/org.service';
11 import {StringComponent} from '@eg/share/string/string.component';
12 import {DialogComponent} from '@eg/share/dialog/dialog.component';
13 import {NgbModal, NgbModalOptions} from '@ng-bootstrap/ng-bootstrap';
16 * Dialog for managing copy notes.
20 selector: 'eg-copy-notes-dialog',
21 templateUrl: 'copy-notes-dialog.component.html'
24 export class CopyNotesDialogComponent
25 extends DialogComponent implements OnInit {
27 // If there are multiple copyIds, only new notes may be applied.
28 // If there is only one copyId, then notes may be applied or removed.
29 @Input() copyIds: number[] = [];
31 mode: string; // create | manage
33 // If true, no attempt is made to save the new notes to the
34 // database. It's assumed this takes place in the calling code.
35 // This is useful for creating notes for new copies.
36 @Input() inPlaceMode = false;
38 // In 'create' mode, we may be adding notes to multiple copies.
39 copies: IdlObject[] = [];
41 // In 'manage' mode we only handle a single copy.
46 curNotePublic = false;
47 newNotes: IdlObject[] = [];
48 delNotes: IdlObject[] = [];
52 @ViewChild('successMsg', { static: true }) private successMsg: StringComponent;
53 @ViewChild('errorMsg', { static: true }) private errorMsg: StringComponent;
56 private modal: NgbModal, // required for passing to parent
57 private toast: ToastService,
58 private net: NetService,
59 private idl: IdlService,
60 private pcrud: PcrudService,
61 private org: OrgService,
62 private auth: AuthService) {
63 super(modal); // required for subclassing
71 open(args: NgbModalOptions): Observable<IdlObject[]> {
76 if (this.copyIds.length === 0 && !this.inPlaceMode) {
77 return throwError('copy ID required');
80 // In manage mode, we can only manage a single copy.
81 // But in create mode, we can add notes to multiple copies.
83 if (this.copyIds.length === 1 && !this.inPlaceMode) {
89 // Observify data loading
90 const obs = from(this.getCopies());
92 // Return open() observable to caller
93 return obs.pipe(switchMap(_ => super.open(args)));
96 getCopies(): Promise<any> {
97 if (this.inPlaceMode) { return Promise.resolve(); }
99 return this.pcrud.search('acp', {id: this.copyIds},
100 {flesh: 1, flesh_fields: {acp: ['notes']}},
103 .toPromise().then(copies => {
104 this.copies = copies;
105 if (copies.length === 1) {
106 this.copy = copies[0];
111 removeNote(note: IdlObject) {
112 this.newNotes = this.newNotes.filter(t => t.id() !== note.id());
114 if (note.isnew() || this.mode === 'create') { return; }
116 const existing = this.copy.notes().filter(n => n.id() === note.id())[0];
117 if (!existing) { return; }
119 existing.isdeleted(true);
120 this.delNotes.push(existing);
122 // Remove from copy for dialog display
123 this.copy.notes(this.copy.notes().filter(n => n.id() !== note.id()));
127 if (!this.curNoteTitle || !this.curNote) { return; }
129 const note = this.idl.create('acpn');
131 note.creator(this.auth.user().id());
132 note.pub(this.curNotePublic ? 't' : 'f');
133 note.title(this.curNoteTitle);
134 note.value(this.curNote);
135 note.id(this.autoId--);
137 this.newNotes.push(note);
140 this.curNoteTitle = '';
141 this.curNotePublic = false;
146 if (this.inPlaceMode) {
147 this.close(this.newNotes);
152 this.newNotes.forEach(note => {
153 this.copies.forEach(copy => {
154 const n = this.idl.clone(note);
155 n.id(null); // remove temp ID, it will be duped
156 n.owning_copy(copy.id());
161 this.pcrud.create(notes).toPromise()
163 if (this.delNotes.length) {
164 return this.pcrud.remove(this.delNotes).toPromise();
167 this.successMsg.current().then(msg => this.toast.success(msg));
168 this.close(this.newNotes.length > 0 || this.delNotes.length > 0);