Projekt

Obecné

Profil

« Předchozí | Další » 

Revize 558c8d57

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

Frontend refactored

Zobrazit rozdíly:

webapp/src/app/add-vacation-dialog/add-vacation-dialog.component.html
1
<h1 mat-dialog-title>{{ 'addVacation.headline' | translate }}</h1>
2

  
3
<div mat-dialog-content>
4
  <div class="vacation-selection-container">
5
    <label id="vacation-type-radio-group-label" class="dialog-label">{{ 'basic.vacationType' | translate }}</label>
6
    <mat-radio-group aria-labelledby="vacation-type-radio-group-label" class="vacation-type-radio-group" [(ngModel)]="selectedVacationType">
7
      <mat-radio-button class="vacation-type-radio-button" [value]=vacationType.SICKDAY>
8
        {{ vacationType.SICKDAY | translate }}
9
      </mat-radio-button>
10
      <mat-radio-button class="vacation-type-radio-button" [value]=vacationType.VACATION>
11
        {{ vacationType.VACATION | translate }}
12
      </mat-radio-button>
13
    </mat-radio-group>
14
  </div>
15
  <div class="datetime-selection-container">
16
    <div class="date-selection">
17
      <span class="dialog-label">{{ 'basic.date' | translate }}</span>
18
      <mat-form-field class="date-input">
19
        <input id="date-input" matInput [matDatepicker]="datePicker" [(ngModel)]="data.date">
20
        <mat-datepicker-toggle matSuffix [for]="datePicker"></mat-datepicker-toggle>
21
        <mat-datepicker #datePicker></mat-datepicker>
22
      </mat-form-field>
23
    </div>
24
    <div class="datetime-interval" *ngIf="selectedVacationType == vacationType.VACATION">
25
      <div class="from-time">
26
        <span class="dialog-label">Od:</span>
27
        <div class="time-input-container">
28
          <input class="time-input" [format]="24" [value]="data.fromTime" [ngxTimepicker]="fromTimePicker">
29
          <ngx-material-timepicker [minutesGap]="MINUTE_STEP" (timeSet)="data.fromTime = $event" #fromTimePicker></ngx-material-timepicker>
30
          <i class="material-icons">access_time</i>
31
        </div>
32
      </div>
33
      <div class="to-time">
34
        <span class="dialog-label">Do:</span>
35
        <div class="time-input-container">
36
          <input class="time-input" [format]="24" [value]="data.toTime" [ngxTimepicker]="toTimePicker">
37
          <ngx-material-timepicker [minutesGap]="MINUTE_STEP" (timeSet)="data.toTime = $event" #toTimePicker></ngx-material-timepicker>
38
          <i class="material-icons">access_time</i>
39
        </div>
40
      </div>
41
    </div>
42
  </div>
43
</div>
44

  
45
<div mat-dialog-actions align="end">
46
  <button mat-raised-button color="primary" (click)="onConfirmClick()">{{ 'button.confirm' | translate }}</button>
47
  <button mat-raised-button color="basic" (click)="onCloseClick()">{{ 'button.close' | translate }}</button>
48
</div>
webapp/src/app/add-vacation-dialog/add-vacation-dialog.component.sass
1
.dialog-label
2
  display: block
3
  font-weight: bold
4
  color: grey
5

  
6
.datetime-picker > *
7
  display: table-cell
8

  
9
.vacation-type-radio-group
10
  display: flex
11
  flex-direction: column
12
  margin: 15px 0
13

  
14
.date-input
15
  width: 200px
16

  
17
.from-time
18
  display: inline-block
19

  
20
.to-time
21
  display: inline-block
22
  margin-left: 3px
23

  
24
.datetime-selection-container
25
  margin-bottom: 10px
26

  
27
.time-input-container
28
  display: inline-block
29
  padding: 2px
30
  border-bottom: 1px solid grey
31

  
32
  .time-input
33
    background-color: transparent
34
    border: 0
35
    outline: none
36
    width: 85px
37

  
38
  .material-icons
39
    font-size: 12px
40
    font-weight: bold
41
    color: grey
