Explorar el Código

Profile consolidated to single place.

tags/2.037
Patrick Sun hace 4 años
padre
commit
0f1d4f5627
Se han modificado 47 ficheros con 970 adiciones y 302 borrados
  1. +3
    -1
      src/app/app-routing.module.ts
  2. +14
    -2
      src/app/app.module.ts
  3. +1
    -1
      src/app/broker-loan-list/broker-loan-list.component.ts
  4. +0
    -141
      src/app/broker-profile/broker-profile.component.html
  5. +0
    -109
      src/app/broker-profile/broker-profile.component.ts
  6. +1
    -1
      src/app/client-loan-list/client-loan-list.component.ts
  7. +1
    -1
      src/app/client-profile/client-profile.component.ts
  8. +1
    -12
      src/app/main-menu-items.ts
  9. +7
    -0
      src/app/message-box/message-box.component.html
  10. +0
    -0
      src/app/message-box/message-box.component.scss
  11. +25
    -0
      src/app/message-box/message-box.component.spec.ts
  12. +38
    -0
      src/app/message-box/message-box.component.ts
  13. +5
    -2
      src/app/models/api-v1-login-response.ts
  14. +10
    -0
      src/app/models/user-extra.model.ts
  15. +1
    -0
      src/app/profile/admin-profile/admin-profile.component.html
  16. +0
    -0
      src/app/profile/admin-profile/admin-profile.component.scss
  17. +25
    -0
      src/app/profile/admin-profile/admin-profile.component.spec.ts
  18. +16
    -0
      src/app/profile/admin-profile/admin-profile.component.ts
  19. +53
    -0
      src/app/profile/broker-profile/broker-profile.component.html
  20. +0
    -0
      src/app/profile/broker-profile/broker-profile.component.scss
  21. +0
    -0
      src/app/profile/broker-profile/broker-profile.component.spec.ts
  22. +40
    -0
      src/app/profile/broker-profile/broker-profile.component.ts
  23. +34
    -0
      src/app/profile/change-password/change-password.component.html
  24. +0
    -0
      src/app/profile/change-password/change-password.component.scss
  25. +25
    -0
      src/app/profile/change-password/change-password.component.spec.ts
  26. +57
    -0
      src/app/profile/change-password/change-password.component.ts
  27. +60
    -0
      src/app/profile/people-profile/people-profile.component.html
  28. +29
    -0
      src/app/profile/people-profile/people-profile.component.scss
  29. +25
    -0
      src/app/profile/people-profile/people-profile.component.spec.ts
  30. +79
    -0
      src/app/profile/people-profile/people-profile.component.ts
  31. +20
    -0
      src/app/profile/profile.component.html
  32. +25
    -0
      src/app/profile/profile.component.scss
  33. +25
    -0
      src/app/profile/profile.component.spec.ts
  34. +63
    -0
      src/app/profile/profile.component.ts
  35. +33
    -0
      src/app/profile/user-profile/user-profile.component.html
  36. +0
    -0
      src/app/profile/user-profile/user-profile.component.scss
  37. +25
    -0
      src/app/profile/user-profile/user-profile.component.spec.ts
  38. +50
    -0
      src/app/profile/user-profile/user-profile.component.ts
  39. +39
    -21
      src/app/service/auth.service.ts
  40. +10
    -2
      src/app/service/menu.service.ts
  41. +44
    -1
      src/app/settings/settings.component.html
  42. +22
    -0
      src/app/settings/settings.component.scss
  43. +50
    -1
      src/app/settings/settings.component.ts
  44. +6
    -3
      src/app/top-bar/top-bar.component.html
  45. +8
    -4
      src/app/top-bar/top-bar.component.ts
  46. BIN
      src/assets/bg.jpg
  47. BIN
      src/assets/img/bg-settings.jpg

+ 3
- 1
src/app/app-routing.module.ts Ver fichero

@@ -10,7 +10,7 @@ import {LoanEditComponent} from './loan-edit/loan-edit.component';
import {LenderUploadsComponent} from './lender-uploads/lender-uploads.component';
import {BrokerLoanListComponent} from './broker-loan-list/broker-loan-list.component';
import {BrokerRewardComponent} from './broker-reward/broker-reward.component';
import {BrokerProfileComponent} from './broker-profile/broker-profile.component';
import {BrokerProfileComponent} from './profile/broker-profile/broker-profile.component';
import {ClientLoanListComponent} from './client-loan-list/client-loan-list.component';
import {ClientProfileComponent} from './client-profile/client-profile.component';
import {E403Component} from './e403/e403.component';
@@ -22,6 +22,7 @@ import {RewardUnpaidComponent} from './reward-unpaid/reward-unpaid.component';
import {PayInComponent} from './pay-in/pay-in.component';
import {PeopleAddComponent} from './people-add/people-add.component';
import {SettingsComponent} from './settings/settings.component';
import {ProfileComponent} from './profile/profile.component';


