LP1803787 Migrate grid action/button click handlers; lint
[Evergreen.git] / Open-ILS / src / eg2 / src / app / staff / admin / server / org-unit-type.component.ts
1 import {Component, Input, ViewChild, OnInit} from '@angular/core';
2 import {Tree, TreeNode} from '@eg/share/tree/tree';
3 import {IdlService, IdlObject} from '@eg/core/idl.service';
4 import {OrgService} from '@eg/core/org.service';
5 import {AuthService} from '@eg/core/auth.service';
6 import {PcrudService} from '@eg/core/pcrud.service';
7 import {ToastService} from '@eg/share/toast/toast.service';
8 import {StringComponent} from '@eg/share/string/string.component';
9 import {ConfirmDialogComponent} from '@eg/share/dialog/confirm.component';
10 import {FmRecordEditorComponent} from '@eg/share/fm-editor/fm-editor.component';
11
12 @Component({
13     templateUrl: './org-unit-type.component.html'
14 })
15
16 export class OrgUnitTypeComponent implements OnInit {
17
18     tree: Tree;
19     selected: TreeNode;
20     @ViewChild('editDialog') editDialog: FmRecordEditorComponent;
21     @ViewChild('editString') editString: StringComponent;
22     @ViewChild('createString') createString: StringComponent;
23     @ViewChild('errorString') errorString: StringComponent;
24     @ViewChild('delConfirm') delConfirm: ConfirmDialogComponent;
25
26     constructor(
27         private idl: IdlService,
28         private org: OrgService,
29         private auth: AuthService,
30         private pcrud: PcrudService,
31         private toast: ToastService
32     ) {}
33
34
35     ngOnInit() {
36         this.loadAoutTree();
37     }
38
39     loadAoutTree() {
40         this.pcrud.search('aout', {depth: 0},
41             {flesh: -1, flesh_fields: {aout: ['children', 'org_units']}},
42             {anonymous: true}
43         ).subscribe(aoutTree => this.ingestAoutTree(aoutTree));
44     }
45
46     // Translate the org unt type tree into a structure EgTree can use.
47     ingestAoutTree(aoutTree) {
48
49         const handleNode = (aoutNode: IdlObject): TreeNode => {
50             if (!aoutNode) { return; }
51
52             // grab number of associated org units, then
53             // clear it so that FmRecordEditor doesn't try
54             // to render the list
55             const orgCount = aoutNode.org_units().length;
56             aoutNode.org_units(null);
57
58             const treeNode = new TreeNode({
59                 id: aoutNode.id(),
60                 label: aoutNode.name(),
61                 callerData: { aout: aoutNode, orgCount: orgCount },
62             });
63
64             aoutNode.children().forEach(childNode =>
65                 treeNode.children.push(handleNode(childNode))
66             );
67
68             return treeNode;
69         };
70
71         const rootNode = handleNode(aoutTree);
72         this.tree = new Tree(rootNode);
73     }
74
75     nodeClicked($event: any) {
76         this.selected = $event;
77     }
78
79     postUpdate(message: StringComponent) {
80         // Modifying org unit types means refetching the org unit
81         // data normally fetched on page load, since it includes
82         // org unit type data.
83         this.org.fetchOrgs().then(
84             ok => {
85                 message.current().then(str => this.toast.success(str));
86             }
87         );
88     }
89
90     edit() {
91         this.editDialog.mode = 'update';
92         this.editDialog.setRecord(this.selected.callerData.aout);
93
94         this.editDialog.open().then(
95             success => {
96                 this.postUpdate(this.editString);
97                 this.loadAoutTree(); // since the tree is never going to
98                                      // be large, just reload the whole
99                                      // thing
100             },
101             rejected => {
102                 if (rejected && rejected.dismissed) {
103                     return;
104                 }
105                 this.errorString.current()
106                     .then(str => this.toast.danger(str));
107             }
108         );
109     }
110
111     remove() {
112         this.delConfirm.open().then(
113             ok => {
114                 this.pcrud.remove(this.selected.callerData.aout)
115                 .subscribe(
116                     ok2 => {},
117                     err => {
118                         this.errorString.current()
119                           .then(str => this.toast.danger(str));
120                     },
121                     ()  => {
122                         // Avoid updating until we know the entire
123                         // pcrud action/transaction completed.
124                         this.loadAoutTree(); // since the tree is never going to
125                                              // be large, just reload the whole
126                                              // thing
127                         this.selected = null;
128                         this.postUpdate(this.editString);
129                     }
130                 );
131             },
132             notConfirmed => {}
133         );
134     }
135
136     addChild() {
137         const parentTreeNode = this.selected;
138         const parentType = parentTreeNode.callerData.aout;
139
140         const newType = this.idl.create('aout');
141         newType.parent(parentType.id());
142         newType.depth(Number(parentType.depth()) + 1);
143
144         this.editDialog.setRecord(newType);
145         this.editDialog.mode = 'create';
146
147         this.editDialog.open().then(
148             result => { // aout object
149
150                 // Add our new node to the tree
151                 const newNode = new TreeNode({
152                     id: result.id(),
153                     label: result.name(),
154                     callerData: { aout: result, orgCount: 0 }
155                 });
156                 this.loadAoutTree(); // since the tree is never going to
157                                      // be large, just reload the whole
158                                      // thing
159                 this.postUpdate(this.createString);
160             },
161
162             rejected => {
163                 if (rejected && rejected.dismissed) {
164                     return;
165                 }
166                 this.errorString.current()
167                     .then(str => this.toast.danger(str));
168             }
169         );
170     }
171 }
172