webapp/src/app/add-vacation-dialog/add-vacation-dialog.component.ts
1
import {Component, Inject} from '@angular/core';
2
import {MAT_DIALOG_DATA, MatDialogRef, MatSnackBar} from '@angular/material';
3
import {VacationType} from '../enums/common.enum';
4
import {FormControl} from '@angular/forms';
5
import {DateFormatterService} from '../services/util/date-formatter.service';
6
import {TranslateService} from '@ngx-translate/core';
7

  
8
@Component({
9
  selector: 'app-add-days-off-dialog',
10
  templateUrl: './add-vacation-dialog.component.html',
11
  styleUrls: ['./add-vacation-dialog.component.sass']
12
})
13
export class AddVacationDialogComponent {
14
  MINUTE_STEP = 15;
15

  
16
  vacationType = VacationType;
17

  
18
  selectedVacationType: VacationType;
19

  
20
  dateFormControl: FormControl = new FormControl();
21

  
22
  constructor(
23
    public dialogRef: MatDialogRef<AddVacationDialogComponent>,
24
    @Inject(MAT_DIALOG_DATA) public data: AddVacationDialogData,
25
    private snackBar: MatSnackBar,
26
    private dateFormatterService: DateFormatterService,
27
    private translateService: TranslateService
28
  ) {
29
    if (this.data.fromTime == null) {
30
      this.data.fromTime = '08:00';
31
    }
32
    if (data.toTime == null) {
33
      this.data.toTime = '16:00';
34
    }
35

  
36
    this.dateFormControl.setValue(data.date);
37
  }
38

  
39
  onConfirmClick(): void {
40
    if (this.selectedVacationType == null) {
41
      this.translateService.get('error.vacationTypeNotSelected').subscribe((res: string) => {
42
        this.snackBar.open(res, 'X', { duration: 5000 });
43
      });
44
    } else {
45
      let data;
46
      const formattedDate = this.dateFormatterService.formatDate(this.data.date);
47

  
48
      if (this.selectedVacationType === VacationType.VACATION) {
49
        data = {
50
          isConfirmed: true,
51
          vacationType: this.selectedVacationType,
52
          date: formattedDate,
53
          fromTime: this.data.fromTime,
54
          toTime: this.data.toTime
55
        };
56
      } else {
57
        data = {
58
          isConfirmed: true,
59
          vacationType: this.selectedVacationType,
60
          date: formattedDate
61
        };
62
      }
63

  
64
      this.dialogRef.close(data);
65
    }
66
  }
67

  
68
  onCloseClick(): void {
69
    this.dialogRef.close({
70
      isConfirmed: false
71
    });
72
  }
73

  
74
}
75

  
76
export interface AddVacationDialogData {
77
  date: Date;
78
  fromTime: string; // 'HH:mm' format
79
  toTime: string; // 'HH:mm' format
80
}
webapp/src/app/add-vacation-dialog/add-vacation-dialog.module.ts
1
import { NgModule } from '@angular/core';
2
import { CommonModule } from '@angular/common';
3
import { AddVacationDialogComponent } from './add-vacation-dialog.component';
4
import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
5
import {
6
  MatButtonModule,
7
  MatDialogModule,
8
  MatDatepickerModule,
9
  MatNativeDateModule,
10
  MatInputModule, MatRadioModule, MatSnackBarModule
11
} from '@angular/material';
12
import {NgbModule} from '@ng-bootstrap/ng-bootstrap';
13
import {FormsModule, ReactiveFormsModule} from '@angular/forms';
14
import {BrowserModule} from '@angular/platform-browser';
15
import {SharedModule} from '../shared/shared.module';
16
import {NgxMaterialTimepickerModule} from 'ngx-material-timepicker';
17
import {TranslateModule} from '@ngx-translate/core';
18

  
19

  
20
@NgModule({
21
  declarations: [AddVacationDialogComponent],
22
  imports: [
23
    CommonModule,
24
    BrowserAnimationsModule,
25
    MatButtonModule,
26
    MatDialogModule,
27
    NgbModule,
28
    FormsModule,
29
    MatDatepickerModule,
30
    MatNativeDateModule,
31
    ReactiveFormsModule,
32
    BrowserModule,
33
    MatInputModule,
34
    MatRadioModule,
35
    MatSnackBarModule,
36
    SharedModule,
37
    NgxMaterialTimepickerModule,
38
    TranslateModule
39
  ],
40
  exports: [
41
    AddVacationDialogComponent
42
  ],
43
  entryComponents: [
44
    AddVacationDialogComponent
45
  ]
46
})
47
export class AddVacationDialogModule { }
webapp/src/app/dashboard/add-vacation-dialog/add-vacation-dialog.component.html
1
<h1 mat-dialog-title>{{ 'addVacation.headline' | translate }}</h1>
2

  
3
<div mat-dialog-content>
4
  <div class="vacation-selection-container">
5
    <label id="vacation-type-radio-group-label" class="dialog-label">{{ 'basic.vacationType' | translate }}</label>
6
    <mat-radio-group aria-labelledby="vacation-type-radio-group-label" class="vacation-type-radio-group" [(ngModel)]="selectedVacationType">
7
      <mat-radio-button class="vacation-type-radio-button" [value]=vacationType.SICKDAY>
8
        {{ vacationType.SICKDAY | translate }}
9
      </mat-radio-button>
10
      <mat-radio-button class="vacation-type-radio-button" [value]=vacationType.VACATION>
11
        {{ vacationType.VACATION | translate }}
12
      </mat-radio-button>
13
    </mat-radio-group>
14
  </div>
15
  <div class="datetime-selection-container">
16
    <div class="date-selection">
17
      <span class="dialog-label">{{ 'basic.date' | translate }}</span>
18
      <mat-form-field class="date-input">
19
        <input id="date-input" matInput [matDatepicker]="datePicker" [(ngModel)]="data.date">
20
        <mat-datepicker-toggle matSuffix [for]="datePicker"></mat-datepicker-toggle>
21
        <mat-datepicker #datePicker></mat-datepicker>
22
      </mat-form-field>
23
    </div>
24
    <div class="datetime-interval" *ngIf="selectedVacationType == vacationType.VACATION">
25
      <div class="from-time">
26
        <span class="dialog-label">Od:</span>
27
        <div class="time-input-container">
28
          <input class="time-input" [format]="24" [value]="data.fromTime" [ngxTimepicker]="fromTimePicker">
29
          <ngx-material-timepicker [minutesGap]="MINUTE_STEP" (timeSet)="data.fromTime = $event" #fromTimePicker></ngx-material-timepicker>
30
          <i class="material-icons">access_time</i>
31
        </div>
32
      </div>
33
      <div class="to-time">
34
        <span class="dialog-label">Do:</span>
35
        <div class="time-input-container">
36
          <input class="time-input" [format]="24" [value]="data.toTime" [ngxTimepicker]="toTimePicker">
37
          <ngx-material-timepicker [minutesGap]="MINUTE_STEP" (timeSet)="data.toTime = $event" #toTimePicker></ngx-material-timepicker>
38
          <i class="material-icons">access_time</i>
39
        </div>
40
      </div>
41
    </div>
42
  </div>
43
</div>
44

  
45
<div mat-dialog-actions align="end">
46
  <button mat-raised-button color="primary" (click)="onConfirmClick()">{{ 'button.confirm' | translate }}</button>
47
  <button mat-raised-button color="basic" (click)="onCloseClick()">{{ 'button.close' | translate }}</button>
48
</div>
webapp/src/app/dashboard/add-vacation-dialog/add-vacation-dialog.component.sass
1
.dialog-label
2
  display: block
3
  font-weight: bold
4
  color: grey
5

  
6
.datetime-picker > *
7
  display: table-cell
8

  
9
.vacation-type-radio-group
10
  display: flex
11
  flex-direction: column
12
  margin: 15px 0
13

  
14
.date-input
15
  width: 200px
16

  
17
.from-time
18
  display: inline-block
19

  
20
.to-time
21
  display: inline-block
22
  margin-left: 3px
23

  
24
.datetime-selection-container
25
  margin-bottom: 10px
26

  
27
.time-input-container
28
  display: inline-block
29
  padding: 2px
30
  border-bottom: 1px solid grey
31

  
32
  .time-input
33
    background-color: transparent
34
    border: 0
35
    outline: none
36
    width: 85px
37

  
38
  .material-icons
39
    font-size: 12px
40
    font-weight: bold
41
    color: grey
