Revize 696f3358
Přidáno uživatelem Václav Jirák před téměř 6 roky(ů)
webapp/src/app/add-days-off-dialog/add-days-off-dialog.component.html | ||
---|---|---|
1 |
<h1 mat-dialog-title>Výběr volna</h1> |
|
2 |
|
|
3 |
<div mat-dialog-content> |
|
4 |
<div> |
|
5 |
<label id="days-off-type-radio-group-label" class="dialog-label">Typ volna</label> |
|
6 |
<mat-radio-group aria-labelledby="days-off-type-radio-group-label" class="days-off-type-radio-group" [(ngModel)]="selectedDaysOffType"> |
|
7 |
<mat-radio-button class="days-off-type-radio-button" *ngFor="let type of daysOffTypes" [value]="type" > |
|
8 |
{{type}} |
|
9 |
</mat-radio-button> |
|
10 |
</mat-radio-group> |
|
11 |
</div> |
|
12 |
|
|
13 |
<div class="datetime-interval"> |
|
14 |
<div class="from-datetime"> |
|
15 |
<label for="from-datetime-input" class="dialog-label">Od:</label> |
|
16 |
<div class="datetime-picker"> |
|
17 |
<mat-form-field> |
|
18 |
<input id="from-datetime-input" matInput [matDatepicker]="startDatePicker" [(ngModel)]="data.fromDate"> |
|
19 |
<mat-datepicker-toggle matSuffix [for]="startDatePicker"></mat-datepicker-toggle> |
|
20 |
<mat-datepicker #startDatePicker></mat-datepicker> |
|
21 |
</mat-form-field> |
|
22 |
<ngb-timepicker [(ngModel)]="data.fromTime" [minuteStep]="MINUTE_STEP"></ngb-timepicker> |
|
23 |
</div> |
|
24 |
</div> |
|
25 |
|
|
26 |
<div class="to-datetime"> |
|
27 |
<label for="to-datetime-input" class="dialog-label">Do:</label> |
|
28 |
<div class="datetime-picker"> |
|
29 |
<mat-form-field> |
|
30 |
<input id="to-datetime-input" matInput [matDatepicker]="endDatePicker" [(ngModel)]="data.toDate"> |
|
31 |
<mat-datepicker-toggle matSuffix [for]="endDatePicker"></mat-datepicker-toggle> |
|
32 |
<mat-datepicker #endDatePicker></mat-datepicker> |
|
33 |
</mat-form-field> |
|
34 |
<ngb-timepicker [(ngModel)]="data.toTime" [minuteStep]="MINUTE_STEP"></ngb-timepicker> |
|
35 |
</div> |
|
36 |
</div> |
|
37 |
</div> |
|
38 |
</div> |
|
39 |
|
|
40 |
<div mat-dialog-actions align="end"> |
|
41 |
<button mat-raised-button color="primary" (click)="onConfirmClick()">Potvrdit</button> |
|
42 |
<button mat-raised-button color="basic" (click)="onCloseClick()">Zavřít</button> |
|
43 |
</div> |
webapp/src/app/add-days-off-dialog/add-days-off-dialog.component.sass | ||
---|---|---|
1 |
.dialog-label |
|
2 |
display: block |
|
3 |
font-weight: bold |
|
4 |
|
|
5 |
.datetime-picker > * |
|
6 |
display: table-cell |
|
7 |
|
|
8 |
.days-off-type-radio-group |
|
9 |
display: flex |
|
10 |
flex-direction: column |
|
11 |
margin: 15px 0 |
webapp/src/app/add-days-off-dialog/add-days-off-dialog.component.ts | ||
---|---|---|
1 |
import { Component, Inject } from '@angular/core'; |
|
2 |
import { MAT_DIALOG_DATA, MatDialogRef, MatSnackBar } from '@angular/material'; |
|
3 |
import { FormControl } from '@angular/forms'; |
|
4 |
|
|
5 |
@Component({ |
|
6 |
selector: 'app-add-days-off-dialog', |
|
7 |
templateUrl: './add-days-off-dialog.component.html', |
|
8 |
styleUrls: ['./add-days-off-dialog.component.sass'] |
|
9 |
}) |
|
10 |
export class AddDaysOffDialogComponent { |
|
11 |
MINUTE_STEP = 15; |
|
12 |
|
|
13 |
selectedDaysOffType: string; |
|
14 |
daysOffTypes: string[] = ['Sick-days', 'Extra dovolená']; |
|
15 |
|
|
16 |
constructor( |
|
17 |
public dialogRef: MatDialogRef<AddDaysOffDialogComponent>, |
|
18 |
@Inject(MAT_DIALOG_DATA) public data: AddDaysOffDialogData, |
|
19 |
private snackBar: MatSnackBar |
|
20 |
) { |
|
21 |
if (this.data.toDate == null) { |
|
22 |
this.data.toDate = this.data.fromDate; |
|
23 |
} |
|
24 |
if (this.data.fromTime == null) { |
|
25 |
this.data.fromTime = {hour: 8, minute: 0}; |
|
26 |
} |
|
27 |
if (data.toTime == null) { |
|
28 |
this.data.toTime = {hour: 16, minute: 0}; |
|
29 |
} |
|
30 |
} |
|
31 |
|
|
32 |
onConfirmClick(): void { |
|
33 |
// TODO lokalizace |
|
34 |
|
|
35 |
if (this.selectedDaysOffType == null) { |
|
36 |
this.snackBar.open('Nevybrán typ volna', 'Zavřít', { duration: 5000 }); |
|
37 |
} else if (this.data.fromDate > this.data.toDate) { |
|
38 |
this.snackBar.open('Datum "od" nemůže být větší než "do"', 'Zavřít', { duration: 5000 }); |
|
39 |
} else { |
|
40 |
// TODO API CALL |
|
41 |
this.dialogRef.close(); |
|
42 |
} |
|
43 |
} |
|
44 |
|
|
45 |
onCloseClick(): void { |
|
46 |
this.dialogRef.close(); |
|
47 |
} |
|
48 |
|
|
49 |
} |
|
50 |
|
|
51 |
export interface AddDaysOffDialogData { |
|
52 |
fromDate: FormControl; |
|
53 |
toDate: FormControl; |
|
54 |
fromTime: { hour: number, minute: number }; |
|
55 |
toTime: { hour: number, minute: number }; |
|
56 |
} |
webapp/src/app/add-days-off-dialog/add-days-off-dialog.module.ts | ||
---|---|---|
1 |
import { NgModule } from '@angular/core'; |
|
2 |
import { CommonModule } from '@angular/common'; |
|
3 |
import { AddDaysOffDialogComponent } from './add-days-off-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 |
|
|
16 |
@NgModule({ |
|
17 |
declarations: [AddDaysOffDialogComponent], |
|
18 |
imports: [ |
|
19 |
CommonModule, |
|
20 |
BrowserAnimationsModule, |
|
21 |
MatButtonModule, |
|
22 |
MatDialogModule, |
|
23 |
NgbModule, |
|
24 |
FormsModule, |
|
25 |
MatDatepickerModule, |
|
26 |
MatNativeDateModule, |
|
27 |
ReactiveFormsModule, |
|
28 |
BrowserModule, |
|
29 |
MatInputModule, |
|
30 |
MatRadioModule, |
|
31 |
MatSnackBarModule |
|
32 |
], |
|
33 |
exports: [ |
|
34 |
AddDaysOffDialogComponent |
|
35 |
], |
|
36 |
entryComponents: [ |
|
37 |
AddDaysOffDialogComponent |
|
38 |
] |
|
39 |
}) |
|
40 |
export class AddDaysOffDialogModule { } |
webapp/src/app/add-vacation-dialog/add-vacation-dialog.component.html | ||
---|---|---|
1 |
<h1 mat-dialog-title>Výběr volna</h1> |
|
2 |
|
|
3 |
<div mat-dialog-content> |
|
4 |
<div> |
|
5 |
<label id="vacation-type-radio-group-label" class="dialog-label">Typ volna: </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}} |
|
9 |
</mat-radio-button> |
|
10 |
<mat-radio-button class="vacation-type-radio-button" [value]=vacationType.VACATION> |
|
11 |
{{vacationType.VACATION}} |
|
12 |
</mat-radio-button> |
|
13 |
</mat-radio-group> |
|
14 |
</div> |
|
15 |
|
|
16 |
<div class="datetime-interval"> |
|
17 |
<div class="from-datetime"> |
|
18 |
<span class="datetime-interval-label">Od:</span> |
|
19 |
<app-datetime [(date)]="data.fromDate" [(time)]="data.fromTime" [minuteStep]="MINUTE_STEP"></app-datetime> |
|
20 |
</div> |
|
21 |
<div class="to-datetime"> |
|
22 |
<span class="datetime-interval-label">Do:</span> |
|
23 |
<app-datetime [(date)]="data.toDate" [(time)]="data.toTime" [minuteStep]="MINUTE_STEP"></app-datetime> |
|
24 |
</div> |
|
25 |
</div> |
|
26 |
</div> |
|
27 |
|
|
28 |
<div mat-dialog-actions align="end"> |
|
29 |
<button mat-raised-button color="primary" (click)="onConfirmClick()">Potvrdit</button> |
|
30 |
<button mat-raised-button color="basic" (click)="onCloseClick()">Zavřít</button> |
|
31 |
</div> |
webapp/src/app/add-vacation-dialog/add-vacation-dialog.component.sass | ||
---|---|---|
1 |
.dialog-label |
|
2 |
display: block |
|
3 |
font-weight: bold |
|
4 |
|
|
5 |
.datetime-picker > * |
|
6 |
display: table-cell |
|
7 |
|
|
8 |
.vacation-type-radio-group |
|
9 |
display: flex |
|
10 |
flex-direction: column |
|
11 |
margin: 15px 0 |
|
12 |
|
|
13 |
.datetime-interval-label |
|
14 |
font-weight: bold |
|
15 |
display: block |
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 |
|
|
5 |
@Component({ |
|
6 |
selector: 'app-add-days-off-dialog', |
|
7 |
templateUrl: './add-vacation-dialog.component.html', |
|
8 |
styleUrls: ['./add-vacation-dialog.component.sass'] |
|
9 |
}) |
|
10 |
export class AddVacationDialogComponent { |
|
11 |
MINUTE_STEP = 15; |
|
12 |
|
|
13 |
vacationType = VacationType; |
|
14 |
|
|
15 |
selectedVacationType: VacationType; |
|
16 |
|
|
17 |
constructor( |
|
18 |
public dialogRef: MatDialogRef<AddVacationDialogComponent>, |
|
19 |
@Inject(MAT_DIALOG_DATA) public data: AddVacationDialogData, |
|
20 |
private snackBar: MatSnackBar |
|
21 |
) { |
|
22 |
if (this.data.toDate == null) { |
|
23 |
this.data.toDate = this.data.fromDate; |
|
24 |
} |
|
25 |
if (this.data.fromTime == null) { |
|
26 |
this.data.fromTime = '08:00'; |
|
27 |
} |
|
28 |
if (data.toTime == null) { |
|
29 |
this.data.toTime = '16:00'; |
|
30 |
} |
|
31 |
} |
|
32 |
|
|
33 |
onConfirmClick(): void { |
|
34 |
if (this.selectedVacationType == null) { |
|
35 |
this.snackBar.open('Nevybrán typ volna', 'Zavřít', { duration: 5000 }); |
|
36 |
} else if (this.data.fromDate > this.data.toDate) { |
|
37 |
this.snackBar.open('Datum "od" nemůže být větší než "do"', 'Zavřít', { duration: 5000 }); |
|
38 |
} else { |
|
39 |
this.dialogRef.close({ |
|
40 |
isConfirmed: true, |
|
41 |
vacationType: this.selectedVacationType, |
|
42 |
fromDate: this.data.fromDate, |
|
43 |
fromTime: this.data.fromTime, |
|
44 |
toDate: this.data.toDate, |
|
45 |
toTime: this.data.toTime |
|
46 |
}); |
|
47 |
} |
|
48 |
} |
|
49 |
|
|
50 |
onCloseClick(): void { |
|
51 |
this.dialogRef.close({ |
|
52 |
isConfirmed: false |
|
53 |
}); |
|
54 |
} |
|
55 |
|
|
56 |
} |
|
57 |
|
|
58 |
export interface AddVacationDialogData { |
|
59 |
fromDate: Date; |
|
60 |
toDate: Date; |
|
61 |
fromTime: string; // 'HH:mm' format |
|
62 |
toTime: string; // 'HH:mm' format |
|
63 |
} |
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 |
|
|
17 |
@NgModule({ |
|
18 |
declarations: [AddVacationDialogComponent], |
|
19 |
imports: [ |
|
20 |
CommonModule, |
|
21 |
BrowserAnimationsModule, |
|
22 |
MatButtonModule, |
|
23 |
MatDialogModule, |
|
24 |
NgbModule, |
|
25 |
FormsModule, |
|
26 |
MatDatepickerModule, |
|
27 |
MatNativeDateModule, |
|
28 |
ReactiveFormsModule, |
|
29 |
BrowserModule, |
|
30 |
MatInputModule, |
|
31 |
MatRadioModule, |
|
32 |
MatSnackBarModule, |
|
33 |
SharedModule |
|
34 |
], |
|
35 |
exports: [ |
|
36 |
AddVacationDialogComponent |
|
37 |
], |
|
38 |
entryComponents: [ |
|
39 |
AddVacationDialogComponent |
|
40 |
] |
|
41 |
}) |
|
42 |
export class AddVacationDialogModule { } |
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 class="employer-dashboard-user-approval" *ngIf="authorizationRequests && authorizationRequests.authorization.length > 0">
|
|
5 |
<div class="employer-dashboard-user-approval" *ngIf="authorizationRequests && authorizationRequests.length > 0"> |
|
6 | 6 |
<app-user-approval |
7 | 7 |
[authorizationRequests]="authorizationRequests" |
8 | 8 |
(userApprovalEvent)="userApproved($event.requestId, $event.approved)" |
9 | 9 |
></app-user-approval> |
10 | 10 |
</div> |
11 | 11 |
|
12 |
<div class="employer-dashboard-days-off-approval" *ngIf="daysOffRequests && daysOffRequests.vacation.length > 0">
|
|
12 |
<div class="employer-dashboard-days-off-approval" *ngIf="vacationRequests && vacationRequests.length > 0">
|
|
13 | 13 |
<app-days-off-approval |
14 |
[daysOffRequests]="daysOffRequests"
|
|
15 |
(daysOffApprovalEvent)="daysOffApproved($event.requestId, $event.approved)"
|
|
14 |
[vacationRequests]="vacationRequests"
|
|
15 |
(vacationApprovalEvent)="vacationApproved($event.requestId, $event.approved)"
|
|
16 | 16 |
></app-days-off-approval> |
17 | 17 |
</div> |
18 | 18 |
|
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>--> |
|
19 |
<div class="employer-dashboard-coming-days-off" *ngIf="oncomingVacation && oncomingVacation.length > 0"> |
|
20 |
<app-coming-days-off |
|
21 |
[oncomingVacation]="oncomingVacation" |
|
22 |
(vacationEdit)="editVacation($event)" |
|
23 |
(vacationRemove)="removeVacation($event)" |
|
24 |
></app-coming-days-off> |
|
25 |
</div> |
|
23 | 26 |
|
24 | 27 |
<div class="employer-dashboard-day-picker"> |
25 |
<app-day-picker |
|
28 |
<app-day-picker #dayPicker
|
|
26 | 29 |
(selectedDate)="onDateSelect($event)" |
27 |
(selectedMonth)="onMonthSelect($event)"
|
|
30 |
(selectedMonth)="onSelectedMonthChange($event)"
|
|
28 | 31 |
></app-day-picker> |
29 | 32 |
</div> |
30 | 33 |
|
... | ... | |
34 | 37 |
|
35 | 38 |
<div class="days-off-info" *ngIf="profile"> |
36 | 39 |
<app-days-off-info |
37 |
[sickDaysRemaining]="profile.sickDay"
|
|
38 |
[extraVacationRemaining]="profile.vacation" |
|
40 |
[sickDaysRemaining]="profile.sickdayCount"
|
|
41 |
[extraVacationRemaining]="profile.vacationCount"
|
|
39 | 42 |
></app-days-off-info> |
40 | 43 |
</div> |
41 | 44 |
|
webapp/src/app/dashboard/employer-dashboard/employer-dashboard.component.ts | ||
---|---|---|
1 |
import {Component, Input, OnInit} from '@angular/core';
|
|
1 |
import {Component, OnInit, ViewChild} from '@angular/core';
|
|
2 | 2 |
import {MatDialog} from '@angular/material'; |
3 |
import {AddDaysOffDialogComponent} from '../../add-days-off-dialog/add-days-off-dialog.component';
|
|
3 |
import {AddVacationDialogComponent} from '../../add-vacation-dialog/add-vacation-dialog.component';
|
|
4 | 4 |
import {UsersService} from '../../services/api/users.service'; |
5 |
import {Requests} from '../../models/requests.model';
|
|
5 |
import {AuthorizationRequest, VacationRequest} from '../../models/requests.model';
|
|
6 | 6 |
import {UserService} from '../../services/api/user.service'; |
7 |
import {ProfileService} from '../../services/api/profile.service'; |
|
8 | 7 |
import {UserProfile} from '../../models/user.model'; |
8 |
import {LocalizationService} from '../../localization/localization.service'; |
|
9 |
import {RequestStatus, RequestTypes} from '../../enums/common.enum'; |
|
10 |
import {Calendar} from '../../models/calendar.model'; |
|
11 |
import {DateToolsService} from '../../services/util/date-tools.service'; |
|
12 |
import {EditVacationDialogComponent} from "../../edit-vacation-dialog/edit-vacation-dialog.component"; |
|
9 | 13 |
|
10 | 14 |
@Component({ |
11 | 15 |
selector: 'app-employer-dashboard', |
... | ... | |
13 | 17 |
styleUrls: ['./employer-dashboard.component.sass'] |
14 | 18 |
}) |
15 | 19 |
export class EmployerDashboardComponent implements OnInit { |
20 |
@ViewChild('dayPicker') calendar; |
|
16 | 21 |
|
17 |
@Input() profile: UserProfile; |
|
18 |
private authorizationRequests: Requests; |
|
19 |
private daysOffRequests: Requests; |
|
22 |
private profile: UserProfile; |
|
23 |
private authorizationRequests: AuthorizationRequest[]; |
|
24 |
private vacationRequests: VacationRequest[]; |
|
25 |
private currentMonthVacation: Calendar[]; |
|
26 |
private oncomingVacation: Calendar[]; |
|
20 | 27 |
|
21 | 28 |
constructor( |
22 | 29 |
public dialog: MatDialog, |
23 |
private profileService: ProfileService,
|
|
24 |
// API
|
|
30 |
private localizationService: LocalizationService,
|
|
31 |
private dateToolsService: DateToolsService,
|
|
25 | 32 |
private userService: UserService, |
26 | 33 |
private usersService: UsersService |
27 | 34 |
) { } |
28 | 35 |
|
29 | 36 |
ngOnInit() { |
30 |
// this.profileService.getProfile() |
|
31 |
// .subscribe((data: UserProfile) => this.profile = data); |
|
32 |
// |
|
33 |
// this.usersService.getAuthorizationRequests() |
|
34 |
// .subscribe((data: Requests) => this.authorizationRequests = data); |
|
35 |
// |
|
36 |
// this.usersService.getVacationRequests() |
|
37 |
// .subscribe((data: Requests) => this.daysOffRequests = data); |
|
37 |
this.loadProfile(); |
|
38 |
this.loadAuthorizationRequests(); |
|
39 |
this.loadVacationRequests(); |
|
40 |
this.loadMonthVacation(this.dateToolsService.toStartOfMonth(new Date())); |
|
41 |
this.loadOncomingVacation(); |
|
38 | 42 |
} |
39 | 43 |
|
40 |
private userApproved(requestId: number, approved: boolean) {
|
|
41 |
// TODO api post call
|
|
42 |
this.authorizationRequests.authorization.splice(0, 1);
|
|
44 |
userApproved(requestId: number, approved: boolean) { |
|
45 |
this.requestApproved(requestId, RequestTypes.AUTHORIZATION, approved)
|
|
46 |
.subscribe(e => this.loadAuthorizationRequests());
|
|
43 | 47 |
} |
44 | 48 |
|
45 |
private daysOffApproved(requestId: number, approved: boolean) { |
|
46 |
// TODO api post call |
|
47 |
this.daysOffRequests.vacation.splice(0, 1); |
|
49 |
vacationApproved(requestId: number, approved: boolean) { |
|
50 |
this.requestApproved(requestId, RequestTypes.VACATION, approved) |
|
51 |
.subscribe(e => this.loadVacationRequests()); |
|
52 |
} |
|
53 |
|
|
54 |
requestApproved(requestId: number, requestType: RequestTypes, approved: boolean) { |
|
55 |
const request = { |
|
56 |
id: requestId, |
|
57 |
status: approved ? RequestStatus.ACCEPTED : RequestStatus.REJECTED |
|
58 |
}; |
|
59 |
|
|
60 |
return this.userService.putUserRequestWithLanguage(request, requestType, this.localizationService.getCurrentLanguage()); |
|
61 |
} |
|
62 |
|
|
63 |
removeVacation(vac: Calendar) { |
|
64 |
this.userService.deleteCalendar(vac.id, this.localizationService.getCurrentLanguage()) |
|
65 |
.subscribe(e => this.loadOncomingVacation()); |
|
66 |
} |
|
67 |
|
|
68 |
editVacation(vac: Calendar) { |
|
69 |
// this.dialog.open(EditVacationDialogComponent, { |
|
70 |
// data: { |
|
71 |
// vacation: vac |
|
72 |
// } |
|
73 |
// }); |
|
48 | 74 |
} |
49 | 75 |
|
50 | 76 |
onDateSelect( date: Date ) { |
51 |
this.dialog.open(AddDaysOffDialogComponent, { |
|
52 |
data: { |
|
53 |
fromDate: date |
|
54 |
} |
|
55 |
}); |
|
77 |
this.dialog |
|
78 |
.open(AddVacationDialogComponent, { |
|
79 |
data: { |
|
80 |
fromDate: date |
|
81 |
} |
|
82 |
}) |
|
83 |
.afterClosed().subscribe(data => { |
|
84 |
if (data && data.isConfirmed) { |
|
85 |
// TODO |
|
86 |
} |
|
87 |
}); |
|
56 | 88 |
} |
57 | 89 |
|
58 |
onMonthSelect(month: number) { |
|
59 |
// TODO API CALL |
|
90 |
onSelectedMonthChange(monthStart: Date) { |
|
91 |
this.loadMonthVacation(monthStart); |
|
92 |
} |
|
93 |
|
|
94 |
private loadProfile() { |
|
95 |
this.userService.getLoggedUserProfile() |
|
96 |
.subscribe((data: UserProfile) => this.profile = data); |
|
97 |
} |
|
98 |
|
|
99 |
private loadAuthorizationRequests() { |
|
100 |
this.usersService.getAuthorizationRequestsWithLanguage(this.localizationService.getCurrentLanguage()) |
|
101 |
.subscribe((data: AuthorizationRequest[]) => this.authorizationRequests = data); |
|
102 |
} |
|
103 |
|
|
104 |
private loadVacationRequests() { |
|
105 |
this.usersService.getVacationRequestsWithLanguage(this.localizationService.getCurrentLanguage()) |
|
106 |
.subscribe((data: VacationRequest[]) => this.vacationRequests = data); |
|
107 |
} |
|
108 |
|
|
109 |
private loadMonthVacation(month: Date) { |
|
110 |
const fromDate = this.dateToolsService.toStartOfMonth(month); |
|
111 |
const toDate = this.dateToolsService.toEndOfMonth(fromDate); |
|
112 |
|
|
113 |
this.userService.getLoggedUserCalendarWithOptions(fromDate, toDate, this.localizationService.getCurrentLanguage(), RequestStatus.ACCEPTED) |
|
114 |
.subscribe((data: Calendar[]) => { |
|
115 |
if (data) { |
|
116 |
this.calendar.setVacation(data); |
|
117 |
} |
|
118 |
}); |
|
119 |
} |
|
120 |
|
|
121 |
private loadOncomingVacation() { |
|
122 |
const fromDate = new Date(); |
|
123 |
|
|
124 |
this.userService.getLoggedUserCalendarWithOptions(fromDate, null, this.localizationService.getCurrentLanguage(), null) |
|
125 |
.subscribe((data: Calendar[]) => this.oncomingVacation = data); |
|
60 | 126 |
} |
61 | 127 |
} |
webapp/src/app/dashboard/employer-dashboard/employer-dashboard.module.ts | ||
---|---|---|
2 | 2 |
import { CommonModule } from '@angular/common'; |
3 | 3 |
import { EmployerDashboardComponent } from './employer-dashboard.component'; |
4 | 4 |
import { DayPickerModule } from '../../day-picker/day-picker.module'; |
5 |
import { DaysOffInfoModule } from '../../days-off-info/days-off-info.module';
|
|
5 |
import { VacationInfoModule } from '../../vacation-info/vacation-info.module';
|
|
6 | 6 |
import { UserApprovalModule } from '../../user-approval/user-approval.module'; |
7 |
import { DaysOffApprovalModule } from '../../days-off-approval/days-off-approval.module';
|
|
8 |
import { OncomingDaysOffModule } from '../../oncoming-days-off/oncoming-days-off.module';
|
|
7 |
import { VacationApprovalModule } from '../../vacation-approval/vacation-approval.module';
|
|
8 |
import { OncomingVacationModule } from '../../oncoming-vacation/oncoming-vacation.module';
|
|
9 | 9 |
import {BrowserAnimationsModule} from '@angular/platform-browser/animations'; |
10 |
import {AddDaysOffDialogModule} from '../../add-days-off-dialog/add-days-off-dialog.module';
|
|
10 |
import {AddVacationDialogModule} from '../../add-vacation-dialog/add-vacation-dialog.module';
|
|
11 | 11 |
import {MatDialogModule} from '@angular/material'; |
12 |
import {EditVacationDialogModule} from '../../edit-vacation-dialog/edit-vacation-dialog.module'; |
|
12 | 13 |
|
13 | 14 |
@NgModule({ |
14 | 15 |
declarations: [ EmployerDashboardComponent ], |
... | ... | |
16 | 17 |
imports: [ |
17 | 18 |
CommonModule, |
18 | 19 |
DayPickerModule, |
19 |
DaysOffInfoModule,
|
|
20 |
VacationInfoModule,
|
|
20 | 21 |
UserApprovalModule, |
21 |
DaysOffApprovalModule,
|
|
22 |
VacationApprovalModule,
|
|
22 | 23 |
DayPickerModule, |
23 |
OncomingDaysOffModule,
|
|
24 |
OncomingVacationModule,
|
|
24 | 25 |
BrowserAnimationsModule, |
25 |
AddDaysOffDialogModule, |
|
26 |
AddVacationDialogModule, |
|
27 |
EditVacationDialogModule, |
|
26 | 28 |
MatDialogModule |
27 | 29 |
] |
28 | 30 |
}) |
webapp/src/app/day-picker/day-picker.component.html | ||
---|---|---|
29 | 29 |
</div> |
30 | 30 |
</div> |
31 | 31 |
|
32 |
<!-- Refresh attribute for localization purposes (refresh component after change of language) --> |
|
33 | 32 |
<mwl-calendar-month-view |
34 | 33 |
[viewDate]="viewDate" |
35 | 34 |
[locale]="locale" |
36 |
[refresh]="localizationService.currentLanguageSubject"
|
|
35 |
[refresh]="refresh"
|
|
37 | 36 |
[events]="events" |
38 | 37 |
[cellTemplate]="customCellTemplate" |
39 | 38 |
(dayClicked)="dayClicked($event.day)" |
... | ... | |
51 | 50 |
<i class="material-icons sickday" *ngIf="event.title == vacationType.SICKDAY">local_hospital</i> |
52 | 51 |
<i class="material-icons vacation" *ngIf="event.title == vacationType.VACATION">beach_access</i> |
53 | 52 |
|
54 |
{{ event.start | date:'HH:mm' }} - {{ event.end | date:'HH:mm' }} |
|
53 |
<span class="time-interval" *ngIf="event.title == vacationType.VACATION"> |
|
54 |
{{ event.start | date:'HH:mm' }} - {{ event.end | date:'HH:mm' }} |
|
55 |
</span> |
|
55 | 56 |
</span> |
56 | 57 |
</ng-template> |
57 | 58 |
</div> |
webapp/src/app/day-picker/day-picker.component.sass | ||
---|---|---|
9 | 9 |
line-height: 45px |
10 | 10 |
text-align: center |
11 | 11 |
|
12 |
|
|
13 | 12 |
.day-picker-month-selection |
14 | 13 |
margin-bottom: 10px |
15 | 14 |
button |
... | ... | |
18 | 17 |
.change-month |
19 | 18 |
color: blue |
20 | 19 |
|
21 |
|
|
22 |
|
|
23 | 20 |
.vacation-type |
24 | 21 |
font-size: 10px |
25 | 22 |
.material-icons |
... | ... | |
28 | 25 |
color: red |
29 | 26 |
.vacation |
30 | 27 |
color: blue |
28 |
.time-interval |
|
29 |
font-size: 10px |
webapp/src/app/day-picker/day-picker.component.ts | ||
---|---|---|
1 |
import { Component, ChangeDetectionStrategy, Input, Output, EventEmitter } from '@angular/core';
|
|
2 |
import { CalendarView, CalendarEvent } from 'angular-calendar';
|
|
1 |
import {ChangeDetectionStrategy, Component, EventEmitter, Output} from '@angular/core';
|
|
2 |
import {CalendarEvent, CalendarView} from 'angular-calendar';
|
|
3 | 3 |
import {LocalizationService} from '../localization/localization.service'; |
4 | 4 |
import {VacationType} from '../enums/common.enum'; |
5 |
import {Calendar} from '../models/calendar.model'; |
|
6 |
import {DateToolsService} from '../services/util/date-tools.service'; |
|
7 |
import {Subject} from 'rxjs'; |
|
5 | 8 |
|
6 | 9 |
@Component({ |
7 | 10 |
selector: 'app-day-picker', |
... | ... | |
17 | 20 |
|
18 | 21 |
private currentMonth: number; |
19 | 22 |
|
23 |
private currentYear: number; |
|
24 |
|
|
20 | 25 |
// Type of calendar (constant) |
21 | 26 |
view: CalendarView = CalendarView.Month; |
22 | 27 |
|
... | ... | |
24 | 29 |
private viewDate: Date; |
25 | 30 |
|
26 | 31 |
// Events which are shown in calendar (title = VacationType) |
27 |
@Input() events: CalendarEvent[] = [];
|
|
32 |
private events: CalendarEvent[] = [];
|
|
28 | 33 |
|
29 | 34 |
// EventEmitter informing about changes of selected date |
30 | 35 |
@Output() selectedDate = new EventEmitter<Date>(); |
31 | 36 |
|
32 |
// EventEmitter informing about changes of selected month |
|
33 |
@Output() selectedMonth = new EventEmitter<number>(); |
|
37 |
// EventEmitter informing about changes of selected month (emits start of the selected month) |
|
38 |
@Output() selectedMonth = new EventEmitter<Date>(); |
|
39 |
|
|
40 |
private refresh: Subject<any> = new Subject(); |
|
41 |
|
|
42 |
constructor( |
|
43 |
private localizationService: LocalizationService, |
|
44 |
private dateToolsService: DateToolsService) { |
|
34 | 45 |
|
35 |
constructor(private localizationService: LocalizationService) { |
|
36 | 46 |
this.locale = localizationService.defaultLanguage; |
37 | 47 |
localizationService.currentLanguageSubject |
38 | 48 |
.subscribe((data) => { |
... | ... | |
41 | 51 |
|
42 | 52 |
this.viewDate = new Date(); |
43 | 53 |
this.currentMonth = this.viewDate.getMonth(); |
54 |
this.currentYear = this.viewDate.getFullYear(); |
|
55 |
|
|
56 |
// Calendar component needs to be refreshed on language switch or else language switch doesn't have an effect |
|
57 |
this.localizationService.currentLanguageSubject.subscribe(e => this.refresh.next()); |
|
58 |
} |
|
59 |
|
|
60 |
public setVacation(vacations: Calendar[]) { |
|
61 |
this.events = []; |
|
62 |
|
|
63 |
for (const vac of vacations) { |
|
64 |
this.events.push({ |
|
65 |
start: this.dateToolsService.toDate(vac.date, vac.from), |
|
66 |
end: this.dateToolsService.toDate(vac.date, vac.to), |
|
67 |
title: vac.type |
|
68 |
}); |
|
69 |
} |
|
70 |
|
|
71 |
this.refresh.next(); |
|
44 | 72 |
} |
45 | 73 |
|
46 | 74 |
/** |
... | ... | |
56 | 84 |
|
57 | 85 |
private setMonth(newMonth: number): void { |
58 | 86 |
this.currentMonth = newMonth % 12; |
59 |
if (this.currentMonth < 0) {
|
|
87 |
if (newMonth < 0) {
|
|
60 | 88 |
this.currentMonth = 11; |
89 |
this.currentYear--; |
|
90 |
} else if (newMonth > 11) { |
|
91 |
this.currentMonth = 0; |
|
92 |
this.currentYear++; |
|
93 |
} else { |
|
94 |
this.currentMonth = newMonth; |
|
61 | 95 |
} |
62 |
this.selectedMonth.emit(this.currentMonth); |
|
96 |
|
|
97 |
this.selectedMonth.emit(new Date(this.currentYear, this.currentMonth, 1, 0, 0, 0)); |
|
63 | 98 |
} |
64 | 99 |
} |
webapp/src/app/days-off-approval/days-off-approval.component.html | ||
---|---|---|
1 |
<div class="days-off-approval-container" *ngIf="daysOffRequests"> |
|
2 |
|
|
3 |
<div class="component-header"> |
|
4 |
Schvalování volna |
|
5 |
</div> |
|
6 |
|
|
7 |
<div class="days-off-approval-list"> |
|
8 |
<div class="row days-off-approval-header"> |
|
9 |
<div class="col-md-3"> Jméno </div> |
|
10 |
<div class="col-md-3"> Typ volna </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> |
|
14 |
<div class="col-md-2"></div> |
|
15 |
</div> |
|
16 |
|
|
17 |
<div class="row days-off-approval" *ngFor="let request of daysOffRequests.vacation"> |
|
18 |
<div class="col-md-3"> |
|
19 |
{{request.user.name.first}} {{request.user.name.last}} |
|
20 |
</div> |
|
21 |
<div class="col-md-3"> |
|
22 |
{{daysOffTypeToString(request.type)}} |
|
23 |
</div> |
|
24 |
<div class="col-md-2"> |
|
25 |
{{request.date | date:'yyyy/MM/dd'}} |
|
26 |
</div> |
|
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 --> |
|
32 |
</div> |
|
33 |
<div class="col-md-2"> |
|
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> |
|
36 |
</div> |
|
37 |
</div> |
|
38 |
</div> |
|
39 |
|
|
40 |
</div> |
webapp/src/app/days-off-approval/days-off-approval.component.sass | ||
---|---|---|
1 |
@import '../../common-styles/basic-component' |
|
2 |
|
|
3 |
.days-off-approval-container |
|
4 |
@extend .basic-component |
|
5 |
|
|
6 |
.days-off-approval-header |
|
7 |
padding: 10px |
|
8 |
margin: 0 |
|
9 |
font-weight: bold |
|
10 |
|
|
11 |
.days-off-approval |
|
12 |
border-bottom: 1px solid gainsboro |
|
13 |
margin: 0 |
|
14 |
padding: 10px |
|
15 |
line-height: 35px |
|
16 |
|
|
17 |
.approve-btn |
|
18 |
margin-right: 2px |
webapp/src/app/days-off-approval/days-off-approval.component.ts | ||
---|---|---|
1 |
import { Component, EventEmitter, Output, Input } from '@angular/core'; |
|
2 |
import {Requests} from '../models/requests.model'; // TODO |
|
3 |
import {VacationType} from '../enums/common.enum'; |
|
4 |
|
|
5 |
@Component({ |
|
6 |
selector: 'app-days-off-approval', |
|
7 |
templateUrl: './days-off-approval.component.html', |
|
8 |
styleUrls: ['./days-off-approval.component.sass'] |
|
9 |
}) |
|
10 |
export class DaysOffApprovalComponent { |
|
11 |
|
|
12 |
@Input() daysOffRequests: Requests; |
|
13 |
@Output() daysOffApprovalEvent = new EventEmitter<{requestId: number, approved: boolean}>(); |
|
14 |
|
|
15 |
constructor() { } |
|
16 |
|
|
17 |
daysOffApprovalCompleted(reqId: number, isApproved: boolean ) { |
|
18 |
this.daysOffApprovalEvent.emit({requestId: reqId, approved: isApproved}); |
|
19 |
} |
|
20 |
|
|
21 |
private daysOffTypeToString(vacationType: VacationType): string { |
|
22 |
switch (vacationType) { |
|
23 |
case VacationType.VACATION: |
|
24 |
return 'Extra dovolená'; |
|
25 |
case VacationType.SICKDAY: |
|
26 |
return 'Sickdays'; |
|
27 |
} |
|
28 |
} |
|
29 |
} |
webapp/src/app/days-off-approval/days-off-approval.module.ts | ||
---|---|---|
1 |
import { NgModule } from '@angular/core'; |
|
2 |
import { DaysOffApprovalComponent } from './days-off-approval.component'; |
|
3 |
import { BrowserModule } from '@angular/platform-browser'; |
|
4 |
|
|
5 |
@NgModule({ |
|
6 |
declarations: [ DaysOffApprovalComponent ], |
|
7 |
exports: [ DaysOffApprovalComponent ], |
|
8 |
imports: [ BrowserModule ] |
|
9 |
}) |
|
10 |
export class DaysOffApprovalModule { } |
webapp/src/app/days-off-info/days-off-info.component.html | ||
---|---|---|
1 |
<div class="days-off-info-container"> |
|
2 |
|
|
3 |
<div class="component-header" translate> |
|
4 |
<!-- TODO--> |
|
5 |
<span translate>daysOffInfo.remaining</span> |
|
6 |
</div> |
|
7 |
|
|
8 |
<div class="days-off-type-container"> |
|
9 |
<span class="days-off-remaining">{{extraVacationRemaining.value}}</span> |
|
10 |
<!-- TODO vypsat jednotky (.unit)--> |
|
11 |
<span class="days-off-type" translate>vacationType.vacation</span> |
|
12 |
</div> |
|
13 |
|
|
14 |
<div class="days-off-type-container"> |
|
15 |
<span class="days-off-remaining">{{sickDaysRemaining.value}}</span> |
|
16 |
<!-- TODO vypsat jednotky (.unit)--> |
|
17 |
<span class="days-off-type" translate>vacationType.sickday</span> |
|
18 |
</div> |
|
19 |
|
|
20 |
</div> |
webapp/src/app/days-off-info/days-off-info.component.sass | ||
---|---|---|
1 |
@import '../../common-styles/basic-component' |
|
2 |
|
|
3 |
.days-off-info-container |
|
4 |
@extend .basic-component |
|
5 |
|
|
6 |
.days-off-type-container |
|
7 |
border-bottom: 1px solid gainsboro |
|
8 |
padding-left: 20px |
|
9 |
|
|
10 |
.days-off-remaining |
|
11 |
color: green |
|
12 |
font-size: 30px |
|
13 |
font-weight: bold |
|
14 |
|
|
15 |
.days-off-type |
|
16 |
color: black |
|
17 |
font-weight: bold |
|
18 |
display: block |
webapp/src/app/days-off-info/days-off-info.component.ts | ||
---|---|---|
1 |
import { Component, Input } from '@angular/core'; |
|
2 |
import {TimeUnit} from '../enums/common.enum'; |
|
3 |
import {LocalizationService} from '../localization/localization.service'; |
|
4 |
|
|
5 |
@Component({ |
|
6 |
selector: 'app-days-off-info', |
|
7 |
templateUrl: './days-off-info.component.html', |
|
8 |
styleUrls: ['./days-off-info.component.sass'] |
|
9 |
}) |
|
10 |
export class DaysOffInfoComponent { |
|
11 |
|
|
12 |
@Input() sickDaysRemaining: { |
|
13 |
value: number; |
|
14 |
unit: TimeUnit; |
|
15 |
}; |
|
16 |
|
|
17 |
@Input() extraVacationRemaining: { |
|
18 |
value: number; |
|
19 |
unit: TimeUnit; |
|
20 |
}; |
|
21 |
|
|
22 |
constructor(private localizationService: LocalizationService) { } |
|
23 |
} |
webapp/src/app/days-off-info/days-off-info.module.ts | ||
---|---|---|
1 |
import { NgModule } from '@angular/core'; |
|
2 |
import { DaysOffInfoComponent } from './days-off-info.component'; |
|
3 |
import {TranslateModule} from '@ngx-translate/core'; |
|
4 |
|
|
5 |
@NgModule({ |
|
6 |
imports: [TranslateModule], |
|
7 |
declarations: [ DaysOffInfoComponent ], |
|
8 |
exports: [ DaysOffInfoComponent ] |
|
9 |
}) |
|
10 |
export class DaysOffInfoModule { } |
webapp/src/app/edit-vacation-dialog/edit-vacation-dialog.component.html | ||
---|---|---|
1 |
<h1 mat-dialog-title>Úprava volna</h1> |
|
2 |
|
|
3 |
<div mat-dialog-content> |
|
4 |
<div> |
|
5 |
<label id="days-off-type-radio-group-label" class="dialog-label">Typ volna</label> |
|
6 |
<mat-radio-group aria-labelledby="days-off-type-radio-group-label" class="days-off-type-radio-group" [(ngModel)]="selectedVacationType"> |
|
7 |
<mat-radio-button class="days-off-type-radio-button" *ngFor="let type of vacationTypes" [value]="type" > |
|
8 |
{{type}} |
|
9 |
</mat-radio-button> |
|
10 |
</mat-radio-group> |
|
11 |
</div> |
|
12 |
|
|
13 |
<div class="datetime-interval"> |
|
14 |
<div class="from-datetime"> |
|
15 |
<label for="from-datetime-input" class="dialog-label">Od:</label> |
|
16 |
<div class="datetime-picker"> |
|
17 |
<mat-form-field> |
|
18 |
<input id="from-datetime-input" matInput [matDatepicker]="startDatePicker" [(ngModel)]="data.fromDate"> |
|
19 |
<mat-datepicker-toggle matSuffix [for]="startDatePicker"></mat-datepicker-toggle> |
|
20 |
<mat-datepicker #startDatePicker></mat-datepicker> |
|
21 |
</mat-form-field> |
|
22 |
<ngb-timepicker [(ngModel)]="data.fromTime" [minuteStep]="MINUTE_STEP"></ngb-timepicker> |
|
23 |
</div> |
|
24 |
</div> |
|
25 |
|
|
26 |
<div class="to-datetime"> |
|
27 |
<label for="to-datetime-input" class="dialog-label">Do:</label> |
|
28 |
<div class="datetime-picker"> |
|
29 |
<mat-form-field> |
|
30 |
<input id="to-datetime-input" matInput [matDatepicker]="endDatePicker" [(ngModel)]="data.toDate"> |
|
31 |
<mat-datepicker-toggle matSuffix [for]="endDatePicker"></mat-datepicker-toggle> |
|
32 |
<mat-datepicker #endDatePicker></mat-datepicker> |
|
33 |
</mat-form-field> |
|
34 |
<ngb-timepicker [(ngModel)]="data.toTime" [minuteStep]="MINUTE_STEP"></ngb-timepicker> |
|
35 |
</div> |
|
36 |
</div> |
|
37 |
</div> |
|
38 |
</div> |
|
39 |
|
|
40 |
<div mat-dialog-actions align="end"> |
|
41 |
<button mat-raised-button color="primary" (click)="onConfirmClick()">Potvrdit</button> |
|
42 |
<button mat-raised-button color="basic" (click)="onCloseClick()">Zavřít</button> |
|
43 |
</div> |
webapp/src/app/edit-vacation-dialog/edit-vacation-dialog.component.sass | ||
---|---|---|
1 |
.dialog-label |
|
2 |
display: block |
|
3 |
font-weight: bold |
|
4 |
|
|
5 |
.datetime-picker > * |
|
6 |
display: table-cell |
|
7 |
|
|
8 |
.days-off-type-radio-group |
|
9 |
display: flex |
|
10 |
flex-direction: column |
|
11 |
margin: 15px 0 |
webapp/src/app/edit-vacation-dialog/edit-vacation-dialog.component.ts | ||
---|---|---|
1 |
import {Component, Inject, Output} from '@angular/core'; |
|
2 |
import { MAT_DIALOG_DATA, MatDialogRef, MatSnackBar } from '@angular/material'; |
|
3 |
import { FormControl } from '@angular/forms'; |
|
4 |
import {Calendar} from '../models/calendar.model'; |
|
5 |
|
|
6 |
@Component({ |
|
7 |
selector: 'app-edit-days-off-dialog', |
|
8 |
templateUrl: './edit-vacation-dialog.component.html', |
|
9 |
styleUrls: ['./edit-vacation-dialog.component.sass'] |
|
10 |
}) |
|
11 |
export class EditVacationDialogComponent { |
|
12 |
MINUTE_STEP = 15; |
|
13 |
|
|
14 |
constructor( |
|
15 |
public dialogRef: MatDialogRef<EditVacationDialogComponent>, |
|
16 |
@Inject(MAT_DIALOG_DATA) public data: EditVacationDialogData, |
|
17 |
private snackBar: MatSnackBar |
|
18 |
) { |
|
19 |
} |
|
20 |
|
|
21 |
onConfirmClick(): void { |
|
22 |
this.dialogRef.close({ |
|
23 |
edited: true, |
|
24 |
date: this.data.vacation.date, |
|
25 |
from: this.data.vacation.from, |
|
26 |
to: this.data.vacation.to |
|
27 |
}); |
|
28 |
} |
|
29 |
|
|
30 |
onCloseClick(): void { |
|
31 |
this.dialogRef.close({ |
|
32 |
edited: false |
|
33 |
} |
|
34 |
); |
|
35 |
} |
|
36 |
} |
|
37 |
|
|
38 |
export interface EditVacationDialogData { |
|
39 |
vacation: Calendar; |
|
40 |
} |
webapp/src/app/edit-vacation-dialog/edit-vacation-dialog.module.ts | ||
---|---|---|
1 |
import { NgModule } from '@angular/core'; |
|
2 |
import { CommonModule } from '@angular/common'; |
|
3 |
import { BrowserAnimationsModule } from '@angular/platform-browser/animations'; |
|
4 |
import { |
|
5 |
MatButtonModule, |
|
6 |
MatDialogModule, |
|
7 |
MatDatepickerModule, |
|
8 |
MatNativeDateModule, |
|
9 |
MatInputModule, MatRadioModule, MatSnackBarModule |
|
10 |
} from '@angular/material'; |
|
11 |
import {NgbModule} from '@ng-bootstrap/ng-bootstrap'; |
|
12 |
import {FormsModule, ReactiveFormsModule} from '@angular/forms'; |
|
13 |
import {BrowserModule} from '@angular/platform-browser'; |
|
14 |
import {EditVacationDialogComponent} from './edit-vacation-dialog.component'; |
|
15 |
|
|
16 |
@NgModule({ |
|
17 |
declarations: [EditVacationDialogComponent], |
|
18 |
imports: [ |
|
19 |
CommonModule, |
|
20 |
BrowserAnimationsModule, |
|
21 |
MatButtonModule, |
|
22 |
MatDialogModule, |
|
23 |
NgbModule, |
|
24 |
FormsModule, |
|
25 |
MatDatepickerModule, |
|
26 |
MatNativeDateModule, |
|
27 |
ReactiveFormsModule, |
|
28 |
BrowserModule, |
|
29 |
MatInputModule, |
|
30 |
MatRadioModule, |
|
31 |
MatSnackBarModule |
|
32 |
], |
|
33 |
exports: [ |
|
34 |
EditVacationDialogComponent |
|
35 |
], |
|
36 |
entryComponents: [ |
|
37 |
EditVacationDialogComponent |
|
38 |
] |
|
39 |
}) |
|
40 |
export class EditVacationDialogModule { } |
webapp/src/app/employees/employees-list.component.ts | ||
---|---|---|
121 | 121 |
.afterClosed().subscribe(data => { |
122 | 122 |
if (data && data.isConfirmed) { |
123 | 123 |
this.settingsService.postDefaultSettingsWithLanguage(this.toSettings(data), this.localizationService.getCurrentLanguage()) |
124 |
.subscribe((foo: any) => console.log(foo));
|
|
124 |
.subscribe(); |
|
125 | 125 |
} |
126 | 126 |
}); |
127 | 127 |
}, |
webapp/src/app/header/header.component.html | ||
---|---|---|
5 | 5 |
<button (click)="localizationService.switchLanguage('en')">EN</button> |
6 | 6 |
<button class="user-info" (click)="onProfileClick()"> |
7 | 7 |
<img class="user-icon" src="../../assets/images/default-user.png"/> |
8 |
<span class="user-name">{{name}}</span>
|
|
8 |
<span *ngIf="profile" class="user-name">{{profile.firstName}} {{profile.lastName}}</span>
|
|
9 | 9 |
</button> |
10 | 10 |
</div> |
11 | 11 |
</div> |
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/api/profile.service'; |
|
5 | 4 |
import {LocalizationService} from '../localization/localization.service'; |
5 |
import {UserService} from '../services/api/user.service'; |
|
6 |
import {UserProfile} from '../models/user.model'; |
|
6 | 7 |
|
7 | 8 |
@Component({ |
8 | 9 |
selector: 'app-header', |
... | ... | |
10 | 11 |
styleUrls: ['./header.component.sass'] |
11 | 12 |
}) |
12 | 13 |
export class HeaderComponent { |
13 |
@Input() name = 'John Doe'; |
|
14 |
|
|
15 |
private notificationSettings: Date; |
|
14 |
profile: UserProfile; |
|
16 | 15 |
|
17 | 16 |
constructor( |
18 | 17 |
private dialog: MatDialog, |
19 |
private profileService: ProfileService,
|
|
20 |
private localizationService: LocalizationService
|
|
18 |
private localizationService: LocalizationService,
|
|
19 |
private userService: UserService
|
|
21 | 20 |
) { |
22 |
// profileService.getProfile()
|
|
23 |
// .subscribe((data: UserProfile) => this.notificationSettings = new Date(data.settings.notification));
|
|
21 |
userService.getLoggedUserProfile()
|
|
22 |
.subscribe((data: UserProfile) => this.profile = data);
|
|
24 | 23 |
} |
25 | 24 |
|
26 | 25 |
onProfileClick(): void { |
27 |
this.dialog.open(ProfileSettingsComponent, {
|
|
28 |
data: {
|
|
29 |
shouldNotify: this.notificationSettings, // TODO potřeba?
|
|
30 |
notifyDate: this.notificationSettings, |
|
31 |
notifyTime: { |
|
32 |
hour: this.notificationSettings.getHours(), |
|
33 |
minute: this.notificationSettings.getMinutes() |
|
34 |
} |
|
35 |
} |
|
36 |
}); |
|
26 |
// TODO (až bude hotovej endpoint na post notifikace)
|
|
27 |
// this.dialog.open(ProfileSettingsComponent, {
|
|
28 |
// data: {
|
|
29 |
// notifyDate: this.notificationSettings,
|
|
30 |
// notifyTime: {
|
|
31 |
// hour: this.notificationSettings.getHours(),
|
|
32 |
// minute: this.notificationSettings.getMinutes()
|
|
33 |
// }
|
|
34 |
// }
|
|
35 |
// });
|
|
37 | 36 |
} |
38 | 37 |
} |
webapp/src/app/models/calendar.model.ts | ||
---|---|---|
4 | 4 |
export interface Calendar { |
5 | 5 |
id: number; |
6 | 6 |
date: string; |
7 |
from: Time;
|
|
8 |
to: Time;
|
|
7 |
from: string;
|
|
8 |
to: string;
|
|
9 | 9 |
type: VacationType; |
10 | 10 |
status: RequestStatus; |
11 | 11 |
} |
webapp/src/app/oncoming-days-off/oncoming-days-off.component.html | ||
---|---|---|
1 |
<div class="oncoming-days-off-container"> |
|
2 |
|
|
3 |
<div class="component-header"> |
|
4 |
Mé nadcházející volno |
|
5 |
</div> |
|
6 |
|
|
7 |
<div class="tasks-list"> |
|
8 |
<div class="row oncoming-days-off-header"> |
|
9 |
<div class="col-md-6"> |
|
10 |
Typ volna |
|
11 |
</div> |
|
12 |
|
|
13 |
<div class="col-md-2"> |
|
14 |
Od |
|
15 |
</div> |
|
16 |
|
|
17 |
<div class="col-md-2"> |
|
18 |
Do |
|
19 |
</div> |
|
20 |
|
|
21 |
<div class="col-md-2"> |
|
22 |
</div> |
|
23 |
</div> |
|
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>--> |
|
42 |
</div> |
|
43 |
|
|
44 |
</div> |
webapp/src/app/oncoming-days-off/oncoming-days-off.component.sass | ||
---|---|---|
1 |
@import '../../common-styles/basic-component' |
|
2 |
|
|
3 |
.oncoming-days-off-container |
|
4 |
@extend .basic-component |
|
5 |
|
|
6 |
.oncoming-days-off-header |
|
7 |
padding: 10px |
|
8 |
margin: 0 |
|
9 |
font-weight: bold |
|
10 |
|
|
11 |
.oncoming-days-off |
|
12 |
border-bottom: 1px solid gainsboro |
|
13 |
margin: 0 |
|
14 |
padding: 10px |
|
15 |
line-height: 35px |
|
16 |
|
|
17 |
.approve-btn |
|
18 |
margin-right: 2px |
webapp/src/app/oncoming-days-off/oncoming-days-off.component.ts | ||
---|---|---|
1 |
import {Component, OnInit} from '@angular/core'; |
|
2 |
import {UserService} from '../services/api/user.service'; |
|
3 |
import {VacationType} from '../enums/common.enum'; |
|
4 |
|
|
5 |
@Component({ |
|
6 |
selector: 'app-coming-days-off', |
|
7 |
templateUrl: './oncoming-days-off.component.html', |
|
8 |
styleUrls: ['./oncoming-days-off.component.sass'] |
|
9 |
}) |
|
10 |
export class OncomingDaysOffComponent implements OnInit { |
|
11 |
|
|
12 |
constructor( |
|
13 |
private userService: UserService |
|
14 |
) { } |
|
15 |
|
|
16 |
ngOnInit() { |
|
17 |
// TODO api call na získání nadcházejících voln |
|
18 |
} |
|
19 |
|
|
20 |
private daysOffRemoved( daysOffId: number ) { |
|
21 |
// TODO api call na odstranění nadcházejícího volna |
|
22 |
} |
|
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 |
|
|
38 |
// TODO |
|
39 |
// days-off-approval duplicate |
|
40 |
private daysOffTypeToString(vacationType: VacationType): string { |
|
41 |
switch (vacationType) { |
|
42 |
case VacationType.VACATION: |
|
43 |
return 'Extra dovolená'; |
|
44 |
case VacationType.SICKDAY: |
|
45 |
return 'Sickdays'; |
|
46 |
} |
|
47 |
} |
|
48 |
} |
webapp/src/app/oncoming-days-off/oncoming-days-off.module.ts | ||
---|---|---|
1 |
import { NgModule } from '@angular/core'; |
|
2 |
import { OncomingDaysOffComponent } from './oncoming-days-off.component'; |
|
3 |
import { BrowserModule } from '@angular/platform-browser'; |
|
4 |
|
|
5 |
@NgModule({ |
|
6 |
declarations: [ OncomingDaysOffComponent ], |
|
7 |
exports: [ OncomingDaysOffComponent ], |
|
8 |
imports: [ BrowserModule ], |
|
9 |
}) |
|
10 |
export class OncomingDaysOffModule {} |
webapp/src/app/oncoming-vacation/oncoming-vacation.component.html | ||
---|---|---|
1 |
<div class="oncoming-days-off-container"> |
|
2 |
|
|
3 |
<div class="component-header"> |
|
4 |
Mé nadcházející volno |
|
5 |
</div> |
|
6 |
|
|
7 |
<table class="table text-center table-hover"> |
|
8 |
<thead class="thead-light"> |
|
9 |
<tr> |
|
10 |
<th>Typ volna</th> |
|
11 |
<th>Datum</th> |
|
12 |
<th>Od</th> |
|
13 |
<th>Do</th> |
|
14 |
<th>Status</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}} |
|
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%"> |
|
37 |
{{vac.status}} |
|
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/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 |
.buttons |
|
14 |
text-align: right |
|
15 |
padding-right: 50px |
|
16 |
|
|
17 |
button |
|
18 |
outline: none |
|
19 |
|
|
20 |
.edit-btn |
|
21 |
font-size: 18px |
|
22 |
margin-right: 2px |
|
23 |
color: orange |
|
24 |
|
|
25 |
.remove-btn |
|
26 |
color: grey |
webapp/src/app/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 |
@Output() vacationEdit = new EventEmitter<Calendar>(); |
|
16 |
|
|
17 |
constructor() { } |
|
18 |
|
|
19 |
ngOnInit() { } |
Také k dispozici: Unified diff
Re #7494 Components connected to API - except profile settings and add vacation components