From: Mike Risher Date: Thu, 19 Dec 2019 17:56:41 +0000 (+0000) Subject: lp1855780 Notification Action Triggers X-Git-Url: https://old-git.evergreen-ils.org/?a=commitdiff_plain;h=refs%2Fheads%2Fuser%2Fmrisher%2Flp1855780-notification-action-triggers-v2;p=working%2FEvergreen.git lp1855780 Notification Action Triggers Port Notification Action Triggers from DOJO to Angular. This consists of 4 grids, each navigated to by its corresponding tab. The Trigger Event Definitions grid allows cloning of records. Signed-off-by: Mike Risher Changes to be committed: modified: Open-ILS/src/eg2/src/app/staff/admin/local/admin-local-splash.component.html modified: Open-ILS/src/eg2/src/app/staff/admin/local/routing.module.ts new file: Open-ILS/src/eg2/src/app/staff/admin/local/triggers/triggers.component.html new file: Open-ILS/src/eg2/src/app/staff/admin/local/triggers/triggers.component.ts new file: Open-ILS/src/eg2/src/app/staff/admin/local/triggers/triggers.module.ts new file: Open-ILS/src/eg2/src/app/staff/admin/local/triggers/triggers_routing.module.ts --- diff --git a/Open-ILS/src/eg2/src/app/staff/admin/local/admin-local-splash.component.html b/Open-ILS/src/eg2/src/app/staff/admin/local/admin-local-splash.component.html index 223d1817cc..a4d2e2df6d 100644 --- a/Open-ILS/src/eg2/src/app/staff/admin/local/admin-local-splash.component.html +++ b/Open-ILS/src/eg2/src/app/staff/admin/local/admin-local-splash.component.html @@ -43,7 +43,7 @@ + routerLink="/staff/admin/local/action_trigger/event_definition"> + + +
+ + + + + + + + + + + + + diff --git a/Open-ILS/src/eg2/src/app/staff/admin/local/triggers/trigger-edit.component.ts b/Open-ILS/src/eg2/src/app/staff/admin/local/triggers/trigger-edit.component.ts new file mode 100644 index 0000000000..85a60d5157 --- /dev/null +++ b/Open-ILS/src/eg2/src/app/staff/admin/local/triggers/trigger-edit.component.ts @@ -0,0 +1,232 @@ +import {Pager} from '@eg/share/util/pager'; +import {Component, OnInit, ViewChild} from '@angular/core'; +import {GridComponent} from '@eg/share/grid/grid.component'; +import {GridDataSource} from '@eg/share/grid/grid'; +import {Router, ActivatedRoute} from '@angular/router'; +import {IdlService, IdlObject} from '@eg/core/idl.service'; +import {PcrudService} from '@eg/core/pcrud.service'; +import {NetService} from '@eg/core/net.service'; +import {AuthService} from '@eg/core/auth.service'; +import {FmRecordEditorComponent} from '@eg/share/fm-editor/fm-editor.component'; +import {StringComponent} from '@eg/share/string/string.component'; +import {ToastService} from '@eg/share/toast/toast.service'; +import {NgbNav, NgbNavChangeEvent} from '@ng-bootstrap/ng-bootstrap'; + +@Component({ + templateUrl: './trigger-edit.component.html' +}) + +export class EditEventDefinitionComponent implements OnInit { + + editTab: 'def' | 'env' | 'param' | 'test' = 'def'; + + evtDefId: number; + evtDefName: String; + testResult1: String = ''; + testResult2: String = ''; + // paramRecord: IdlObject; + + envDataSource: GridDataSource = new GridDataSource(); + paramDataSource: GridDataSource = new GridDataSource(); + // reactorsDataSource: GridDataSource = new GridDataSource(); + // validatorsDataSource: GridDataSource = new GridDataSource(); + // triggerTab: 'eventDefinitions' | 'hooks' | 'reactors' | 'validators' = 'eventDefinitions'; + // idlClass: string; + + @ViewChild('paramDialog', {static: false}) paramDialog: FmRecordEditorComponent; + @ViewChild('envDialog', {static: false}) envDialog: FmRecordEditorComponent; + // @ViewChild('reactorDialog', {static: false}) reactorDialog: FmRecordEditorComponent; + // @ViewChild('validatorDialog', {static: false}) validatorDialog: FmRecordEditorComponent; + +//TODO remove static: false? + + @ViewChild('envGrid', {static: false}) envGrid: GridComponent; + @ViewChild('paramGrid', {static: false}) paramGrid: GridComponent; + // @ViewChild('reactorsGrid', {static: false}) reactorsGrid: GridComponent; + // @ViewChild('validatorsGrid', {static: false}) validatorsGrid: GridComponent; + + @ViewChild('updateSuccessString', {static: false}) updateSuccessString: StringComponent; + @ViewChild('updateFailedString', {static: false}) updateFailedString: StringComponent; + @ViewChild('cloneSuccessString', {static: false}) cloneSuccessString: StringComponent; + @ViewChild('cloneFailedString', {static: false}) cloneFailedString: StringComponent; + @ViewChild('deleteFailedString', {static: false}) deleteFailedString: StringComponent; + @ViewChild('deleteSuccessString', {static: false}) deleteSuccessString: StringComponent; + @ViewChild('createSuccessString', {static: false}) createSuccessString: StringComponent; + @ViewChild('createErrString', {static: false}) createErrString: StringComponent; + + constructor( + private idl: IdlService, + private pcrud: PcrudService, + private toast: ToastService, + private router: Router, + private route: ActivatedRoute, + private net: NetService, + private auth: AuthService, + ) { + } + + ngOnInit() { + this.evtDefId = parseInt(this.route.snapshot.paramMap.get('id'), 10); + + this.pcrud.search('atevdef', + {id: this.evtDefId}, {}).toPromise().then(rec => { + this.evtDefName = rec.name(); + }); + + this.envDataSource.getRows = (pager: Pager, sort: any[]) => { + return this.pcrud.search('atenv', + {event_def: this.evtDefId}, {}); + }; + + this.paramDataSource.getRows = (pager: Pager, sort: any[]) => { + return this.pcrud.search('atevparam', + {event_def: this.evtDefId}, {}); + }; + } + + onTabChange(event: NgbNavChangeEvent) { + this.editTab = event.nextId; + } + + createNewEnv = () => { + this.createNewThing(this.envDialog, this.envGrid, 'atenv'); + } + + createNewParam = () => { + this.createNewThing(this.paramDialog, this.paramGrid, 'atevparam'); + } + + createNewThing = (currentDialog: any, currentGrid: any, idl: any) => { + currentDialog.mode = 'create'; + currentDialog.recordId = null; + const newRecord = this.idl.create(idl); + newRecord.event_def(this.evtDefId); + currentDialog.mode = 'create'; + currentDialog.record = newRecord; + currentDialog.open({size: 'lg'}).subscribe( + ok => { + this.createSuccessString.current() + .then(str => this.toast.success(str)); + currentGrid.reload(); + }, + rejection => { + if (!rejection.dismissed) { + this.createErrString.current() + .then(str => this.toast.danger(str)); + } + } + ); + } + + deleteSelected = (idlThings: IdlObject[]) => { + let currentGrid; + if (idlThings[0].classname =='atenv') { + currentGrid = this.envGrid; + } else { + currentGrid = this.paramGrid; + } + idlThings.forEach(idlThing => idlThing.isdeleted(true)); + this.pcrud.autoApply(idlThings).subscribe( + val => { + console.debug('deleted: ' + val); + this.deleteSuccessString.current() + .then(str => this.toast.success(str)); + currentGrid.reload(); + }, + err => { + this.deleteFailedString.current() + .then(str => this.toast.danger(str)); + } + ); + } + + editSelected = (selectedRecords: IdlObject[]) => { + const editOneThing = (record: IdlObject) => { + if (!record) { return; } + this.showEditDialog(record).then( + () => editOneThing(selectedRecords.shift())); + }; + editOneThing(selectedRecords.shift()); + } + + showEditDialog = (selectedRecord: IdlObject): Promise => { + let currentDialog; + let currentGrid; + if (selectedRecord.classname == 'atenv') { + currentDialog = this.envDialog; + currentGrid = this.envGrid; + } else { + currentDialog = this.paramDialog + currentGrid = this.paramGrid; + } + currentDialog.mode = 'update'; + const clone = this.idl.clone(selectedRecord); + currentDialog.record = clone; + return new Promise((resolve, reject) => { + currentDialog.open({size: 'lg'}).subscribe( + result => { + this.updateSuccessString.current() + .then(str => this.toast.success(str)); + currentGrid.reload(); + resolve(result); + }, + error => { + this.updateFailedString.current() + .then(str => this.toast.danger(str)); + reject(error); + } + ); + }); + } + + runTest = (barcode) => { + console.log("rt") + console.log(barcode) + if (!barcode) { + return; + } + this.net.request( + 'open-ils.circ', 'open-ils.circ.trigger_event_by_def_and_barcode.fire', + this.auth.token(), this.evtDefId, barcode + ).subscribe(res => { + console.log(res); + this.testResult1 = 'Event: '+ res.ilsevent + ': ' + res.textcode + ' ->'; + this.testResult2 = res.desc; + }); + } + + clearTestResults = () => { + this.testResult1 = ''; + this.testResult2 = ''; + } + + + // function evtTestCirc() { + // var barcode = circTestBarcode.attr('value'); + // if(!barcode) return; + + // progressDialog.show(); + + // function handleResponse(r) { + // var evt = openils.Util.readResponse(r); + // progressDialog.hide(); + // if(evt && evt != '0') { + // var output = evt.template_output(); + // if(!output) output = evt.error_output(); + // var pre = document.createElement('pre'); + // pre.innerHTML = output.data(); + // openils.Util.appendClear('test-event-output', pre); + // openils.Util.show('test-event-output'); + // } + // } + + // fieldmapper.standardRequest( + // ['open-ils.circ', 'open-ils.circ.trigger_event_by_def_and_barcode.fire'], + // { async: true, + // params: [openils.User.authtoken, eventDefId, barcode], + // oncomplete: handleResponse + // } + // ); + // } + +} diff --git a/Open-ILS/src/eg2/src/app/staff/admin/local/triggers/triggers.component.html b/Open-ILS/src/eg2/src/app/staff/admin/local/triggers/triggers.component.html new file mode 100644 index 0000000000..bae3dc5760 --- /dev/null +++ b/Open-ILS/src/eg2/src/app/staff/admin/local/triggers/triggers.component.html @@ -0,0 +1,123 @@ + + + + + + + + + + + + + + +
+ + + + + + + + + + + + diff --git a/Open-ILS/src/eg2/src/app/staff/admin/local/triggers/triggers.component.ts b/Open-ILS/src/eg2/src/app/staff/admin/local/triggers/triggers.component.ts new file mode 100644 index 0000000000..0dba05622c --- /dev/null +++ b/Open-ILS/src/eg2/src/app/staff/admin/local/triggers/triggers.component.ts @@ -0,0 +1,252 @@ +import {Pager} from '@eg/share/util/pager'; +import {Component, OnInit, ViewChild} from '@angular/core'; +import {GridComponent} from '@eg/share/grid/grid.component'; +import {GridDataSource} from '@eg/share/grid/grid'; +import {Router} from '@angular/router'; +import {IdlService, IdlObject} from '@eg/core/idl.service'; +import {PcrudService} from '@eg/core/pcrud.service'; +import {FmRecordEditorComponent} from '@eg/share/fm-editor/fm-editor.component'; +import {StringComponent} from '@eg/share/string/string.component'; +import {ToastService} from '@eg/share/toast/toast.service'; +import {NgbNav, NgbNavChangeEvent} from '@ng-bootstrap/ng-bootstrap'; + +@Component({ + templateUrl: './triggers.component.html' +}) + +export class TriggersComponent implements OnInit { + + eventsDataSource: GridDataSource = new GridDataSource(); + hooksDataSource: GridDataSource = new GridDataSource(); + reactorsDataSource: GridDataSource = new GridDataSource(); + validatorsDataSource: GridDataSource = new GridDataSource(); + triggerTab: 'eventDefinitions' | 'hooks' | 'reactors' | 'validators' = 'eventDefinitions'; + idlClass: string; + + @ViewChild('eventDialog', {static: false}) eventDialog: FmRecordEditorComponent; + @ViewChild('hookDialog', {static: false}) hookDialog: FmRecordEditorComponent; + @ViewChild('reactorDialog', {static: false}) reactorDialog: FmRecordEditorComponent; + @ViewChild('validatorDialog', {static: false}) validatorDialog: FmRecordEditorComponent; + + @ViewChild('eventsGrid', {static: false}) eventsGrid: GridComponent; + @ViewChild('hooksGrid', {static: false}) hooksGrid: GridComponent; + @ViewChild('reactorsGrid', {static: false}) reactorsGrid: GridComponent; + @ViewChild('validatorsGrid', {static: false}) validatorsGrid: GridComponent; + + @ViewChild('updateSuccessString', {static: false}) updateSuccessString: StringComponent; + @ViewChild('updateFailedString', {static: false}) updateFailedString: StringComponent; + @ViewChild('cloneSuccessString', {static: false}) cloneSuccessString: StringComponent; + @ViewChild('cloneFailedString', {static: false}) cloneFailedString: StringComponent; + @ViewChild('deleteFailedString', {static: false}) deleteFailedString: StringComponent; + @ViewChild('deleteSuccessString', {static: false}) deleteSuccessString: StringComponent; + @ViewChild('createSuccessString', {static: false}) createSuccessString: StringComponent; + @ViewChild('createErrString', {static: false}) createErrString: StringComponent; + + constructor( + private idl: IdlService, + private pcrud: PcrudService, + private toast: ToastService, + private router: Router, + ) { + } + + ngOnInit() { + this.eventsDataSource.getRows = (pager: Pager, sort: any[]) => { + const orderEventsBy: any = {atevdef: 'name'}; + if (sort.length) { + orderEventsBy.atevdef = sort[0].name + ' ' + sort[0].dir; + } + return this.doSearch('atevdef', orderEventsBy, this.eventsDataSource, pager); + }; + + this.hooksDataSource.getRows = (pager: Pager, sort: any[]) => { + const orderHooksBy: any = {ath: 'key'}; + if (sort.length) { + orderHooksBy.ath = sort[0].name + ' ' + sort[0].dir; + } + return this.doSearch('ath', orderHooksBy, this.hooksDataSource, pager); + }; + + this.reactorsDataSource.getRows = (pager: Pager, sort: any[]) => { + const orderReactorsBy: any = {atreact: 'module'}; + if (sort.length) { + orderReactorsBy.atreact = sort[0].name + ' ' + sort[0].dir; + } + return this.doSearch('atreact', orderReactorsBy, this.reactorsDataSource, pager); + }; + + this.validatorsDataSource.getRows = (pager: Pager, sort: any[]) => { + const orderValidatorsBy: any = {atval: 'module'}; + if (sort.length) { + orderValidatorsBy.atval = sort[0].name + ' ' + sort[0].dir; + } + return this.doSearch('atval', orderValidatorsBy, this.validatorsDataSource, pager); + }; + } + + doSearch(idlString: any, currentOrderBy: any, currentDataSource: any, pager: Pager) { + const base: Object = {}; + base[this.idl.classes[idlString].pkey] = {'!=' : null}; + const query: any = new Array(); + query.push(base); + Object.keys(currentDataSource.filters).forEach(key => { + Object.keys(currentDataSource.filters[key]).forEach(key2 => { + query.push(currentDataSource.filters[key][key2]); + }); + }); + return this.pcrud.search(idlString, + query, { + offset: pager.offset, + limit: pager.limit, + order_by: currentOrderBy + }); + } + + onTabChange(event: NgbNavChangeEvent) { + this.triggerTab = event.nextId; + } + + createNewEvent = () => { + this.createNewThing(this.eventDialog, this.eventsGrid); + } + + createNewHook = () => { + this.createNewThing(this.hookDialog, this.hooksGrid); + } + + createNewReactor = () => { + this.createNewThing(this.reactorDialog, this.reactorsGrid); + } + + createNewValidator = () => { + this.createNewThing(this.validatorDialog, this.validatorsGrid); + } + + createNewThing = (currentDialog: any, currentGrid: any) => { + currentDialog.mode = 'create'; + currentDialog.recordId = null; + currentDialog.record = null; + currentDialog.open({size: 'lg'}).subscribe( + ok => { + this.createSuccessString.current() + .then(str => this.toast.success(str)); + currentGrid.reload(); + }, + rejection => { + if (!rejection.dismissed) { + this.createErrString.current() + .then(str => this.toast.danger(str)); + } + } + ); + } + + editSelected = (selectedRecords: IdlObject[]) => { + if (this.triggerTab == 'eventDefinitions') { + this.editEventDefinition(selectedRecords); + return; + } + const editOneThing = (record: IdlObject) => { + if (!record) { return; } + this.showEditDialog(record).then( + () => editOneThing(selectedRecords.shift())); + }; + editOneThing(selectedRecords.shift()); + } + + editEventDefinition = (selectedRecords: IdlObject[]) => { + console.log("edit ed"); + let id=selectedRecords[0].id(); + this.router.navigate(['/staff/admin/local/action_trigger/event_definition/' + id]); + } + + lookUpIdl (idl: string) { + let currentDialog; + let currentGrid; + switch (idl) { + case 'atevdef': + currentDialog = this.eventDialog; + currentGrid = this.eventsGrid; + break; + case 'ath': + currentDialog = this.hookDialog; + currentGrid = this.hooksGrid; + break; + case 'atreact': + currentDialog = this.reactorDialog; + currentGrid = this.reactorsGrid; + break; + case 'atval': + currentDialog = this.validatorDialog; + currentGrid = this.validatorsGrid; + break; + default: + console.debug('Unknown class name'); + } + return {currentDialog: currentDialog, currentGrid: currentGrid}; + } + + showEditDialog = (selectedRecord: IdlObject): Promise => { + const idl = selectedRecord.classname; + const lookupResults = this.lookUpIdl(idl); + const currentDialog = lookupResults.currentDialog; + const currentGrid = lookupResults.currentGrid; + currentDialog.mode = 'update'; + const clone = this.idl.clone(selectedRecord); + currentDialog.record = clone; + return new Promise((resolve, reject) => { + currentDialog.open({size: 'lg'}).subscribe( + result => { + this.updateSuccessString.current() + .then(str => this.toast.success(str)); + currentGrid.reload(); + resolve(result); + }, + error => { + this.updateFailedString.current() + .then(str => this.toast.danger(str)); + reject(error); + } + ); + }); + } + + deleteSelected = (idlThings: IdlObject[]) => { + const idl = idlThings[0].classname; + const currentGrid = this.lookUpIdl(idl).currentGrid; + idlThings.forEach(idlThing => idlThing.isdeleted(true)); + this.pcrud.autoApply(idlThings).subscribe( + val => { + console.debug('deleted: ' + val); + this.deleteSuccessString.current() + .then(str => this.toast.success(str)); + currentGrid.reload(); + }, + err => { + this.deleteFailedString.current() + .then(str => this.toast.danger(str)); + } + ); + } + + cloneSelected = (idlThings: IdlObject[]) => { + const clone = this.idl.clone(idlThings[0]); + clone.id(null); + this.eventDialog.mode = 'create'; + this.eventDialog.recordId = null; + this.eventDialog.record = clone; + this.eventDialog.open({size: 'lg'}).subscribe( + ok => { + this.cloneSuccessString.current() + .then(str => this.toast.success(str)); + this.eventsGrid.reload(); + }, + rejection => { + if (!rejection.dismissed) { + this.cloneFailedString.current() + .then(str => this.toast.danger(str)); + } + } + ); + } +} diff --git a/Open-ILS/src/eg2/src/app/staff/admin/local/triggers/triggers.module.ts b/Open-ILS/src/eg2/src/app/staff/admin/local/triggers/triggers.module.ts new file mode 100644 index 0000000000..e2908c8cea --- /dev/null +++ b/Open-ILS/src/eg2/src/app/staff/admin/local/triggers/triggers.module.ts @@ -0,0 +1,20 @@ +import {NgModule} from '@angular/core'; +import {AdminCommonModule} from '@eg/staff/admin/common.module'; +import {TriggersComponent} from './triggers.component'; +import {TriggersRoutingModule} from './triggers_routing.module'; +import {EditEventDefinitionComponent} from './trigger-edit.component'; + +@NgModule({ + declarations: [ + TriggersComponent, + EditEventDefinitionComponent + ], + imports: [ + AdminCommonModule, + TriggersRoutingModule, + ], + exports: [], + providers: [] +}) + +export class TriggersModule {} diff --git a/Open-ILS/src/eg2/src/app/staff/admin/local/triggers/triggers_routing.module.ts b/Open-ILS/src/eg2/src/app/staff/admin/local/triggers/triggers_routing.module.ts new file mode 100644 index 0000000000..fffd4670ce --- /dev/null +++ b/Open-ILS/src/eg2/src/app/staff/admin/local/triggers/triggers_routing.module.ts @@ -0,0 +1,19 @@ +import {NgModule} from '@angular/core'; +import {RouterModule, Routes} from '@angular/router'; +import {TriggersComponent} from './triggers.component'; +import {EditEventDefinitionComponent} from './trigger-edit.component'; + +const routes: Routes = [{ + path: '', + component: TriggersComponent +},{ + path: ':id', + component: EditEventDefinitionComponent +}]; + +@NgModule({ + imports: [RouterModule.forChild(routes)], + exports: [RouterModule] +}) + +export class TriggersRoutingModule {}