webapp/src/app/dashboard/add-vacation-dialog/add-vacation-dialog.component.ts
1
import {Component, Inject} from '@angular/core';
2
import {MAT_DIALOG_DATA, MatDialogRef, MatSnackBar} from '@angular/material';
3
import {VacationType} from '../../enums/common.enum';
4
import {FormControl} from '@angular/forms';
5
import {DateFormatterService} from '../../services/util/date-formatter.service';
6
import {TranslateService} from '@ngx-translate/core';
7

  
8
@Component({
9
  selector: 'app-add-days-off-dialog',
10
  templateUrl: './add-vacation-dialog.component.html',
11
  styleUrls: ['./add-vacation-dialog.component.sass']
12
})
13
export class AddVacationDialogComponent {
14
  MINUTE_STEP = 15;
15

  
16
  vacationType = VacationType;
17

  
18
  selectedVacationType: VacationType;
19

  
20
  dateFormControl: FormControl = new FormControl();
21

  
22
  constructor(
23
    public dialogRef: MatDialogRef<AddVacationDialogComponent>,
24
    @Inject(MAT_DIALOG_DATA) public data: AddVacationDialogData,
25
    private snackBar: MatSnackBar,
26
    private dateFormatterService: DateFormatterService,
27
    private translateService: TranslateService
28
  ) {
29
    if (this.data.fromTime == null) {
30
      this.data.fromTime = '08:00';
31
    }
32
    if (data.toTime == null) {
33
      this.data.toTime = '16:00';
34
    }
35

  
36
    this.dateFormControl.setValue(data.date);
37
  }
38

  
39
  onConfirmClick(): void {
40
    if (this.selectedVacationType == null) {
41
      this.translateService.get('error.vacationTypeNotSelected').subscribe((res: string) => {
42
        this.snackBar.open(res, 'X', { duration: 5000 });
43
      });
44
    } else {
45
      let data;
46
      const formattedDate = this.dateFormatterService.formatDate(this.data.date);
47

  
48
      if (this.selectedVacationType === VacationType.VACATION) {
49
        data = {
50
          isConfirmed: true,
51
          vacationType: this.selectedVacationType,
52
          date: formattedDate,
53
          fromTime: this.data.fromTime,
54
          toTime: this.data.toTime
55
        };
56
      } else {
57
        data = {
58
          isConfirmed: true,
59
          vacationType: this.selectedVacationType,
60
          date: formattedDate
61
        };
62
      }
63

  
64
      this.dialogRef.close(data);
65
    }
66
  }
67

  
68
  onCloseClick(): void {
69
    this.dialogRef.close({
70
      isConfirmed: false
71
    });
72
  }
73

  
74
}
75

  
76
export interface AddVacationDialogData {
77
  date: Date;
78
  fromTime: string; // 'HH:mm' format
79
  toTime: string; // 'HH:mm' format
80
}
webapp/src/app/dashboard/add-vacation-dialog/add-vacation-dialog.module.ts
1
import { NgModule } from '@angular/core';
2
import { CommonModule } from '@angular/common';
3
import { AddVacationDialogComponent } from './add-vacation-dialog.component';
4
import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
5
import {
6
  MatButtonModule,
7
  MatDialogModule,
8
  MatDatepickerModule,
9
  MatNativeDateModule,
10
  MatInputModule, MatRadioModule, MatSnackBarModule
11
} from '@angular/material';
12
import {NgbModule} from '@ng-bootstrap/ng-bootstrap';
13
import {FormsModule, ReactiveFormsModule} from '@angular/forms';
14
import {BrowserModule} from '@angular/platform-browser';
15
import {SharedModule} from '../../shared/shared.module';
16
import {NgxMaterialTimepickerModule} from 'ngx-material-timepicker';
17
import {TranslateModule} from '@ngx-translate/core';
18

  
19

  
20
@NgModule({
21
  declarations: [AddVacationDialogComponent],
22
  imports: [
23
    CommonModule,
24
    BrowserAnimationsModule,
25
    MatButtonModule,
26
    MatDialogModule,
27
    NgbModule,
28
    FormsModule,
29
    MatDatepickerModule,
30
    MatNativeDateModule,
31
    ReactiveFormsModule,
32
    BrowserModule,
33
    MatInputModule,
34
    MatRadioModule,
35
    MatSnackBarModule,
36
    SharedModule,
37
    NgxMaterialTimepickerModule,
38
    TranslateModule
39
  ],
40
  exports: [
41
    AddVacationDialogComponent
42
  ],
43
  entryComponents: [
44
    AddVacationDialogComponent
45
  ]
46
})
47
export class AddVacationDialogModule { }
webapp/src/app/dashboard/dashboard.component.html
1
<app-employer-dashboard></app-employer-dashboard>
1
<div class="container-fluid h-100">
2
  <div class="row">
3
    <div class="col-lg-8 mid-panel">
4

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

  
13
      <div class="dashboard-vacation-approval"
14
           *ngIf="vacationRequests && vacationRequests.length > 0 && isEmployer()">
15
        <app-days-off-approval
16
          [vacationRequests]="vacationRequests"
17
          (vacationApprovalEvent)="vacationApproved($event.requestId, $event.approved)"
18
        ></app-days-off-approval>
19
      </div>
20

  
21
      <div class="dashboard-oncoming-vacation"
22
           *ngIf="oncomingVacation && oncomingVacation.length > 0">
23
        <app-coming-days-off
24
          [oncomingVacation]="oncomingVacation"
25
          (vacationRemove)="removeVacation($event)"
26
        ></app-coming-days-off>
27
      </div>
28

  
29
      <div class="dashboard-day-picker">
30
        <app-day-picker #dayPicker
31
                        (selectedDate)="onDateSelect($event)"
32
                        (selectedMonth)="onSelectedMonthChange($event)"
33
        ></app-day-picker>
34
      </div>
35

  
36
    </div>
37

  
38
    <div class="col-lg-4 right-panel">
39

  
40
      <div class="days-off-info" *ngIf="profile">
41
        <app-vacation-info
42
          [sickDaysRemaining]="profile.sickDayCount - profile.takenSickDayCount"
43
          [extraVacationRemaining]="profile.vacationCount"
44
        ></app-vacation-info>
45
      </div>
46

  
47
    </div>
48
  </div>
