]> git.evergreen-ils.org Git - Evergreen.git/blob - Open-ILS/src/eg2/src/app/staff/admin/local/triggers/trigger-edit.component.ts
LP#1855780: avoid race condition when deleting env or params
[Evergreen.git] / Open-ILS / src / eg2 / src / app / staff / admin / local / triggers / trigger-edit.component.ts
1 import {Pager} from '@eg/share/util/pager';
2 import {Component, OnInit, ViewChild} from '@angular/core';
3 import {GridComponent} from '@eg/share/grid/grid.component';
4 import {GridDataSource} from '@eg/share/grid/grid';
5 import {ActivatedRoute} from '@angular/router';
6 import {IdlService, IdlObject} from '@eg/core/idl.service';
7 import {PcrudService} from '@eg/core/pcrud.service';
8 import {NetService} from '@eg/core/net.service';
9 import {AuthService} from '@eg/core/auth.service';
10 import {FmRecordEditorComponent} from '@eg/share/fm-editor/fm-editor.component';
11 import {StringComponent} from '@eg/share/string/string.component';
12 import {ToastService} from '@eg/share/toast/toast.service';
13 import {NgbNav, NgbNavChangeEvent} from '@ng-bootstrap/ng-bootstrap';
14 import {Router} from '@angular/router';
15
16 @Component({
17     templateUrl: './trigger-edit.component.html'
18 })
19
20 export class EditEventDefinitionComponent implements OnInit {
21
22     evtDefId: number;
23     evtDefName: String;
24
25     testErr1: String = '';
26     testErr2: String = '';
27     testResult: String = '';
28     testDone: Boolean = false;
29
30     envDataSource: GridDataSource = new GridDataSource();
31     paramDataSource: GridDataSource = new GridDataSource();
32
33     editTab: 'def' | 'env' | 'param' | 'test' = 'def';
34
35     @ViewChild('paramDialog') paramDialog: FmRecordEditorComponent;
36     @ViewChild('envDialog') envDialog: FmRecordEditorComponent;
37
38     @ViewChild('envGrid') envGrid: GridComponent;
39     @ViewChild('paramGrid') paramGrid: GridComponent;
40
41     @ViewChild('updateSuccessString') updateSuccessString: StringComponent;
42     @ViewChild('updateFailedString') updateFailedString: StringComponent;
43     @ViewChild('cloneSuccessString') cloneSuccessString: StringComponent;
44     @ViewChild('cloneFailedString') cloneFailedString: StringComponent;
45     @ViewChild('deleteFailedString') deleteFailedString: StringComponent;
46     @ViewChild('deleteSuccessString') deleteSuccessString: StringComponent;
47     @ViewChild('createSuccessString') createSuccessString: StringComponent;
48     @ViewChild('createErrString') createErrString: StringComponent;
49
50     constructor(
51         private router: Router,
52         private idl: IdlService,
53         private pcrud: PcrudService,
54         private toast: ToastService,
55         private route: ActivatedRoute,
56         private net: NetService,
57         private auth: AuthService,
58     ) {
59     }
60
61     ngOnInit() {
62         this.evtDefId = parseInt(this.route.snapshot.paramMap.get('id'), 10);
63
64         // get current event def name to display on the banner
65         this.pcrud.search('atevdef',
66             {id: this.evtDefId}, {}).toPromise().then(rec => {
67             this.evtDefName = rec.name();
68         });
69
70         this.envDataSource.getRows = (pager: Pager, sort: any[]) => {
71             return this.pcrud.search('atenv',
72                 {event_def: this.evtDefId}, {});
73         };
74
75         this.paramDataSource.getRows = (pager: Pager, sort: any[]) => {
76             return this.pcrud.search('atevparam',
77                 {event_def: this.evtDefId}, {});
78         };
79     }
80
81     onTabChange(event: NgbNavChangeEvent) {
82         this.editTab = event.nextId;
83     }
84
85     createNewEnv = () => {
86         this.createNewThing(this.envDialog, this.envGrid, 'atenv');
87     }
88
89     createNewParam = () => {
90         this.createNewThing(this.paramDialog, this.paramGrid, 'atevparam');
91     }
92
93     createNewThing = (currentDialog: any, currentGrid: any, idl: any) => {
94         currentDialog.mode = 'create';
95         currentDialog.recordId = null;
96         const newRecord = this.idl.create(idl);
97         newRecord.event_def(this.evtDefId);
98         currentDialog.mode = 'create';
99         currentDialog.record = newRecord;
100         currentDialog.open({size: 'lg'}).subscribe(
101             ok => {
102                 this.createSuccessString.current()
103                     .then(str => this.toast.success(str));
104                 currentGrid.reload();
105             },
106             rejection => {
107                 if (!rejection.dismissed) {
108                     this.createErrString.current()
109                         .then(str => this.toast.danger(str));
110                 }
111             }
112         );
113     }
114
115     deleteSelected = (idlThings: IdlObject[]) => {
116         let currentGrid;
117         if (idlThings[0].classname === 'atenv') {
118             currentGrid = this.envGrid;
119         } else {
120             currentGrid = this.paramGrid;
121         }
122         idlThings.forEach(idlThing => idlThing.isdeleted(true));
123         let _deleted = 0;
124         this.pcrud.autoApply(idlThings).subscribe(
125             val => {
126                 console.debug('deleted: ' + val);
127                 this.deleteSuccessString.current()
128                     .then(str => this.toast.success(str));
129                 _deleted++;
130             },
131             err => {
132                 this.deleteFailedString.current()
133                     .then(str => this.toast.danger(str));
134             },
135             () => {
136                 if (_deleted > 0) {
137                     currentGrid.reload();
138                 }
139             }
140         );
141     }
142
143     editSelected = (selectedRecords: IdlObject[]) => {
144         const editOneThing = (record: IdlObject) => {
145             if (!record) { return; }
146             this.showEditDialog(record).then(
147                 () => editOneThing(selectedRecords.shift()));
148         };
149         editOneThing(selectedRecords.shift());
150     }
151
152     showEditDialog = (selectedRecord: IdlObject): Promise<any> => {
153         let currentDialog;
154         let currentGrid;
155         if (selectedRecord.classname === 'atenv') {
156             currentDialog = this.envDialog;
157             currentGrid = this.envGrid;
158         } else {
159             currentDialog = this.paramDialog;
160             currentGrid = this.paramGrid;
161         }
162         currentDialog.mode = 'update';
163         const clone = this.idl.clone(selectedRecord);
164         currentDialog.record = clone;
165         return new Promise((resolve, reject) => {
166             currentDialog.open({size: 'lg'}).subscribe(
167                 result => {
168                     this.updateSuccessString.current()
169                         .then(str => this.toast.success(str));
170                     currentGrid.reload();
171                     resolve(result);
172                 },
173                 error => {
174                     this.updateFailedString.current()
175                         .then(str => this.toast.danger(str));
176                     reject(error);
177                }
178            );
179        });
180     }
181
182     runTest = (barcode) => {
183         if (!barcode) {
184             return;
185         }
186         this.clearTestResults();
187         this.net.request(
188             'open-ils.circ', 'open-ils.circ.trigger_event_by_def_and_barcode.fire',
189             this.auth.token(), this.evtDefId, barcode
190         ).subscribe(res => {
191             this.testDone = true;
192             if (res.ilsevent) {
193                 this.testErr1 = 'Event:  ' + res.ilsevent + ':  ' + res.textcode + ' ->';
194                 this.testErr2 = res.desc;
195             } else {
196                 this.testResult = res.template_output().data();
197             }
198         });
199     }
200
201     clearTestResults = () => {
202         this.testDone = false;
203         this.testErr1 = '';
204         this.testErr2 = '';
205         this.testResult = '';
206     }
207     back = () => {
208         this.router.navigate(['/staff/admin/local/action_trigger/event_definition/']);
209     }
210 }