refractor(breadcrumb): enhance breadcrumb (#129)

Enhance breadcrumb design and generation

Fixes #106
This commit is contained in:
Abhay Chawla
2018-07-17 00:23:00 +05:30
committed by GitHub
parent 3c9d012e8c
commit 4a30432fa9
32 changed files with 227 additions and 69 deletions
@@ -0,0 +1,140 @@
<mat-card class="container m-t-40">
<mat-card-header>
<mat-radio-group class="example-radio-group" [(ngModel)]="currentUserType" fxLayout="row" fxLayoutGap="50px">
<mat-radio-button class="example-radio-button" *ngFor="let userType of userTypes" [value]="userType">
{{ userType }}
</mat-radio-button>
</mat-radio-group>
</mat-card-header>
<ng-container *ngIf="currentUserType === 'Existing User'">
<mat-card-content class="m-t-20">
<form fxLayout="column" fxLayoutGap="10px">
<mat-form-field>
<mat-select placeholder="Office">
<mat-option *ngFor="let office of officeData" [value]="office.value">
{{ office.viewValue }}
</mat-option>
</mat-select>
</mat-form-field>
<mat-form-field>
<mat-select placeholder="Staff">
<mat-option *ngFor="let staff of staffData" [value]="staff.value">
{{ staff.viewValue }}
</mat-option>
</mat-select>
</mat-form-field>
<mat-form-field>
<mat-select placeholder="Client">
<mat-option *ngFor="let client of clientData" [value]="client.value">
{{ client.viewValue }}
</mat-option>
</mat-select>
</mat-form-field>
</form>
</mat-card-content>
<mat-card-actions fxLayout="row" fxLayout.xs="column" fxLayoutAlign="center" fxLayoutGap="5px">
<button mat-raised-button color="primary"><mat-icon>lock_open</mat-icon>&nbsp;&nbsp;Activate Self Service User</button>
<button mat-raised-button>Cancel</button>
</mat-card-actions>
</ng-container>
<ng-container *ngIf="currentUserType === 'New User'">
<mat-card-content class="m-t-20">
<form>
<mat-grid-list cols="2" rowHeight="80px"> <!-- TODO: Dynamic columns to make responsive and hide the blank tile or find some other way -->
<mat-grid-tile>
<mat-form-field fxFlex class="m-10">
<mat-select placeholder="Office">
<mat-option *ngFor="let office of officeData" [value]="office.value">
{{ office.viewValue }}
</mat-option>
</mat-select>
</mat-form-field>
</mat-grid-tile>
<mat-grid-tile>
<mat-form-field fxFlex class="m-10">
<mat-select placeholder="Staff">
<mat-option *ngFor="let staff of staffData" [value]="staff.value">
{{ staff.viewValue }}
</mat-option>
</mat-select>
</mat-form-field>
</mat-grid-tile>
<mat-grid-tile>
<mat-form-field fxFlex class="m-10">
<input matInput placeholder="Username">
</mat-form-field>
</mat-grid-tile>
<mat-grid-tile>
</mat-grid-tile>
<mat-grid-tile>
<mat-form-field fxFlex class="m-10">
<input matInput placeholder="First Name">
</mat-form-field>
</mat-grid-tile>
<mat-grid-tile>
<mat-form-field fxFlex class="m-10">
<input matInput placeholder="Last Name">
</mat-form-field>
</mat-grid-tile>
<mat-grid-tile>
<mat-form-field fxFlex class="m-10">
<mat-select placeholder="Gender">
<mat-option *ngFor="let gender of genderData" [value]="gender.value">
{{ gender.viewValue }}
</mat-option>
</mat-select>
</mat-form-field>
</mat-grid-tile>
<mat-grid-tile>
<mat-form-field fxFlex class="m-10">
<input matInput [matDatepicker]="picker" placeholder="Date of Birth">
<mat-datepicker-toggle matSuffix [for]="picker"></mat-datepicker-toggle>
<mat-datepicker #picker></mat-datepicker>
</mat-form-field>
</mat-grid-tile>
<mat-grid-tile>
<mat-form-field fxFlex class="m-10">
<input matInput placeholder="Email">
</mat-form-field>
</mat-grid-tile>
<mat-grid-tile>
<mat-form-field fxFlex class="m-10">
<input matInput placeholder="Mobile No">
</mat-form-field>
</mat-grid-tile>
</mat-grid-list>
</form>
</mat-card-content>
<mat-card-actions fxLayout="row" fxLayout.xs="column" fxLayoutAlign="center" fxLayoutGap="5px">
<button mat-raised-button color="primary"><mat-icon>create</mat-icon>&nbsp;&nbsp;Create Self Service User</button>
<button mat-raised-button>Cancel</button>
</mat-card-actions>
</ng-container>
</mat-card>
@@ -0,0 +1,25 @@
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();
});
});
@@ -0,0 +1,23 @@
import { Component, OnInit } from '@angular/core';
@Component({
selector: 'mifosx-create-user',
templateUrl: './create-user.component.html',
styleUrls: ['./create-user.component.scss']
})
export class CreateUserComponent implements OnInit {
isCollapsed = false;
userTypes = ['Existing User', 'New User'];
currentUserType = this.userTypes[0];
officeData: string[];
staffData: string[];
clientData: string[];
genderData: string[];
constructor() { }
ngOnInit() {
}
}
@@ -0,0 +1,94 @@
<mat-card class="container m-t-40">
<mat-card-header>
</mat-card-header>
<mat-card-content class="m-t-20">
<form>
<mat-grid-list cols="2" rowHeight="80px"> <!-- TODO: Dynamic columns to make responsive and hide the blank tile or find some other way -->
<mat-grid-tile>
<mat-form-field fxFlex class="m-10">
<mat-select placeholder="Office">
<mat-option *ngFor="let office of officeData" [value]="office.value">
{{ office.viewValue }}
</mat-option>
</mat-select>
</mat-form-field>
</mat-grid-tile>
<mat-grid-tile>
<mat-form-field fxFlex class="m-10">
<mat-select placeholder="Staff">
<mat-option *ngFor="let staff of staffData" [value]="staff.value">
{{ staff.viewValue }}
</mat-option>
</mat-select>
</mat-form-field>
</mat-grid-tile>
<mat-grid-tile>
<mat-form-field fxFlex class="m-10">
<input matInput placeholder="Username">
</mat-form-field>
</mat-grid-tile>
<mat-grid-tile>
</mat-grid-tile>
<mat-grid-tile>
<mat-form-field fxFlex class="m-10">
<input matInput placeholder="First Name">
</mat-form-field>
</mat-grid-tile>
<mat-grid-tile>
<mat-form-field fxFlex class="m-10">
<input matInput placeholder="Last Name">
</mat-form-field>
</mat-grid-tile>
<mat-grid-tile>
<mat-form-field fxFlex class="m-10">
<mat-select placeholder="Gender">
<mat-option *ngFor="let gender of genderData" [value]="gender.value">
{{ gender.viewValue }}
</mat-option>
</mat-select>
</mat-form-field>
</mat-grid-tile>
<mat-grid-tile>
<mat-form-field fxFlex class="m-10">
<input matInput [matDatepicker]="picker" placeholder="Date of Birth">
<mat-datepicker-toggle matSuffix [for]="picker"></mat-datepicker-toggle>
<mat-datepicker #picker></mat-datepicker>
</mat-form-field>
</mat-grid-tile>
<mat-grid-tile>
<mat-form-field fxFlex class="m-10">
<input matInput placeholder="Email">
</mat-form-field>
</mat-grid-tile>
<mat-grid-tile>
<mat-form-field fxFlex class="m-10">
<input matInput placeholder="Mobile No">
</mat-form-field>
</mat-grid-tile>
</mat-grid-list>
</form>
</mat-card-content>
<mat-card-actions fxLayout="row" fxLayout.xs="column" fxLayoutAlign="center" fxLayoutGap="5px">
<button mat-raised-button color="primary">Submit</button>
<button mat-raised-button>Cancel</button>
</mat-card-actions>
</mat-card>
@@ -0,0 +1,25 @@
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();
});
});
@@ -0,0 +1,19 @@
import { Component, OnInit } from '@angular/core';
@Component({
selector: 'mifosx-edit-user',
templateUrl: './edit-user.component.html',
styleUrls: ['./edit-user.component.scss']
})
export class EditUserComponent implements OnInit {
officeData: string[];
staffData: string[];
genderData: string[];
constructor() { }
ngOnInit() {
}
}
@@ -0,0 +1,15 @@
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();
}));
});
@@ -0,0 +1,32 @@
import { Injectable } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import { Observable } from 'rxjs/internal/Observable';
import { map } from 'rxjs/internal/operators/map';
@Injectable({
providedIn: 'root'
})
export class UserService {
constructor(private http: HttpClient) { }
getUsers(): Observable<any> {
return this.http.get<any>(`/users?fields=id,firstname,lastname,email,officeName,staff&tenantIdentifier=default&pretty=true`)
.pipe(
map((res) => {
res.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 res;
})
);
}
getUser(): Observable<any> {
return this.http.disableApiPrefix().get('http://localhost:4200/assets/mock/user.mock.json');
}
}
@@ -0,0 +1,90 @@
<mat-card class="container m-t-40">
<div fxLayout="row" fxLayoutGap="30px" class="m-b-20">
<!-- <mat-card-header> -->
<!-- <mat-grid-list cols="1" rowHeight="80px">
<mat-grid-tile> -->
<mat-form-field fxFlex>
<input matInput (keyup)="applyFilter($event.target.value)" placeholder="Filter">
</mat-form-field>
<!-- </mat-grid-tile> -->
<!-- <mat-grid-tile> -->
<!-- <mat-card-actions> -->
<!-- <button mat-raised-button color="primary"><mat-icon>lock_open</mat-icon>&nbsp;&nbsp;Activate</button> -->
<!-- <button mat-raised-button color="primary"><mat-icon>lock</mat-icon>&nbsp;&nbsp;Deactivate</button> -->
<button mat-raised-button color="primary" [routerLink]="['/self-service/users/create']"><mat-icon>add</mat-icon>&nbsp;&nbsp;Create User</button>
<!-- </mat-card-actions> -->
<!-- </mat-grid-tile> -->
<!-- </mat-grid-list> -->
<!-- </mat-card-header> -->
</div>
<mat-card-content 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> Name </th>
<td mat-cell *matCellDef="let user"><span class="mobile-label">Name: </span>{{ user.name }} </td>
</ng-container>
<ng-container matColumnDef="id">
<th mat-header-cell *matHeaderCellDef mat-sort-header> User ID </th>
<td mat-cell *matCellDef="let user"><span class="mobile-label">User ID: </span>{{ user.id }}</td>
</ng-container>
<ng-container matColumnDef="email">
<th mat-header-cell *matHeaderCellDef mat-sort-header> Email ID </th>
<td mat-cell *matCellDef="let user"><span class="mobile-label">Email ID: </span>{{ user.email }}</td>
</ng-container>
<ng-container matColumnDef="status">
<th mat-header-cell *matHeaderCellDef mat-sort-header="isSelfServiceUser"> Status </th>
<td mat-cell *matCellDef="let user">
<span class="mobile-label">Status: </span>
<div [className]="user.isSelfServiceUser === true ? 'active' : 'inactive'">
<mat-icon matTooltip="{{ user.isSelfServiceUser === true ? 'Active' : 'Inactive' }}" matTooltipPosition="right">lens</mat-icon>
</div>
</td>
</ng-container>
<ng-container matColumnDef="officeName">
<th mat-header-cell *matHeaderCellDef mat-sort-header> Office </th>
<td mat-cell *matCellDef="let user"><span class="mobile-label">Office: </span>{{ user.officeName }}</td>
</ng-container>
<ng-container matColumnDef="staff">
<th mat-header-cell *matHeaderCellDef mat-sort-header> Staff </th>
<td mat-cell *matCellDef="let user"><span class="mobile-label">Staff: </span>{{ user.staff }}</td>
</ng-container>
<tr mat-header-row *matHeaderRowDef="displayedColumns"></tr>
<tr mat-row *matRowDef="let row; columns: displayedColumns;" (click)="selection.toggle(row)"></tr>
</table>
<mat-paginator [pageSizeOptions]="[10, 25, 50, 100]" showFirstLastButtons></mat-paginator>
</mat-card-content>
</mat-card>
@@ -0,0 +1,53 @@
// td, th {
// text-align: center;
// }
// ngb-pagination {
// margin: 20px 0px;
// }
.mat-table {
width: 100%;
}
// .mat-form-field {
// width: 100%;
// }
.mobile-label {
display: none;
}
.inactive {
color: grey;
}
.active {
color: green;
}
// @media(max-width: 600px) {
// .mobile-label {
// width: 80px;
// display: inline-block;
// font-weight: bold;
// }
// .mat-header-row {
// display: none;
// }
// .mat-row {
// display: flex;
// flex-direction: column;
// align-items: start;
// padding: 68px 24px;
// min-height: 108px;
// }
// .mat-cell {
// flex: 1;
// display: flex;
// align-items: center;
// min-height: inherit;
// }
// }
@@ -0,0 +1,25 @@
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();
});
});
@@ -0,0 +1,55 @@
import { Component, OnInit, ViewChild } from '@angular/core';
import { SelectionModel } from '@angular/cdk/collections';
import { MatPaginator, MatSort, MatTableDataSource } from '@angular/material';
import { UserService } from './user.service';
export interface User {
name: string;
id: number;
email: string;
isSelfServiceUser: boolean;
officeName: string;
staff: string;
}
@Component({
selector: 'mifosx-users',
templateUrl: './users.component.html',
styleUrls: ['./users.component.scss']
})
export class UsersComponent implements OnInit {
displayedColumns: string[] = ['select', 'name', 'id', 'email', 'status', 'officeName', 'staff'];
dataSource: any;
selection = new SelectionModel<User>(true, []);
@ViewChild(MatPaginator) paginator: MatPaginator;
@ViewChild(MatSort) sort: MatSort;
constructor(private userService: UserService) { }
ngOnInit() {
this.userService.getUsers().subscribe((data: User[]) => {
this.dataSource = new MatTableDataSource(data);
this.dataSource.paginator = this.paginator;
this.dataSource.sort = this.sort;
});
}
applyFilter(filterValue: string) {
this.dataSource.filter = filterValue.trim().toLowerCase();
}
isAllSelected() {
const numSelected = this.selection.selected.length;
const numRows = this.dataSource.data.length;
return numSelected === numRows;
}
masterToggle() {
this.isAllSelected() ?
this.selection.clear() :
this.dataSource.data.forEach((row: User) => this.selection.select(row));
}
}
@@ -0,0 +1,102 @@
<mat-card class="container m-t-40">
<mat-card-header>
<mat-icon matTooltip="Status" matTooltipPosition="above">lens</mat-icon>&nbsp;&nbsp;User ID: 123456
</mat-card-header>
<mat-card-actions align="right">
<button mat-raised-button color="primary" [routerLink]="['/self-service/users/view/123456/edit']"><mat-icon>edit</mat-icon>&nbsp;&nbsp;Edit</button>
<button mat-raised-button color="primary" (click)="openDialog()"><mat-icon>settings</mat-icon>&nbsp;&nbsp;Change Password</button>
<button mat-raised-button color="primary"><mat-icon>lock</mat-icon>&nbsp;&nbsp;Deactivate</button>
</mat-card-actions>
<mat-card-content>
<mat-grid-list cols="2" rowHeight="40px" style="width: 600px;">
<mat-grid-tile>
Username
</mat-grid-tile>
<mat-grid-tile>
abhaychawla
</mat-grid-tile>
<mat-grid-tile>
First Name
</mat-grid-tile>
<mat-grid-tile>
Abhay
</mat-grid-tile>
<mat-grid-tile>
Last Name
</mat-grid-tile>
<mat-grid-tile>
Chawla
</mat-grid-tile>
<mat-grid-tile>
Gender
</mat-grid-tile>
<mat-grid-tile>
Male
</mat-grid-tile>
<mat-grid-tile>
Date of Birth
</mat-grid-tile>
<mat-grid-tile>
18/06/1997
</mat-grid-tile>
<mat-grid-tile>
Email
</mat-grid-tile>
<mat-grid-tile>
abhay.chawla97@gmail.com
</mat-grid-tile>
<mat-grid-tile>
Mobile
</mat-grid-tile>
<mat-grid-tile>
9871105236
</mat-grid-tile>
<mat-grid-tile>
Office
</mat-grid-tile>
<mat-grid-tile>
Head Office
</mat-grid-tile>
<mat-grid-tile>
Staff
</mat-grid-tile>
<mat-grid-tile>
Smith W
</mat-grid-tile>
<mat-grid-tile>
Activation Date
</mat-grid-tile>
<mat-grid-tile>
12/03/2018
</mat-grid-tile>
</mat-grid-list>
</mat-card-content>
</mat-card>
@@ -0,0 +1,25 @@
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();
});
});
@@ -0,0 +1,19 @@
import { Component, OnInit } from '@angular/core';
@Component({
selector: 'mifosx-view-user',
templateUrl: './view-user.component.html',
styleUrls: ['./view-user.component.scss']
})
export class ViewUserComponent implements OnInit {
constructor() { }
ngOnInit() {
}
openDialog() {
// TODO: Change Password Dialog
}
}
@@ -0,0 +1,16 @@
import { Injectable } from '@angular/core';
import { Resolve } from '@angular/router';
import { Observable, of } from 'rxjs';
import { UserService } from '../user.service';
@Injectable()
export class ViewUserResolver implements Resolve<Object> {
constructor(private userService: UserService) {}
resolve(): Observable<any> {
return this.userService.getUser();
}
}