49
</div>
webapp/src/app/dashboard/dashboard.component.sass
1
.row
2
  padding: 0
3

  
4
.mid-panel
5
  padding: 10px 0 0 10px
6

  
7
.right-panel
8
  padding: 10px 10px 0 10px
9

  
10
.dashboard-user-approval
11
  padding: 0 0 10px 0
12

  
13
.dashboard-vacation-approval
14
  padding: 0 0 10px 0
15

  
16
.dashboard-oncoming-vacation
17
  padding: 0 0 10px 0
webapp/src/app/dashboard/dashboard.component.ts
1
import { Component, OnInit } from '@angular/core';
1
import {Component, OnInit, ViewChild} from '@angular/core';
2
import {MatDialog} from '@angular/material';
3
import {AddVacationDialogComponent} from './add-vacation-dialog/add-vacation-dialog.component';
4
import {UsersService} from '../services/api/users.service';
5
import {AuthorizationRequest, VacationRequest} from '../models/requests.model';
6
import {UserService} from '../services/api/user.service';
7
import {UserProfile} from '../models/user.model';
8
import {LocalizationService} from '../localization/localization.service';
9
import {RequestStatus, RequestTypes, UserType} from '../enums/common.enum';
10
import {Calendar} from '../models/calendar.model';
11
import {DateToolsService} from '../services/util/date-tools.service';
2 12

  
3 13
@Component({
4 14
  selector: 'app-dashboard',
......
6 16
  styleUrls: ['./dashboard.component.sass']
7 17
})
8 18
export class DashboardComponent implements OnInit {
19
  @ViewChild('dayPicker') calendar;
9 20

  
10
  constructor() { }
21
  private profile: UserProfile;
22
  private authorizationRequests: AuthorizationRequest[];
23
  private vacationRequests: VacationRequest[];
24
  private oncomingVacation: Calendar[];
25

  
26
  private selectedMonth: Date;
27

  
28
  constructor(
29
    public dialog: MatDialog,
30
    private localizationService: LocalizationService,
31
    private dateToolsService: DateToolsService,
32
    private userService: UserService,
33
    private usersService: UsersService
34
  ) { }
11 35

  
12 36
  ngOnInit() {
37
    this.selectedMonth = this.dateToolsService.toStartOfMonth(new Date());
38

  
39
    this.userService.getLoggedUserProfile()
40
      .subscribe((data: UserProfile) => {
41
        this.profile = data;
42
        if (this.isEmployer()) {
43
          this.loadAuthorizationRequests();
44
          this.loadVacationRequests();
45
        }
46
      });
47

  
48
    this.loadMonthVacation(this.selectedMonth);
49
    this.loadOncomingVacation();
50
  }
51

  
52
  userApproved(requestId: number, approved: boolean) {
53
    this.requestApproved(requestId, RequestTypes.AUTHORIZATION, approved)
54
      .subscribe(() => this.loadAuthorizationRequests());
55
  }
56

  
57
  vacationApproved(requestId: number, approved: boolean) {
58
    this.requestApproved(requestId, RequestTypes.VACATION, approved)
59
      .subscribe(() => this.loadVacationRequests());
60
  }
61

  
62
  requestApproved(requestId: number, requestType: RequestTypes, approved: boolean) {
63
    const request = {
64
      id: requestId,
65
      status: approved ? RequestStatus.ACCEPTED : RequestStatus.REJECTED
66
    };
67

  
68
    return this.userService.putUserRequestWithLanguage(request, requestType, this.localizationService.getCurrentLanguage());
69
  }
70

  
71
  removeVacation(vac: Calendar) {
72
    this.userService.deleteCalendar(vac.id, this.localizationService.getCurrentLanguage())
73
      .subscribe(() => {
74
        this.loadOncomingVacation();
75
        this.loadMonthVacation(this.selectedMonth);
76
        this.loadProfile();
77
      });
78
  }
79

  
80
  onDateSelect( date: Date ) {
81
    this.dialog
82
      .open(AddVacationDialogComponent, {
83
        data: {
84
          date
85
        }
86
      })
87
      .afterClosed().subscribe(data => {
88
      if (data && data.isConfirmed) {
89
        this.userService.postCalendarWithLanguage(
90
          {
91
            date: data.date,
92
            from: data.fromTime,
93
            to: data.toTime,
94
            type: data.vacationType
95
          },
96
          this.localizationService.getCurrentLanguage()
97
        ).subscribe(() => {
98
          this.loadMonthVacation(this.selectedMonth);
99
          this.loadOncomingVacation();
100
          this.loadProfile();
101
        });
102
      }
103
    });
13 104
  }
14 105

  
106
  onSelectedMonthChange(monthStart: Date) {
107
    this.selectedMonth = monthStart;
108
    this.loadMonthVacation(monthStart);
109
  }
110

  
111
  isEmployer(): boolean {
112
    if (this.profile) {
113
      return this.profile.role === UserType.EMPLOYER;
114
    } else {
115
      return false;
116
    }
117
  }
118

  
119
  private loadProfile() {
120
    this.userService.getLoggedUserProfile()
121
      .subscribe((data: UserProfile) => this.profile = data);
122
  }
123

  
124
  private loadAuthorizationRequests() {
125
    this.usersService.getAuthorizationRequestsWithLanguage(this.localizationService.getCurrentLanguage(), RequestStatus.PENDING)
126
      .subscribe((data: AuthorizationRequest[]) => this.authorizationRequests = data);
127
  }
128

  
129
  private loadVacationRequests() {
130
    this.usersService.getVacationRequestsWithLanguage(this.localizationService.getCurrentLanguage(), RequestStatus.PENDING)
131
      .subscribe((data: VacationRequest[]) => this.vacationRequests = data);
132
  }
133

  
134
  private loadMonthVacation(month: Date) {
135
    const fromDate = this.dateToolsService.toStartOfMonth(month);
136
    const toDate = this.dateToolsService.toEndOfMonth(fromDate);
137

  
138
    this.userService.getLoggedUserCalendarWithOptions(fromDate, toDate, this.localizationService.getCurrentLanguage(), RequestStatus.ACCEPTED)
139
      .subscribe((data: Calendar[]) => {
140
        if (data) {
141
          this.calendar.setVacation(data);
142
        }
143
      });
144
  }
145

  
146
  private loadOncomingVacation() {
147
    const fromDate = new Date();
148

  
149
    this.userService.getLoggedUserCalendarWithOptions(fromDate, null, this.localizationService.getCurrentLanguage(), null)
150
      .subscribe((data: Calendar[]) => this.oncomingVacation = data);
151
  }
15 152
}
webapp/src/app/dashboard/dashboard.module.ts
1
import {NgModule} from '@angular/core';
2
import {EmployerDashboardModule} from './employer-dashboard/employer-dashboard.module';
1
import { NgModule } from '@angular/core';
2
import { CommonModule } from '@angular/common';
3
import { DayPickerModule } from '../shared/day-picker/day-picker.module';
4
import { VacationInfoModule } from '../shared/vacation-info/vacation-info.module';
5
import { UserApprovalModule } from './user-approval/user-approval.module';
6
import { VacationApprovalModule } from './vacation-approval/vacation-approval.module';
7
import { OncomingVacationModule } from './oncoming-vacation/oncoming-vacation.module';
8
import {BrowserAnimationsModule} from '@angular/platform-browser/animations';
9
import {AddVacationDialogModule} from './add-vacation-dialog/add-vacation-dialog.module';
10
import {MatDialogModule} from '@angular/material';
3 11
import {DashboardComponent} from './dashboard.component';
4 12

  
5 13
@NgModule({
6 14
  declarations: [ DashboardComponent ],
7 15
  exports:      [ DashboardComponent ],
8 16
  imports: [
9
    EmployerDashboardModule
17
    CommonModule,
18
    DayPickerModule,
19
    VacationInfoModule,
20
    UserApprovalModule,
21
    VacationApprovalModule,
22
    DayPickerModule,
23
    OncomingVacationModule,
24
    BrowserAnimationsModule,
25
    AddVacationDialogModule,
26
    MatDialogModule
10 27
  ]
11 28
})
12 29
export class DashboardModule { }
webapp/src/app/dashboard/employer-dashboard/employer-dashboard.component.html
1
<div class="container-fluid h-100">
2
  <div class="row">
