lp1857910 Field Documentation Port
[evergreen-equinox.git] / Open-ILS / src / eg2 / src / app / staff / admin / local / field-documentation / field-documentation.component.ts
1 import {Component, OnInit, Input, ViewChild, ViewEncapsulation} from'@angular/core';
2 import {Router} from '@angular/router';
3 import {Observable, Observer, of} from 'rxjs';
4 import {map} from 'rxjs/operators';
5 import {FmRecordEditorComponent} from '@eg/share/fm-editor/fm-editor.component';
6 import {GridDataSource} from '@eg/share/grid/grid';
7 import {GridComponent} from '@eg/share/grid/grid.component';
8 import {Pager} from '@eg/share/util/pager';
9 import {AuthService} from '@eg/core/auth.service';
10 import {IdlObject, IdlService} from '@eg/core/idl.service';
11 import {PcrudService} from '@eg/core/pcrud.service';
12 import {StringComponent} from '@eg/share/string/string.component';
13 import {ToastService} from '@eg/share/toast/toast.service';
14
15 @Component({
16     templateUrl: './field-documentation.component.html'
17 })
18
19 export class FieldDocumentationComponent implements OnInit {
20
21     idlEntries: any[] = [];
22     fieldOptions: any = {};
23     @Input() selectedClass: any;
24     @Input() fields: [] = [];
25     gridDataSource: GridDataSource;
26     @ViewChild('fieldClassSelector', {static: true}) fieldClassSelector: any;
27     @ViewChild('fieldSelector', {static: true}) fieldSelector: any;
28     @ViewChild('editDialog', { static: true }) editDialog: FmRecordEditorComponent;
29     @ViewChild('fieldDocGrid', { static: true }) fieldDocGrid: GridComponent;
30     @ViewChild('updateSuccessString', { static: true }) updateSuccessString: StringComponent;
31     @ViewChild('createSuccessString', { static: false }) createSuccessString: StringComponent;
32     @ViewChild('createFailedString', { static: false }) createFailedString: StringComponent;
33     @ViewChild('updateFailedString', { static: false }) updateFailedString: StringComponent;
34
35     constructor(
36     private auth: AuthService,
37         private idl: IdlService,
38         private pcrud: PcrudService,
39         private toast: ToastService
40     ) {}
41
42     ngOnInit() {
43         this.gridDataSource = new GridDataSource();
44         Object.values(this.idl.classes).forEach(idlClass => {
45             let fields = [];
46             Object.values(idlClass['field_map']).forEach(field => {
47                 // We can safely ignore virtual fields...
48                 if (!field['virtual']) {
49                     fields.push({
50                         id: field['name'],
51                         label: field['label'] ? field['label'] : field['name']
52                     });
53                 }
54             });
55             if (idlClass['label']) {
56                 this.idlEntries.push({
57                     label: idlClass['label'],
58                     id: idlClass['name'],
59                     fields: fields
60                 });
61             }
62         });
63         this.idlEntries.sort((a, b) => {
64             let textA = a.label.toUpperCase();
65             let textB = b.label.toUpperCase();
66             return (textA < textB) ? -1 : (textA > textB) ? 1 : 0;
67         });
68         if (this.selectedClass) this.setGrid();
69         this.fieldDocGrid.onRowActivate.subscribe((fieldDoc: IdlObject) => {
70             this.showEditDialog(fieldDoc);
71         });
72
73         this.fieldOptions = {
74             fm_class: {
75                 customTemplate: {
76                     template:this.fieldClassSelector,
77                     context: {
78                         fieldentries: this.idlEntries,
79                         selectedEntry: this.selectedClass
80                     }
81                 }
82             },
83             field: {
84                 customTemplate: {
85                     template: this.fieldSelector,
86                     context: {
87                         selectedEntry: null
88                     }
89                 }
90             }
91         }
92     }
93
94     setClass(idlClass, entry?) {
95         if (this.editDialog.record) this.editDialog.record.fm_class(idlClass.id);
96         this.fieldOptions.fm_class.customTemplate.context.selectedEntry = idlClass;
97         this.fields = idlClass.fields;
98         
99         if (entry && entry.field()) this.setField(
100             idlClass.fields.find(o => o.id == entry.field()),
101         );
102     }
103
104     setField(entry) {
105         if (this.editDialog.record) this.editDialog.record.field(entry.id);
106         this.fieldOptions.field.customTemplate.context.selectedEntry = entry;
107     }
108
109     setGrid() {
110         this.gridDataSource.data = [];
111         this.setCurrentFieldDoc();
112     }
113
114     setCurrentFieldDoc() {
115         if (this.selectedClass) {
116             this.fields = this.selectedClass.fields;
117             this.pcrud.search('fdoc',
118                 {fm_class: this.selectedClass.id}
119             ).subscribe(fdocs => {
120                 this.gridDataSource.data.push(fdocs);
121             });
122         }
123     }
124
125     setFieldOptions(field) {
126         field.owner(this.auth.user().ws_ou());
127         this.fieldOptions.fm_class.customTemplate.context.selectedEntry = this.selectedClass;
128         this.fieldOptions.field.customTemplate.context.fields = this.selectedClass ? this.selectedClass.fields : [];
129         this.fieldOptions.field.customTemplate.context.record = field;
130         if (this.selectedClass) {
131             this.setClass(this.selectedClass, field);
132         }
133     }
134
135     showEditDialog(field: IdlObject): Promise<any> {
136         this.editDialog.mode = 'update';
137         this.editDialog.recordId = field.id();
138         this.setFieldOptions(field);
139         return new Promise((resolve, reject) => {
140             this.editDialog.open({size: 'lg'}).subscribe(result => {
141                 this.updateSuccessString.current()
142                     .then(str => this.toast.success(str));
143                 this.setGrid();
144                 resolve(result);
145             }, error => {
146                 this.updateFailedString.current()
147                     .then(str => this.toast.danger(str));
148             });
149         });
150     }
151
152     editSelected(fields: IdlObject[]) {
153         const editOneFieldDoc = (fieldDoc: IdlObject) => {
154             if (!fieldDoc) return;
155             
156             this.showEditDialog(fieldDoc).then(
157                 () => editOneFieldDoc(fields.shift())
158             );
159         }
160
161         editOneFieldDoc(fields.shift());
162     }
163
164     createNew() {
165         this.editDialog.mode = 'create';
166         this.editDialog.recordId = null;
167         this.editDialog.record = this.idl.create('fdoc');
168         this.setFieldOptions(this.editDialog.record);
169         this.editDialog.open({size: 'lg'}).subscribe(
170             ok => {
171                 this.createSuccessString.current()
172                     .then(str => this.toast.success(str));
173                 this.setGrid();
174             },
175             rejection => {
176                 if (!rejection.dismissed) {
177                     this.createFailedString.current()
178                         .then(str => this.toast.danger(str));
179                 }
180             }
181         );
182     }
183 }