diff --git a/src/app/system/manage-hooks/add-event-dialog/add-event-dialog.component.html b/src/app/system/manage-hooks/add-event-dialog/add-event-dialog.component.html new file mode 100644 index 000000000..283a8214a --- /dev/null +++ b/src/app/system/manage-hooks/add-event-dialog/add-event-dialog.component.html @@ -0,0 +1,55 @@ +

Add Event

+ + + +
+ +
+ + + Select Grouping + + + {{ grouping.name }} + + + + Grouping is required + + + + + Select Entity + + + {{ entity.name }} + + + + Entity is required + + + + + Select Action + + + {{ action }} + + + + Action is required + + + +
+ +
+ +
+ + + + + diff --git a/src/app/system/manage-hooks/add-event-dialog/add-event-dialog.component.scss b/src/app/system/manage-hooks/add-event-dialog/add-event-dialog.component.scss new file mode 100644 index 000000000..e69de29bb diff --git a/src/app/system/manage-hooks/add-event-dialog/add-event-dialog.component.spec.ts b/src/app/system/manage-hooks/add-event-dialog/add-event-dialog.component.spec.ts new file mode 100644 index 000000000..9744d9c91 --- /dev/null +++ b/src/app/system/manage-hooks/add-event-dialog/add-event-dialog.component.spec.ts @@ -0,0 +1,25 @@ +import { async, ComponentFixture, TestBed } from '@angular/core/testing'; + +import { AddEventDialogComponent } from './add-event-dialog.component'; + +describe('AddEventDialogComponent', () => { + let component: AddEventDialogComponent; + let fixture: ComponentFixture; + + beforeEach(async(() => { + TestBed.configureTestingModule({ + declarations: [ AddEventDialogComponent ] + }) + .compileComponents(); + })); + + beforeEach(() => { + fixture = TestBed.createComponent(AddEventDialogComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/src/app/system/manage-hooks/add-event-dialog/add-event-dialog.component.ts b/src/app/system/manage-hooks/add-event-dialog/add-event-dialog.component.ts new file mode 100644 index 000000000..75cb76b1b --- /dev/null +++ b/src/app/system/manage-hooks/add-event-dialog/add-event-dialog.component.ts @@ -0,0 +1,73 @@ +/** Angular Imports */ +import { Component, OnInit, Inject } from '@angular/core'; +import { MatDialogRef, MAT_DIALOG_DATA } from '@angular/material'; +import { FormBuilder, FormGroup, Validators } from '@angular/forms'; + +/** + * Add Event Dialog Component. + */ +@Component({ + selector: 'mifosx-add-event-dialog', + templateUrl: './add-event-dialog.component.html', + styleUrls: ['./add-event-dialog.component.scss'] +}) +export class AddEventDialogComponent implements OnInit { + + /** Event Form. */ + eventForm: FormGroup; + /** Entity Data. */ + entityData: Array = new Array(); + /** Action Data. */ + actionData: Array = new Array(); + + /** + * @param {MatDialogRef} dialogRef Component reference to dialog. + * @param {FormBuilder} formBuilder Form Builder. + * @param {any} data Provides grouping, entities and actions data to fill dropdowns. + */ + constructor(public dialogRef: MatDialogRef, + public formBuilder: FormBuilder, + @Inject(MAT_DIALOG_DATA) public data: any) { + } + + /** + * Creates add event form. + */ + ngOnInit() { + this.eventForm = this.formBuilder.group({ + 'grouping': ['', Validators.required], + 'entity': ['', Validators.required], + 'action': ['', Validators.required] + }); + this.setGroupingListener(); + this.setEntityListener(); + } + + /** + * Subscribes to the grouping dropdown to set entity data for that row accordingly. + */ + setGroupingListener() { + this.eventForm.get('grouping').valueChanges + .subscribe(changedGrouping => { + this.entityData = this.data.groupings.find((grouping: any) => grouping.name === changedGrouping).entities; + }); + } + + /** + * Subscribes to the entity dropdown to set entity data for that row accordingly. + */ + setEntityListener() { + this.eventForm.get('entity').valueChanges + .subscribe(changedEntity => { + this.actionData = this.entityData[0].actions; + }); + } + + /** + * Closes the dialog and returns value of the form. + */ + submit() { + this.dialogRef.close(this.eventForm.value); + } + +} diff --git a/src/app/system/manage-hooks/create-hook/create-hook.component.html b/src/app/system/manage-hooks/create-hook/create-hook.component.html new file mode 100644 index 000000000..6c85cd83c --- /dev/null +++ b/src/app/system/manage-hooks/create-hook/create-hook.component.html @@ -0,0 +1,159 @@ +
+ + + +
+ + + +
+ + + Hook Template + + + {{ hookTemplate.name }} + + + + Hook Template is required + + + + + Display Name + + + Display Name is required + + + +
+ + Is Active? + +
+ +
+ +
+ + + Content Type + + + json + + + form + + + + Content Type is required + + + + + Phone Number + + {{input.value?.length || 0}}/10 + + Payload URL is required + + + + + Payload URL + + + Payload URL is required + + + +
+ +
+ + + SMS Provider + + + SMS Provider is required + + + + + SMS Provider Account ID + + + SMS Provider Account ID is required + + + + + SMS Provider Token + + + SMS Provider Token is required + + + +
+ +
+ + + +
+ +
+ +

Events

+ + + +
+ + + + + + + + + + + + + + + + + + + + + +
Entity Name {{ event.entityName }} Action Name {{ event.actionName }} Actions + +
+ +
+ + + + + + +
+ +
+ +
diff --git a/src/app/system/manage-hooks/create-hook/create-hook.component.scss b/src/app/system/manage-hooks/create-hook/create-hook.component.scss new file mode 100644 index 000000000..3344ae538 --- /dev/null +++ b/src/app/system/manage-hooks/create-hook/create-hook.component.scss @@ -0,0 +1,17 @@ +@media (min-width: 992px) { + + .is-active-wrapper { + position: relative; + + .is-active { + padding: 0 0 17.5px 0; + position: absolute; + bottom: 0; + right: 0; + } + } +} + +table { + width: 100%; +} diff --git a/src/app/system/manage-hooks/create-hook/create-hook.component.spec.ts b/src/app/system/manage-hooks/create-hook/create-hook.component.spec.ts new file mode 100644 index 000000000..272ae47db --- /dev/null +++ b/src/app/system/manage-hooks/create-hook/create-hook.component.spec.ts @@ -0,0 +1,25 @@ +import { async, ComponentFixture, TestBed } from '@angular/core/testing'; + +import { CreateHookComponent } from './create-hook.component'; + +describe('CreateHookComponent', () => { + let component: CreateHookComponent; + let fixture: ComponentFixture; + + beforeEach(async(() => { + TestBed.configureTestingModule({ + declarations: [ CreateHookComponent ] + }) + .compileComponents(); + })); + + beforeEach(() => { + fixture = TestBed.createComponent(CreateHookComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/src/app/system/manage-hooks/create-hook/create-hook.component.ts b/src/app/system/manage-hooks/create-hook/create-hook.component.ts new file mode 100644 index 000000000..1d2c318ec --- /dev/null +++ b/src/app/system/manage-hooks/create-hook/create-hook.component.ts @@ -0,0 +1,164 @@ +/** Angular Imports */ +import { Component, OnInit, ViewChild } from '@angular/core'; +import { ActivatedRoute, Router } from '@angular/router'; +import { FormBuilder, FormGroup, Validators } from '@angular/forms'; +import { MatTableDataSource, MatPaginator, MatSort, MatDialog } from '@angular/material'; + +/** Custom Services */ +import { SystemService } from '../../system.service'; + +/** Custom Components */ +import { AddEventDialogComponent } from '../add-event-dialog/add-event-dialog.component'; +import { DeleteDialogComponent } from 'app/shared/delete-dialog/delete-dialog.component'; + +/** + * Create Hook Component. + */ +@Component({ + selector: 'mifosx-create-hook', + templateUrl: './create-hook.component.html', + styleUrls: ['./create-hook.component.scss'] +}) +export class CreateHookComponent implements OnInit { + + /** Hooks Template Data. */ + hooksTemplateData: any; + /** Hook Form. */ + hookForm: FormGroup; + /** Columns to be displayed in events table. */ + displayedColumns: string[] = ['entityName', 'actionName', 'actions']; + /** Data source for events table. */ + dataSource: MatTableDataSource; + /** Events Data. */ + eventsData: any[] = []; + /** Sorter for events table. */ + @ViewChild(MatSort) sort: MatSort; + + /** + * Retrieves the hooks template data from `resolve`. + * @param {ActivatedRoute} route Activated Route. + * @param {SystemService} systemService System Service. + * @param {Router} router Router for navigation. + * @param {FormBuilder} formBuilder Form Builder. + * @param {MatDialog} dialog Dialog Reference. + */ + constructor(private route: ActivatedRoute, + private systemService: SystemService, + private router: Router, + private formBuilder: FormBuilder, + private dialog: MatDialog) { + this.route.data.subscribe((data: { hooksTemplate: any }) => { + this.hooksTemplateData = data.hooksTemplate; + }); + } + + /** + * Creates the hook form. + */ + ngOnInit() { + this.createHookForm(); + this.hookForm.get('name').valueChanges.subscribe(name => { + if (name === 'Web') { + this.hookForm.get('contentType').enable(); + this.hookForm.get('phoneNumber').disable(); + this.hookForm.get('smsProvider').disable(); + this.hookForm.get('smsProviderAccountId').disable(); + this.hookForm.get('smsProviderToken').disable(); + } else { + this.hookForm.get('contentType').disable(); + this.hookForm.get('phoneNumber').enable(); + this.hookForm.get('smsProvider').enable(); + this.hookForm.get('smsProviderAccountId').enable(); + this.hookForm.get('smsProviderToken').enable(); + } + }); + this.setEvents(); + } + + /** + * Initializes the data source, paginator and sorter for events table. + */ + setEvents() { + this.dataSource = new MatTableDataSource(this.eventsData); + this.dataSource.sort = this.sort; + } + + /** + * Creates the hook form. + */ + createHookForm() { + this.hookForm = this.formBuilder.group({ + 'name': ['Web', Validators.required], + 'displayName': ['', Validators.required], + 'isActive': [''], + 'phoneNumber': [{ value: '', disabled: true }, Validators.required], + 'smsProvider': [{ value: '', disabled: true }, Validators.required], + 'smsProviderAccountId': [{ value: '', disabled: true }, Validators.required], + 'smsProviderToken': [{ value: '', disabled: true }, Validators.required], + 'contentType': ['', Validators.required], + 'payloadUrl': ['', Validators.required] + }); + } + + /** + * Adds the event form to given events form array. + */ + addEvent() { + const addEventDialogRef = this.dialog.open(AddEventDialogComponent, { + data: this.hooksTemplateData + }); + addEventDialogRef.afterClosed().subscribe((response: any) => { + if (response) { + this.eventsData.push({ entityName: response.entity, + actionName: response.action }); + this.dataSource.connect().next(this.eventsData); + } + }); + } + + /** + * Removes the event form from given events form array at given index. + * @param {number} index Array index from where event form needs to be removed. + */ + deleteEvent(index: number) { + const deleteEventDialogRef = this.dialog.open(DeleteDialogComponent, { + data: { deleteContext: `event with entity name of ${this.eventsData[index].entityName}` } + }); + deleteEventDialogRef.afterClosed().subscribe((response: any) => { + if (response.delete) { + this.eventsData.splice(index, 1); + this.dataSource.connect().next(this.eventsData); + } + }); + } + + /** + * Submits the hook form and creates hook, + * if successful redirects to view created hook. + */ + submit() { + const hook: { + name: string, isActive: boolean, displayName: string, events: any, + config: { + 'Payload URL': string, 'Content Type'?: string, 'SMS Provider'?: string, + 'SMS Provider Account Id'?: string, 'SMS Provider Token'?: string + } + } = { + name: this.hookForm.get('name').value, + isActive: this.hookForm.get('isActive').value, + displayName: this.hookForm.get('displayName').value, + events: this.eventsData, + config: { + 'Payload URL': this.hookForm.get('payloadUrl').value, + 'Content Type': this.hookForm.get('contentType').enabled ? this.hookForm.get('contentType').value : undefined, + 'SMS Provider': this.hookForm.get('smsProvider').enabled ? this.hookForm.get('smsProvider').value : undefined, + 'SMS Provider Account Id': this.hookForm.get('smsProviderAccountId').enabled ? this.hookForm.get('smsProviderAccountId').value : undefined, + 'SMS Provider Token': this.hookForm.get('smsProviderToken').enabled ? this.hookForm.get('smsProviderToken').value : undefined + } + }; + this.systemService.createHook(hook) + .subscribe((response: any) => { + this.router.navigate(['../', response.resourceId], {relativeTo: this.route}); + }); + } +} diff --git a/src/app/system/manage-hooks/edit-hook/edit-hook.component.html b/src/app/system/manage-hooks/edit-hook/edit-hook.component.html new file mode 100644 index 000000000..7dea58a16 --- /dev/null +++ b/src/app/system/manage-hooks/edit-hook/edit-hook.component.html @@ -0,0 +1,159 @@ +
+ + + +
+ + + +
+ + + Hook Template + + + {{ hookTemplate.name }} + + + + Hook Template is required + + + + + Display Name + + + Display Name is required + + + +
+ + Is Active? + +
+ +
+ +
+ + + Content Type + + + json + + + form + + + + Content Type is required + + + + + Phone Number + + {{input.value?.length || 0}}/10 + + Payload URL is required + + + + + Payload URL + + + Payload URL is required + + + +
+ +
+ + + SMS Provider + + + SMS Provider is required + + + + + SMS Provider Account ID + + + SMS Provider Account ID is required + + + + + SMS Provider Token + + + SMS Provider Token is required + + + +
+ +
+ + + +
+ +
+ +

Events

+ + + +
+ + + + + + + + + + + + + + + + + + + + + +
Entity Name {{ event.entityName }} Action Name {{ event.actionName }} Actions + +
+ +
+ + + + + + +
+ +
+ +
diff --git a/src/app/system/manage-hooks/edit-hook/edit-hook.component.scss b/src/app/system/manage-hooks/edit-hook/edit-hook.component.scss new file mode 100644 index 000000000..3344ae538 --- /dev/null +++ b/src/app/system/manage-hooks/edit-hook/edit-hook.component.scss @@ -0,0 +1,17 @@ +@media (min-width: 992px) { + + .is-active-wrapper { + position: relative; + + .is-active { + padding: 0 0 17.5px 0; + position: absolute; + bottom: 0; + right: 0; + } + } +} + +table { + width: 100%; +} diff --git a/src/app/system/manage-hooks/edit-hook/edit-hook.component.spec.ts b/src/app/system/manage-hooks/edit-hook/edit-hook.component.spec.ts new file mode 100644 index 000000000..2b0405eb0 --- /dev/null +++ b/src/app/system/manage-hooks/edit-hook/edit-hook.component.spec.ts @@ -0,0 +1,25 @@ +import { async, ComponentFixture, TestBed } from '@angular/core/testing'; + +import { EditHookComponent } from './edit-hook.component'; + +describe('EditHookComponent', () => { + let component: EditHookComponent; + let fixture: ComponentFixture; + + beforeEach(async(() => { + TestBed.configureTestingModule({ + declarations: [ EditHookComponent ] + }) + .compileComponents(); + })); + + beforeEach(() => { + fixture = TestBed.createComponent(EditHookComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/src/app/system/manage-hooks/edit-hook/edit-hook.component.ts b/src/app/system/manage-hooks/edit-hook/edit-hook.component.ts new file mode 100644 index 000000000..d0d79caee --- /dev/null +++ b/src/app/system/manage-hooks/edit-hook/edit-hook.component.ts @@ -0,0 +1,158 @@ +/** Angular Imports */ +import { Component, OnInit, ViewChild } from '@angular/core'; +import { ActivatedRoute, Router } from '@angular/router'; +import { FormBuilder, FormGroup, Validators } from '@angular/forms'; +import { MatTableDataSource, MatPaginator, MatSort, MatDialog } from '@angular/material'; + +/** Custom Services */ +import { SystemService } from '../../system.service'; + +/** Custom Components */ +import { AddEventDialogComponent } from '../add-event-dialog/add-event-dialog.component'; +import { DeleteDialogComponent } from 'app/shared/delete-dialog/delete-dialog.component'; + +/** + * Edit Hook Component. + */ +@Component({ + selector: 'mifosx-edit-hook', + templateUrl: './edit-hook.component.html', + styleUrls: ['./edit-hook.component.scss'] +}) +export class EditHookComponent implements OnInit { + + /** Hooks Template Data. */ + hooksTemplateData: any; + /** Hook Data. */ + hookData: any; + /** Hook Form. */ + hookForm: FormGroup; + /** Columns to be displayed in events table. */ + displayedColumns: string[] = ['entityName', 'actionName', 'actions']; + /** Data source for events table. */ + dataSource: MatTableDataSource; + /** Events Data. */ + eventsData: any[] = []; + /** Boolean to check if events data is changed or not. */ + eventsDataChanged: Boolean = false; + /** Sorter for events table. */ + @ViewChild(MatSort) sort: MatSort; + + /** + * Retrieves the hooks template data from `resolve`. + * @param {ActivatedRoute} route Activated Route. + * @param {SystemService} systemService System Service. + * @param {Router} router Router for navigation. + * @param {FormBuilder} formBuilder Form Builder. + * @param {MatDialog} dialog Dialog Reference. + */ + constructor(private route: ActivatedRoute, + private systemService: SystemService, + private router: Router, + private formBuilder: FormBuilder, + private dialog: MatDialog) { + this.route.data.subscribe(( data: { hooksTemplate: any, hook: any }) => { + this.hooksTemplateData = data.hooksTemplate; + this.hookData = data.hook; + this.eventsData = data.hook.events ? data.hook.events : []; + }); + } + + /** + * Creates the hook form. + */ + ngOnInit() { + this.createHookForm(); + this.setEvents(); + } + + /** + * Initializes the data source, paginator and sorter for events table. + */ + setEvents() { + this.dataSource = new MatTableDataSource(this.eventsData); + this.dataSource.sort = this.sort; + } + + /** + * Creates the hook form. + */ + createHookForm() { + this.hookForm = this.formBuilder.group({ + 'name': [{ value: this.hookData.name, disabled: true }, Validators.required], + 'displayName': [this.hookData.displayName, Validators.required], + 'isActive': [this.hookData.isActive], + 'phoneNumber': [{ value: this.hookData.name === 'SMS Bridge' ? this.hookData.config[1].fieldValue : '', disabled: this.hookData.name !== 'SMS Bridge' }, Validators.required], + 'smsProvider': [{ value: this.hookData.name === 'SMS Bridge' ? this.hookData.config[2].fieldValue : '', disabled: this.hookData.name !== 'SMS Bridge' }, Validators.required], + 'smsProviderAccountId': [{ value: this.hookData.name === 'SMS Bridge' ? this.hookData.config[3].fieldValue : '', disabled: this.hookData.name !== 'SMS Bridge' }, Validators.required], + 'smsProviderToken': [{ value: this.hookData.name === 'SMS Bridge' ? this.hookData.config[4].fieldValue : '', disabled: this.hookData.name !== 'SMS Bridge' }, Validators.required], + 'contentType': [{ value: this.hookData.name === 'Web' ? this.hookData.config[0].fieldValue : '', disabled: this.hookData.name !== 'Web' }, Validators.required], + 'payloadUrl': [this.hookData.name === 'Web' ? this.hookData.config[1].fieldValue : this.hookData.config[0].fieldValue, Validators.required] + }); + } + + /** + * Adds the event form to given events form array. + */ + addEvent() { + const addEventDialogRef = this.dialog.open(AddEventDialogComponent, { + data: this.hooksTemplateData + }); + addEventDialogRef.afterClosed().subscribe((response: any) => { + if (response) { + this.eventsData.push({ entityName: response.entity, + actionName: response.action }); + this.dataSource.connect().next(this.eventsData); + this.eventsDataChanged = true; + } + }); + } + + /** + * Removes the event form from given events form array at given index. + * @param {number} index Array index from where event form needs to be removed. + */ + deleteEvent(index: number) { + const deleteEventDialogRef = this.dialog.open(DeleteDialogComponent, { + data: { deleteContext: `event with entity name of ${this.eventsData[index].entityName}` } + }); + deleteEventDialogRef.afterClosed().subscribe((response: any) => { + if (response.delete) { + this.eventsData.splice(index, 1); + this.dataSource.connect().next(this.eventsData); + this.eventsDataChanged = true; + } + }); + } + + /** + * Submits the hook form and updates hook, + * if successful redirects to view updated hook. + */ + submit() { + const hook: { + name: string, isActive: boolean, displayName: string, events: any, + config: { + 'Payload URL': string, 'Content Type'?: string, 'SMS Provider'?: string, + 'SMS Provider Account Id'?: string, 'SMS Provider Token'?: string + } + } = { + name: this.hookForm.get('name').value, + isActive: this.hookForm.get('isActive').value, + displayName: this.hookForm.get('displayName').value, + events: this.eventsData, + config: { + 'Payload URL': this.hookForm.get('payloadUrl').value, + 'Content Type': this.hookForm.get('contentType').enabled ? this.hookForm.get('contentType').value : undefined, + 'SMS Provider': this.hookForm.get('smsProvider').enabled ? this.hookForm.get('smsProvider').value : undefined, + 'SMS Provider Account Id': this.hookForm.get('smsProviderAccountId').enabled ? this.hookForm.get('smsProviderAccountId').value : undefined, + 'SMS Provider Token': this.hookForm.get('smsProviderToken').enabled ? this.hookForm.get('smsProviderToken').value : undefined + } + }; + this.systemService.updateHook(this.hookData.id, hook) + .subscribe((response: any) => { + this.router.navigate(['../'], {relativeTo: this.route}); + }); + } + +} diff --git a/src/app/system/manage-hooks/hooks-template.resolver.ts b/src/app/system/manage-hooks/hooks-template.resolver.ts new file mode 100644 index 000000000..4918520c2 --- /dev/null +++ b/src/app/system/manage-hooks/hooks-template.resolver.ts @@ -0,0 +1,30 @@ +/** Angular Imports */ +import { Injectable } from '@angular/core'; +import { Resolve } from '@angular/router'; + +/** rxjs Imports */ +import { Observable } from 'rxjs'; + +/** Custom Services */ +import { SystemService } from '../system.service'; + +/** + * Hooks template data resolver. + */ +@Injectable() +export class HooksTemplateResolver implements Resolve { + + /** + * @param {SystemService} systemService System service. + */ + constructor(private systemService: SystemService) {} + + /** + * Returns the hooks template data. + * @returns {Observable} + */ + resolve(): Observable { + return this.systemService.getHooksTemplate(); + } + +} diff --git a/src/app/system/manage-hooks/manage-hooks.component.html b/src/app/system/manage-hooks/manage-hooks.component.html index 847437757..a87a65760 100644 --- a/src/app/system/manage-hooks/manage-hooks.component.html +++ b/src/app/system/manage-hooks/manage-hooks.component.html @@ -1,5 +1,5 @@
- @@ -38,7 +38,7 @@ - + diff --git a/src/app/system/manage-hooks/manage-hooks.component.ts b/src/app/system/manage-hooks/manage-hooks.component.ts index 7a67ec0a1..f78d5d892 100644 --- a/src/app/system/manage-hooks/manage-hooks.component.ts +++ b/src/app/system/manage-hooks/manage-hooks.component.ts @@ -3,11 +3,8 @@ import { Component, OnInit, ViewChild } from '@angular/core'; import { MatTableDataSource, MatPaginator, MatSort } from '@angular/material'; import { ActivatedRoute } from '@angular/router'; -/** rxjs Imports */ -import { of } from 'rxjs'; - /** - * Manage Hooks component. + * Manage Hooks Component. */ @Component({ selector: 'mifosx-manage-hooks', diff --git a/src/app/system/manage-hooks/manage-hooks.resolver.ts b/src/app/system/manage-hooks/manage-hooks.resolver.ts index 8226bd9af..34620043c 100644 --- a/src/app/system/manage-hooks/manage-hooks.resolver.ts +++ b/src/app/system/manage-hooks/manage-hooks.resolver.ts @@ -20,7 +20,7 @@ export class ManageHooksResolver implements Resolve { constructor(private systemService: SystemService) {} /** - * Returns the manage hooks data. + * Returns the hooks data. * @returns {Observable} */ resolve(): Observable { diff --git a/src/app/system/manage-hooks/view-hook/hook.resolver.ts b/src/app/system/manage-hooks/view-hook/hook.resolver.ts new file mode 100644 index 000000000..4d0d745ea --- /dev/null +++ b/src/app/system/manage-hooks/view-hook/hook.resolver.ts @@ -0,0 +1,31 @@ +/** Angular Imports */ +import { Injectable } from '@angular/core'; +import {ActivatedRouteSnapshot, Resolve} from '@angular/router'; + +/** rxjs Imports */ +import { Observable } from 'rxjs'; + +/** Custom Services */ +import { SystemService } from '../../system.service'; + +/** + * Hook data resolver. + */ +@Injectable() +export class HookResolver implements Resolve { + + /** + * @param {SystemService} systemService System service. + */ + constructor(private systemService: SystemService) {} + + /** + * Returns the manage hooks data. + * @returns {Observable} + */ + resolve(route: ActivatedRouteSnapshot): Observable { + const hookId = route.paramMap.get('id'); + return this.systemService.getHook(hookId); + } + +} diff --git a/src/app/system/manage-hooks/view-hook/view-hook.component.html b/src/app/system/manage-hooks/view-hook/view-hook.component.html new file mode 100644 index 000000000..7d39ecd8d --- /dev/null +++ b/src/app/system/manage-hooks/view-hook/view-hook.component.html @@ -0,0 +1,129 @@ +
+ + + + + +
+ +
+ + + + + +
+ +
+ Hook Name: +
+ +
+ {{ hookData.displayName }} +
+ +
+ Status: +
+ +
+ {{ hookData.isActive ? 'Active' : 'Inactive' }} +
+ +
+ Activation Date: +
+ +
+ {{ hookData.createdAt | date }} +
+ +
+ Updated on: +
+ +
+ {{ hookData.updatedAt | date }} +
+ +
+ Events: +
+ +
+ + + + {{ event.actionName + ' - ' + event.entityName }} + +
+ +
+ +
+ +
+ Content Type: +
+ +
+ {{ hookData.config[0].fieldValue }} +
+ +
+ Payload URL: +
+ +
+ {{ hookData.config[1].fieldValue }} +
+ +
+ {{ hookData.config[0].fieldValue }} +
+ +
+ Phone Number: +
+ +
+ {{ hookData.config[1].fieldValue }} +
+ +
+ SMS Provider: +
+ +
+ {{ hookData.config[2].fieldValue }} +
+ +
+ SMS Provider Account ID: +
+ +
+ {{ hookData.config[3].fieldValue }} +
+ +
+ SMS Provider Token: +
+ +
+ {{ hookData.config[4].fieldValue }} +
+ +
+ +
+ +
+ +
diff --git a/src/app/system/manage-hooks/view-hook/view-hook.component.scss b/src/app/system/manage-hooks/view-hook/view-hook.component.scss new file mode 100644 index 000000000..46cf44760 --- /dev/null +++ b/src/app/system/manage-hooks/view-hook/view-hook.component.scss @@ -0,0 +1,10 @@ +.container { + max-width: 37rem; + + .content { + div { + margin: 1rem 0; + word-wrap: break-word; + } + } +} diff --git a/src/app/system/manage-hooks/view-hook/view-hook.component.spec.ts b/src/app/system/manage-hooks/view-hook/view-hook.component.spec.ts new file mode 100644 index 000000000..7a37870a7 --- /dev/null +++ b/src/app/system/manage-hooks/view-hook/view-hook.component.spec.ts @@ -0,0 +1,25 @@ +import { async, ComponentFixture, TestBed } from '@angular/core/testing'; + +import { ViewHookComponent } from './view-hook.component'; + +describe('ViewHookComponent', () => { + let component: ViewHookComponent; + let fixture: ComponentFixture; + + beforeEach(async(() => { + TestBed.configureTestingModule({ + declarations: [ ViewHookComponent ] + }) + .compileComponents(); + })); + + beforeEach(() => { + fixture = TestBed.createComponent(ViewHookComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/src/app/system/manage-hooks/view-hook/view-hook.component.ts b/src/app/system/manage-hooks/view-hook/view-hook.component.ts new file mode 100644 index 000000000..f39dbeb7a --- /dev/null +++ b/src/app/system/manage-hooks/view-hook/view-hook.component.ts @@ -0,0 +1,61 @@ +/** Angular Imports */ +import { Component, OnInit } from '@angular/core'; +import { ActivatedRoute, Router } from '@angular/router'; +import { MatDialog } from '@angular/material'; + +/** Custom Components */ +import { DeleteDialogComponent } from '../../../shared/delete-dialog/delete-dialog.component'; + +/** Custom Services */ +import { SystemService } from '../../system.service'; + +/** + * View Hook Component. + */ +@Component({ + selector: 'mifosx-view-hook', + templateUrl: './view-hook.component.html', + styleUrls: ['./view-hook.component.scss'] +}) +export class ViewHookComponent implements OnInit { + + /** Hook Data. */ + hookData: any; + + /** + * Retrieves the hook data from `resolve`. + * @param {ActivatedRoute} route Activated Route. + * @param {MatDialog} dialog Dialog Reference. + * @param {SystemService} systemService System Service. + * @param {Router} router Router for navigation. + */ + constructor(private route: ActivatedRoute, + private dialog: MatDialog, + private systemService: SystemService, + private router: Router) { + this.route.data.subscribe((data: { hook: any }) => { + this.hookData = data.hook; + }); + } + + ngOnInit() { + } + + /** + * Deletes the current hook. + */ + delete() { + const deleteHookDialogRef = this.dialog.open(DeleteDialogComponent, { + data: { deleteContext: `hook ${this.hookData.id}` } + }); + deleteHookDialogRef.afterClosed().subscribe((response: any) => { + if (response.delete) { + this.systemService.deleteHook(this.hookData.id) + .subscribe(() => { + this.router.navigate(['/system/hooks']); + }); + } + }); + } + +} diff --git a/src/app/system/system-routing.module.ts b/src/app/system/system-routing.module.ts index 6007446b9..76c698677 100644 --- a/src/app/system/system-routing.module.ts +++ b/src/app/system/system-routing.module.ts @@ -14,6 +14,9 @@ import { EditCodeComponent } from './codes/edit-code/edit-code.component'; import { ExternalServicesComponent } from './external-services/external-services.component'; import { ManageDataTablesComponent } from './manage-data-tables/manage-data-tables.component'; import { ManageHooksComponent } from './manage-hooks/manage-hooks.component'; +import { ViewHookComponent } from './manage-hooks/view-hook/view-hook.component'; +import { CreateHookComponent } from './manage-hooks/create-hook/create-hook.component'; +import { EditHookComponent } from './manage-hooks/edit-hook/edit-hook.component'; import { RolesAndPermissionsComponent } from './roles-and-permissions/roles-and-permissions.component'; import { AddRoleComponent } from './roles-and-permissions/add-role/add-role.component'; import { ManageSurveysComponent } from './manage-surveys/manage-surveys.component'; @@ -43,6 +46,8 @@ import { CodeResolver } from './codes/code.resolver'; import { CodeValuesResolver } from './codes/view-code/code-values.resolver'; import { ManageDataTablesResolver } from './manage-data-tables/manage-data-tables.resolver'; import { ManageHooksResolver } from './manage-hooks/manage-hooks.resolver'; +import { HookResolver } from './manage-hooks/view-hook/hook.resolver'; +import { HooksTemplateResolver } from './manage-hooks/hooks-template.resolver'; import { RolesAndPermissionsResolver } from './roles-and-permissions/roles-and-permissions.resolver'; import { ManageSurveysResolver } from './manage-surveys/manage-surveys.resolver'; import { ManageSchedulerJobsResolver } from './manage-scheduler-jobs/manage-scheduler-jobs.resolver'; @@ -214,11 +219,46 @@ const routes: Routes = [ }, { path: 'hooks', - component: ManageHooksComponent, - resolve: { - hooks: ManageHooksResolver - }, data: { title: extract('Manage Hooks'), breadcrumb: 'Manage Hooks' }, + children: [ + { + path: '', + component: ManageHooksComponent, + resolve: { + hooks: ManageHooksResolver + } + }, + { + path: 'create', + component: CreateHookComponent, + data: { title: extract('Create Hook'), breadcrumb: 'Create' }, + resolve: { + hooksTemplate: HooksTemplateResolver + } + }, + { + path: ':id', + data: { title: extract('View Hook'), routeParamBreadcrumb: 'id' }, + children: [ + { + path: '', + component: ViewHookComponent, + resolve: { + hook: HookResolver + } + }, + { + path: 'edit', + component: EditHookComponent, + data: { title: extract('Edit Hook'), breadcrumb: 'Edit', routeParamBreadcrumb: false }, + resolve: { + hooksTemplate: HooksTemplateResolver, + hook: HookResolver + } + } + ] + } + ] }, { path: 'roles-and-permissions', @@ -375,6 +415,8 @@ const routes: Routes = [ CodeValuesResolver, ManageDataTablesResolver, ManageHooksResolver, + HookResolver, + HooksTemplateResolver, RolesAndPermissionsResolver, ManageSurveysResolver, ManageSchedulerJobsResolver, diff --git a/src/app/system/system.module.ts b/src/app/system/system.module.ts index f696d5f93..fbb9358a2 100644 --- a/src/app/system/system.module.ts +++ b/src/app/system/system.module.ts @@ -36,9 +36,13 @@ import { ManageReportsComponent } from './manage-reports/manage-reports.componen import { ViewReportComponent } from './manage-reports/view-report/view-report.component'; import { CreateReportComponent } from './manage-reports/create-report/create-report.component'; import { EditReportComponent } from './manage-reports/edit-report/edit-report.component'; +import { EditHookComponent } from './manage-hooks/edit-hook/edit-hook.component'; +import { ViewHookComponent } from './manage-hooks/view-hook/view-hook.component'; +import { CreateHookComponent } from './manage-hooks/create-hook/create-hook.component'; /** Dialog Component Imports */ import { ReportParameterDialogComponent } from './manage-reports/report-parameter-dialog/report-parameter-dialog.component'; +import { AddEventDialogComponent } from './manage-hooks/add-event-dialog/add-event-dialog.component'; @NgModule({ imports: [ @@ -76,10 +80,15 @@ import { ReportParameterDialogComponent } from './manage-reports/report-paramete CreateReportComponent, EditReportComponent, ReportParameterDialogComponent, - AddRoleComponent + AddRoleComponent, + EditHookComponent, + ViewHookComponent, + CreateHookComponent, + AddEventDialogComponent ], entryComponents: [ - ReportParameterDialogComponent + ReportParameterDialogComponent, + AddEventDialogComponent ] }) export class SystemModule { } diff --git a/src/app/system/system.service.ts b/src/app/system/system.service.ts index 20734edbc..a347bb60b 100644 --- a/src/app/system/system.service.ts +++ b/src/app/system/system.service.ts @@ -32,6 +32,46 @@ export class SystemService { return this.http.get('/hooks'); } + /** + * @param {string} hookId Hook ID of Hook. + * @returns {Observable} + */ + getHook(hookId: string): Observable { + return this.http.get(`/hooks/${hookId}`); + } + + /** + * @returns {Observable} Hooks Template. + */ + getHooksTemplate(): Observable { + return this.http.get('/hooks/template'); + } + + /** + * @param {any} hook Hook to be created. + * @returns {Observable} + */ + createHook(hook: any): Observable { + return this.http.post('/hooks', hook); + } + + /** + * @param {string} hookId Hook ID of Hook to be updated. + * @param {any} hook Hook to be updated. + * @returns {Observable} + */ + updateHook(hookId: string, hook: any): Observable { + return this.http.put(`/hooks/${hookId}`, hook); + } + + /** + * @param {string} hookId Hook ID of Hook to be deleted. + * @returns {Observable} + */ + deleteHook(hookId: string): Observable { + return this.http.delete(`/hooks/${hookId}`); + } + /** * @returns {Observable} Fetches Roles and Permissions */