3
    <div class="col-lg-8 mid-panel">
4

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

  
13
      <div class="employer-dashboard-vacation-approval"
14
           *ngIf="vacationRequests && vacationRequests.length > 0 && isEmployer()">
15
        <app-days-off-approval
16
          [vacationRequests]="vacationRequests"
17
          (vacationApprovalEvent)="vacationApproved($event.requestId, $event.approved)"
18
        ></app-days-off-approval>
19
      </div>
20

  
21
      <div class="employer-dashboard-oncoming-vacation"
22
           *ngIf="oncomingVacation && oncomingVacation.length > 0">
23
        <app-coming-days-off
24
          [oncomingVacation]="oncomingVacation"
25
          (vacationRemove)="removeVacation($event)"
26
        ></app-coming-days-off>
27
      </div>
28

  
29
      <div class="employer-dashboard-day-picker">
30
        <app-day-picker #dayPicker
31
          (selectedDate)="onDateSelect($event)"
32
          (selectedMonth)="onSelectedMonthChange($event)"
33
        ></app-day-picker>
34
      </div>
35

  
36
    </div>
37

  
38
    <div class="col-lg-4 right-panel">
39

  
40
      <div class="days-off-info" *ngIf="profile">
41
        <app-vacation-info
42
          [sickDaysRemaining]="profile.sickDayCount - profile.takenSickDayCount"
43
          [extraVacationRemaining]="profile.vacationCount"
44
        ></app-vacation-info>
45
      </div>
46

  
47
    </div>
48
  </div>
49
</div>
webapp/src/app/dashboard/employer-dashboard/employer-dashboard.component.sass
1
.row
2
  padding: 0
3

  
4
.mid-panel
5
  padding: 10px 0 0 10px
6

  
7
.right-panel
8
  padding: 10px 10px 0 10px
9

  
10
.employer-dashboard-user-approval
11
  padding: 0 0 10px 0
12

  
13
.employer-dashboard-vacation-approval
14
  padding: 0 0 10px 0
15

  
16
.employer-dashboard-oncoming-vacation
17
  padding: 0 0 10px 0
