diff --git a/src/app/organization/organization-routing.module.ts b/src/app/organization/organization-routing.module.ts index a3b809791..9beb93ded 100644 --- a/src/app/organization/organization-routing.module.ts +++ b/src/app/organization/organization-routing.module.ts @@ -14,12 +14,14 @@ import { LoanProvisioningCriteriaComponent } from './loan-provisioning-criteria/ import { OfficesComponent } from './offices/offices.component'; import { EmployeesComponent } from './employees/employees.component'; import { CurrenciesComponent } from './currencies/currencies.component'; +import { SmsCampaignsComponent } from './sms-campaigns/sms-campaigns.component'; /** Custom Resolvers */ import { LoanProvisioningCriteriaResolver } from './loan-provisioning-criteria/loan-provisioning-criteria.resolver'; import { OfficesResolver } from './offices/offices.resolver'; import { EmployeesResolver } from './employees/employees.resolver'; import { CurrenciesResolver } from './currencies/currencies.resolver'; +import { SmsCampaignsResolver } from './sms-campaigns/sms-campaigns.resolver'; /** Organization Routes */ const routes: Routes = [ @@ -63,6 +65,14 @@ const routes: Routes = [ resolve: { currencies: CurrenciesResolver } + }, + { + path: 'sms-campaigns', + component: SmsCampaignsComponent, + data: { title: extract('SMS Campaigns'), breadcrumb: 'SMS Campaigns' }, + resolve: { + smsCampaigns: SmsCampaignsResolver + } } ] } @@ -81,7 +91,8 @@ const routes: Routes = [ LoanProvisioningCriteriaResolver, OfficesResolver, EmployeesResolver, - CurrenciesResolver + CurrenciesResolver, + SmsCampaignsResolver ] }) export class OrganizationRoutingModule { } diff --git a/src/app/organization/organization.component.html b/src/app/organization/organization.component.html index f5b4075ba..732261f42 100644 --- a/src/app/organization/organization.component.html +++ b/src/app/organization/organization.component.html @@ -129,7 +129,7 @@

Manage payment types

