feat: user profile page (#1209)

Fixes: #1208
This commit is contained in:
Karan Takalkar
2020-08-16 16:27:01 +05:30
committed by GitHub
parent 537d8482c7
commit a2066e721a
10 changed files with 273 additions and 1 deletions
+2
View File
@@ -36,6 +36,7 @@ import { UsersModule } from './users/users.module';
import { ReportsModule } from './reports/reports.module';
import { NotificationsModule } from './notifications/notifications.module';
import { CollectionsModule } from './collections/collections.module';
import { ProfileModule } from './profile/profile.module';
/** Main Routing Module */
import { AppRoutingModule } from './app-routing.module';
@@ -55,6 +56,7 @@ import { AppRoutingModule } from './app-routing.module';
CoreModule,
HomeModule,
LoginModule,
ProfileModule,
SettingsModule,
NavigationModule,
ClientsModule,
@@ -43,6 +43,9 @@ export class SidenavComponent implements OnInit {
.subscribe(() => this.router.navigate(['/login'], { replaceUrl: true }));
}
/**
* Opens Mifos JIRA Wiki page.
*/
help() {
window.open('https://mifosforge.jira.com/wiki/spaces/docs/pages/52035622/User+Manual', '_blank');
}
@@ -98,6 +98,18 @@
<!-- Application User Help Menu -->
<mat-menu #applicationMenu="matMenu" [overlapTrigger]="false">
<button mat-menu-item (click)="help()">
<mat-icon matListIcon>
<fa-icon icon="question-circle" size="sm"></fa-icon>
</mat-icon>
<span>Help</span>
</button>
<button mat-menu-item [routerLink]="['/profile']">
<mat-icon>
<fa-icon icon="user" size="sm"></fa-icon>
</mat-icon>
<span>Profile</span>
</button>
<button mat-menu-item [routerLink]="['/settings']">
<mat-icon>
<fa-icon icon="cog" size="sm"></fa-icon>
@@ -106,7 +118,7 @@
</button>
<button mat-menu-item (click)="logout()" id="logout">
<mat-icon>
<fa-icon icon="sign-out-alt" size="sm"></fa-icon>
<fa-icon icon="sign-out-alt" size="sm"></fa-icon>
</mat-icon>
<span>Sign Out</span>
</button>
@@ -80,6 +80,16 @@ export class ToolbarComponent implements OnInit {
.subscribe(() => this.router.navigate(['/login'], { replaceUrl: true }));
}
/**
* Opens Mifos JIRA Wiki page.
*/
help() {
window.open('https://mifosforge.jira.com/wiki/spaces/docs/pages/52035622/User+Manual', '_blank');
}
/**
* Opens Keyboard shortcuts dialog.
*/
showKeyboardShortcuts() {
const dialogRef = this.dialog.open(KeyboardShortcutsDialogComponent);
dialogRef.afterClosed().subscribe((response: any) => {});
+33
View File
@@ -0,0 +1,33 @@
/** Angular Imports */
import { NgModule } from '@angular/core';
import { Routes, RouterModule } from '@angular/router';
/** Routing Imports */
import { Route } from '../core/route/route.service';
/** Translation Imports */
import { extract } from '../core/i18n/i18n.service';
/** Custom Components */
import { ProfileComponent } from './profile.component';
/** Profile Routes */
const routes: Routes = [
Route.withShell([
{
path: 'profile',
component: ProfileComponent,
data: { title: extract('Profile'), breadcrumb: 'Profile' },
}
])
];
/**
* Profile Routing Module
*/
@NgModule({
imports: [RouterModule.forChild(routes)],
exports: [RouterModule],
providers: []
})
export class ProfileRoutingModule { }
+84
View File
@@ -0,0 +1,84 @@
<div class="container m-b-20" fxLayout="row" fxLayout.lt-md="column" fxLayoutAlign="end" fxLayoutGap="2%">
<button mat-raised-button color="primary" [routerLink]="['/system', 'roles-and-permissions']">
<fa-icon icon="check"></fa-icon>&nbsp;&nbsp;
Permissions
</button>
<button mat-raised-button color="primary" (click)="changeUserPassword()">
<fa-icon icon="cog"></fa-icon>&nbsp;&nbsp;
Change Password
</button>
</div>
<div class="container" fxLayout="column" fxLayoutGap="2%">
<mat-card>
<div fxLayout="row wrap" class="content">
<div fxFlex="50%" class="header">
User Id
</div>
<div fxFlex="50%">
{{ profileData.userId }}
</div>
<div fxFlex="50%" class="header">
User Name
</div>
<div fxFlex="50%">
{{ profileData.username }}
</div>
<div fxFlex="50%" class="header">
Office
</div>
<div fxFlex="50%">
{{ profileData.officeName }}
</div>
<div fxFlex="50%" class="header">
Status
</div>
<div fxFlex="50%">
{{ profileData.authenticated ? 'Authenticated' : 'Not Authenticated' }}
</div>
<div fxFlex="50%" class="header">
Language
</div>
<div fxFlex="50%">
{{ language }}
</div>
</div>
</mat-card>
<mat-card>
<table class="mat-elevation-z1" mat-table [dataSource]="dataSource">
<ng-container matColumnDef="role">
<th mat-header-cell *matHeaderCellDef> Role </th>
<td mat-cell *matCellDef="let role"> {{ role.name }} </td>
</ng-container>
<ng-container matColumnDef="description">
<th mat-header-cell *matHeaderCellDef> Description </th>
<td mat-cell *matCellDef="let role">{{ role.description }}</td>
</ng-container>
<tr mat-header-row *matHeaderRowDef="displayedColumns"></tr>
<tr mat-row *matRowDef="let row; columns: displayedColumns;"></tr>
</table>
</mat-card>
</div>
+14
View File
@@ -0,0 +1,14 @@
.container {
max-width: 37rem;
.content {
div {
margin: 1rem 0;
word-wrap: break-word;
&.header {
font-weight: 500;
}
}
}
}
+25
View File
@@ -0,0 +1,25 @@
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
import { ProfileComponent } from './profile.component';
describe('ProfileComponent', () => {
let component: ProfileComponent;
let fixture: ComponentFixture<ProfileComponent>;
beforeEach(async(() => {
TestBed.configureTestingModule({
declarations: [ ProfileComponent ]
})
.compileComponents();
}));
beforeEach(() => {
fixture = TestBed.createComponent(ProfileComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
it('should create', () => {
expect(component).toBeTruthy();
});
});
+68
View File
@@ -0,0 +1,68 @@
/** Angular Imports */
import { Component, OnInit } from '@angular/core';
import { MatTableDataSource, MatDialog } from '@angular/material';
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';
/**
* Profile Component.
*/
@Component({
selector: 'mifosx-profile',
templateUrl: './profile.component.html',
styleUrls: ['./profile.component.scss']
})
export class ProfileComponent implements OnInit {
/** Profile Data */
profileData: any;
/** Language, TODO: Update when df, locale settings are setup */
language = 'English';
/** Roles Table Datasource */
dataSource = new MatTableDataSource();
/** Columns to be displayed in user roles table. */
displayedColumns: string[] = ['role', 'description'];
/**
* @param {AuthenticationService} authenticationService Authentication Service
* @param {UserService} userService Users Service
* @param {Router} router Router
* @param {MatDialog} dialog Mat Dialog
*/
constructor(private authenticationService: AuthenticationService,
private userService: UserService,
private router: Router,
public dialog: MatDialog) {
this.profileData = authenticationService.getCredentials();
}
ngOnInit() {
this.dataSource = new MatTableDataSource(this.profileData.roles);
}
/**
* Change Password of the user.
*/
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.profileData.userId, data).subscribe(() => {
this.router.navigate(['/home']);
});
}
});
}
}
+21
View File
@@ -0,0 +1,21 @@
/** Angular Imports */
import { NgModule } from '@angular/core';
/** Custom Modules */
import { SharedModule } from '../shared/shared.module';
import { ProfileRoutingModule } from './profile-routing.module';
/** Custom Components */
import { ProfileComponent } from './profile.component';
/**
* Profile Module
*/
@NgModule({
declarations: [ProfileComponent],
imports: [
SharedModule,
ProfileRoutingModule
]
})
export class ProfileModule { }