webapp/src/app/dashboard/employer-dashboard/employer-dashboard.component.ts
1
import {Component, OnInit, ViewChild} from '@angular/core';
2
import {MatDialog} from '@angular/material';
3
import {AddVacationDialogComponent} from '../../add-vacation-dialog/add-vacation-dialog.component';
4
import {UsersService} from '../../services/api/users.service';
5
import {AuthorizationRequest, VacationRequest} from '../../models/requests.model';
6
import {UserService} from '../../services/api/user.service';
7
import {UserProfile} from '../../models/user.model';
8
import {LocalizationService} from '../../localization/localization.service';
9
import {RequestStatus, RequestTypes, UserType} from '../../enums/common.enum';
10
import {Calendar} from '../../models/calendar.model';
11
import {DateToolsService} from '../../services/util/date-tools.service';
12

  
13
@Component({
14
  selector: 'app-employer-dashboard',
15
  templateUrl: './employer-dashboard.component.html',
16
  styleUrls: ['./employer-dashboard.component.sass']
17
})
18
export class EmployerDashboardComponent implements OnInit {
19
  @ViewChild('dayPicker') calendar;
20

  
21
  private profile: UserProfile;
22
  private authorizationRequests: AuthorizationRequest[];
23
  private vacationRequests: VacationRequest[];
24
  private oncomingVacation: Calendar[];
25

  
26
  private selectedMonth: Date;
27

  
28
  constructor(
29
    public dialog: MatDialog,
30
    private localizationService: LocalizationService,
31
    private dateToolsService: DateToolsService,
32
    private userService: UserService,
33
    private usersService: UsersService
34
  ) { }
35

  
36
  ngOnInit() {
37
    this.selectedMonth = this.dateToolsService.toStartOfMonth(new Date());
38

  
39
    this.userService.getLoggedUserProfile()
40
      .subscribe((data: UserProfile) => {
41
        this.profile = data;
42
        if (this.isEmployer()) {
43
          this.loadAuthorizationRequests();
44
          this.loadVacationRequests();
45
        }
46
      });
47

  
48
    this.loadMonthVacation(this.selectedMonth);
49
    this.loadOncomingVacation();
50
  }
51

  
52
  userApproved(requestId: number, approved: boolean) {
53
    this.requestApproved(requestId, RequestTypes.AUTHORIZATION, approved)
54
      .subscribe(() => this.loadAuthorizationRequests());
55
  }
56

  
57
  vacationApproved(requestId: number, approved: boolean) {
58
    this.requestApproved(requestId, RequestTypes.VACATION, approved)
59
      .subscribe(() => this.loadVacationRequests());
60
  }
61

  
62
  requestApproved(requestId: number, requestType: RequestTypes, approved: boolean) {
63
    const request = {
64
      id: requestId,
65
      status: approved ? RequestStatus.ACCEPTED : RequestStatus.REJECTED
66
    };
67

  
68
    return this.userService.putUserRequestWithLanguage(request, requestType, this.localizationService.getCurrentLanguage());
69
  }
70

  
71
  removeVacation(vac: Calendar) {
72
    this.userService.deleteCalendar(vac.id, this.localizationService.getCurrentLanguage())
73
      .subscribe(() => {
74
        this.loadOncomingVacation();
75
        this.loadMonthVacation(this.selectedMonth);
76
        this.loadProfile();
77
      });
78
  }
79

  
80
  onDateSelect( date: Date ) {
81
    this.dialog
82
      .open(AddVacationDialogComponent, {
83
        data: {
84
          date
85
        }
86
      })
87
      .afterClosed().subscribe(data => {
88
        if (data && data.isConfirmed) {
89
          this.userService.postCalendarWithLanguage(
90
            {
91
              date: data.date,
92
              from: data.fromTime,
93
              to: data.toTime,
94
              type: data.vacationType
95
            },
96
            this.localizationService.getCurrentLanguage()
97
          ).subscribe(() => {
98
            this.loadMonthVacation(this.selectedMonth);
99
            this.loadOncomingVacation();
100
            this.loadProfile();
101
          });
102
        }
103
      });
104
  }
105

  
106
  onSelectedMonthChange(monthStart: Date) {
107
    this.selectedMonth = monthStart;
108
    this.loadMonthVacation(monthStart);
109
  }
110

  
111
  isEmployer(): boolean {
112
    if (this.profile) {
113
      return this.profile.role === UserType.EMPLOYER;
114
    } else {
115
      return false;
116
    }
117
  }
118

  
119
  private loadProfile() {
120
    this.userService.getLoggedUserProfile()
121
      .subscribe((data: UserProfile) => this.profile = data);
122
  }
123

  
124
  private loadAuthorizationRequests() {
125
    this.usersService.getAuthorizationRequestsWithLanguage(this.localizationService.getCurrentLanguage(), RequestStatus.PENDING)
126
      .subscribe((data: AuthorizationRequest[]) => this.authorizationRequests = data);
127
  }
128

  
129
  private loadVacationRequests() {
130
    this.usersService.getVacationRequestsWithLanguage(this.localizationService.getCurrentLanguage(), RequestStatus.PENDING)
131
      .subscribe((data: VacationRequest[]) => this.vacationRequests = data);
132
  }
133

  
134
  private loadMonthVacation(month: Date) {
135
    const fromDate = this.dateToolsService.toStartOfMonth(month);
136
    const toDate = this.dateToolsService.toEndOfMonth(fromDate);
137

  
138
    this.userService.getLoggedUserCalendarWithOptions(fromDate, toDate, this.localizationService.getCurrentLanguage(), RequestStatus.ACCEPTED)
139
      .subscribe((data: Calendar[]) => {
140
        if (data) {
141
          this.calendar.setVacation(data);
142
        }
143
      });
144
  }
145

  
146
  private loadOncomingVacation() {
147
    const fromDate = new Date();
148

  
149
    this.userService.getLoggedUserCalendarWithOptions(fromDate, null, this.localizationService.getCurrentLanguage(), null)
150
      .subscribe((data: Calendar[]) => this.oncomingVacation = data);
151
  }
152
}
webapp/src/app/dashboard/employer-dashboard/employer-dashboard.module.ts
1
import { NgModule } from '@angular/core';
2
import { CommonModule } from '@angular/common';
3
import { EmployerDashboardComponent } from './employer-dashboard.component';
4
import { DayPickerModule } from '../../day-picker/day-picker.module';
5
import { VacationInfoModule } from '../../vacation-info/vacation-info.module';
6
import { UserApprovalModule } from '../../user-approval/user-approval.module';
7
import { VacationApprovalModule } from '../../vacation-approval/vacation-approval.module';
8
import { OncomingVacationModule } from '../../oncoming-vacation/oncoming-vacation.module';
9
import {BrowserAnimationsModule} from '@angular/platform-browser/animations';
10
import {AddVacationDialogModule} from '../../add-vacation-dialog/add-vacation-dialog.module';
11
import {MatDialogModule} from '@angular/material';
12

  
13
@NgModule({
14
  declarations: [ EmployerDashboardComponent ],
15
  exports:      [ EmployerDashboardComponent ],
16
  imports: [
17
    CommonModule,
18
    DayPickerModule,
19
    VacationInfoModule,
20
    UserApprovalModule,
21
    VacationApprovalModule,
22
    DayPickerModule,
23
    OncomingVacationModule,
24
    BrowserAnimationsModule,
25
    AddVacationDialogModule,
26
    MatDialogModule
27
  ]
28
})
29
export class EmployerDashboardModule { }
webapp/src/app/dashboard/oncoming-vacation/oncoming-vacation.component.html
1
<div class="oncoming-days-off-container">
2

  
3
  <div class="component-header">
4
    {{'oncomingVacation.headline' | translate}}
5
  </div>
6

  
7
  <table class="table text-center table-hover">
8
    <thead class="thead-light">
9
      <tr>
10
        <th>{{'basic.vacationType' | translate}}</th>
11
        <th>{{'basic.date' | translate}}</th>
12
        <th>{{'basic.from' | translate}}</th>
13
        <th>{{'basic.to' | translate}}</th>
14
        <th>{{'oncomingVacation.status' | translate}}</th>
15
        <th></th>
16
      </tr>
17
    </thead>
18
    <tbody>
19
      <tr *ngFor="let vac of oncomingVacation">
20
        <td style="width:15%">
21
          {{vac.type | translate}}
