Projekt

Obecné

Profil

« Předchozí | Další » 

Revize 9c7b1b63

Přidáno uživatelem Václav Jirák před téměř 6 roky(ů)

Re #7462 Dashboard connected to GET methods of REST API

Zobrazit rozdíly:

webapp/src/app/dashboard/employer-dashboard/employer-dashboard.component.html
2 2
  <div class="row">
3 3
    <div class="col-lg-8 mid-panel">
4 4

  
5
      <div *ngIf="usersToApprove.length > 0" class="employer-dashboard-user-approval">
5
      <div class="employer-dashboard-user-approval" *ngIf="authorizationRequests && authorizationRequests.authorization.length > 0">
6 6
        <app-user-approval
7
          [usersToApprove]="usersToApprove"
8
          (userApprovedAction)="userApproved($event.user, $event.approved)"
7
          [authorizationRequests]="authorizationRequests"
8
          (userApprovalEvent)="userApproved($event.requestId, $event.approved)"
9 9
        ></app-user-approval>
10 10
      </div>
11 11

  
12
      <div *ngIf="daysOffToApprove.length > 0" class="employer-dashboard-days-off-approval">
12
      <div class="employer-dashboard-days-off-approval" *ngIf="daysOffRequests && daysOffRequests.vacation.length > 0">
13 13
        <app-days-off-approval
14
          [daysOffToApprove]="daysOffToApprove"
15
          (daysOffApprovalAction)="daysOffApproved($event.daysOff, $event.approved)"
14
          [daysOffRequests]="daysOffRequests"
15
          (daysOffApprovalEvent)="daysOffApproved($event.requestId, $event.approved)"
16 16
        ></app-days-off-approval>
17 17
      </div>
18 18

  
19
      <div *ngIf="oncomingDaysOff.length > 0" class="employer-dashboard-coming-days-off">
20
        <app-coming-days-off
21
          [oncomingDaysOff]="oncomingDaysOff"
22
          (daysOffRemovedAction)="daysOffRemoved($event.daysOff)"
23
        ></app-coming-days-off>
24
      </div>
19
<!--      TODO odkomentovat, až bude komponenta hotova -->
20
<!--      <div class="employer-dashboard-coming-days-off">-->
21
<!--        <app-coming-days-off></app-coming-days-off>-->
22
<!--      </div>-->
25 23

  
26 24
      <div class="employer-dashboard-day-picker">
27 25
        <app-day-picker
......
33 31

  
34 32
    <div class="col-lg-4 right-panel">
35 33

  
36
      <app-days-off-info
37
        [sickDaysRemaining]="5"
38
        [extraVacationRemaining]="10"
39
      ></app-days-off-info>
34
      <div class="days-off-info" *ngIf="profile">
35
        <app-days-off-info
36
          [sickDaysRemaining]="profile.sickDay"
37
          [extraVacationRemaining]="profile.vacation"
38
        ></app-days-off-info>
39
      </div>
40 40

  
41 41
    </div>
42 42
  </div>