- + diff --git a/src/app/organization/organization.module.ts b/src/app/organization/organization.module.ts index 54fd47c97..93c24f46a 100644 --- a/src/app/organization/organization.module.ts +++ b/src/app/organization/organization.module.ts @@ -4,6 +4,7 @@ import { NgModule } from '@angular/core'; /** Custom Modules */ import { SharedModule } from '../shared/shared.module'; import { OrganizationRoutingModule } from './organization-routing.module'; +import { PipesModule } from 'app/pipes/pipes.module'; /** Custom Components */ import { OrganizationComponent } from './organization.component'; @@ -11,6 +12,7 @@ import { LoanProvisioningCriteriaComponent } from './loan-provisioning-criteria/ import { OfficesComponent } from './offices/offices.component'; import { EmployeesComponent } from './employees/employees.component'; import { CurrenciesComponent } from './currencies/currencies.component'; +import { SmsCampaignsComponent } from './sms-campaigns/sms-campaigns.component'; /** * Organization Module @@ -20,14 +22,16 @@ import { CurrenciesComponent } from './currencies/currencies.component'; @NgModule({ imports: [ SharedModule, - OrganizationRoutingModule + OrganizationRoutingModule, + PipesModule ], declarations: [ OrganizationComponent, LoanProvisioningCriteriaComponent, OfficesComponent, EmployeesComponent, - CurrenciesComponent + CurrenciesComponent, + SmsCampaignsComponent ] }) export class OrganizationModule { } diff --git a/src/app/organization/organization.service.ts b/src/app/organization/organization.service.ts index c5912e44f..d1d0299d0 100644 --- a/src/app/organization/organization.service.ts +++ b/src/app/organization/organization.service.ts @@ -46,4 +46,11 @@ export class OrganizationService { return this.http.get('/currencies'); } + /** + * @returns {Observable} SMS Campaigns data + */ + getSmsCampaigns(): Observable { + return this.http.get('/smscampaigns'); + } + } diff --git a/src/app/organization/sms-campaigns/sms-campaigns.component.html b/src/app/organization/sms-campaigns/sms-campaigns.component.html new file mode 100644 index 000000000..e647f9cd2 --- /dev/null +++ b/src/app/organization/sms-campaigns/sms-campaigns.component.html @@ -0,0 +1,66 @@ +
+ + + +
+ +
+ +
+ + Filter + + +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Name {{ smsCampaign.campaignName }} Template Message {{ smsCampaign.campaignMessage }} Campaign Type {{ smsCampaign.campaignType.value }} Trigger Type {{ smsCampaign.triggerType.value }} Status +
+ +
+
Approved By {{ smsCampaign.smsCampaignTimeLine.submittedByUsername }}
+ + + +
+ +
diff --git a/src/app/organization/sms-campaigns/sms-campaigns.component.scss b/src/app/organization/sms-campaigns/sms-campaigns.component.scss new file mode 100644 index 000000000..94e48997c --- /dev/null +++ b/src/app/organization/sms-campaigns/sms-campaigns.component.scss @@ -0,0 +1,7 @@ +table { + width: 100%; + + .select-row:hover { + cursor: pointer; + } +} diff --git a/src/app/organization/sms-campaigns/sms-campaigns.component.spec.ts b/src/app/organization/sms-campaigns/sms-campaigns.component.spec.ts new file mode 100644 index 000000000..c1a83f21e --- /dev/null +++ b/src/app/organization/sms-campaigns/sms-campaigns.component.spec.ts @@ -0,0 +1,25 @@ +import { async, ComponentFixture, TestBed } from '@angular/core/testing'; + +import { SmsCampaignsComponent } from './sms-campaigns.component'; + +describe('SmsCampaignsComponent', () => { + let component: SmsCampaignsComponent; + let fixture: ComponentFixture; + + beforeEach(async(() => { + TestBed.configureTestingModule({ + declarations: [ SmsCampaignsComponent ] + }) + .compileComponents(); + })); + + beforeEach(() => { + fixture = TestBed.createComponent(SmsCampaignsComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/src/app/organization/sms-campaigns/sms-campaigns.component.ts b/src/app/organization/sms-campaigns/sms-campaigns.component.ts new file mode 100644 index 000000000..dff62c3a8 --- /dev/null +++ b/src/app/organization/sms-campaigns/sms-campaigns.component.ts @@ -0,0 +1,74 @@ +/** Angular Imports */ +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'; + +/** + * SMS Campaigns component. + */ +@Component({ + selector: 'mifosx-sms-campaigns', + templateUrl: './sms-campaigns.component.html', + styleUrls: ['./sms-campaigns.component.scss'] +}) +export class SmsCampaignsComponent implements OnInit { + + /** SMS Campaigns data. */ + smsCampaignsData: any; + /** Columns to be displayed in sms campaigns table. */ + displayedColumns: string[] = ['campaignName', 'campaignMessage', 'campaignType.value', 'triggerType.value', 'campaignStatus.value', 'smsCampaignTimeLine.submittedByUsername']; + /** Data source for SMS campaigns table. */ + dataSource: MatTableDataSource; + + /** Paginator for SMS campaigns table. */ + @ViewChild(MatPaginator) paginator: MatPaginator; + /** Sorter for SMS campaigns table. */ + @ViewChild(MatSort) sort: MatSort; + + /** + * Retrieves the SMS campaigns data from `resolve`. + * @param {ActivatedRoute} route Activated Route. + */ + constructor(private route: ActivatedRoute) { + this.route.data.subscribe(( data: { smsCampaigns: any }) => { + this.smsCampaignsData = data.smsCampaigns.pageItems; + }); + } + + /** + * Filters data in SMS campaigns table based on passed value. + * @param {string} filterValue Value to filter data. + */ + applyFilter(filterValue: string) { + this.dataSource.filter = filterValue.trim().toLowerCase(); + } + + /** + * Sets the SMS campaigns table. + */ + ngOnInit() { + this.setSmsCampaigns(); + } + + /** + * Initializes the data source, paginator and sorter for SMS campaigns table. + */ + setSmsCampaigns() { + this.dataSource = new MatTableDataSource(this.smsCampaignsData); + this.dataSource.sortingDataAccessor = (item, property) => { + switch (property) { + case 'campaignType.value': return item.campaignType.value; + case 'triggerType.value': return item.triggerType.value; + case 'campaignStatus.value': return item.campaignStatus.value; + case 'smsCampaignTimeLine.submittedByUsername': return item.smsCampaignTimeLine.submittedByUsername; + default: return item[property]; + } + }; + this.dataSource.paginator = this.paginator; + this.dataSource.sort = this.sort; + } + +} diff --git a/src/app/organization/sms-campaigns/sms-campaigns.resolver.ts b/src/app/organization/sms-campaigns/sms-campaigns.resolver.ts new file mode 100644 index 000000000..b7ad29b59 --- /dev/null +++ b/src/app/organization/sms-campaigns/sms-campaigns.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 { OrganizationService } from '../organization.service'; + +/** + * SMS Campaigns data resolver. + */ +@Injectable() +export class SmsCampaignsResolver implements Resolve { + + /** + * @param {OrganizationService} organizationService Organization service. + */ + constructor(private organizationService: OrganizationService) {} + + /** + * Returns the SMS Campaigns data. + * @returns {Observable} + */ + resolve(): Observable { + return this.organizationService.getSmsCampaigns(); + } + +} diff --git a/src/app/pipes/status-lookup.pipe.ts b/src/app/pipes/status-lookup.pipe.ts index 0920b194f..36a72b665 100644 --- a/src/app/pipes/status-lookup.pipe.ts +++ b/src/app/pipes/status-lookup.pipe.ts @@ -35,7 +35,10 @@ export class StatusLookupPipe implements PipeTransform { 'clientStatusType.submitted.and.pending.approval': 'status-pending', 'clientStatusTYpe.approved': 'status-approved', 'clientStatusType.transfer.in.progress': 'status-transfer-progress', // write - 'clientStatusType.transfer.on.hold': 'status-transfer-hold' // write + 'clientStatusType.transfer.on.hold': 'status-transfer-hold', // write + 'smsCampaignStatus.active': 'status-active', + 'smsCampaignStatus.pending': 'status-pending', + 'smsCampaignStatus.closed': 'status-closed', }; return cssClassNameLookup[status]; }