WEB-59 removed self-service from codebase (#2374)

This commit is contained in:
Gopi Kishan
2025-04-01 21:21:25 -06:00
committed by GitHub
parent 664494545a
commit cc41a10027
53 changed files with 4 additions and 1720 deletions
-2
View File
@@ -22,7 +22,6 @@ import { ClientsModule } from './clients/clients.module';
import { GroupsModule } from './groups/groups.module';
import { CentersModule } from './centers/centers.module';
import { AccountingModule } from './accounting/accounting.module';
import { SelfServiceModule } from './self-service/self-service.module';
import { SystemModule } from './system/system.module';
import { ProductsModule } from './products/products.module';
import { OrganizationModule } from './organization/organization.module';
@@ -96,7 +95,6 @@ export function HttpLoaderFactory(http: HttpClient) {
GroupsModule,
CentersModule,
AccountingModule,
SelfServiceModule,
SystemModule,
ProductsModule,
OrganizationModule,
@@ -14,5 +14,4 @@
<mifosx-add-client-charge *ngIf="actions['Add Charge']"></mifosx-add-client-charge>
<mifosx-take-survey *ngIf="actions['Take Survey']"></mifosx-take-survey>
<mifosx-client-screen-reports *ngIf="actions['Client Screen Reports']"></mifosx-client-screen-reports>
<mifosx-create-self-service-user *ngIf="actions['Create Self Service User']"></mifosx-create-self-service-user>
<mifosx-add-client-collateral *ngIf="actions['Create Collateral']"></mifosx-add-client-collateral>
@@ -28,7 +28,6 @@ export class ClientActionsComponent {
'Add Charge': boolean;
'Take Survey': boolean;
'Client Screen Reports': boolean;
'Create Self Service User': boolean;
'Create Collateral': boolean;
} = {
'Assign Staff': false,
@@ -46,7 +45,6 @@ export class ClientActionsComponent {
'Add Charge': false,
'Take Survey': false,
'Client Screen Reports': false,
'Create Self Service User': false,
'Create Collateral': false
};
@@ -1,122 +0,0 @@
<div class="container">
<mat-card>
<form [formGroup]="createSelfServiceForm" (ngSubmit)="submit()">
<mat-card-content>
<div div fxLayout="row wrap" fxLayoutGap="2%" fxLayout.lt-md="column">
<mat-form-field fxFlex="48%">
<mat-label> {{ 'labels.inputs.User Name' | translate }} </mat-label>
<input matInput required formControlName="username" />
<mat-error *ngIf="createSelfServiceForm.controls.username.hasError('required')">
{{ 'labels.inputs.User Name' | translate }} {{ 'labels.commons.is' | translate }}
<strong>{{ 'labels.commons.required' | translate }}</strong>
</mat-error>
</mat-form-field>
<mat-form-field fxFlex="48%">
<mat-label> {{ 'labels.inputs.First Name' | translate }} </mat-label>
<input matInput required formControlName="firstname" />
<mat-error *ngIf="createSelfServiceForm.controls.firstname.hasError('required')">
{{ 'labels.inputs.First Name' | translate }} {{ 'labels.commons.is' | translate }}
<strong>{{ 'labels.commons.required' | translate }}</strong>
</mat-error>
</mat-form-field>
<mat-form-field fxFlex="48%">
<mat-label> {{ 'labels.inputs.Last Name' | translate }} </mat-label>
<input matInput required formControlName="lastname" />
<mat-error *ngIf="createSelfServiceForm.controls.lastname.hasError('required')">
{{ 'labels.inputs.Last Name' | translate }} {{ 'labels.commons.is' | translate }}
<strong>{{ 'labels.commons.required' | translate }}</strong>
</mat-error>
</mat-form-field>
<mat-form-field fxFlex="48%">
<mat-label> {{ 'labels.inputs.Email' | translate }} </mat-label>
<input matInput required formControlName="email" />
<mat-error *ngIf="createSelfServiceForm.controls.email.hasError('required')">
{{ 'labels.inputs.Email' | translate }} {{ 'labels.commons.is' | translate }}
<strong>{{ 'labels.commons.required' | translate }}</strong>
</mat-error>
<mat-error *ngIf="createSelfServiceForm.controls.email.hasError('email')">
{{ 'labels.inputs.Email should be a' | translate }}
<strong>{{ 'labels.inputs.valid' | translate }}</strong> {{ 'labels.inputs.email' | translate }}.
</mat-error>
</mat-form-field>
<mat-checkbox labelPosition="before" formControlName="sendPasswordToEmail" fxFlex="48%">
{{ 'labels.inputs.Auto Generate Password' | translate }}
</mat-checkbox>
<div fxFlex="48%" fxLayoutGap="5px" fxLayout="row">
<mat-checkbox labelPosition="before" formControlName="passwordNeverExpires">
{{ 'labels.inputs.Override Password Expire Policy' | translate }} ?
</mat-checkbox>
<i
class="fa fa-question-circle fa fa-align-left"
title="{{ 'labels.inputs.Determines if passwords do not expire' | translate }}"
></i>
</div>
<mat-form-field fxFlex="48%" *ngIf="!hidePasswordField">
<mat-label>{{ 'labels.inputs.Password' | translate }}</mat-label>
<input matInput formControlName="password" type="password" />
<mat-error *ngIf="createSelfServiceForm.controls.password.hasError('required')">
{{ 'labels.inputs.Password' | translate }} <strong>{{ 'labels.commons.is required' | translate }}</strong>
</mat-error>
<mat-error *ngIf="createSelfServiceForm.controls.password.hasError('minlength')">
{{ 'labels.commons.Password should be at least' | translate }}
<strong>{{ 'labels.commons.12 characters long' | translate }}</strong>
</mat-error>
<mat-error *ngIf="createSelfServiceForm.controls.password.hasError('maxlength')">
{{ 'labels.commons.Password should not be more than' | translate }}
<strong>{{ 'labels.commons.50 characters long' | translate }}</strong>
</mat-error>
<mat-error
*ngIf="
createSelfServiceForm.controls.password.hasError('pattern') &&
!(
createSelfServiceForm.controls.password.hasError('minlength') ||
createSelfServiceForm.controls.password.hasError('maxlength')
)
"
>
{{ 'labels.commons.Password should include a' | translate }}
<strong>{{ 'labels.commons.numeral' | translate }}</strong> {{ 'labels.commons.and at' | translate }}
<strong>{{ 'labels.commons.least one uppercase' | translate }}</strong>
, <strong>{{ 'labels.commons.lowercase and special character' | translate }}</strong>
</mat-error>
</mat-form-field>
<mat-form-field fxFlex="48%" *ngIf="!hidePasswordField">
<mat-label> {{ 'labels.inputs.Repeat Password' | translate }} </mat-label>
<input matInput required formControlName="repeatPassword" type="password" />
<mat-error *ngIf="createSelfServiceForm.controls.repeatPassword.hasError('required')">
{{ 'labels.inputs.Repeat password' | translate }} {{ 'labels.commons.is' | translate }}
<strong>{{ 'labels.commons.required' | translate }}</strong>
</mat-error>
<mat-error *ngIf="createSelfServiceForm.controls.repeatPassword.hasError('notequal')">
{{ 'labels.inputs.Passwords should be' | translate }}
<strong>{{ 'labels.inputs.matched' | translate }}</strong>
</mat-error>
</mat-form-field>
<mat-form-field fxFlex="48%">
<mat-label> {{ 'labels.inputs.Status' | translate }} </mat-label>
<input matInput formControlName="status" />
</mat-form-field>
</div>
<mat-card-actions fxLayoutGap="5px" fxLayout="row" fxLayout.xs="column" fxLayoutAlign="center">
<button type="button" mat-raised-button [routerLink]="['../../']">
{{ 'labels.buttons.Cancel' | translate }}
</button>
<button mat-raised-button color="primary" [disabled]="!createSelfServiceForm.valid">
{{ 'labels.buttons.Activate Self Service User' | translate }}
</button>
<i class="fa fa-question-circle fa-2x" title="Activate Self Service User Help"></i>
</mat-card-actions>
</mat-card-content>
</form>
</mat-card>
</div>
@@ -1,17 +0,0 @@
.fa-question-circle {
color: #1abc9c;
}
.fa {
display: inline-block;
font-family: FontAwesome;
font-style: normal;
font-weight: normal;
line-height: 1;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
}
mat-card {
box-sizing: border-box;
}
@@ -1,24 +0,0 @@
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
import { CreateSelfServiceUserComponent } from './create-self-service-user.component';
describe('CreateSelfServiceUserComponent', () => {
let component: CreateSelfServiceUserComponent;
let fixture: ComponentFixture<CreateSelfServiceUserComponent>;
beforeEach(async(() => {
TestBed.configureTestingModule({
declarations: [CreateSelfServiceUserComponent]
}).compileComponents();
}));
beforeEach(() => {
fixture = TestBed.createComponent(CreateSelfServiceUserComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
it('should create', () => {
expect(component).toBeTruthy();
});
});
@@ -1,109 +0,0 @@
/** Angular Imports. */
import { Component, OnInit } from '@angular/core';
import {
UntypedFormBuilder,
UntypedFormGroup,
UntypedFormControl,
Validators,
AbstractControl,
ValidationErrors,
ValidatorFn
} from '@angular/forms';
import { ActivatedRoute, Router } from '@angular/router';
import { Subscription } from 'rxjs';
/** Client Services. */
import { ClientsService } from 'app/clients/clients.service';
import { PasswordsUtility } from 'app/core/utils/passwords-utility';
@Component({
selector: 'mifosx-create-self-service-user',
templateUrl: './create-self-service-user.component.html',
styleUrls: ['./create-self-service-user.component.scss']
})
export class CreateSelfServiceUserComponent implements OnInit {
createSelfServiceForm: UntypedFormGroup;
clientData: any;
hidePasswordField = true;
constructor(
private formBuilder: UntypedFormBuilder,
private route: ActivatedRoute,
private clientService: ClientsService,
private router: Router,
private passwordsUtility: PasswordsUtility
) {
this.route.data.subscribe((data: { clientActionData: any }) => {
this.clientData = data.clientActionData;
});
}
ngOnInit(): void {
this.createSelfServiceUser();
this.sendPasswordToEmailChange();
}
/**
* Send Password To Email Change.
*/
sendPasswordToEmailChange() {
this.createSelfServiceForm.controls.sendPasswordToEmail.valueChanges.subscribe((value: any) => {
if (value === true) {
this.hidePasswordField = true;
this.createSelfServiceForm.removeControl('password');
this.createSelfServiceForm.removeControl('repeatPassword');
} else {
this.hidePasswordField = false;
this.createSelfServiceForm.addControl(
'password',
new UntypedFormControl('', this.passwordsUtility.getPasswordValidators())
);
this.createSelfServiceForm.addControl(
'repeatPassword',
new UntypedFormControl('', [
Validators.required,
this.passwordsUtility.confirmPassword('password')])
);
}
});
}
/**
* Create Self User Form.
*/
createSelfServiceUser() {
this.createSelfServiceForm = this.formBuilder.group({
username: new UntypedFormControl('', [Validators.required]),
firstname: new UntypedFormControl(this.clientData.firstname, [Validators.required]),
lastname: new UntypedFormControl(this.clientData.lastname, [Validators.required]),
email: new UntypedFormControl('', [
Validators.required,
Validators.email
]),
sendPasswordToEmail: new UntypedFormControl(true),
passwordNeverExpires: new UntypedFormControl(false),
status: new UntypedFormControl({
value: this.clientData.subStatus.active ? 'Active' : 'Inactive',
disabled: true
})
});
}
/**
* Submit form.
*/
submit() {
if (!this.createSelfServiceForm.get('passwordNeverExpires').value) {
this.createSelfServiceForm.removeControl('passwordNeverExpires');
}
const clientId = this.clientData.id.toString();
const selfServiceForm = this.createSelfServiceForm.value;
(selfServiceForm.roles = [2]), (selfServiceForm.isSelfServiceUser = true);
selfServiceForm.staffId = this.clientData.staffId;
selfServiceForm.clients = [clientId];
selfServiceForm.officeId = this.clientData.officeId;
this.clientService.createSelfServiceUser(selfServiceForm).subscribe(() => {
this.router.navigate(['../../general'], { relativeTo: this.route });
});
}
}
@@ -317,9 +317,6 @@
{{ 'labels.buttons.View Standing Instructions' | translate }}
</button>
</span>
<button mat-menu-item (click)="doAction('Create Self Service User')">
{{ 'labels.buttons.Create Self Service User' | translate }}
</button>
</mat-menu>
</mat-card-title-group>
</mat-card-header>
@@ -75,7 +75,6 @@ export class ClientsViewComponent implements OnInit {
case 'Undo Rejection':
case 'Add Charge':
case 'Create Collateral':
case 'Create Self Service User':
case 'Client Screen Reports':
this.router.navigate([`actions/${name}`], { relativeTo: this.route });
break;
-2
View File
@@ -54,7 +54,6 @@ import { ClientPreviewStepComponent } from './client-stepper/client-preview-step
import { ClientAddressStepComponent } from './client-stepper/client-address-step/client-address-step.component';
import { ClientFamilyMemberDialogComponent } from './client-stepper/client-family-members-step/client-family-member-dialog/client-family-member-dialog.component';
import { CaptureImageDialogComponent } from './clients-view/custom-dialogs/capture-image-dialog/capture-image-dialog.component';
import { CreateSelfServiceUserComponent } from './clients-view/client-actions/create-self-service-user/create-self-service-user.component';
import { AddClientCollateralComponent } from './clients-view/client-actions/add-client-collateral/add-client-collateral.component';
import { ClientDatatableStepComponent } from './client-stepper/client-datatable-step/client-datatable-step.component';
@@ -117,7 +116,6 @@ import { ClientDatatableStepComponent } from './client-stepper/client-datatable-
ClientAddressStepComponent,
ClientFamilyMemberDialogComponent,
CaptureImageDialogComponent,
CreateSelfServiceUserComponent,
AddClientCollateralComponent,
ClientDatatableStepComponent
],
@@ -57,8 +57,6 @@ export class ClientActionsResolver implements Resolve<Object> {
case 'Accept Transfer':
case 'Reject Transfer':
return this.clientsService.getClientTransferProposalDate(clientId);
case 'Create Self Service User':
return this.clientsService.getClientData(clientId);
default:
return undefined;
}
@@ -25,6 +25,9 @@ import { OAuth2Token } from './o-auth2-token.model';
*/
@Injectable()
export class AuthenticationService {
changePassword(userId: string, passwordObj: any) {
return this.http.put(`/users/${userId}`, passwordObj);
}
// User logged in boolean
private userLoggedIn: boolean;
@@ -48,10 +48,5 @@ export const frequentActivities: any[] = [
path: '/templates',
icon: 'address-card',
toolTip: 'Templates'
},
{
path: '/self-service',
icon: 'laptop',
toolTip: 'Self Service'
}
];
@@ -147,8 +147,6 @@ export class SidenavComponent implements OnInit, AfterViewInit {
this.pushActivity('/products');
} else if (activity.includes('/templates')) {
this.pushActivity('/templates');
} else if (activity.includes('/self-service')) {
this.pushActivity('/self-service');
}
});
this.mappedActivities.reverse();
@@ -44,17 +44,6 @@
<fa-icon class="mr-05" icon="shield-alt" size="lg"></fa-icon>
{{ 'labels.menus.Admin' | translate }}
</a>
<a
#selfService
mat-tab-link
class="tab-link"
[matMenuTriggerFor]="selfServiceMenu"
#selfServiceMenuTrigger="matMenuTrigger"
>
<fa-icon class="mr-05" icon="users" size="lg"></fa-icon>
{{ 'labels.menus.Self Service' | translate }}
</a>
<a #configWizard mat-tab-link class="tab-link" (click)="openDialog()">
<fa-icon class="mr-05" icon="info" size="lg"></fa-icon>
{{ 'labels.menus.Configuration Wizard' | translate }}
@@ -104,7 +93,6 @@
<button mat-menu-item [routerLink]="['/accounting']">{{ 'labels.menus.Accounting' | translate }}</button>
<button mat-menu-item [matMenuTriggerFor]="reportsMenu">{{ 'labels.menus.Reports' | translate }}</button>
<button mat-menu-item [matMenuTriggerFor]="adminMenu">{{ 'labels.menus.Admin' | translate }}</button>
<button mat-menu-item [matMenuTriggerFor]="selfServiceMenu">{{ 'labels.menus.Self Service' | translate }}</button>
</span>
</mat-menu>
@@ -127,16 +115,6 @@
<button mat-menu-item routerLink="/templates">{{ 'labels.menus.Templates' | translate }}</button>
</mat-menu>
<mat-menu #selfServiceMenu="matMenu" [overlapTrigger]="false">
<button mat-menu-item [routerLink]="['/self-service/users']">{{ 'labels.menus.User Management' | translate }}</button>
<button mat-menu-item [routerLink]="['/self-service/app-configuration']">
{{ 'labels.menus.App Configuration' | translate }}
</button>
<!-- <button mat-menu-item [routerLink]="['/self-service/task-management']">
{{ 'labels.menus.Task Management' | translate }}
</button> -->
</mat-menu>
<!-- Application User Help Menu -->
<mat-menu #applicationMenu="matMenu" [overlapTrigger]="false">
<button mat-menu-item (click)="help()">
@@ -227,8 +205,6 @@
</ng-template>
<ng-template #templateSelfService let-popover="popover">
<h2>{{ 'labels.menus.Self Service' | translate }}</h2>
<p class="mw300">{{ 'labels.text.Dropdown self service user administrative portal' | translate }}</p>
<div fxLayout="row" fxLayoutAlign="end" fxLayoutGap="2%" fxLayout.lt-md="column">
<button mat-raised-button color="warn" (click)="popover.close(); configurationWizardService.closeConfigWizard()">
{{ 'labels.buttons.Close' | translate }}
-6
View File
@@ -7,14 +7,9 @@ const activities: any[] = [
{ activity: 'organization', path: '/organization' },
{ activity: 'system', path: '/system' },
{ activity: 'templates', path: '/templates' },
{ activity: 'self-service users', path: '/self-service/users' },
{ activity: 'self-service app-configuration', path: '/self-service/app-configuration' },
{ activity: 'task management', path: '/self-service/task-management' },
{ activity: 'create group', path: '' },
{ activity: 'create center', path: '/centers/create' },
{ activity: 'configuration', path: '/system/global-configurations' },
{ activity: 'tasks', path: '/self-service/task-management' },
{ activity: 'create template', path: '/self-service/task-management' },
{ activity: 'create loan product', path: '/products/loan-products/create' },
{ activity: 'create saving product', path: '/products/saving-products/create' },
{ activity: 'roles', path: '/system/roles-and-permissions' },
@@ -55,7 +50,6 @@ const activities: any[] = [
{ activity: 'audit', path: '/products/audit-trails' },
{ activity: 'create accounting closure', path: '' },
{ activity: 'navigation', path: '/navigation' },
{ activity: 'system users', path: '/self-service/users' },
{ activity: '', path: 'home' }
];
+1 -3
View File
@@ -7,7 +7,6 @@ import { Router } from '@angular/router';
/** Custom Services */
import { AuthenticationService } from 'app/core/authentication/authentication.service';
import { ChangePasswordDialogComponent } from 'app/shared/change-password-dialog/change-password-dialog.component';
import { UserService } from 'app/self-service/users/user.service';
import { SettingsService } from 'app/settings/settings.service';
/**
@@ -41,7 +40,6 @@ export class ProfileComponent implements OnInit {
constructor(
private authenticationService: AuthenticationService,
private settingsService: SettingsService,
private userService: UserService,
private router: Router,
public dialog: MatDialog
) {
@@ -65,7 +63,7 @@ export class ProfileComponent implements OnInit {
const password = response.password;
const repeatPassword = response.repeatPassword;
const data = { password: password, repeatPassword: repeatPassword };
this.userService.changePassword(this.profileData.userId, data).subscribe(() => {
this.authenticationService.changePassword(this.profileData.userId, data).subscribe(() => {
this.router.navigate(['/home']);
});
}
@@ -1,141 +0,0 @@
<div class="container">
<mat-accordion>
<mat-expansion-panel>
<mat-expansion-panel-header>
<mat-panel-title>
{{ 'labels.inputs.Main Configuration' | translate }}
</mat-panel-title>
</mat-expansion-panel-header>
<div fxLayout="column">
<mat-form-field>
<mat-label>{{ 'labels.inputs.Name of the Organization' | translate }}</mat-label>
<input matInput />
</mat-form-field>
<mat-form-field>
<mat-label>{{ 'labels.inputs.Description' | translate }}</mat-label>
<textarea matInput></textarea>
</mat-form-field>
<mat-form-field>
<mat-label>{{ 'labels.inputs.Summary' | translate }}</mat-label>
<textarea matInput></textarea>
</mat-form-field>
<mat-form-field>
<mat-label>{{ 'labels.inputs.Default Language' | translate }}</mat-label>
<mat-select>
<mat-option *ngFor="let language of languages" [value]="language">
{{ language }}
</mat-option>
</mat-select>
</mat-form-field>
<mat-form-field>
<mat-label>{{ 'labels.inputs.Default Date Format' | translate }}</mat-label>
<mat-select>
<mat-option *ngFor="let dateFormat of dateFormats" [value]="dateFormat">
{{ dateFormat }}
</mat-option>
</mat-select>
</mat-form-field>
</div>
</mat-expansion-panel>
<mat-expansion-panel>
<mat-expansion-panel-header>
<mat-panel-title>
{{ 'labels.inputs.Images' | translate }}
</mat-panel-title>
</mat-expansion-panel-header>
<div fxLayout="column">
<span class="header">{{ 'labels.inputs.Favicon' | translate }}</span>
<mifosx-file-upload></mifosx-file-upload>
<span class="header">{{ 'labels.inputs.Cover Image' | translate }}</span>
<mifosx-file-upload></mifosx-file-upload>
<span class="header">{{ 'labels.inputs.Logo' | translate }}</span>
<mifosx-file-upload></mifosx-file-upload>
<span class="header">{{ 'labels.inputs.Logo with Organization Name' | translate }}</span>
<mifosx-file-upload></mifosx-file-upload>
</div>
</mat-expansion-panel>
<mat-expansion-panel>
<mat-expansion-panel-header>
<mat-panel-title>
{{ 'labels.inputs.Theme and Font' | translate }}
</mat-panel-title>
</mat-expansion-panel-header>
<div fxLayout="column">
<span class="header">{{ 'labels.inputs.Mobile Banking App' | translate }}</span>
<mat-form-field>
<mat-label>{{ 'labels.inputs.Default Theme' | translate }}</mat-label>
<mat-select>
<mat-option *ngFor="let theme of mobileAppThemes" [value]="theme">
{{ theme }}
</mat-option>
</mat-select>
</mat-form-field>
<mat-form-field>
<mat-label>{{ 'labels.inputs.Default Font' | translate }}</mat-label>
<mat-select>
<mat-option *ngFor="let font of mobileAppFonts" [value]="font">
{{ font }}
</mat-option>
</mat-select>
</mat-form-field>
<span class="header">{{ 'labels.inputs.Online Banking App' | translate }}</span>
<mat-form-field>
<mat-label>{{ 'labels.inputs.Default Theme' | translate }}</mat-label>
<mat-select>
<mat-option *ngFor="let theme of onlineBankingAppThemes" [value]="theme">
{{ theme }}
</mat-option>
</mat-select>
</mat-form-field>
<mat-form-field>
<mat-label>{{ 'labels.inputs.Default Font' | translate }}</mat-label>
<mat-select>
<mat-option *ngFor="let font of onlineBankingAppFonts" [value]="font">
{{ font }}
</mat-option>
</mat-select>
</mat-form-field>
</div>
</mat-expansion-panel>
<mat-expansion-panel>
<mat-expansion-panel-header>
<mat-panel-title>
{{ 'labels.inputs.Contact Information' | translate }}
</mat-panel-title>
</mat-expansion-panel-header>
<div fxLayout="column">
<mat-form-field>
<mat-label>{{ 'labels.inputs.Website' | translate }}</mat-label>
<input type="url" matInput />
</mat-form-field>
<mat-form-field>
<mat-label>{{ 'labels.inputs.Email' | translate }}</mat-label>
<input type="email" matInput />
</mat-form-field>
<mat-form-field>
<mat-label>{{ 'labels.inputs.Contact No' | translate }}</mat-label>
<input type="tel" matInput />
</mat-form-field>
</div>
</mat-expansion-panel>
</mat-accordion>
</div>
@@ -1,3 +0,0 @@
.header {
font-weight: 500;
}
@@ -1,24 +0,0 @@
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
import { AppConfigurationComponent } from './app-configuration.component';
describe('AppConfigurationComponent', () => {
let component: AppConfigurationComponent;
let fixture: ComponentFixture<AppConfigurationComponent>;
beforeEach(async(() => {
TestBed.configureTestingModule({
declarations: [AppConfigurationComponent]
}).compileComponents();
}));
beforeEach(() => {
fixture = TestBed.createComponent(AppConfigurationComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
it('should create', () => {
expect(component).toBeTruthy();
});
});
@@ -1,29 +0,0 @@
/** Angular Imports */
import { Component } from '@angular/core';
/**
* Self service app configuration component.
*
* TODO: Complete functionality once API is available.
*/
@Component({
selector: 'mifosx-app-configuration',
templateUrl: './app-configuration.component.html',
styleUrls: ['./app-configuration.component.scss']
})
export class AppConfigurationComponent {
/** Placeholder for languages. */
languages: any;
/** Placeholder for date formats. */
dateFormats: any;
/** Placeholder for mobile app themes. */
mobileAppThemes: any;
/** Placeholder for mobile app fonts. */
mobileAppFonts: any;
/** Placeholder for online banking app themes. */
onlineBankingAppThemes: any;
/** Placeholder for online banking app fonts. */
onlineBankingAppFonts: any;
constructor() {}
}
@@ -1,100 +0,0 @@
/** Angular Imports */
import { NgModule } from '@angular/core';
import { Routes, RouterModule } from '@angular/router';
/** Routing Imports */
import { Route } from '../core/route/route.service';
/** Custom Components */
import { SelfServiceComponent } from './self-service.component';
import { UsersComponent } from './users/users.component';
import { CreateUserComponent } from './users/create-user/create-user.component';
import { ViewUserComponent } from './users/view-user/view-user.component';
import { EditUserComponent } from './users/edit-user/edit-user.component';
import { AppConfigurationComponent } from './app-configuration/app-configuration.component';
import { TaskManagementComponent } from './task-management/task-management.component';
/** Custom Resolvers */
import { ViewUserResolver } from './users/view-user/view-user.resolver';
import { OfficesResolver } from 'app/organization/offices/common-resolvers/offices.resolver';
import { UsersResolver } from 'app/users/users.resolver';
/** Self Service Admin Portal Routes */
const routes: Routes = [
Route.withShell([
{
path: 'self-service',
component: SelfServiceComponent,
data: { title: 'Self Service', breadcrumb: 'Self Service', addBreadcrumbLink: false },
children: [
{
path: 'users',
data: { title: 'Self Service Users', breadcrumb: 'Users' },
children: [
{
path: '',
component: UsersComponent,
resolve: {
users: UsersResolver
}
},
{
path: 'create',
component: CreateUserComponent,
data: { title: 'Create Self Service User', breadcrumb: 'Create' },
resolve: {
offices: OfficesResolver
}
},
{
path: 'view/:id',
data: { title: 'View Self Service User', routeResolveBreadcrumb: [
'user',
'username'
] },
resolve: {
user: ViewUserResolver
},
children: [
{
path: '',
component: ViewUserComponent
},
{
path: 'edit',
component: EditUserComponent,
data: { title: 'Edit Self Service User', breadcrumb: 'Edit', routeResolveBreadcrumb: false }
}
]
}
]
},
{
path: 'app-configuration',
component: AppConfigurationComponent,
data: { title: 'Self Service App Configuration', breadcrumb: 'App Configuration' }
},
{
path: 'task-management',
component: TaskManagementComponent,
data: { title: 'Self Service Task Management', breadcrumb: 'Task Management' }
}
]
}
])
];
/**
* Self Service Routing Module
*
* Configures the self service admin portal routes.
*/
@NgModule({
imports: [RouterModule.forChild(routes)],
exports: [RouterModule],
providers: [
ViewUserResolver
]
})
export class SelfServiceRoutingModule {}
@@ -1 +0,0 @@
<router-outlet></router-outlet>
@@ -1,24 +0,0 @@
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
import { SelfServiceComponent } from './self-service.component';
describe('SelfServiceComponent', () => {
let component: SelfServiceComponent;
let fixture: ComponentFixture<SelfServiceComponent>;
beforeEach(async(() => {
TestBed.configureTestingModule({
declarations: [SelfServiceComponent]
}).compileComponents();
}));
beforeEach(() => {
fixture = TestBed.createComponent(SelfServiceComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
it('should create', () => {
expect(component).toBeTruthy();
});
});
@@ -1,16 +0,0 @@
/** Angular Imports */
import { Component } from '@angular/core';
/**
* Self service component.
*
* All components related to self service admin portal are routed here.
*/
@Component({
selector: 'mifosx-self-service',
templateUrl: './self-service.component.html',
styleUrls: ['./self-service.component.scss']
})
export class SelfServiceComponent {
constructor() {}
}
@@ -1,13 +0,0 @@
import { SelfServiceModule } from './self-service.module';
describe('SelfServiceModule', () => {
let selfServiceModule: SelfServiceModule;
beforeEach(() => {
selfServiceModule = new SelfServiceModule();
});
it('should create an instance', () => {
expect(selfServiceModule).toBeTruthy();
});
});
@@ -1,37 +0,0 @@
/** Angular Imports */
import { NgModule } from '@angular/core';
/** Custom Modules */
import { SharedModule } from '../shared/shared.module';
import { SelfServiceRoutingModule } from './self-service-routing.module';
/** Custom Components */
import { SelfServiceComponent } from './self-service.component';
import { UsersComponent } from './users/users.component';
import { CreateUserComponent } from './users/create-user/create-user.component';
import { ViewUserComponent } from './users/view-user/view-user.component';
import { EditUserComponent } from './users/edit-user/edit-user.component';
import { AppConfigurationComponent } from './app-configuration/app-configuration.component';
import { TaskManagementComponent } from './task-management/task-management.component';
/**
* Self Service Module
*
* All components related to self service admin portal functions should be declared here.
*/
@NgModule({
imports: [
SharedModule,
SelfServiceRoutingModule
],
declarations: [
SelfServiceComponent,
UsersComponent,
CreateUserComponent,
ViewUserComponent,
EditUserComponent,
AppConfigurationComponent,
TaskManagementComponent
]
})
export class SelfServiceModule {}
@@ -1,3 +0,0 @@
<div class="container">
<p>{{ 'labels.inputs.TODO' | translate }}: {{ 'labels.inputs.task-management component' | translate }}.</p>
</div>
@@ -1,24 +0,0 @@
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
import { TaskManagementComponent } from './task-management.component';
describe('TaskManagementComponent', () => {
let component: TaskManagementComponent;
let fixture: ComponentFixture<TaskManagementComponent>;
beforeEach(async(() => {
TestBed.configureTestingModule({
declarations: [TaskManagementComponent]
}).compileComponents();
}));
beforeEach(() => {
fixture = TestBed.createComponent(TaskManagementComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
it('should create', () => {
expect(component).toBeTruthy();
});
});
@@ -1,22 +0,0 @@
import { Component, OnInit } from '@angular/core';
@Component({
selector: 'mifosx-task-management',
templateUrl: './task-management.component.html',
styleUrls: ['./task-management.component.scss']
})
export class TaskManagementComponent implements OnInit {
tasks: Array<any>;
constructor() {
this.tasks = [];
}
ngOnInit(): void {
this.loadTasks();
}
loadTasks(): void {
// logic to load tasks
}
}
@@ -1,140 +0,0 @@
<div class="container" [class.small-width-container]="userType.value === 'Existing User'">
<mat-card>
<mat-card-header class="m-b-20">
<mat-radio-group fxLayout="row" fxLayoutGap="20px" [formControl]="userType">
<mat-radio-button *ngFor="let type of userTypes" [value]="type">
{{ type }}
</mat-radio-button>
</mat-radio-group>
</mat-card-header>
<div *ngIf="userType.value === 'Existing User'">
<form [formGroup]="createUserForm">
<mat-card-content>
<div fxLayout="column">
<mat-form-field>
<mat-label>{{ 'labels.inputs.Office' | translate }}</mat-label>
<mat-select required formControlName="officeId">
<mat-option *ngFor="let office of offices" [value]="office.id">
{{ office.name }}
</mat-option>
</mat-select>
<mat-error *ngIf="createUserForm.controls.officeId.hasError('required')">
{{ 'labels.inputs.Office' | translate }} {{ 'labels.commons.is' | translate }}
<strong>{{ 'labels.commons.required' | translate }}</strong>
</mat-error>
</mat-form-field>
<mat-form-field>
<mat-label>{{ 'labels.inputs.Staff' | translate }}</mat-label>
<mat-select formControlName="staffId">
<mat-option *ngFor="let staff of staffOptions" [value]="staff.id">
{{ staff.displayName }}
</mat-option>
</mat-select>
</mat-form-field>
<mat-form-field>
<mat-label>{{ 'labels.inputs.Client' | translate }}</mat-label>
<mat-select>
<mat-option *ngFor="let client of clientData" [value]="client">
{{ client }}
</mat-option>
</mat-select>
</mat-form-field>
</div>
</mat-card-content>
<mat-card-actions fxLayout="row" fxLayout.xs="column" fxLayoutAlign="center" fxLayoutGap="5px">
<button type="button" mat-raised-button [routerLink]="['../']">
{{ 'labels.buttons.Cancel' | translate }}
</button>
<button mat-raised-button color="accent">
<fa-icon icon="lock-open" class="m-r-10"></fa-icon>
{{ 'labels.buttons.Activate Self Service User' | translate }}
</button>
</mat-card-actions>
</form>
</div>
<div *ngIf="userType.value === 'New User'">
<form [formGroup]="createUserForm">
<mat-card-content>
<div fxLayout="row wrap" fxLayoutGap="2%" fxLayout.lt-md="column">
<mat-form-field>
<mat-label>{{ 'labels.inputs.Office' | translate }}</mat-label>
<mat-select required formControlName="officeId">
<mat-option *ngFor="let office of offices" [value]="office.id">
{{ office.name }}
</mat-option>
</mat-select>
<mat-error *ngIf="createUserForm.controls.officeId.hasError('required')">
{{ 'labels.inputs.Office' | translate }} {{ 'labels.commons.is' | translate }}
<strong>{{ 'labels.commons.required' | translate }}</strong>
</mat-error>
</mat-form-field>
<mat-form-field fxFlex="48%">
<mat-label>{{ 'labels.inputs.Staff' | translate }}</mat-label>
<mat-select formControlName="staffId">
<mat-option *ngFor="let staff of staffOptions" [value]="staff.id">
{{ staff.displayName }}
</mat-option>
</mat-select>
</mat-form-field>
<mat-form-field fxFlex="48%">
<mat-label>{{ 'labels.inputs.User Name' | translate }}</mat-label>
<input type="text" matInput />
</mat-form-field>
<span fxFlex="48%" fxHide.lt-md></span>
<mat-form-field fxFlex="48%">
<mat-label>{{ 'labels.inputs.First Name' | translate }}</mat-label>
<input type="text" matInput />
</mat-form-field>
<mat-form-field fxFlex="48%">
<mat-label>{{ 'labels.inputs.Last Name' | translate }}</mat-label>
<input type="text" matInput />
</mat-form-field>
<mat-form-field fxFlex="48%">
<mat-label>{{ 'labels.inputs.Gender' | translate }}</mat-label>
<mat-select>
<mat-option *ngFor="let gender of genderData" [value]="gender">
{{ gender }}
</mat-option>
</mat-select>
</mat-form-field>
<mat-form-field fxFlex="48%" (click)="dateOfBirthDatePicker.open()">
<mat-label>{{ 'labels.inputs.Date of Birth' | translate }}</mat-label>
<input matInput [min]="minDate" [max]="maxDate" [matDatepicker]="dateOfBirthDatePicker" />
<mat-datepicker-toggle matSuffix [for]="dateOfBirthDatePicker"></mat-datepicker-toggle>
<mat-datepicker #dateOfBirthDatePicker></mat-datepicker>
</mat-form-field>
<mat-form-field fxFlex="48%">
<mat-label>{{ 'labels.inputs.Email' | translate }}</mat-label>
<input type="email" matInput />
</mat-form-field>
<mat-form-field fxFlex="48%">
<mat-label>{{ 'labels.inputs.Mobile No' | translate }}</mat-label>
<input type="tel" matInput />
</mat-form-field>
</div>
</mat-card-content>
<mat-card-actions fxLayout="row" fxLayout.xs="column" fxLayoutAlign="center" fxLayoutGap="5px">
<button type="button" mat-raised-button [routerLink]="['../']">
{{ 'labels.buttons.Cancel' | translate }}
</button>
<button mat-raised-button color="primary">{{ 'labels.buttons.Submit' | translate }}</button>
</mat-card-actions>
</form>
</div>
</mat-card>
</div>
@@ -1,3 +0,0 @@
.small-width-container {
max-width: 37rem;
}
@@ -1,24 +0,0 @@
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
import { CreateUserComponent } from './create-user.component';
describe('CreateUserComponent', () => {
let component: CreateUserComponent;
let fixture: ComponentFixture<CreateUserComponent>;
beforeEach(async(() => {
TestBed.configureTestingModule({
declarations: [CreateUserComponent]
}).compileComponents();
}));
beforeEach(() => {
fixture = TestBed.createComponent(CreateUserComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
it('should create', () => {
expect(component).toBeTruthy();
});
});
@@ -1,95 +0,0 @@
/** Angular Imports */
import { Component, OnInit } from '@angular/core';
import { UntypedFormBuilder, UntypedFormControl, UntypedFormGroup, Validators } from '@angular/forms';
import { ActivatedRoute, Router } from '@angular/router';
import { ClientsService } from 'app/clients/clients.service';
import { SettingsService } from 'app/settings/settings.service';
/**
* Create self service user component.
*
* TODO: Complete functionality once API is available.
*/
@Component({
selector: 'mifosx-create-user',
templateUrl: './create-user.component.html',
styleUrls: ['./create-user.component.scss']
})
export class CreateUserComponent implements OnInit {
/** Create Client Form */
createUserForm: UntypedFormGroup;
/** Denotes type of user. */
userTypes = [
'Existing User',
'New User'
];
/** Radio button group form control for type of user. */
userType = new UntypedFormControl(this.userTypes[0]);
/** Placeholder for office data. */
offices: any[] = [];
/** Placeholder for staff data. */
staffOptions: any[] = [];
/** Placeholder for staff data. */
genderOptions: any[] = [];
/** Placeholder for client data. */
clientData: any[] = [];
/** Placeholder for gender data. */
genderData = [
'Male',
'Female'
];
/** Minimum date of birth of user allowed. */
minDate = new Date(1900, 0, 1);
/** Maximum date of birth of user allowed. */
maxDate = new Date();
/**
* @param {SettingsService} settingsService Settings Service
*/
constructor(
private formBuilder: UntypedFormBuilder,
private route: ActivatedRoute,
private clientService: ClientsService,
private settingsService: SettingsService
) {
this.route.data.subscribe((data: { offices: any }) => {
this.offices = data.offices;
});
}
ngOnInit() {
this.minDate = this.settingsService.minAllowedDate;
this.maxDate = this.settingsService.businessDate;
this.setClientForm();
this.buildDependencies();
}
/**
* Creates the client form.
*/
setClientForm() {
this.createUserForm = this.formBuilder.group({
officeId: [
'',
Validators.required
],
staffId: [
'',
Validators.required
]
});
}
/**
* Adds controls conditionally.
*/
buildDependencies() {
this.createUserForm.get('officeId').valueChanges.subscribe((officeId: number) => {
this.clientService.getClientWithOfficeTemplate(officeId).subscribe((clientTemplate: any) => {
this.staffOptions = clientTemplate.staffOptions;
this.genderOptions = clientTemplate.genderOptions;
});
});
}
}
@@ -1,77 +0,0 @@
<div class="container">
<mat-card>
<form>
<mat-card-content>
<div fxLayout="row wrap" fxLayoutGap="2%" fxLayout.lt-md="column">
<mat-form-field fxFlex="48%">
<mat-label>{{ 'labels.inputs.Office' | translate }}</mat-label>
<mat-select>
<mat-option *ngFor="let office of officeData" [value]="office">
{{ office }}
</mat-option>
</mat-select>
</mat-form-field>
<mat-form-field fxFlex="48%">
<mat-label>{{ 'labels.inputs.Staff' | translate }}</mat-label>
<mat-select>
<mat-option *ngFor="let staff of staffData" [value]="staff">
{{ staff }}
</mat-option>
</mat-select>
</mat-form-field>
<mat-form-field fxFlex="48%">
<mat-label>{{ 'labels.inputs.User Name' | translate }}</mat-label>
<input type="text" matInput />
</mat-form-field>
<span fxFlex="48%" fxHide.lt-md></span>
<mat-form-field fxFlex="48%">
<mat-label>{{ 'labels.inputs.First Name' | translate }}</mat-label>
<input type="text" matInput />
</mat-form-field>
<mat-form-field fxFlex="48%">
<mat-label>{{ 'labels.inputs.Last Name' | translate }}</mat-label>
<input type="text" matInput />
</mat-form-field>
<mat-form-field fxFlex="48%">
<mat-label>{{ 'labels.inputs.Gender' | translate }}</mat-label>
<mat-select>
<mat-option *ngFor="let gender of genderData" [value]="gender">
{{ gender }}
</mat-option>
</mat-select>
</mat-form-field>
<mat-form-field fxFlex="48%" (click)="dateOfBirthDatePicker.open()">
<mat-label>{{ 'labels.inputs.Date of Birth' | translate }}</mat-label>
<input matInput [min]="minDate" [max]="maxDate" [matDatepicker]="dateOfBirthDatePicker" />
<mat-datepicker-toggle matSuffix [for]="dateOfBirthDatePicker"></mat-datepicker-toggle>
<mat-datepicker #dateOfBirthDatePicker></mat-datepicker>
</mat-form-field>
<mat-form-field fxFlex="48%">
<mat-label>{{ 'labels.inputs.Email' | translate }}</mat-label>
<input type="email" matInput />
</mat-form-field>
<mat-form-field fxFlex="48%">
<mat-label>{{ 'labels.inputs.Mobile No' | translate }}</mat-label>
<input type="tel" matInput />
</mat-form-field>
</div>
</mat-card-content>
<mat-card-actions fxLayout="row" fxLayout.xs="column" fxLayoutAlign="center" fxLayoutGap="5px">
<button type="button" mat-raised-button [routerLink]="['../']">
{{ 'labels.buttons.Cancel' | translate }}
</button>
<button mat-raised-button color="primary">{{ 'labels.buttons.Submit' | translate }}</button>
</mat-card-actions>
</form>
</mat-card>
</div>
@@ -1,24 +0,0 @@
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
import { EditUserComponent } from './edit-user.component';
describe('EditUserComponent', () => {
let component: EditUserComponent;
let fixture: ComponentFixture<EditUserComponent>;
beforeEach(async(() => {
TestBed.configureTestingModule({
declarations: [EditUserComponent]
}).compileComponents();
}));
beforeEach(() => {
fixture = TestBed.createComponent(EditUserComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
it('should create', () => {
expect(component).toBeTruthy();
});
});
@@ -1,35 +0,0 @@
/** Angular Imports */
import { Component, OnInit } from '@angular/core';
import { SettingsService } from 'app/settings/settings.service';
/**
* Edit self service user component.
*
* TODO: Complete functionality once API is available.
*/
@Component({
selector: 'mifosx-edit-user',
templateUrl: './edit-user.component.html',
styleUrls: ['./edit-user.component.scss']
})
export class EditUserComponent implements OnInit {
/** Placeholder for office data. */
officeData: any;
/** Placeholder for staff data. */
staffData: any;
/** Placeholder for gender data. */
genderData: any;
/** Minimum date of birth of user allowed. */
minDate = new Date(1900, 0, 1);
/** Maximum date of birth of user allowed. */
maxDate = new Date();
/**
* @param {SettingsService} settingsService Settings Service
*/
constructor(private settingsService: SettingsService) {}
ngOnInit() {
this.maxDate = this.settingsService.businessDate;
}
}
-9
View File
@@ -1,9 +0,0 @@
/** Self Service User model. */
export interface User {
id: number;
name: string;
email: string;
isSelfServiceUser: boolean;
officeName: string;
staff: string;
}
@@ -1,15 +0,0 @@
import { TestBed, inject } from '@angular/core/testing';
import { UserService } from './user.service';
describe('UserService', () => {
beforeEach(() => {
TestBed.configureTestingModule({
providers: [UserService]
});
});
it('should be created', inject([UserService], (service: UserService) => {
expect(service).toBeTruthy();
}));
});
@@ -1,57 +0,0 @@
/** Angular Routes */
import { Injectable } from '@angular/core';
import { HttpClient, HttpParams } from '@angular/common/http';
/** rxjs Imports */
import { Observable } from 'rxjs';
import { map } from 'rxjs/operators';
/** Custom Models */
import { User } from './user.model';
/**
* Self service users service.
*
* TODO: Complete functionality once API is available.
*/
@Injectable({
providedIn: 'root'
})
export class UserService {
/**
* @param {HttpClient} http Http Client to send requests.
*/
constructor(private http: HttpClient) {}
/**
* Gets all the self service users.
*
* TODO: To be replaced once API is available.
*/
getUsers(): Observable<User[]> {
const httpParams = new HttpParams().set('fields', 'id,firstname,lastname,email,officeName,staff');
return this.http.get('/users', { params: httpParams }).pipe(
map((users: any) => {
users.forEach((user: any) => {
user.name = `${user.firstname} ${user.lastname}`;
user.staff = user.staff ? `${user.staff.firstname} ${user.staff.lastname}` : '';
delete user.firstname;
delete user.lastname;
});
return users as User[];
})
);
}
/**
* Change User Password.
* @param userId User Id of users
* @param password New Password of the user
* @returns {Observable<any>}
*
* TODO: update endpoint once API available
*/
changePassword(userId: string, passwordObj: any) {
return this.http.put(`/users/${userId}`, passwordObj);
}
}
@@ -1,94 +0,0 @@
<div class="container m-b-20" fxLayout="row" fxLayout.lt-md="column" fxLayoutAlign="end" fxLayoutGap="20px">
<!-- TODO: Update to show only Activate/Inactivate button at a time according to selection in table. -->
<button mat-raised-button color="accent">
<fa-icon icon="lock-open" class="m-r-10"></fa-icon>
{{ 'labels.buttons.Activate' | translate }}
</button>
<button mat-raised-button color="warn">
<fa-icon icon="lock" class="m-r-10"></fa-icon>
{{ 'labels.buttons.Deactivate' | translate }}
</button>
<button mat-raised-button color="primary" [routerLink]="['create']">
<fa-icon icon="plus" class="m-r-10"></fa-icon>
{{ 'labels.buttons.Create User' | translate }}
</button>
</div>
<div class="container">
<div fxLayout="row">
<mat-form-field fxFlex>
<mat-label>{{ 'labels.inputs.Filter' | translate }}</mat-label>
<input matInput type="text" (keyup)="applyFilter($event.target.value)" />
</mat-form-field>
</div>
<div class="mat-elevation-z8">
<table mat-table [dataSource]="dataSource" matSort>
<ng-container matColumnDef="select">
<th mat-header-cell *matHeaderCellDef>
<mat-checkbox
(change)="$event ? masterToggle() : null"
[checked]="selection.hasValue() && isAllSelected()"
[indeterminate]="selection.hasValue() && !isAllSelected()"
>
</mat-checkbox>
</th>
<td mat-cell *matCellDef="let row">
<mat-checkbox
(click)="$event.stopPropagation()"
(change)="$event ? selection.toggle(row) : null"
[checked]="selection.isSelected(row)"
>
</mat-checkbox>
</td>
</ng-container>
<ng-container matColumnDef="name">
<th mat-header-cell *matHeaderCellDef mat-sort-header>{{ 'labels.inputs.name' | translate }}</th>
<td mat-cell *matCellDef="let user">{{ user.name }}</td>
</ng-container>
<ng-container matColumnDef="id">
<th mat-header-cell *matHeaderCellDef mat-sort-header>{{ 'labels.inputs.User ID' | translate }}</th>
<td mat-cell *matCellDef="let user">{{ user.id }}</td>
</ng-container>
<ng-container matColumnDef="email">
<th mat-header-cell *matHeaderCellDef mat-sort-header>{{ 'labels.inputs.Email ID' | translate }}</th>
<td mat-cell *matCellDef="let user">{{ user.email }}</td>
</ng-container>
<ng-container matColumnDef="status">
<th mat-header-cell *matHeaderCellDef mat-sort-header="isSelfServiceUser">
{{ 'labels.inputs.Status' | translate }}
</th>
<td mat-cell *matCellDef="let user">
<div [className]="user.isSelfServiceUser === true ? 'active' : 'inactive'">
<fa-icon
matTooltip="{{ user.isSelfServiceUser === true ? 'Active' : 'Inactive' }}"
matTooltipPosition="right"
icon="circle"
size="lg"
></fa-icon>
</div>
</td>
</ng-container>
<ng-container matColumnDef="officeName">
<th mat-header-cell *matHeaderCellDef mat-sort-header>{{ 'labels.inputs.Office' | translate }}</th>
<td mat-cell *matCellDef="let user">{{ user.officeName }}</td>
</ng-container>
<ng-container matColumnDef="staff">
<th mat-header-cell *matHeaderCellDef mat-sort-header>{{ 'labels.inputs.Staff' | translate }}</th>
<td mat-cell *matCellDef="let user">{{ user.staff }}</td>
</ng-container>
<tr mat-header-row *matHeaderRowDef="displayedColumns"></tr>
<tr mat-row *matRowDef="let row; columns: displayedColumns" [routerLink]="['view', row.id]"></tr>
<!-- TODO: Update route once API is setup. -->
</table>
<mat-paginator [pageSizeOptions]="[10, 25, 50, 100]" showFirstLastButtons></mat-paginator>
</div>
</div>
@@ -1,12 +0,0 @@
table {
width: 100%;
}
// TODO: CONFIGURE THESE CLASSES GLOBALLY
.inactive {
color: #d3d3d3;
}
.active {
color: #32cd32;
}
@@ -1,24 +0,0 @@
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
import { UsersComponent } from './users.component';
describe('UsersComponent', () => {
let component: UsersComponent;
let fixture: ComponentFixture<UsersComponent>;
beforeEach(async(() => {
TestBed.configureTestingModule({
declarations: [UsersComponent]
}).compileComponents();
}));
beforeEach(() => {
fixture = TestBed.createComponent(UsersComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
it('should create', () => {
expect(component).toBeTruthy();
});
});
@@ -1,98 +0,0 @@
/** Angular Imports */
import { Component, OnInit, ViewChild } from '@angular/core';
import { ActivatedRoute } from '@angular/router';
import { SelectionModel } from '@angular/cdk/collections';
import { MatPaginator } from '@angular/material/paginator';
import { MatSort } from '@angular/material/sort';
import { MatTableDataSource } from '@angular/material/table';
/** Custom Services */
import { UserService } from './user.service';
/** Custom Model */
import { User } from './user.model';
/**
* Self service users component.
*
* TODO: Complete functionality once API is available.
*/
@Component({
selector: 'mifosx-users',
templateUrl: './users.component.html',
styleUrls: ['./users.component.scss']
})
export class UsersComponent implements OnInit {
/** Self service users. */
userData: User[];
/** Columns to be displayed in users table. */
displayedColumns: string[] = [
'select',
'name',
'id',
'email',
'status',
'officeName',
'staff'
];
/** Data source for users table. */
dataSource: MatTableDataSource<User>;
/** Selection model for users table. */
selection = new SelectionModel<User>(true, []);
/** Paginator for users table. */
@ViewChild(MatPaginator, { static: true }) paginator: MatPaginator;
/** Sorter for users table. */
@ViewChild(MatSort, { static: true }) sort: MatSort;
/**
* Retrieves the users data from `resolve`.
* @param {ActivatedRoute} route Activated Route.
*/
constructor(private route: ActivatedRoute) {
this.route.data.subscribe((data: { users: User[] }) => {
this.userData = [];
data.users.forEach((user: any) => {
if (user.isSelfServiceUser) {
this.userData.push(user);
}
});
});
}
/**
* Initializes the data source, paginator and sorter for users table.
*/
ngOnInit() {
this.dataSource = new MatTableDataSource(this.userData);
this.dataSource.paginator = this.paginator;
this.dataSource.sort = this.sort;
}
/**
* Filters data in users table based on passed value.
* @param {string} filterValue Value to filter data.
*/
applyFilter(filterValue: string) {
this.dataSource.filter = filterValue.trim().toLowerCase();
}
/**
* Checks if all rows of users table are selected.
* @returns {boolean} True if all rows are selected.
*/
isAllSelected(): boolean {
const numSelected = this.selection.selected.length;
const numRows = this.dataSource.data.length;
return numSelected === numRows;
}
/**
* Toggles selection for all rows of users table.
*/
masterToggle() {
this.isAllSelected()
? this.selection.clear()
: this.dataSource.data.forEach((row: User) => this.selection.select(row));
}
}
@@ -1,119 +0,0 @@
<div class="container m-b-20" fxLayout="row" fxLayout.lt-md="column" fxLayoutAlign="end" fxLayoutGap="2%">
<!-- TODO: Update to show only Activate/Inactivate button at a time according to status of user. -->
<button mat-raised-button color="primary" [routerLink]="['edit']">
<fa-icon icon="edit" class="m-r-10"></fa-icon>
{{ 'labels.buttons.Edit' | translate }}
</button>
<button mat-raised-button color="primary" (click)="changeUserPassword()">
<fa-icon icon="cog" class="m-r-10"></fa-icon>
{{ 'labels.buttons.Change Password' | translate }}
</button>
<button mat-raised-button color="accent">
<fa-icon icon="lock-open" class="m-r-10"></fa-icon>
{{ 'labels.buttons.Activate' | translate }}
</button>
<button mat-raised-button color="warn">
<fa-icon icon="lock" class="m-r-10"></fa-icon>
{{ 'labels.buttons.Deactivate' | translate }}
</button>
</div>
<div class="container">
<mat-card>
<mat-card-content>
<div fxLayout="row wrap" class="content">
<div fxFlex="100%" class="header">
<fa-icon icon="circle" size="lg" matTooltip="{{ user.status }}" matTooltipPosition="above"></fa-icon>
&nbsp;&nbsp;
{{ 'labels.inputs.ID' | translate }}: {{ user.id }}
</div>
<div fxFlex="50%" class="header">
{{ 'labels.inputs.User Name' | translate }}
</div>
<div fxFlex="50%">
{{ user.username }}
</div>
<div fxFlex="50%" class="header">
{{ 'labels.inputs.First Name' | translate }}
</div>
<div fxFlex="50%">
{{ user.firstName }}
</div>
<div fxFlex="50%" class="header">
{{ 'labels.inputs.Last Name' | translate }}
</div>
<div fxFlex="50%">
{{ user.lastName }}
</div>
<div fxFlex="50%" class="header">
{{ 'labels.inputs.Gender' | translate }}
</div>
<div fxFlex="50%">
{{ user.gender }}
</div>
<div fxFlex="50%" class="header">
{{ 'labels.inputs.Date of Birth' | translate }}
</div>
<div fxFlex="50%">
{{ user.dateOfBirth }}
</div>
<div fxFlex="50%" class="header">
{{ 'labels.inputs.Email' | translate }}
</div>
<div fxFlex="50%">
{{ user.email }}
</div>
<div fxFlex="50%" class="header">
{{ 'labels.inputs.Mobile' | translate }}
</div>
<div fxFlex="50%">
{{ user.mobile }}
</div>
<div fxFlex="50%" class="header">
{{ 'labels.inputs.Office' | translate }}
</div>
<div fxFlex="50%">
{{ user.office }}
</div>
<div fxFlex="50%" class="header">
{{ 'labels.inputs.Staff' | translate }}
</div>
<div fxFlex="50%">
{{ user.staff }}
</div>
<div fxFlex="50%" class="header">
{{ 'labels.inputs.Activation Date' | translate }}
</div>
<div fxFlex="50%">
{{ user.activationDate }}
</div>
</div>
</mat-card-content>
<mat-card-actions fxLayout="row" fxLayout.xs="column" fxLayoutAlign="center" fxLayoutGap="5px">
<button type="button" color="primary" mat-raised-button [routerLink]="['../../']">
{{ 'labels.buttons.Back' | translate }}
</button>
</mat-card-actions>
</mat-card>
</div>
@@ -1,14 +0,0 @@
.container {
max-width: 37rem;
.content {
div {
margin: 1rem 0;
word-wrap: break-word;
&.header {
font-weight: 500;
}
}
}
}
@@ -1,24 +0,0 @@
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
import { ViewUserComponent } from './view-user.component';
describe('ViewUserComponent', () => {
let component: ViewUserComponent;
let fixture: ComponentFixture<ViewUserComponent>;
beforeEach(async(() => {
TestBed.configureTestingModule({
declarations: [ViewUserComponent]
}).compileComponents();
}));
beforeEach(() => {
fixture = TestBed.createComponent(ViewUserComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
it('should create', () => {
expect(component).toBeTruthy();
});
});
@@ -1,62 +0,0 @@
/** Angular Imports */
import { Component } from '@angular/core';
import { ActivatedRoute, Router } from '@angular/router';
import { ChangePasswordDialogComponent } from 'app/shared/change-password-dialog/change-password-dialog.component';
import { MatDialog } from '@angular/material/dialog';
/** Custom Services. */
import { UserService } from '../user.service';
/**
* View self service user component.
*
* TODO: Complete functionality once API is available.
*/
@Component({
selector: 'mifosx-view-user',
templateUrl: './view-user.component.html',
styleUrls: ['./view-user.component.scss']
})
export class ViewUserComponent {
/** Self service user. */
user: any;
/**
* Retrieves the user data from `resolve`.
* @param {ActivatedRoute} route Activated Route.
* @param {UserService} userService Users Service.
* @param {ActivatedRoute} route Activated Route.
* @param {Router} router Router for navigation.
* @param {MatDialog} dialog Dialog reference.
*/
constructor(
private route: ActivatedRoute,
private userService: UserService,
private router: Router,
private dialog: MatDialog
) {
this.route.data.subscribe((data: { user: any }) => {
this.user = data.user;
});
}
/**
* Open Dialog to Change Password
*/
changeUserPassword() {
const changeUserPasswordDialogRef = this.dialog.open(ChangePasswordDialogComponent, {
width: '400px',
height: '300px'
});
changeUserPasswordDialogRef.afterClosed().subscribe((response: any) => {
if (response.password && response.repeatPassword) {
const password = response.password;
const repeatPassword = response.repeatPassword;
const data = { password: password, repeatPassword: repeatPassword };
this.userService.changePassword(this.user.id, data).subscribe(() => {
this.router.navigate(['/..']);
});
}
});
}
}
@@ -1,31 +0,0 @@
/** Angular Imports */
import { Injectable } from '@angular/core';
import { Resolve } from '@angular/router';
/** rxjs Imports */
import { Observable } from 'rxjs';
/** Custom Services */
/** Custom Model */
import { User } from '../user.model';
import { UsersService } from 'app/users/users.service';
/**
* View self service user data resolver.
*/
@Injectable()
export class ViewUserResolver implements Resolve<Object> {
/**
* @param {UserService} userService Self service user service.
*/
constructor(private userService: UsersService) {}
/**
* Returns the user data.
* @returns {Observable<User>}
*/
resolve(): Observable<User> {
return this.userService.getUser('1');
}
}