22
        </td>
23

  
24
        <td style="width:15%">
25
          {{vac.date}}
26
        </td>
27

  
28
        <td style="width:15%">
29
          {{vac.from}}
30
        </td>
31

  
32
        <td style="width:15%">
33
          {{vac.to}}
34
        </td>
35

  
36
        <td style="width:15%" class="status {{vac.status}}">
37
          {{vac.status | translate}}
38
        </td>
39

  
40
        <td class="buttons">
41
<!--          <button mat-icon-button (click)="vacationEdit.emit(vac)">-->
42
<!--            <i class="material-icons edit-btn">edit</i>-->
43
<!--          </button>-->
44
          <button mat-icon-button (click)="vacationRemove.emit(vac)">
45
            <i class="material-icons remove-btn">delete</i>
46
          </button>
47
        </td>
48
      </tr>
49
    </tbody>
50
  </table>
51

  
52
</div>
webapp/src/app/dashboard/oncoming-vacation/oncoming-vacation.component.sass
1
@import '../../../common-styles/basic-component'
2

  
3
.oncoming-days-off-container
4
  @extend .basic-component
5

  
6
  table
7
    margin-top: 10px
8

  
9
    td
10
      text-align: center
11
      vertical-align: middle
12

  
13
    .status
14
      font-weight: bold
15

  
16
    .ACCEPTED
17
      color: green
18

  
19
    .PENDING
20
      color: orange
21

  
22
    .REJECTED
23
      color: red
24

  
25
    .buttons
26
      text-align: right
27
      padding-right: 50px
28

  
29
    button
30
      outline: none
31

  
32
    .edit-btn
33
      font-size: 18px
34
      margin-right: 2px
35
      color: orange
36

  
37
    .remove-btn
38
      color: grey
webapp/src/app/dashboard/oncoming-vacation/oncoming-vacation.component.ts
1
import {Component, EventEmitter, Input, OnInit, Output} from '@angular/core';
2
import {Calendar} from '../../models/calendar.model';
3

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

  
11
  @Input() oncomingVacation: Calendar[];
12

  
13
  @Output() vacationRemove = new EventEmitter<Calendar>();
14

  
15
  constructor() { }
16

  
17
  ngOnInit() { }
18
}
webapp/src/app/dashboard/oncoming-vacation/oncoming-vacation.module.ts
1
import {NgModule} from '@angular/core';
2
import {OncomingVacationComponent} from './oncoming-vacation.component';
3
import {BrowserModule} from '@angular/platform-browser';
4
import {MatButtonModule} from '@angular/material';
5
import {TranslateModule} from '@ngx-translate/core';
6
import {CommonModule} from '@angular/common';
7

  
8
@NgModule({
9
  declarations: [OncomingVacationComponent ],
10
  exports: [OncomingVacationComponent ],
11
  imports: [BrowserModule, MatButtonModule, TranslateModule, CommonModule],
12
})
13
export class OncomingVacationModule {}
webapp/src/app/dashboard/user-approval/user-approval.component.html
1
<div class="user-approval-container">
2

  
3
  <div class="component-header">
4
    {{'userApproval.headline' | translate}}
5
  </div>
6

  
7
  <table class="table text-center table-hover">
8
    <thead class="thead-light">
9
    <tr>
10
      <th style="width: 35%">{{'basic.name' | translate}}</th>
11
      <th style="width: 35%">{{'userApproval.requestDate' | translate}}</th>
12
      <th></th>
13
    </tr>
14
    </thead>
15
    <tbody>
16
      <tr *ngFor="let request of authorizationRequests">
17
        <td>
18
          {{request.firstName}} {{request.lastName}}
19
        </td>
20
        <td>
21
          {{request.timestamp | date:'yyyy/MM/dd'}}
22
        </td>
23
        <td class="buttons">
24
          <button mat-icon-button (click)="userApproved(request.id, true)">
25
            <i class="material-icons approve-btn">done</i>
26
          </button>
27
          <button mat-icon-button (click)="userApproved(request.id, false)">
28
            <i class="material-icons reject-btn">delete</i>
29
          </button>
30
        </td>
31
      </tr>
32
    </tbody>
33
  </table>
34

  
35
</div>
webapp/src/app/dashboard/user-approval/user-approval.component.sass
1
@import '../../../common-styles/basic-component'
2

  
3
.user-approval-container
4
  @extend .basic-component
5

  
6
  table
7
    margin-top: 10px
8

  
9
    td
10
      text-align: center
11
      vertical-align: middle
12

  
13
    .buttons
14
      text-align: right
15
      padding-right: 50px
16

  
17
    button
18
      outline: none
19

  
20
    .approve-btn
21
      margin-right: 2px
22
      color: green
23

  
24
    .reject-btn
25
      color: grey
webapp/src/app/dashboard/user-approval/user-approval.component.ts
1
import {Component, EventEmitter, Input, Output} from '@angular/core';
2
import {AuthorizationRequest} from '../../models/requests.model';
3
import {LocalizationService} from '../../localization/localization.service';
4

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

  
12
  @Input() authorizationRequests: AuthorizationRequest[];
13
  @Output() userApprovalEvent = new EventEmitter<{requestId: number, approved: boolean}>();
14

  
15
  constructor(private localizationService: LocalizationService) { }
16

  
17
  private userApproved(reqId: number, isApproved: boolean) {
18
    this.userApprovalEvent.emit({requestId: reqId, approved: isApproved});
19
  }
20
}
webapp/src/app/dashboard/user-approval/user-approval.module.ts
1
import { NgModule } from '@angular/core';
2
import { UserApprovalComponent } from './user-approval.component';
3
import { BrowserModule } from '@angular/platform-browser';
4
import {MatButtonModule} from '@angular/material';
5
import {TranslateModule} from '@ngx-translate/core';
6
import {CommonModule} from '@angular/common';
7

  
8
@NgModule({
9
  declarations: [ UserApprovalComponent ],
10
  exports:      [ UserApprovalComponent ],
11
  imports: [BrowserModule, MatButtonModule, TranslateModule, CommonModule]
12
})
13
export class UserApprovalModule { }
webapp/src/app/dashboard/vacation-approval/vacation-approval.component.html
1
<div class="days-off-approval-container">
2

  
3
  <div class="component-header">