webapp/src/app/dashboard/employer-dashboard/employer-dashboard.component.ts
1
import { Component, OnInit } from '@angular/core';
2
import { UserToApprove } from '../../user-approval/user-to-approve.model';
3
import { DaysOff } from '../../shared/days-off.model';
4
import { OffDayType } from '../../shared/off-day-type';
1
import {Component, Input, OnInit} from '@angular/core';
5 2
import { MatDialog } from '@angular/material';
6 3
import { AddDaysOffDialogComponent } from '../../add-days-off-dialog/add-days-off-dialog.component';
4
import {UsersService} from '../../services/users.service';
5
import {Requests} from '../../models/requests.model';
6
import {UserProfile} from '../../models/user-profile.model';
7
import {UserService} from '../../services/user.service';
8
import {ProfileService} from "../../services/profile.service";
7 9

  
8 10
@Component({
9 11
  selector: 'app-employer-dashboard',
......
12 14
})
13 15
export class EmployerDashboardComponent implements OnInit {
14 16

  
15
  usersToApprove: UserToApprove[] = [
16
    { date: new Date(), email: 'kek@kek.cz', name: 'Václav Jirák' },
17
    { date: new Date(), email: 'kuadas@kek.cz', name: 'Věnceslav Kárij' }
18
  ];
17
  @Input() profile: UserProfile;
18
  private authorizationRequests: Requests;
19
  private daysOffRequests: Requests;
19 20

  
20
  daysOffToApprove: DaysOff[] = [
21
    { username: 'Václav Jirák', dateFrom: new Date(2019, 10, 13), dateTo: new Date(), type: OffDayType.Sickday },
22
    { username: 'Václav Jirák', dateFrom: new Date(2019, 10, 1), dateTo: new Date(), type: OffDayType.ExtraVacation },
23
  ];
24

  
25
  daysOff: DaysOff[] = [
26
    {
27
      username: '',
28
      dateFrom: new Date(2019, 5, 5),
29
      dateTo: new Date(2019, 5, 6),
30
      type: OffDayType.ExtraVacation
31
    },
32
    {
33
      username: '',
34
      dateFrom: new Date(2019, 5, 8),
35
      dateTo: new Date(2019, 5, 8),
36
      type: OffDayType.Sickday
37
    },
38
    {
39
      username: '',
40
      dateFrom: new Date(2019, 3, 8),
41
      dateTo: new Date(2019, 3, 9),
42
      type: OffDayType.Sickday
43
    },
44
  ];
45

  
46
  oncomingDaysOff: DaysOff[] = [];
47

  
48
  constructor(public dialog: MatDialog) { }
21
  constructor(
22
    public dialog: MatDialog,
23
    private profileService: ProfileService,
24
    // API
25
    private userService: UserService,
26
    private usersService: UsersService
27
  ) { }
49 28

  
50 29
  ngOnInit() {
51
    this.oncomingDaysOff = this.calculateComingDaysOff();
52
  }
30
    this.profileService.getProfile()
31
      .subscribe((data: UserProfile) => this.profile = data);
53 32

  
54
  onDateSelect( date: Date ) {
55
    this.dialog.open(AddDaysOffDialogComponent, {
56
      data: {
57
        fromDate: date
58
      }
59
    });
60
  }
33
    this.usersService.getAuthorizationRequests()
34
      .subscribe((data: Requests) => this.authorizationRequests = data);
61 35

  
62
  userApproved( user: UserToApprove, approved: boolean ) {
63
    console.log(user.name + ' - approved: ' + approved);
64
    this.usersToApprove.splice(
65
      this.usersToApprove.indexOf(user), 1
66
    );
36
    this.usersService.getVacationRequests()
37
      .subscribe((data: Requests) => this.daysOffRequests = data);
67 38
  }
68 39

  
69
  daysOffApproved(daysOff: DaysOff, approved: boolean) {
70
    console.log(daysOff.username + ', ' + approved);
71
    this.daysOffToApprove.splice(
72
      this.daysOffToApprove.indexOf(daysOff), 1
73
    );
40
  private userApproved(requestId: number, approved: boolean) {
41
    // TODO api post call
42
    this.authorizationRequests.authorization.splice(0, 1);
74 43
  }
75 44

  
76
  daysOffRemoved(daysOff: DaysOff) {
77
    this.daysOff.splice(
78
      this.daysOff.indexOf(daysOff), 1
79
    );
80
    this.oncomingDaysOff.splice(
81
      this.oncomingDaysOff.indexOf(daysOff), 1
82
    );
45
  private daysOffApproved(requestId: number, approved: boolean) {
46
    // TODO api post call
47
    this.daysOffRequests.vacation.splice(0, 1);
83 48
  }
84 49

  
85
  private calculateComingDaysOff(): DaysOff[] {
86
    let oncomingDaysOff: DaysOff[] = [];
87

  
88
    const today = new Date();
89
    this.daysOff.forEach((dayOff) => {
90
      if (dayOff.dateTo >= today) {
91
        oncomingDaysOff.push(dayOff);
50
  onDateSelect( date: Date ) {
51
    this.dialog.open(AddDaysOffDialogComponent, {
52
      data: {
53
        fromDate: date
92 54
      }
93 55
    });
94

  
95
    return oncomingDaysOff;
96 56
  }
97 57
}
webapp/src/app/days-off-approval/days-off-approval.component.html
1
<div class="days-off-approval-container">
1
<div class="days-off-approval-container" *ngIf="daysOffRequests">
2 2

  
3 3
  <div class="component-header">
4 4
    Schvalování volna
......
8 8
    <div class="row days-off-approval-header">
9 9
      <div class="col-md-3"> Jméno </div>
10 10
      <div class="col-md-3"> Typ volna </div>
11
      <div class="col-md-2"> Od </div>
12
      <div class="col-md-2"> Do </div>
11
      <div class="col-md-2"> Datum </div>
12
      <div class="col-md-1"> Od </div>
13
      <div class="col-md-1"> Do </div>
13 14
      <div class="col-md-2"></div>
14 15
    </div>
15 16

  
16
    <div class="row days-off-approval" *ngFor="let daysOff of daysOffToApprove">
17
    <div class="row days-off-approval" *ngFor="let request of daysOffRequests.vacation">
17 18
      <div class="col-md-3">
18
        {{daysOff.username}}
19
        {{request.user.name.first}} {{request.user.name.last}}
19 20
      </div>
20

  
21 21
      <div class="col-md-3">
22
        {{daysOffTypeToString(daysOff.type)}}
22
        {{daysOffTypeToString(request.type)}}
23 23
      </div>
24

  
25 24
      <div class="col-md-2">
26
        {{daysOff.dateFrom | date:'yyyy/MM/dd'}}
25
        {{request.date | date:'yyyy/MM/dd'}}
27 26
      </div>
28
      <div class="col-md-2">
29
        {{daysOff.dateTo | date:'yyyy/MM/dd'}}
27
      <div class="col-md-1">
28
        {{request.from}} <!-- TODO lepší formatting -->
29
      </div>
30
      <div class="col-md-1">
31
        {{request.to}} <!-- TODO lepší formatting -->
30 32
      </div>
31 33
      <div class="col-md-2">
32
        <div class="btn btn-success approve-btn" (click)="daysOffApprovalCompleted(daysOff, true)">✓</div>
33
        <div class="btn btn-danger reject-btn"   (click)="daysOffApprovalCompleted(daysOff, false)">X</div>
34
        <div class="btn btn-success approve-btn" (click)="daysOffApprovalCompleted(request.id, true)">✓</div>
35
        <div class="btn btn-danger reject-btn"   (click)="daysOffApprovalCompleted(request.id, false)">X</div>
34 36
      </div>
35 37
    </div>
36 38
  </div>
webapp/src/app/days-off-approval/days-off-approval.component.ts
1
import { Component, EventEmitter, Input, OnInit, Output } from '@angular/core';
2
import { DaysOff } from '../shared/days-off.model';
3
import { OffDayType } from '../shared/off-day-type';
1
import { Component, EventEmitter, Output, Input } from '@angular/core';
2
import {Requests} from '../models/requests.model';
3
import {VacationType} from '../enums/common.enum';
4 4

  
5 5
@Component({
6 6
  selector: 'app-days-off-approval',
7 7
  templateUrl: './days-off-approval.component.html',
8 8
  styleUrls: ['./days-off-approval.component.sass']
9 9
})
10
export class DaysOffApprovalComponent implements OnInit {
10
export class DaysOffApprovalComponent {
11 11

  
12
  @Input()  daysOffToApprove: DaysOff[];
13
  @Output() daysOffApprovalAction = new EventEmitter<{daysOff: DaysOff, approved: boolean}>();
12
  @Input() daysOffRequests: Requests;
13
  @Output() daysOffApprovalEvent = new EventEmitter<{requestId: number, approved: boolean}>();
14 14

  
15 15
  constructor() { }
16 16

  
17
  ngOnInit() {
17
  daysOffApprovalCompleted(reqId: number, isApproved: boolean ) {
18
    this.daysOffApprovalEvent.emit({requestId: reqId, approved: isApproved});
18 19
  }
19 20

  
20
  daysOffApprovalCompleted(daysOffApproved: DaysOff, isApproved: boolean ) {
21
    this.daysOffApprovalAction.emit({daysOff: daysOffApproved, approved: isApproved});
22
  }
23

  
24
  private daysOffTypeToString(taskType: OffDayType): string {
25
    switch (taskType) {
26
      case OffDayType.ExtraVacation:
21
  private daysOffTypeToString(vacationType: VacationType): string {
22
    switch (vacationType) {
23
      case VacationType.VACATION:
27 24
        return 'Extra dovolená';
28
      case OffDayType.Sickday:
25
      case VacationType.SICKDAY:
29 26
        return 'Sickdays';
30 27
    }
31 28
  }
webapp/src/app/days-off-info/days-off-info.component.html
5 5
  </div>
6 6

  
7 7
  <div class="days-off-type-container">
8
    <span class="days-off-remaining">{{extraVacationRemaining}}</span>
8
    <span class="days-off-remaining">{{extraVacationRemaining.value}}</span>
9
    <!--    TODO vypsat jednotky (.unit)-->
9 10
    <span class="days-off-type">Extra dovolená</span>
10 11
  </div>
11 12

  
12 13
  <div class="days-off-type-container">
13
    <span class="days-off-remaining">{{sickDaysRemaining}}</span>
14
    <span class="days-off-remaining">{{sickDaysRemaining.value}}</span>
15
    <!--    TODO vypsat jednotky (.unit)-->
14 16
    <span class="days-off-type">Sickdays</span>
15 17
  </div>
16 18

  
webapp/src/app/days-off-info/days-off-info.component.ts
1 1
import { Component, Input } from '@angular/core';
2
import {TimeUnit} from "../enums/common.enum";
2 3

  
3 4
@Component({
4 5
  selector: 'app-days-off-info',
......
7 8
})
8 9
export class DaysOffInfoComponent {
9 10

  
10
  @Input() sickDaysRemaining: number;
11
  @Input() sickDaysRemaining: {
12
    value: number;
13
    unit: TimeUnit;
14
  };
11 15

  
12
  @Input() extraVacationRemaining: number;
16
  @Input() extraVacationRemaining: {
17
    value: number;
18
    unit: TimeUnit;
19
  };
13 20

  
14 21
  constructor() { }
15 22
}
webapp/src/app/header/header.component.ts
1 1
import { Component, Input } from '@angular/core';
2 2
import { MatDialog } from '@angular/material';
3 3
import { ProfileSettingsComponent } from '../profile-settings/profile-settings.component';
4
import { ProfileService } from '../services/profile.service';
5
import { UserProfile } from '../models/user-profile.model';
4 6

  
5 7
@Component({
6 8
  selector: 'app-header',
......
10 12
export class HeaderComponent {
11 13
  @Input() name = 'John Doe';
12 14

  
13
  constructor(private dialog: MatDialog) { }
15
  private notificationSettings: Date;
16

  
17
  constructor(
18
    private dialog: MatDialog,
19
    private profileService: ProfileService
20
    ) {
21
    profileService.getProfile()
22
      .subscribe((data: UserProfile) => this.notificationSettings = new Date(data.settings.notification));
23
  }
14 24

  
15 25
  onProfileClick(): void {
16 26
    this.dialog.open(ProfileSettingsComponent, {
17 27
      data: {
28
        shouldNotify: this.notificationSettings, // TODO potřeba?
29
        notifyDate: this.notificationSettings,
30
        notifyTime: {
31
          hour: this.notificationSettings.getHours(),
32
          minute: this.notificationSettings.getMinutes()
33
        }
18 34
      }
19 35
    });
20 36
  }
webapp/src/app/oncoming-days-off/oncoming-days-off.component.html
22 22
      </div>
23 23
    </div>
24 24

  
25
    <div class="row oncoming-days-off" *ngFor="let daysOff of oncomingDaysOff">
26
      <div class="col-md-6">
27
        {{offDayTypeToString(daysOff.type)}}
28
      </div>
29

  
30
      <div class="col-md-2">
31
        {{daysOff.dateFrom | date:'yyyy/MM/dd'}}
32
      </div>
33

  
34
      <div class="col-md-2">
35
        {{daysOff.dateTo | date:'yyyy/MM/dd'}}
36
      </div>
37

  
38
      <div class="col-md-2">
39
        <div class="btn btn-danger reject-btn" (click)="daysOffRemoved(daysOff)">X</div>
40
      </div>
41
    </div>
25
<!--    <div class="row oncoming-days-off" *ngFor="let daysOff of oncomingDaysOff">-->
26
<!--      <div class="col-md-6">-->
27
<!--        {{offDayTypeToString(daysOff.type)}}-->
28
<!--      </div>-->
29

  
30
<!--      <div class="col-md-2">-->
31
<!--        {{daysOff.dateFrom | date:'yyyy/MM/dd'}}-->
32
<!--      </div>-->
33

  
34
<!--      <div class="col-md-2">-->
35
<!--        {{daysOff.dateTo | date:'yyyy/MM/dd'}}-->
36
<!--      </div>-->
37

  
38
<!--      <div class="col-md-2">-->
39
<!--        <div class="btn btn-danger reject-btn" (click)="daysOffRemoved(daysOff)">X</div>-->
40
<!--      </div>-->
41
<!--    </div>-->
42 42
  </div>
43 43

  
44 44
</div>
webapp/src/app/oncoming-days-off/oncoming-days-off.component.ts
1
import {Component, EventEmitter, Input, OnInit, Output} from '@angular/core';
2
import {DaysOff} from '../shared/days-off.model';
3
import {OffDayType} from '../shared/off-day-type';
1
import {Component, OnInit} from '@angular/core';
2
import {UserService} from '../services/user.service';
3
import {VacationType} from '../enums/common.enum';
4 4

  
5 5
@Component({
6 6
  selector: 'app-coming-days-off',
......
9 9
})
10 10
export class OncomingDaysOffComponent implements OnInit {
11 11

  
12
  @Input()  oncomingDaysOff: DaysOff[];
13
  @Output() daysOffRemovedAction = new EventEmitter<{daysOff: DaysOff}>();
14

  
15
  constructor() { }
12
  constructor(
13
    private userService: UserService
14
  ) { }
16 15

  
17 16
  ngOnInit() {
17
    // TODO api call na získání nadcházejících voln
18 18
  }
19 19

  
20
  private daysOffRemoved( removedDaysOff: DaysOff ) {
21
    this.daysOffRemovedAction.emit( {daysOff: removedDaysOff } );
20
  private daysOffRemoved( daysOffId: number ) {
21
    // TODO api call na odstranění nadcházejícího volna
22 22
  }
23 23

  
24
  // TODO možná zbytečný - bude api call na získání nadcházejících voln
25
  // private calculateComingDaysOff(): DaysOff[] {
26
  //   let oncomingDaysOff: DaysOff[] = [];
27
  //
28
  //   const today = new Date();
29
  //   this.daysOff.forEach((dayOff) => {
30
  //     if (dayOff.dateTo >= today) {
31
  //       oncomingDaysOff.push(dayOff);
32
  //     }
33
  //   });
34
  //
35
  //   return oncomingDaysOff;
36
  // }
37

  
24 38
  // TODO
25 39
  //  days-off-approval duplicate
26
  private offDayTypeToString(taskType: OffDayType): string {
27
    switch (taskType) {
28
      case OffDayType.ExtraVacation:
40
  private daysOffTypeToString(vacationType: VacationType): string {
41
    switch (vacationType) {
42
      case VacationType.VACATION:
29 43
        return 'Extra dovolená';
30
      case OffDayType.Sickday:
44
      case VacationType.SICKDAY:
31 45
        return 'Sickdays';
32 46
    }
33 47
  }
webapp/src/app/services/profile.service.ts
1
import { Injectable } from '@angular/core';
2
import {UserProfile} from '../models/user-profile.model';
3
import {UserService} from './user.service';
4
import {Observable} from 'rxjs';
5

  
6
@Injectable({
7
  providedIn: 'root'
8
})
9
export class ProfileService {
10
  private profile: UserProfile;
11

  
12
  constructor(
13
    private userService: UserService
14
  ) {
15
    userService.getEmployeeProfile(1)
16
      .subscribe((data: UserProfile) => this.profile = data);
17
  }
18

  
19
  getProfile(): Observable<UserProfile> {
20
    return new Observable((observer) => {
21
      if (this.profile) {
22
        observer.next(this.profile);
23
        observer.complete();
24
      } else {
25
        this.userService.getEmployeeProfile(1) // TODO zmenit id na prihlaseneho uzivatele
26
          .subscribe((data: UserProfile) => {
27
            this.profile = data;
28
            observer.next(this.profile);
29
            observer.complete();
30
          });
31
      }
32
    });
33
  }
34

  
35
}
webapp/src/app/shared/days-off.model.ts
1
import { OffDayType } from './off-day-type';
2

  
3
export class DaysOff {
4
  username: string;
5
  dateFrom: Date;
6
  dateTo: Date;
7
  type: OffDayType;
8
}
webapp/src/app/shared/off-day-type.ts
1
export enum OffDayType {
2
  ExtraVacation,
3
  Sickday
4
}
webapp/src/app/user-approval/user-approval.component.html
4 4
    Schvalování uživatelů
5 5
  </div>
6 6

  
7
  <div class="user-approval-list">
8
    <div class="row user-to-approve-container" *ngFor="let user of usersToApprove">
9
      <div class="col-md-4">
10
        {{user.name}}
11
      </div>
12
      <div class="col-md-4">
13
        {{user.email}}
7
  <div class="row user-approval-header">
8
    <div class="col-md-5"> Jméno </div>
9
    <div class="col-md-5"> Datum žádosti </div>
10
    <div class="col-md-2"></div>
11
  </div>
12

  
13
  <div class="user-approval-list" *ngIf="authorizationRequests">
14
    <div class="row user-to-approve-container" *ngFor="let request of authorizationRequests.authorization">
15
      <div class="col-md-5">
16
        {{request.user.name.first}} {{request.user.name.last}}
14 17
      </div>
15
      <div class="col-md-2">
16
        {{user.date | date:'yyyy/MM/dd'}}
18
      <div class="col-md-5">
19
        {{request.date | date:'yyyy/MM/dd'}}
17 20
      </div>
18 21
      <div class="col-md-2">
19
        <div class="btn btn-success approve-user-btn" (click)="userApproved(user, true)">✓</div>
20
        <div class="btn btn-danger reject-user-btn"   (click)="userApproved(user, false)">X</div>
22
        <div class="btn btn-success approve-user-btn" (click)="userApproved(request.id, true)">✓</div>
23
        <div class="btn btn-danger reject-user-btn"   (click)="userApproved(request.id, false)">X</div>
21 24
      </div>
22 25
    </div>
23 26
  </div>
webapp/src/app/user-approval/user-approval.component.sass
3 3
.user-approval-container
4 4
  @extend .basic-component
5 5

  
6
  .user-approval-header
7
    padding: 10px
8
    margin: 0
9
    font-weight: bold
10

  
6 11
  .user-to-approve-container
7 12
    border-bottom: 1px solid gainsboro
8 13
    margin: 0
webapp/src/app/user-approval/user-approval.component.ts
1
import { Component, EventEmitter, Input, Output } from '@angular/core';
2
import { UserToApprove } from './user-to-approve.model';
3

  
1
import {Component, EventEmitter, Input, Output} from '@angular/core';
2
import {Requests} from '../models/requests.model';
4 3

  
5 4
@Component({
6 5
  selector: 'app-user-approval',
......
9 8
})
10 9
export class UserApprovalComponent {
11 10

  
12
  @Input()  usersToApprove: UserToApprove[];
13
  @Output() userApprovedAction = new EventEmitter<{user: UserToApprove, approved: boolean}>();
11
  @Input() authorizationRequests: Requests;
12
  @Output() userApprovalEvent = new EventEmitter<{requestId: number, approved: boolean}>();
14 13

  
15 14
  constructor() { }
16 15

  
17
  userApproved(approvedUser: UserToApprove, isApproved: boolean) {
18
    this.userApprovedAction.emit({user: approvedUser, approved: isApproved});
16
  private userApproved(reqId: number, isApproved: boolean) {
17
    this.userApprovalEvent.emit({requestId: reqId, approved: isApproved});
19 18
  }
20

  
21 19
}
webapp/src/app/user-approval/user-to-approve.model.ts
1
export class UserToApprove {
2
  name: string;
3
  email: string;
4
  date: Date;
5
}
webapp/src/environments/environment.ts
1 1
export const environment = {
2 2
  production: false,
3
  apiUrl: 'http://localhost:9080/'
3
  apiUrl: 'http://192.168.99.100:9080/'
4 4
};

Také k dispozici: Unified diff