const routes: Routes = [
@@ -50,6 +51,7 @@ const routes: Routes = [
{path : 'lender-uploads', component: LenderUploadsComponent, canActivate: [AuthGuard] },
{path : 'list-all-people', component: LenderUploadsComponent, canActivate: [AuthGuard] },
{path : 'people-add', component: PeopleAddComponent, canActivate: [AuthGuard] },
{path : 'profile', component: ProfileComponent, canActivate: [AuthGuard] },
{path : 'e403', component: E403Component, },
];


+ 14
- 2
src/app/app.module.ts Ver fichero

@@ -66,7 +66,7 @@ import { PeopleCardComponent } from './people-card/people-card.component';
import { LenderUploadsComponent } from './lender-uploads/lender-uploads.component';
import { BrokerLoanListComponent } from './broker-loan-list/broker-loan-list.component';
import { BrokerRewardComponent } from './broker-reward/broker-reward.component';
import { BrokerProfileComponent } from './broker-profile/broker-profile.component';
import { BrokerProfileComponent } from './profile/broker-profile/broker-profile.component';
import { ClientLoanListComponent } from './client-loan-list/client-loan-list.component';
import { ClientProfileComponent } from './client-profile/client-profile.component';
import { E403Component } from './e403/e403.component';
@@ -80,6 +80,12 @@ import { PayInComponent } from './pay-in/pay-in.component';
import { PeopleAddComponent } from './people-add/people-add.component';
import { ListAllPeopleComponent } from './list-all-people/list-all-people.component';
import { SettingsComponent } from './settings/settings.component';
import { ProfileComponent } from './profile/profile.component';
import { PeopleProfileComponent } from './profile/people-profile/people-profile.component';
import { MessageBoxComponent } from './message-box/message-box.component';
import { UserProfileComponent } from './profile/user-profile/user-profile.component';
import { AdminProfileComponent } from './profile/admin-profile/admin-profile.component';
import { ChangePasswordComponent } from './profile/change-password/change-password.component';



@@ -130,7 +136,13 @@ import { SettingsComponent } from './settings/settings.component';
PayInComponent,
PeopleAddComponent,
ListAllPeopleComponent,
SettingsComponent
SettingsComponent,
ProfileComponent,
PeopleProfileComponent,
MessageBoxComponent,
UserProfileComponent,
AdminProfileComponent,
ChangePasswordComponent
],
imports: [
BrowserModule,

+ 1
- 1
src/app/broker-loan-list/broker-loan-list.component.ts Ver fichero

@@ -20,7 +20,7 @@ export class BrokerLoanListComponent implements OnInit {

ngOnInit(): void {
this.brokerLoans = this.lss;
this.broker = this.auth.loggedIn.user;
this.broker = this.auth.loggedIn.User;
this.loadData();
}


+ 0
- 141
src/app/broker-profile/broker-profile.component.html Ver fichero

@@ -1,141 +0,0 @@
<div class="container outer">
<bkp-divider-shadow-bottom></bkp-divider-shadow-bottom>
<div class="vertical-spacer"></div>
<div class="container inner">
<div class="row justify-content-center">
<div class="col-sm-12">
<h5> Edit : {{broker.First + ' ' + broker.Last}} </h5>

<div class="dropzone-wrapper">
<div class="fileselect-wrapper">
<div class="row justify-content-center">
<div #brokerPhoto class="broker-photo" [ngStyle]="{'background-image' : avatarUrl }" ></div>
</div>

<kendo-fileselect
#fileSelect
zoneId="myZone"
[restrictions]="myRestrictions"
[showFileList]="false"
(select)="onSelect($event)"
>
</kendo-fileselect>
only jpg and png are allowed

</div>
</div>
<div class="vertical-spacer"></div>

<form class="k-form" #brokerForm="ngForm" (submit)="save(brokerForm)">
<ng-container >
<fieldset class="k-form-fieldset">
<kendo-formfield>
<kendo-label [for]="First" text="First Name (only Admin can change)"></kendo-label>
<kendo-textbox kendoTextBox #First name="First" [(ngModel)]="broker.First"
[showSuccessIcon]="broker.Display.length >= 3 && broker.Display.length <=44 "> </kendo-textbox>
<kendo-formerror>First name is required</kendo-formerror>
</kendo-formfield>
<div class="vertical-spacer"></div>

<kendo-formfield>
<kendo-label [for]="Last" text="Last Name (only Admin can change)"></kendo-label>
<kendo-textbox kendoTextBox #Last name="Last" [(ngModel)]="broker.Last"
[showSuccessIcon]="broker.Display.length >= 3 && broker.Display.length <=44 "></kendo-textbox>
<kendo-formerror>Last Name is required</kendo-formerror>
</kendo-formfield>
<div class="vertical-spacer"></div>

<kendo-formfield>
<kendo-label [for]="Display" text="Display As"></kendo-label>
<kendo-textbox #Display name="Display" [(ngModel)]="broker.Display" required [minlength]="3" [maxlength]="120"
[showSuccessIcon]="broker.Display.length >= 3 && broker.Display.length <=100 "> </kendo-textbox>
<kendo-formerror>Display name cannot empty</kendo-formerror>
</kendo-formfield>
<div class="vertical-spacer"></div>

<kendo-formfield>
<kendo-label [for]="License" text="License"></kendo-label>
<kendo-textbox #License name="License" [(ngModel)]="broker.License" required [minlength]="3" [maxlength]="120"
[showSuccessIcon]="broker.License.length >= 0 && broker.License.length <=20 "> </kendo-textbox>
<kendo-formerror>license is required, key in unknown if have one</kendo-formerror>
</kendo-formfield>
<div class="vertical-spacer"></div>

<kendo-formfield>
<kendo-label [for]="BSB" text="BSB"></kendo-label>
<kendo-textbox #BSB name="BSB" [(ngModel)]="broker.BSB" required [minlength]="3" [maxlength]="7"
[showSuccessIcon]="broker.BSB.length >= 0 && broker.BSB.length <=7"> </kendo-textbox>
<kendo-formerror>BSB required for accepting payment</kendo-formerror>
</kendo-formfield>
<div class="vertical-spacer"></div>

<kendo-formfield>
<kendo-label [for]="ACC" text="ACC"></kendo-label>
<kendo-textbox #ACC name="ACC" [(ngModel)]="broker.ACC" required [minlength]="3" [maxlength]="11"
[showSuccessIcon]="broker.ACC.length >= 0 && broker.ACC.length <=11 "> </kendo-textbox>
<kendo-formerror>ACC is required for accepting payment</kendo-formerror>
</kendo-formfield>
<div class="vertical-spacer"></div>

<kendo-formfield>
<kendo-label [for]="Organization" text="Organization"></kendo-label>
<kendo-textbox #Organization name="Organization" [(ngModel)]="broker.Organization" required
[disabled]="true" [minlength]="3" [maxlength]="25"
[showSuccessIcon]="broker.Organization.length >= 1 && broker.Organization.length <=25 ">
</kendo-textbox>
<kendo-formerror>Organization is required, (only changed by admin)</kendo-formerror>
</kendo-formfield>
<div class="vertical-spacer"></div>

</fieldset>
</ng-container>
<div class="k-form-buttons k-buttons-end">
<div>
<button kendoButton class="k-button k-primary" type="submit" icon="save"
[disabled]="brokerForm.form.status !=='VALID'"> Save </button>
</div>
</div>
</form>

<kendo-switch [(ngModel)]="changePassword" ngModelOptions="{standalone: true}"> </kendo-switch> Change Password
<div class="vertical-spacer"></div>
<form *ngIf="changePassword" [formGroup]="ChangePassForm" class="k-form" (submit)="savePassword()">
<kendo-formfield>
<kendo-label [for]="OldPassword" text="Current Password"></kendo-label>
<input kendoTextBox #OldPassword name="OldPassword" formControlName="OldPassword"
type="password" [minlength]="3" [maxlength]="25" />
<kendo-formerror>Current password is needed (3-20 chars)</kendo-formerror>
</kendo-formfield>

<kendo-formfield>
<kendo-label [for]="NewPass" text="New Password"></kendo-label>
<input kendoTextBox #NewPass name="NewPass" formControlName="NewPass"
[minlength]="3" [maxlength]="25" type="password" />
<kendo-formerror>New password is needed (3-20 chars)</kendo-formerror>
</kendo-formfield>

<kendo-formfield>
<kendo-label [for]="NewPass1" text="New Password (repeat) "></kendo-label>
<input kendoTextBox #NewPass1 name="NewPass1" formControlName="NewPass1"
[minlength]="3" [maxlength]="25" type="password" />

<kendo-formerror>New password repeat is needed (3-20 chars) </kendo-formerror>
</kendo-formfield>
<div class="vertical-spacer"></div>

<button *ngIf="passEqual() && ! ChangePassForm.invalid" kendoButton class="k-button k-primary" type="submit" icon="save"> Change Password </button>
</form>

</div>
</div>
</div>
<div class="vertical-spacer"></div>


<kendo-dialog title="Message " *ngIf="opened" (close)="close('cancel')" [minWidth]="250" [width]="450">
<p style="margin: 30px; text-align: center;">{{ Message }}</p>
<kendo-dialog-actions>
<button kendoButton (click)="close('Ok, I got it')" primary="true">Yes</button>
</kendo-dialog-actions>
</kendo-dialog>
</div>

+ 0
- 109
src/app/broker-profile/broker-profile.component.ts Ver fichero

@@ -1,109 +0,0 @@
import {Component, Input, OnInit, ViewChild} from '@angular/core';
import {PeopleModel} from '../models/people.model';
import {LoanSummaryService} from '../service/loan_summary.service';
import {AuthService} from '../service/auth.service';
import {FormControl, FormGroup, NgForm} from '@angular/forms';
import {FileInfo, FileRestrictions, FileSelectComponent, SelectEvent} from '@progress/kendo-angular-upload';
import {PeopleService} from '../service/people.service';
import {BrokerModel} from '../models/broker.model';
import {ConfirmedValidator} from '../validator/confirmed.validator';


@Component({
selector: 'app-broker-profile',
templateUrl: './broker-profile.component.html',
styleUrls: ['./broker-profile.component.scss']
})
export class BrokerProfileComponent implements OnInit {

@Input() public broker: BrokerModel = BrokerModel.EmptyNew();
@ViewChild('fileSelect', {static: true}) fs: FileSelectComponent;
public avatarUrl = 'url(https://svr2021.lawipac.com:8080/api/v1/avatar/1000)' ;
public myRestrictions: FileRestrictions = {
allowedExtensions: ['.jpg', '.png', '.jpeg'],
maxFileSize: 2194304
};

public opened = false; // dialog box
public Message = ''; // dialog message

public changePassword = false;
public ChangePassForm: FormGroup = new FormGroup({
OldPassword: new FormControl(),
NewPass: new FormControl(),
NewPass1: new FormControl(),
});

constructor( private auth: AuthService, private ps: PeopleService) { }

ngOnInit(): void {
this.broker = BrokerModel.getFromUserAndExtra(this.auth.loggedIn.user, this.auth.loggedIn.userExtra);
this.avatarUrl = 'url(' + this.auth.getUrl('avatar/' + this.broker.Id) + ')';
}

public save(brokerForm: NgForm): void{
if (! brokerForm.touched || brokerForm.form.pristine) {
return;
}
this.ps.saveBroker(this.broker).subscribe( () => {
this.showDialog('updated successfully ');
brokerForm.form.markAsPristine();
}, err => {
this.showDialog('Failed to Update: ' + err.toString());
});
}

public savePassword(): void{
this.ps.savePassword(this.broker.Id, this.ChangePassForm.value).subscribe(
() => {
this.showDialog('Password Changed');
}, err => {
this.showDialog('Failed to Change Password :' + err.toString());
}
);
}

public passEqual(): boolean{
const v = this.ChangePassForm.value;
if ( this.ChangePassForm.valid && v.NewPass === v.NewPass1 && this.ChangePassForm.touched) {
return true;
}else{
this.ChangePassForm.controls['NewPass1'].setErrors({'incorrect': true});
}
return false;
}

public onSelect(ev: SelectEvent): void {
if (ev.files) {
ev.files.every((file: FileInfo) => {
if (file.rawFile && !file.validationErrors) {
const reader = new FileReader();

reader.onloadend = () => {
const str = reader.result as string;
this.ps.updateAvatar(str, this.broker.Id).subscribe( resp => {
this.avatarUrl = 'url(' + str + ' )';
}, err => {
this.showDialog('Failed to Update Avatar: ' + err.toString());
});
this.fs.clearFiles();
};
reader.readAsDataURL(file.rawFile);
}else{
this.showDialog('Only jpg, and png are supported (max 2MB)');
setTimeout(() => { this.fs.clearFiles(); }, 10);
}
return false; // we only take first file
});
}
}

public showDialog(msg: string): void {
this.Message = msg;
this.opened = true; // open dialog
}

public close(status): void {
this.opened = false;
}
}

+ 1
- 1
src/app/client-loan-list/client-loan-list.component.ts Ver fichero

@@ -15,7 +15,7 @@ export class ClientLoanListComponent implements OnInit {
constructor(private ls: LoanSingleService, private auth: AuthService) { }

ngOnInit(): void {
this.ls.getLoanByClient(this.auth.loggedIn.user.Id).subscribe(
this.ls.getLoanByClient(this.auth.loggedIn.User.Id).subscribe(
resp => {
this.Loans = [];
resp.forEach( v => {

+ 1
- 1
src/app/client-profile/client-profile.component.ts Ver fichero

@@ -27,7 +27,7 @@ export class ClientProfileComponent implements OnInit {


ngOnInit(): void {
this.User = this.auth.loggedIn.user;
this.User = this.auth.loggedIn.User;
this.avatarUrl = 'url(' + this.auth.getUrl('avatar/' + this.User.Id) + ')';
}


+ 1
- 12
src/app/main-menu-items.ts Ver fichero

@@ -42,7 +42,7 @@ export const mainMenuItems: any[] = [
text: 'People',
icon: 'user',
items: [
{ text: 'Add ', icon: 'plus', url: './#add-people' },
{ text: 'Add ', icon: 'plus', url: './#people-add' },
{ text: 'List All', fa: faIdCard , url: './#list-all-people'},
{ text: '--', separator: 'true' },
{ text: 'Admin', icon: 'email', url: './#send-to-all-people'},
@@ -63,12 +63,6 @@ export const brokerMenuItems: any[] = [
icon: 'dollar',
url: './#broker-reward'
},
{
text: 'Profile',
fa: faIdCard,
url: './#broker-profile'
},

];

export const userMenuItems: any[] = [
@@ -77,11 +71,6 @@ export const userMenuItems: any[] = [
icon: 'categorize',
url: './#client-loan-list'
},
{
text: 'Profile',
fa: faIdCard,
url: './#client-profile'
},
];

export const peopleMenuItems: any[] = [

+ 7
- 0
src/app/message-box/message-box.component.html Ver fichero

@@ -0,0 +1,7 @@
<kendo-dialog title="{{Title}} " *ngIf="opened" (close)="close('cancel')" [minWidth]="250" [width]="450">
<p style="margin: 30px; text-align: center;">{{ Message }}</p>
<kendo-dialog-actions>
<button kendoButton *ngIf="Mode!='YesOnly'" (click)="close('no')" primary="true">{{NoButtonText}}</button>
<button kendoButton (click)="close('yes')" primary="true">{{YesButtonText}}</button>
</kendo-dialog-actions>
</kendo-dialog>

+ 0
- 0
src/app/message-box/message-box.component.scss Ver fichero


+ 25
- 0
src/app/message-box/message-box.component.spec.ts Ver fichero

@@ -0,0 +1,25 @@
import { ComponentFixture, TestBed } from '@angular/core/testing';

import { MessageBoxComponent } from './message-box.component';

describe('MessageBoxComponent', () => {
let component: MessageBoxComponent;
let fixture: ComponentFixture<MessageBoxComponent>;

beforeEach(async () => {
await TestBed.configureTestingModule({
declarations: [ MessageBoxComponent ]
})
.compileComponents();
});

beforeEach(() => {
fixture = TestBed.createComponent(MessageBoxComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});

it('should create', () => {
expect(component).toBeTruthy();
});
});

+ 38
- 0
src/app/message-box/message-box.component.ts Ver fichero

@@ -0,0 +1,38 @@
import {Component, Input, OnInit, EventEmitter, Output} from '@angular/core';


@Component({
selector: 'app-message-box',
templateUrl: './message-box.component.html',
styleUrls: ['./message-box.component.scss']
})
export class MessageBoxComponent implements OnInit {
@Input() YesButtonText = 'Ok I got it';
@Input() NoButtonText = 'No';
@Input() Title = 'Please Notice';
@Input() Mode = 'YesOnly';

@Output() onClose = new EventEmitter<string>();

public opened = false; // dialog box
public Message = ''; // dialog message

constructor() { }

ngOnInit(): void {
}

public close(status: string): void {
this.onClose.emit(status);
this.opened = false;
}

public Show(Msg: string, mode?: string, title?: string, yesText?: string, noText?: string): void{
this.Message = Msg;
this.Mode = mode || 'YesOnly';
this.Title = title || 'Please notice';
this.YesButtonText = yesText || 'Ok I got it';
this.NoButtonText = noText || 'No';
this.opened = true;
}
}

+ 5
- 2
src/app/models/api-v1-login-response.ts Ver fichero

@@ -12,13 +12,16 @@ export class ApiV1LoginResponse {
public session: string,
public sessionExpire: number, // unix timestamp
public role: string,
public user: PeopleModel,
public userExtra?: UserExtraModel // extra user informaiton
public User: PeopleModel,
public UserExtra?: UserExtraModel // extra user informaiton
) {
this.login = login;
this.machineId = machineId;
this.session = session;
this.sessionExpire = sessionExpire;
this.role = role;
this.User = User;
this.UserExtra = UserExtra;
}

public static EmptyNew(): ApiV1LoginResponse{

+ 10
- 0
src/app/models/user-extra.model.ts Ver fichero

@@ -11,5 +11,15 @@ export class UserExtraModel {
Object.assign(this, payload);
}

public static EmptyNew(): UserExtraModel {
const rt = new UserExtraModel({});
rt.BSB = '';
rt.ACC = '';
rt.License = '';
rt.Organization = '';
rt.Enabled = false;
rt.Login = '';
return rt;
}
}


+ 1
- 0
src/app/profile/admin-profile/admin-profile.component.html Ver fichero

@@ -0,0 +1 @@
<hr>

+ 0
- 0
src/app/profile/admin-profile/admin-profile.component.scss Ver fichero


+ 25
- 0
src/app/profile/admin-profile/admin-profile.component.spec.ts Ver fichero

@@ -0,0 +1,25 @@
import { ComponentFixture, TestBed } from '@angular/core/testing';

import { AdminProfileComponent } from './admin-profile.component';

describe('AdminProfileComponent', () => {
let component: AdminProfileComponent;
let fixture: ComponentFixture<AdminProfileComponent>;

beforeEach(async () => {
await TestBed.configureTestingModule({
declarations: [ AdminProfileComponent ]
})
.compileComponents();
});

beforeEach(() => {
fixture = TestBed.createComponent(AdminProfileComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});

it('should create', () => {
expect(component).toBeTruthy();
});
});

+ 16
- 0
src/app/profile/admin-profile/admin-profile.component.ts Ver fichero

@@ -0,0 +1,16 @@
import {Component, Input, OnInit} from '@angular/core';

@Component({
selector: 'app-admin-profile',
templateUrl: './admin-profile.component.html',
styleUrls: ['./admin-profile.component.scss']
})
export class AdminProfileComponent implements OnInit {
@Input() public PeopleId = '0';

constructor() { }

ngOnInit(): void {
}

}

+ 53
- 0
src/app/profile/broker-profile/broker-profile.component.html Ver fichero

@@ -0,0 +1,53 @@
<h5> Broker Related : {{broker.Display }} </h5>

<div class="vertical-spacer"></div>

<form class="k-form" #brokerForm="ngForm" (submit)="save(brokerForm)">
<ng-container >
<fieldset class="k-form-fieldset">
<kendo-formfield>
<kendo-label [for]="License" text="License"></kendo-label>
<kendo-textbox #License name="License" [(ngModel)]="broker.License" required [minlength]="3" [maxlength]="120"
> </kendo-textbox>
<kendo-formerror>license is required, key in unknown if have one</kendo-formerror>
</kendo-formfield>
<div class="vertical-spacer"></div>

<kendo-formfield>
<kendo-label [for]="BSB" text="BSB"></kendo-label>
<kendo-textbox #BSB name="BSB" [(ngModel)]="broker.BSB" required [minlength]="3" [maxlength]="7"
> </kendo-textbox>
<kendo-formerror>BSB required for accepting payment</kendo-formerror>
</kendo-formfield>
<div class="vertical-spacer"></div>

<kendo-formfield>
<kendo-label [for]="ACC" text="ACC"></kendo-label>
<kendo-textbox #ACC name="ACC" [(ngModel)]="broker.ACC" required [minlength]="3" [maxlength]="11"
> </kendo-textbox>
<kendo-formerror>ACC is required for accepting payment</kendo-formerror>
</kendo-formfield>
<div class="vertical-spacer"></div>

<kendo-formfield>
<kendo-label [for]="Organization" text="Organization"></kendo-label>
<kendo-textbox #Organization name="Organization" [(ngModel)]="broker.Organization" required
[disabled]="!showAdmin" [minlength]="3" [maxlength]="25"
>
</kendo-textbox>
<kendo-formerror>Organization is required, (only changed by admin)</kendo-formerror>
</kendo-formfield>
<div class="vertical-spacer"></div>

</fieldset>
</ng-container>
<div class="k-form-buttons k-buttons-end">
<div>
<button kendoButton class="k-button k-primary" type="submit" icon="save"
[disabled]="brokerForm.form.status !=='VALID'"> Save Broker</button>
</div>
</div>
</form>


<app-message-box #messageBox></app-message-box>

src/app/broker-profile/broker-profile.component.scss → src/app/profile/broker-profile/broker-profile.component.scss Ver fichero


src/app/broker-profile/broker-profile.component.spec.ts → src/app/profile/broker-profile/broker-profile.component.spec.ts Ver fichero


+ 40
- 0
src/app/profile/broker-profile/broker-profile.component.ts Ver fichero

@@ -0,0 +1,40 @@
import {Component, Input, OnInit, ViewChild} from '@angular/core';
import {AuthService} from '../../service/auth.service';
import {FormControl, FormGroup, NgForm} from '@angular/forms';
import {FileInfo, FileRestrictions, FileSelectComponent, SelectEvent} from '@progress/kendo-angular-upload';
import {PeopleService} from '../../service/people.service';
import {BrokerModel} from '../../models/broker.model';
import {MessageBoxComponent} from '../../message-box/message-box.component';



@Component({
selector: 'app-broker-profile',
templateUrl: './broker-profile.component.html',
styleUrls: ['./broker-profile.component.scss']
})
export class BrokerProfileComponent implements OnInit {
@Input() public PeopleId = '';
@Input() public showAdmin: false;
@Input() public broker: BrokerModel = BrokerModel.EmptyNew();
@ViewChild('messageBox', {static: true})msgBox: MessageBoxComponent;

constructor( private auth: AuthService, private ps: PeopleService) { }

ngOnInit(): void {
this.broker = BrokerModel.getFromUserAndExtra(this.auth.loggedIn.User, this.auth.loggedIn.UserExtra);
}

public save(brokerForm: NgForm): void{
if (! brokerForm.touched || brokerForm.form.pristine) {
return;
}
this.ps.saveBroker(this.broker).subscribe( () => {
this.msgBox.Show('updated successfully ');
brokerForm.form.markAsPristine();
}, err => {
this.msgBox.Show('Failed to Update: ' + err.toString());
});
}

}

+ 34
- 0
src/app/profile/change-password/change-password.component.html Ver fichero

@@ -0,0 +1,34 @@
<div *ngIf="canChangePassword()">
<kendo-switch [(ngModel)]="changePassword" ngModelOptions="{standalone: true}" (valueChange)="hidePass()">
</kendo-switch> &nbsp; Change Password
</div>

<div class="vertical-spacer"></div>
<form *ngIf="changePassword" [formGroup]="ChangePassForm" class="k-form" (submit)="savePassword()">
<kendo-formfield>
<kendo-label [for]="OldPassword" text="Current Password"></kendo-label>
<input kendoTextBox #OldPassword name="OldPassword" formControlName="OldPassword"
type="password" [minlength]="3" [maxlength]="25" />
<kendo-formerror>Current password is needed (3-20 chars)</kendo-formerror>
</kendo-formfield>

<kendo-formfield>
<kendo-label [for]="NewPass" text="New Password"></kendo-label>
<input kendoTextBox #NewPass name="NewPass" formControlName="NewPass"
[minlength]="3" [maxlength]="25" type="password" />
<kendo-formerror>New password is needed (3-20 chars)</kendo-formerror>
</kendo-formfield>

<kendo-formfield>
<kendo-label [for]="NewPass1" text="New Password (repeat) "></kendo-label>
<input kendoTextBox #NewPass1 name="NewPass1" formControlName="NewPass1"
[minlength]="3" [maxlength]="25" type="password" />

<kendo-formerror>New password repeat is needed (3-20 chars) </kendo-formerror>
</kendo-formfield>
<div class="vertical-spacer"></div>

<button *ngIf="passwordEqual() && ! ChangePassForm.invalid" kendoButton class="k-button k-primary" type="submit" icon="save"> Change Password </button>
</form>

<app-message-box #messageBox ></app-message-box>

+ 0
- 0
src/app/profile/change-password/change-password.component.scss Ver fichero


+ 25
- 0
src/app/profile/change-password/change-password.component.spec.ts Ver fichero

@@ -0,0 +1,25 @@
import { ComponentFixture, TestBed } from '@angular/core/testing';

import { ChangePasswordComponent } from './change-password.component';

describe('ChangePasswordComponent', () => {
let component: ChangePasswordComponent;
let fixture: ComponentFixture<ChangePasswordComponent>;

beforeEach(async () => {
await TestBed.configureTestingModule({
declarations: [ ChangePasswordComponent ]
})
.compileComponents();
});

beforeEach(() => {
fixture = TestBed.createComponent(ChangePasswordComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});

it('should create', () => {
expect(component).toBeTruthy();
});
});

+ 57
- 0
src/app/profile/change-password/change-password.component.ts Ver fichero

@@ -0,0 +1,57 @@
import {Component, Input, OnInit, ViewChild} from '@angular/core';
import {FormControl, FormGroup} from '@angular/forms';
import {AuthService} from '../../service/auth.service';
import {PeopleService} from '../../service/people.service';
import {MessageBoxComponent} from '../../message-box/message-box.component';

@Component({
selector: 'app-change-password',
templateUrl: './change-password.component.html',
styleUrls: ['./change-password.component.scss']
})
export class ChangePasswordComponent implements OnInit {
@Input() PeopleId = '';
@ViewChild('messageBox', {static: true}) msgBox: MessageBoxComponent;

public changePassword = false;

public ChangePassForm: FormGroup = new FormGroup({
OldPassword: new FormControl(),
NewPass: new FormControl(),
NewPass1: new FormControl(),
});
constructor(private auth: AuthService, private ps: PeopleService) { }

ngOnInit(): void {
}
public hidePass(): void{
if ( this.changePassword ) {
this.ChangePassForm.reset();
}
}

public savePassword(): void{
this.ps.savePassword('0', this.ChangePassForm.value).subscribe(
() => {
this.changePassword = false;
this.msgBox.Show('Password Changed');
}, err => {
this.msgBox.Show('Failed to Change Password :' + err.toString());
}
);
}

public passwordEqual(): boolean{
const v = this.ChangePassForm.value;
if ( this.ChangePassForm.valid && v.NewPass === v.NewPass1 && this.ChangePassForm.touched && v.NewPass1 !== '') {
return true;
}else{
this.ChangePassForm.get('NewPass1').setErrors({incorrect: true});
}
return false;
}

public canChangePassword(): boolean {
return this.auth.isBroker() || this.auth.isAdmin();
}
}

+ 60
- 0
src/app/profile/people-profile/people-profile.component.html Ver fichero

@@ -0,0 +1,60 @@
<app-message-box #messagebox (onClose)="onDialogClose($event)"></app-message-box>

<h5> <kendo-icon [name]="'ascx'" > </kendo-icon> &nbsp; Personal Information </h5>

<div class="dropzone-wrapper">
<div class="fileselect-wrapper">
<div class="row justify-content-center">
<div #peoplePhoto class="people-photo" [ngStyle]="{'background-image' : avatarUrl }" ></div>
</div>

<kendo-fileselect
#fileSelect
zoneId="myZone"
[restrictions]="myRestrictions"
[showFileList]="false"
(select)="onSelectAvatar($event)"

>
</kendo-fileselect>
</div>
</div>

<div class="vertical-spacer"></div>

<form class="k-form" #peopleForm="ngForm" (submit)="save(peopleForm)">
<ng-container >
<fieldset class="k-form-fieldset">
<kendo-formfield>
<kendo-label [for]="First" text="First Name (only Admin can change)"></kendo-label>
<kendo-textbox kendoTextBox #First name="First" [(ngModel)]="People.First"
[showSuccessIcon]="People.Display.length >= 3 && People.Display.length <=44 "> </kendo-textbox>
<kendo-formerror>First name is required</kendo-formerror>
</kendo-formfield>
<div class="vertical-spacer"></div>

<kendo-formfield>
<kendo-label [for]="Last" text="Last Name (only Admin can change)"></kendo-label>
<kendo-textbox kendoTextBox #Last name="Last" [(ngModel)]="People.Last"
[showSuccessIcon]="People.Display.length >= 3 && People.Display.length <=44 "></kendo-textbox>
<kendo-formerror>Last Name is required</kendo-formerror>
</kendo-formfield>
<div class="vertical-spacer"></div>

<kendo-formfield>
<kendo-label [for]="Display" text="Display As"></kendo-label>
<kendo-textbox #Display name="Display" [(ngModel)]="People.Display" required [minlength]="3" [maxlength]="120"
[showSuccessIcon]="People.Display.length >= 3 && People.Display.length <=100 "> </kendo-textbox>
<kendo-formerror>Display name cannot empty</kendo-formerror>
</kendo-formfield>
<div class="vertical-spacer"></div>

</fieldset>
</ng-container>
<div class="k-form-buttons k-buttons-end">
<div>
<button kendoButton class="k-button k-primary" type="submit" icon="save"
[disabled]="peopleForm.form.status !=='VALID'"> Save Personal Information</button>
</div>
</div>
</form>

+ 29
- 0
src/app/profile/people-profile/people-profile.component.scss Ver fichero

@@ -0,0 +1,29 @@

.dropzoneInvisible{
opacity:0.1;
}

.avatar {
width: 100%;
}

.people-photo {
display: inline-block;
width: 256px;
height: 256px;
border-radius: 50%;
background-size: 256px 256px;
background-position: center center;
vertical-align: middle;
line-height: 132px;
margin-left: 5px;
margin-bottom: 10px;
background-repeat: no-repeat;
box-shadow: 1px 1px 10px #000000;
}


div.vertical-spacer {
height:1px;
margin-bottom: 30px;
}

+ 25
- 0
src/app/profile/people-profile/people-profile.component.spec.ts Ver fichero

@@ -0,0 +1,25 @@
import { ComponentFixture, TestBed } from '@angular/core/testing';

import { PeopleProfileComponent } from './people-profile.component';

describe('PeopleProfileComponent', () => {
let component: PeopleProfileComponent;
let fixture: ComponentFixture<PeopleProfileComponent>;

beforeEach(async () => {
await TestBed.configureTestingModule({
declarations: [ PeopleProfileComponent ]
})
.compileComponents();
});

beforeEach(() => {
fixture = TestBed.createComponent(PeopleProfileComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});

it('should create', () => {
expect(component).toBeTruthy();
});
});

+ 79
- 0
src/app/profile/people-profile/people-profile.component.ts Ver fichero

@@ -0,0 +1,79 @@
import {Component, Input, OnInit, ViewChild} from '@angular/core';
import {MessageBoxComponent} from '../../message-box/message-box.component';
import {FileInfo, FileRestrictions, FileSelectComponent, SelectEvent} from '@progress/kendo-angular-upload';
import {AuthService} from '../../service/auth.service';
import {PeopleService} from '../../service/people.service';
import {NgForm} from '@angular/forms';
import {PeopleModel} from '../../models/people.model';

@Component({
selector: 'app-people-profile',
templateUrl: './people-profile.component.html',
styleUrls: ['./people-profile.component.scss']
})
export class PeopleProfileComponent implements OnInit {
@Input() PeopleId = '';
public People: PeopleModel = PeopleModel.EmptyNew();
public avatarUrl = 'url(https://svr2021.lawipac.com:8080/api/v1/avatar/1000)' ;
public myRestrictions: FileRestrictions = {
allowedExtensions: ['.jpg', '.png', '.jpeg'],
maxFileSize: 2194304
};
@ViewChild('messagebox', {static: true}) msgBox: MessageBoxComponent;
@ViewChild('fileSelect', {static: true}) fs: FileSelectComponent;

constructor(private auth: AuthService, private ps: PeopleService) { }

ngOnInit(): void {
this.People = this.auth.loggedIn.User;
this.avatarUrl = 'url(' + this.auth.getUrl('avatar/' + this.PeopleId) + ')';
this.avatarUrl = 'url(' + this.auth.getUrl('avatar/' + this.PeopleId) + ')';
}

onDialogClose(status: string): void {
console.log(status);
}

public onSelectAvatar(ev: SelectEvent): void {
if (ev.files) {
ev.files.every((file: FileInfo) => {
if (file.rawFile && !file.validationErrors) {
const reader = new FileReader();

reader.onloadend = () => {
const str = reader.result as string;

this.ps.updateAvatar(str, this.PeopleId).subscribe( resp => {
this.avatarUrl = 'url(' + str + ' )';
}, err => {
this.msgBox.Show('Failed to Update Avatar: ' + err.toString());
});
this.fs.clearFiles();
};
reader.readAsDataURL(file.rawFile);
}else{
this.msgBox.Show('Only jpg, and png are supported (max 2MB)');
setTimeout(() => { this.fs.clearFiles(); }, 10);
}
return false; // we only take first file
});
}
}


public save(peopleForm: NgForm): void{
if (! peopleForm.touched || peopleForm.form.pristine) {
this.msgBox.Show('Nothing has been changed');
return;
}
this.ps.saveUser(this.People).subscribe( () => {
this.msgBox.Show('Updated successfully ');
if ( this.auth.loggedIn.User.Id === this.People.Id ) {
this.auth.UpdatePeopleInfo(this.People);
}
peopleForm.form.markAsPristine();
}, err => {
this.msgBox.Show('Failed to Update: ' + err.toString());
});
}
}

+ 20
- 0
src/app/profile/profile.component.html Ver fichero

@@ -0,0 +1,20 @@


<div class="parent">
<div class="container settings">
<div class="row justify-content-center">
<div class="col-sm-12">
<app-people-profile #peopleProfile *ngIf="showPeople()" [PeopleId]="PeopleId" ></app-people-profile>
<div *ngIf="showUser()" class="vertical-spacer"> <hr></div>
<app-user-profile #userProfile *ngIf="showUser()" [PeopleId]="PeopleId" [showAdmin]="showAdmin()"></app-user-profile>
<div *ngIf="showBroker()" class="vertical-spacer"><hr></div>
<app-broker-profile #brokerProfile *ngIf="showBroker()" [PeopleId]="PeopleId" [showAdmin]="showAdmin()"></app-broker-profile>
<div *ngIf="showAdmin()" class="vertical-spacer"><hr></div>
<app-admin-profile #adminProfile *ngIf="showAdmin()" [PeopleId]="PeopleId" ></app-admin-profile>
<div *ngIf="showPassword()" class="vertical-spacer" ><hr></div>
<app-change-password #changePassword *ngIf="showPassword()" [PeopleId]="PeopleId" ></app-change-password>
</div>
</div>
</div>
</div>


+ 25
- 0
src/app/profile/profile.component.scss Ver fichero

@@ -0,0 +1,25 @@
div.parent {
display: table;
width: 100%;
height: 100vh;
opacity: 0.95;
background: url('/assets/img/bg-settings.jpg') no-repeat center center fixed;
background-size: cover;
}


.settings {
max-width: 800px;
text-align: center;
vertical-align: middle;
padding: 20px;
box-shadow: 0 0 6px black;
border-radius: 5px;
background-color: white;
margin: 10% auto 100px;
}

div.vertical-spacer {
height:1px;
margin-bottom: 30px;
}

+ 25
- 0
src/app/profile/profile.component.spec.ts Ver fichero

@@ -0,0 +1,25 @@
import { ComponentFixture, TestBed } from '@angular/core/testing';

import { ProfileComponent } from './profile.component';

describe('ProfileComponent', () => {
let component: ProfileComponent;
let fixture: ComponentFixture<ProfileComponent>;

beforeEach(async () => {
await TestBed.configureTestingModule({
declarations: [ ProfileComponent ]
})
.compileComponents();
});

beforeEach(() => {
fixture = TestBed.createComponent(ProfileComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});

it('should create', () => {
expect(component).toBeTruthy();
});
});

+ 63
- 0
src/app/profile/profile.component.ts Ver fichero

@@ -0,0 +1,63 @@
import {Component, Input, OnInit, ViewChild} from '@angular/core';
import {FormControl, FormGroup} from '@angular/forms';
import {AuthService} from '../service/auth.service';
import {PeopleService} from '../service/people.service';
import {PeopleProfileComponent} from './people-profile/people-profile.component';
import {BrokerProfileComponent} from './broker-profile/broker-profile.component';
import {UserProfileComponent} from './user-profile/user-profile.component';

@Component({
selector: 'app-profile',
templateUrl: './profile.component.html',
styleUrls: ['./profile.component.scss']
})
export class ProfileComponent implements OnInit {
@Input() PeopleId = '';
@ViewChild('peopleProfile', {static: true}) pp: PeopleProfileComponent;
@ViewChild('userProfile', {static: true}) up: UserProfileComponent;
@ViewChild('brokerProfile', {static: true}) bp: BrokerProfileComponent;

public role = 'client';

constructor(private auth: AuthService, private ps: PeopleService) { }

ngOnInit(): void {
this.role = this.auth.loggedIn.role;
this.PeopleId = this.auth.loggedIn.User.Id;
console.log('profile people id', this.PeopleId);
}


public showPeople(): boolean {
return true; // always true
}

public showUser(): boolean {
return this.isUser() || this.isBroker() || this.isAdmin();
}

public showBroker(): boolean {
return this.isBroker() && ! this.isAdmin();
}

public showAdmin(): boolean {
return this.isAdmin();
}

public showPassword(): boolean {
return this.isUser() || this.isBroker() || this.isAdmin();
}

public isAdmin(): boolean {
return this.auth.isAdmin();
}

public isBroker(): boolean {
return this.auth.isBroker();
}

public isUser(): boolean {
return this.auth.isUser();
}

}

+ 33
- 0
src/app/profile/user-profile/user-profile.component.html Ver fichero

@@ -0,0 +1,33 @@
<h5 *ngIf="canEditUser()" > <kendo-icon [name]="'ascx'" > </kendo-icon> &nbsp; Login Related </h5>

<form *ngIf="canEditUser()" class="k-form" #userForm="ngForm" (submit)="save(userForm)">
<ng-container >
<fieldset class="k-form-fieldset">
<kendo-formfield>
<kendo-label [for]="Login" text="Unique Login id:"></kendo-label>
<kendo-textbox kendoTextBox #Login name="Login" [(ngModel)]="UserExtra.Login"
[disabled] = "!showAdmin"
[showSuccessIcon]="UserExtra.Login.length >= 3 && UserExtra.Login.length <=44 "> </kendo-textbox>
<kendo-formerror>First name is required</kendo-formerror>
</kendo-formfield>
<div class="vertical-spacer"></div>

<kendo-formfield *ngIf="showAdmin ">
<label class="k-label">Allow Login &nbsp;
<input type="checkbox" name="enabled" kendoCheckBox
[(ngModel)]="UserExtra.Enabled" [disabled]="currentUserIsAdmin()"/>
</label>
</kendo-formfield>
<div class="vertical-spacer"></div>

</fieldset>
</ng-container>
<div class="k-form-buttons k-buttons-end">
<div>
<button kendoButton class="k-button k-primary" type="submit" icon="save"
[disabled]="userForm.form.status !=='VALID'"> Modify Login</button>
</div>
</div>
</form>

<app-message-box #messageBox ></app-message-box>

+ 0
- 0
src/app/profile/user-profile/user-profile.component.scss Ver fichero


+ 25
- 0
src/app/profile/user-profile/user-profile.component.spec.ts Ver fichero

@@ -0,0 +1,25 @@
import { ComponentFixture, TestBed } from '@angular/core/testing';

import { UserProfileComponent } from './user-profile.component';

describe('UserProfileComponent', () => {
let component: UserProfileComponent;
let fixture: ComponentFixture<UserProfileComponent>;

beforeEach(async () => {
await TestBed.configureTestingModule({
declarations: [ UserProfileComponent ]
})
.compileComponents();
});

beforeEach(() => {
fixture = TestBed.createComponent(UserProfileComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});

it('should create', () => {
expect(component).toBeTruthy();
});
});

+ 50
- 0
src/app/profile/user-profile/user-profile.component.ts Ver fichero

@@ -0,0 +1,50 @@
import {Component, Input, OnInit, ViewChild} from '@angular/core';
import {UserExtraModel} from '../../models/user-extra.model';
import {NgForm} from '@angular/forms';
import {AuthService} from '../../service/auth.service';
import {HttpClient} from '@angular/common/http';
import {MessageBoxComponent} from '../../message-box/message-box.component';

@Component({
selector: 'app-user-profile',
templateUrl: './user-profile.component.html',
styleUrls: ['./user-profile.component.scss']
})
export class UserProfileComponent implements OnInit {
@Input() public PeopleId = '';
@Input() public showAdmin: false;

public UserExtra: UserExtraModel = UserExtraModel.EmptyNew();
@ViewChild('messageBox', {static: true}) msgBox: MessageBoxComponent;

constructor(private auth: AuthService, private http: HttpClient) { }

ngOnInit(): void {
this.PeopleId = this.auth.loggedIn.User.Id;
this.UserExtra = this.auth.loggedIn.UserExtra;
}

public save(userForm: NgForm): void {
const expected = userForm.form.get('Login').value;
this.http.post<string>(this.auth.getUrl('user/' + this.PeopleId), this.UserExtra).subscribe(
resp => {
if ( resp === expected ) {
this.msgBox.Show('Successfully Changed');
}else{
this.msgBox.Show('Login not Changed: ' + resp );
}
}, err => {
this.msgBox.Show('Error Occurred' + err.toString());
}
);
}

public currentUserIsAdmin(): boolean {
return this.auth.loggedIn.role === 'admin';
}

public canEditUser(): boolean {
return this.UserExtra !== undefined && this.UserExtra.Login !== undefined;
}

}

+ 39
- 21
src/app/service/auth.service.ts Ver fichero

@@ -1,5 +1,5 @@
import {EventEmitter, Injectable, OnDestroy, OnInit} from '@angular/core';
import {HttpClient, HttpEvent, HttpHandler, HttpInterceptor, HttpParams, HttpRequest} from '@angular/common/http';
import {EventEmitter, Injectable} from '@angular/core';
import {HttpClient} from '@angular/common/http';
import {ApiV1LoginResponse} from '../models/api-v1-login-response';
import {Router} from '@angular/router';
import {PeopleModel} from '../models/people.model';
@@ -10,8 +10,8 @@ export class AuthService {

public apiUrl = 'https://svr2021.lawipac.com:8080/api/v1/';
public apiWsUrl = 'wss://svr2021.lawipac.com:8080/api/v1/ws';
//public apiUrl = 'https://c5016.biukop.com.au:8080/api/v1/';
//public apiWsUrl = 'wss://c5016.biukop.com.au:8080/api/v1/ws';
// public apiUrl = 'https://c5016.biukop.com.au:8080/api/v1/';
// public apiWsUrl = 'wss://c5016.biukop.com.au:8080/api/v1/ws';
public loggedIn = ApiV1LoginResponse.EmptyNew();
loginSuccess = new EventEmitter <ApiV1LoginResponse>();

@@ -32,11 +32,11 @@ export class AuthService {
sfm.session,
sfm.sessionExpire,
sfm.role,
new PeopleModel(sfm.user.Id, sfm.user.First, sfm.user.Last, sfm.user.Middle, sfm.user.Title, sfm.user.Display, sfm.user.Nick)
new PeopleModel(sfm.User.Id, sfm.User.First, sfm.User.Last, sfm.User.Middle, sfm.User.Title, sfm.User.Display, sfm.User.Nick)
);

if ( sfm.userExtra !== undefined ) {
this.loggedIn.userExtra = new UserExtraModel(sfm.userExtra);
if ( sfm.UserExtra !== undefined ) {
this.loggedIn.UserExtra = new UserExtraModel(sfm.UserExtra);
}

this.loginSuccess.emit(this.loggedIn);
@@ -66,30 +66,29 @@ export class AuthService {
this.loggedIn.machineId = responseData['Biukop-Mid'];
this.loggedIn.sessionExpire = responseData.sessionExpire;
this.loggedIn.role = responseData.role;
if ( responseData.user !== undefined) {
this.loggedIn.user = new PeopleModel(
responseData.user.Id,
responseData.user.First,
responseData.user.Last,
responseData.user.Middle,
responseData.user.Title,
responseData.user.Display,
responseData.user.Nick
if ( responseData.User !== undefined) {
this.loggedIn.User = new PeopleModel(
responseData.User.Id,
responseData.User.First,
responseData.User.Last,
responseData.User.Middle,
responseData.User.Title,
responseData.User.Display,
responseData.User.Nick
);

if (responseData.userExtra !== undefined ) {
this.loggedIn.userExtra = new UserExtraModel(responseData.userExtra);
if (responseData.UserExtra !== undefined ) {
this.loggedIn.UserExtra = new UserExtraModel(responseData.UserExtra);
}
}else{
this.loggedIn.user = PeopleModel.EmptyNew();
this.loggedIn.User = PeopleModel.EmptyNew();
}

this.saveSessionInfo();
this.loginSuccess.emit(responseData);
},
error => {
const fail = ApiV1LoginResponse.EmptyNew();
this.loggedIn = fail;
this.loggedIn = ApiV1LoginResponse.EmptyNew();
console.log('login error', error);
this.loginSuccess.emit(this.loggedIn);
}
@@ -131,4 +130,23 @@ export class AuthService {
// not found if arrive here
return s;
}

public UpdatePeopleInfo(people: PeopleModel): void{
this.loggedIn.User.Display = people.Display;
this.loggedIn.User.First = people.First;
this.loggedIn.User.Last = people.Last;
this.saveSessionInfo();
}

public isAdmin(): boolean {
return this.loggedIn.role === 'admin';
}

public isBroker(): boolean {
return this.loggedIn.role === 'broker';
}

public isUser(): boolean {
return this.loggedIn.login === true;
}
}

+ 10
- 2
src/app/service/menu.service.ts Ver fichero

@@ -1,9 +1,17 @@
import { EventEmitter, Injectable } from '@angular/core';
import {HttpClient} from '@angular/common/http';
import {AuthService} from './auth.service';
import {ClonerService} from './clone.service';
import {Router} from '@angular/router';


@Injectable()
export class MenuService {

itemClicked = new EventEmitter <any>();

itemClicked = new EventEmitter <any>();
constructor(auth: AuthService, private router: Router ){ }
// display profile editing based on current user
public showProfile(): void {
this.router.navigate(['/profile']);
}
}

+ 44
- 1
src/app/settings/settings.component.html Ver fichero

@@ -1 +1,44 @@
<p>settings works!</p>
<div class="parent">
<div class="container settings">
<div class="row justify-content-center">
<div class="col-6">
<kendo-switch [(ngModel)]="changeAdminPassword" ngModelOptions="{standalone: true}" (valueChange)="hideAdminPass()"> </kendo-switch> Change Admin Password
<div class="vertical-spacer"></div>
<form *ngIf="changeAdminPassword" [formGroup]="ChangeAdminPassForm" class="k-form" (submit)="saveAdminPassword()">
<kendo-formfield>
<kendo-label [for]="OldPassword" text="Current Password"></kendo-label>
<input kendoTextBox #OldPassword name="OldPassword" formControlName="OldPassword"
type="password" [minlength]="3" [maxlength]="25" />
<kendo-formerror>Current password is needed (3-20 chars)</kendo-formerror>
</kendo-formfield>

<kendo-formfield>
<kendo-label [for]="NewPass" text="New Password"></kendo-label>
<input kendoTextBox #NewPass name="NewPass" formControlName="NewPass"
[minlength]="3" [maxlength]="25" type="password" />
<kendo-formerror>New password is needed (3-20 chars)</kendo-formerror>
</kendo-formfield>

<kendo-formfield>
<kendo-label [for]="NewPass1" text="New Password (repeat) "></kendo-label>
<input kendoTextBox #NewPass1 name="NewPass1" formControlName="NewPass1"
[minlength]="3" [maxlength]="25" type="password" />

<kendo-formerror>New password repeat is needed (3-20 chars) </kendo-formerror>
</kendo-formfield>
<div class="vertical-spacer"></div>

<button *ngIf="adminPasswordEqual() && ! ChangeAdminPassForm.invalid" kendoButton class="k-button k-primary" type="submit" icon="save"> Change Password </button>
</form>
</div>
</div>
</div>
</div>

<kendo-dialog title="Message " *ngIf="opened" (close)="close('cancel')" [minWidth]="250" [width]="450">
<p style="margin: 30px; text-align: center;">{{ Message }}</p>
<kendo-dialog-actions>
<button kendoButton (click)="close('Ok, I got it')" primary="true">Yes</button>
</kendo-dialog-actions>
</kendo-dialog>


+ 22
- 0
src/app/settings/settings.component.scss Ver fichero

@@ -0,0 +1,22 @@
div.parent {
display: table;
width: 100%;
height: 100vh;
opacity: 0.95;
background: url('/assets/img/bg-settings.jpg') no-repeat center center fixed;
background-size: cover;
}


.settings {
margin-left: auto;
margin-right: auto;
margin-top: 10%;
max-width: 600px;
text-align: center;
vertical-align: middle;
padding: 20px;
box-shadow: 0 0 6px black;
border-radius: 5px;
background-color: white;
}

+ 50
- 1
src/app/settings/settings.component.ts Ver fichero

@@ -1,4 +1,7 @@
import { Component, OnInit } from '@angular/core';
import {AuthService} from '../service/auth.service';
import {PeopleService} from '../service/people.service';
import {FormControl, FormGroup} from '@angular/forms';

@Component({
selector: 'app-settings',
@@ -6,10 +9,56 @@ import { Component, OnInit } from '@angular/core';
styleUrls: ['./settings.component.scss']
})
export class SettingsComponent implements OnInit {
public changeAdminPassword = false;
public opened = false; // dialog box
public Message = ''; // dialog message

constructor() { }
public ChangeAdminPassForm: FormGroup = new FormGroup({
OldPassword: new FormControl(),
NewPass: new FormControl(),
NewPass1: new FormControl(),
});
constructor(private auth: AuthService, private ps: PeopleService) { }

ngOnInit(): void {
setTimeout(() => {
this.changeAdminPassword = true;
}, 1000);
}


public hideAdminPass(): void{
if ( this.changeAdminPassword ) {
this.ChangeAdminPassForm.reset();
}
}

public saveAdminPassword(): void{
this.ps.savePassword('0', this.ChangeAdminPassForm.value).subscribe(
() => {
this.showDialog('Password Changed');
}, err => {
this.showDialog('Failed to Change Password :' + err.toString());
}
);
}

public adminPasswordEqual(): boolean{
const v = this.ChangeAdminPassForm.value;
if ( this.ChangeAdminPassForm.valid && v.NewPass === v.NewPass1 && this.ChangeAdminPassForm.touched && v.NewPass1 !== '') {
return true;
}else{
this.ChangeAdminPassForm.controls['NewPass1'].setErrors({'incorrect': true});
}
return false;
}

public showDialog(msg: string): void {
this.Message = msg;
this.opened = true; // open dialog
}

public close(status): void {
this.opened = false;
}
}

+ 6
- 3
src/app/top-bar/top-bar.component.html Ver fichero

@@ -1,7 +1,10 @@
<kendo-appbar id='topBar' *ngIf='login && showMenu' class='appbar' [position]="'top'" [positionMode]="'sticky'">
<kendo-appbar-section *ngIf="LoggedInUser && LoggedInUser.Id !==''">
<kendo-avatar [imageSrc]="loggedInUserAvatar()" [shape]="'circle'" [width]="'26px'" [height]="'26px'" (click)="logout()"></kendo-avatar>
<span>{{LoggedInUser.Display}}</span>
<kendo-avatar [imageSrc]="loggedInUserAvatar()" class="k-cursor-pointer"
[shape]="'circle'" [width]="'26px'" [height]="'26px'" (click)="profile()">

</kendo-avatar>
<span class="k-cursor-pointer" (click)="profile()">{{LoggedInUser.Display}}</span>
</kendo-appbar-section>
<span class="k-appbar-separator"></span>

@@ -32,7 +35,7 @@


<kendo-appbar-section>
<kendo-avatar [imageSrc]="Avatar" [shape]="'circle'" [width]="'26px'" [height]="'26px'" (click)="logout()"></kendo-avatar>
<kendo-avatar class="k-cursor-pointer" [imageSrc]="Avatar" [shape]="'circle'" [width]="'26px'" [height]="'26px'" (click)="logout()"></kendo-avatar>
</kendo-appbar-section>
</kendo-appbar>


+ 8
- 4
src/app/top-bar/top-bar.component.ts Ver fichero

@@ -29,20 +29,20 @@ export class TopBarComponent implements OnInit , OnDestroy {

ngOnInit(): void {
this.initAndSubLogin();
console.log(this);
}

public initAndSubLogin(): void{
this.login = this.authService.loggedIn.login;
this.LoggedInUser = this.authService.loggedIn.user;
this.LoggedInUser = this.authService.loggedIn.User;

this.selectMenuShow(this.authService.loggedIn.role);

this.loginSub = this.authService.loginSuccess.subscribe(
(rsp: ApiV1LoginResponse) => {
this.login = rsp.login;
this.LoggedInUser = this.authService.loggedIn.user;
this.LoggedInUser = this.authService.loggedIn.User;
this.selectMenuShow(rsp.role);

}
);
}
@@ -102,7 +102,11 @@ export class TopBarComponent implements OnInit , OnDestroy {
}

public loggedInUserAvatar(): string {
return this.authService.getUrl('avatar/') + this.authService.loggedIn.user.Id;
return this.authService.getUrl('avatar/') + this.authService.loggedIn.User.Id;
}

public profile(): void {
this.menuService.showProfile();
}

}

BIN
src/assets/bg.jpg Ver fichero

Antes Después
Anchura: 792  |  Altura: 552  |  Tamaño: 52KB

BIN
src/assets/img/bg-settings.jpg Ver fichero

Antes Después
Anchura: 1920  |  Altura: 1080  |  Tamaño: 239KB

Cargando…
Cancelar
Guardar