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
-1
View File
@@ -8,7 +8,6 @@ check that page contains button "Institution"
check that page contains button "Accounting"
check that page contains button "Reports"
check that page contains button "Admin"
check that page contains button "Self Service"
check that page contains button "Configuration Wizard"
logout
validate-login-page
-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');
}
}