4
    {{'vacationApproval.headline' | translate}}
5
  </div>
6

  
7
  <table class="table text-center table-hover">
8
    <thead class="thead-light">
9
      <tr>
10
        <th scope="col"> {{'basic.name' | translate}}</th>
11
        <th scope="col"> {{'vacationApproval.requestDate' | translate}}</th>
12
        <th scope="col"> {{'basic.vacationType' | translate}} </th>
13
        <th scope="col"> {{'basic.date' | translate}} </th>
14
        <th scope="col"> {{'basic.from' | translate}} </th>
15
        <th scope="col"> {{'basic.to' | translate}} </th>
16
        <th></th>
17
      </tr>
18
    </thead>
19
    <tbody>
20
    <tr *ngFor="let request of vacationRequests">
21
      <td>
22
        {{request.firstName}} {{request.lastName}}
23
      </td>
24
      <td>
25
        {{request.timestamp | date:'yyyy/MM/dd HH:mm'}}
26
      </td>
27
      <td>
28
        {{request.type | translate}}
29
      </td>
30
      <td>
31
        {{request.date | date:'yyyy/MM/dd'}}
32
      </td>
33
      <td>
34
        {{request.from}}
35
      </td>
36
      <td>
37
        {{request.to}}
38
      </td>
39
      <td class="buttons">
40
        <button mat-icon-button (click)="vacationApprovalCompleted(request.id, true)">
41
          <i class="material-icons approve-btn">done</i>
42
        </button>
43
        <button mat-icon-button (click)="vacationApprovalCompleted(request.id, false)">
44
          <i class="material-icons reject-btn">delete</i>
45
        </button>
46
      </td>
47
    </tr>
48
    </tbody>
49
  </table>
50
</div>
webapp/src/app/dashboard/vacation-approval/vacation-approval.component.sass
1
@import '../../../common-styles/basic-component'
2

  
3
.days-off-approval-container
4
  @extend .basic-component
5

  
6
  table
7
    margin-top: 10px
8

  
9
  td
10
    text-align: center
11
    vertical-align: middle
12

  
13
  .buttons
14
    text-align: right
15
    padding-right: 50px
16

  
17
  button
18
    outline: none
19

  
20
  .approve-btn
21
    margin-right: 2px
22
    color: green
23

  
24
  .reject-btn
25
    color: grey
26

  
webapp/src/app/dashboard/vacation-approval/vacation-approval.component.ts
1
import { Component, EventEmitter, Output, Input } from '@angular/core';
2
import { VacationRequest } from '../../models/requests.model';
3

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

  
11
  @Input() vacationRequests: VacationRequest[];
12
  @Output() vacationApprovalEvent = new EventEmitter<{requestId: number, approved: boolean}>();
13

  
14
  constructor() { }
15

  
16
  vacationApprovalCompleted(reqId: number, isApproved: boolean ) {
17
    this.vacationApprovalEvent.emit({requestId: reqId, approved: isApproved});
18
  }
19
}
webapp/src/app/dashboard/vacation-approval/vacation-approval.module.ts
1
import {NgModule} from '@angular/core';
2
import {VacationApprovalComponent} from './vacation-approval.component';
3
import {BrowserModule} from '@angular/platform-browser';
4
import {MatButtonModule} from '@angular/material';
5
import {TranslateModule} from '@ngx-translate/core';
6
import {CommonModule} from '@angular/common';
7

  
8
@NgModule({
9
  declarations: [VacationApprovalComponent],
10
  exports: [VacationApprovalComponent],
11
  imports: [BrowserModule, MatButtonModule, TranslateModule, CommonModule]
12
})
13
export class VacationApprovalModule {
14
}
webapp/src/app/day-picker/day-picker.component.html
1
<div class="day-picker-container">
2
  <div class="row text-center day-picker-month-selection">
3
    <div class="col-4"></div>
4
    <div class="col-1">
5
      <button
6
        mat-icon-button
7
        mwlCalendarPreviousView
8
        [view]="view"
9
        [(viewDate)]="viewDate"
10
        (click)="setMonth(currentMonth - 1)"
11
      >
12
        <i class="material-icons change-month">navigate_before</i>
13
      </button>
14
    </div>
15
    <div class="col-2">
16
      <span id="day-picker-date">{{ viewDate | calendarDate:(view + 'ViewTitle'):locale }}</span>
17
    </div>
18
    <div class="col-1">
19
      <button
20
        mat-icon-button
21
        mwlCalendarNextView
22
        [view]="view"
23
        [(viewDate)]="viewDate"
24
        (click)="setMonth(currentMonth + 1)"
25
      >
26
        <i class="material-icons change-month">navigate_next</i>
27
      </button>
28
      <div class="col-4"></div>
29
    </div>
30
  </div>
31

  
32
  <mwl-calendar-month-view
33
    [viewDate]="viewDate"
34
    [locale]="locale"
35
    [refresh]="refresh"
36
    [events]="events"
37
    [cellTemplate]="customCellTemplate"
38
    (dayClicked)="dayClicked($event.day)"
39
    weekStartsOn="1"
40
  >
41
  </mwl-calendar-month-view>
42

  
43
  <ng-template #customCellTemplate let-day="day" let-locale="locale">
44
    <div class="cal-cell-top">
45
      <span class="cal-day-number">
46
        {{ day.date | calendarDate:'monthViewDayNumber':locale }}
47
      </span>
48
    </div>
49
      <span class="vacation-type" *ngFor="let event of day.events">
50
        <i class="material-icons sickday" *ngIf="event.title == vacationType.SICKDAY">local_hospital</i>
51
        <i class="material-icons vacation" *ngIf="event.title == vacationType.VACATION">beach_access</i>
52

  
53
        <span class="time-interval" *ngIf="event.title == vacationType.VACATION">
54
          {{ event.start | date:'HH:mm' }} - {{ event.end | date:'HH:mm' }}
55
        </span>
56
      </span>
57
  </ng-template>
58
</div>
webapp/src/app/day-picker/day-picker.component.sass
1
@import '../../common-styles/basic-component'
2

  
3
.day-picker-container
4
  @extend .basic-component
5

  
6
#day-picker-date
... Rozdílový soubor je zkrácen, protože jeho délka přesahuje max. limit.

Také k dispozici: Unified diff