@skysoftware-co/bayan-hr-widgets-ui 2.0.25 → 2.0.27
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/ng-package.json +9 -0
- package/package.json +3 -15
- package/src/assets/i18n/ar.json +166 -0
- package/src/assets/i18n/en.json +166 -0
- package/src/assets/i18n/fr.json +166 -0
- package/src/lib/my-calendar-widget/my-calendar-widget.component.html +25 -0
- package/src/lib/my-calendar-widget/my-calendar-widget.component.ts +220 -0
- package/src/lib/my-main-details-widget/my-main-details-widget.component.html +157 -0
- package/src/lib/my-main-details-widget/my-main-details-widget.component.ts +179 -0
- package/src/lib/my-next-week-vacation-insights-widget/components/next-week-vacation-insights-popup/next-week-vacation-insights-popup.component.html +131 -0
- package/src/lib/my-next-week-vacation-insights-widget/components/next-week-vacation-insights-popup/next-week-vacation-insights-popup.component.ts +119 -0
- package/src/lib/my-next-week-vacation-insights-widget/my-next-week-vacation-insights-widget.component.html +35 -0
- package/src/lib/my-next-week-vacation-insights-widget/my-next-week-vacation-insights-widget.component.ts +110 -0
- package/src/lib/my-profile/address-widget/my-profile-address-widget.component.html +57 -0
- package/src/lib/my-profile/address-widget/my-profile-address-widget.component.ts +70 -0
- package/src/lib/my-profile/bank-info-widget/my-profile-bank-info-widget.component.html +101 -0
- package/src/lib/my-profile/bank-info-widget/my-profile-bank-info-widget.component.ts +89 -0
- package/src/lib/my-profile/contact-widget/my-profile-contact-widget.component.html +89 -0
- package/src/lib/my-profile/contact-widget/my-profile-contact-widget.component.ts +78 -0
- package/src/lib/my-profile/contract-widget/my-profile-contract-widget.component.html +63 -0
- package/src/lib/my-profile/contract-widget/my-profile-contract-widget.component.ts +73 -0
- package/src/lib/my-profile/degrees-widget/my-profile-degrees-widget-component.html +86 -0
- package/src/lib/my-profile/degrees-widget/my-profile-degrees-widget-component.ts +98 -0
- package/src/lib/my-profile/dependents-documents-widget/my-profile-dependents-documents-widget.html +83 -0
- package/src/lib/my-profile/dependents-documents-widget/my-profile-dependents-documents-widget.ts +126 -0
- package/src/lib/my-profile/documents-widgets/components/document-card/document-card.component.html +53 -0
- package/src/lib/my-profile/documents-widgets/components/document-card/document-card.component.ts +50 -0
- package/src/lib/my-profile/documents-widgets/components/document-row/document-row.component.html +48 -0
- package/src/lib/my-profile/documents-widgets/components/document-row/document-row.component.ts +44 -0
- package/src/lib/my-profile/documents-widgets/components/document-tablet-card/document-tablet-card.component.html +46 -0
- package/src/lib/my-profile/documents-widgets/components/document-tablet-card/document-tablet-card.component.ts +47 -0
- package/src/lib/my-profile/employee-dependents-widget/my-profile-employee-dependents-component.html +50 -0
- package/src/lib/my-profile/employee-dependents-widget/my-profile-employee-dependents-component.ts +63 -0
- package/src/lib/my-profile/entitlements-others-widget/my-profile-entitlements-others-widget.component.html +26 -0
- package/src/lib/my-profile/entitlements-others-widget/my-profile-entitlements-others-widget.component.ts +66 -0
- package/src/lib/my-profile/experiences-widget/my-profile-experiences-widget-component.html +93 -0
- package/src/lib/my-profile/experiences-widget/my-profile-experiences-widget-component.ts +102 -0
- package/src/lib/my-profile/indemnity-widget/my-profile-indemnity-widget.component.html +49 -0
- package/src/lib/my-profile/indemnity-widget/my-profile-indemnity-widget.component.ts +79 -0
- package/src/lib/my-profile/job-info-widget/my-profile-job-info-widget.component.html +71 -0
- package/src/lib/my-profile/job-info-widget/my-profile-job-info-widget.component.ts +73 -0
- package/src/lib/my-profile/languages-widget/my-profile-languages-widget.component.html +23 -0
- package/src/lib/my-profile/languages-widget/my-profile-languages-widget.component.ts +70 -0
- package/src/lib/my-profile/medical-insurance-widget/components/medical-insurance-card/medical-insurance-card.component.html +18 -0
- package/src/lib/my-profile/medical-insurance-widget/components/medical-insurance-card/medical-insurance-card.component.ts +29 -0
- package/src/lib/my-profile/medical-insurance-widget/my-profile-medical-insurance-widget.component.html +52 -0
- package/src/lib/my-profile/medical-insurance-widget/my-profile-medical-insurance-widget.component.ts +103 -0
- package/src/lib/my-profile/official-documents-widget/my-profile-official-documents-widget.html +82 -0
- package/src/lib/my-profile/official-documents-widget/my-profile-official-documents-widget.ts +119 -0
- package/src/lib/my-profile/other-nationalities-widget/my-profile-other-nationalities-widget.component.html +23 -0
- package/src/lib/my-profile/other-nationalities-widget/my-profile-other-nationalities-widget.component.ts +70 -0
- package/src/lib/my-profile/personal-info-main-widget/my-profile-personal-info-main-widget.component.html +115 -0
- package/src/lib/my-profile/personal-info-main-widget/my-profile-personal-info-main-widget.component.ts +75 -0
- package/src/lib/my-profile/salary-widget/my-profile-salary-widget.component.html +37 -0
- package/src/lib/my-profile/salary-widget/my-profile-salary-widget.component.ts +85 -0
- package/src/lib/my-profile/service-charge-widget/my-profile-service-charge-widget.component.html +16 -0
- package/src/lib/my-profile/service-charge-widget/my-profile-service-charge-widget.component.ts +101 -0
- package/src/lib/my-profile/ticket-widget/components/ticket-card/ticket-card.component.html +23 -0
- package/src/lib/my-profile/ticket-widget/components/ticket-card/ticket-card.component.ts +26 -0
- package/src/lib/my-profile/ticket-widget/my-profile-ticket-widget.component.html +68 -0
- package/src/lib/my-profile/ticket-widget/my-profile-ticket-widget.component.ts +93 -0
- package/src/lib/my-profile/vacations-widget/my-profile-vacations-widget.component.html +34 -0
- package/src/lib/my-profile/vacations-widget/my-profile-vacations-widget.component.ts +66 -0
- package/src/lib/my-team-subordinates-popup-widget/components/employee-main-info-card/employee-information-card.component.ts +65 -0
- package/src/lib/my-team-subordinates-popup-widget/components/employee-main-info-card/employee-main-info-card.component.html +57 -0
- package/src/lib/my-team-subordinates-popup-widget/components/my-team-subordinates-popup/my-team-popup.component.html +108 -0
- package/src/lib/my-team-subordinates-popup-widget/components/my-team-subordinates-popup/my-team-popup.component.ts +332 -0
- package/src/lib/my-upcoming-events-widget/components/event-item/event-item.component.html +53 -0
- package/src/lib/my-upcoming-events-widget/components/event-item/event-item.component.ts +42 -0
- package/src/lib/my-upcoming-events-widget/components/event-tab-bar/event-tab-bar.component.html +21 -0
- package/src/lib/my-upcoming-events-widget/components/event-tab-bar/event-tab-bar.component.ts +44 -0
- package/src/lib/my-upcoming-events-widget/components/events-popup/events-popup.component.html +67 -0
- package/src/lib/my-upcoming-events-widget/components/events-popup/events-popup.component.ts +74 -0
- package/src/lib/my-upcoming-events-widget/my-upcoming-events-widget.component.html +74 -0
- package/src/lib/my-upcoming-events-widget/my-upcoming-events-widget.component.ts +199 -0
- package/src/lib/services/hr-self-widgets.service.ts +624 -0
- package/src/lib/shared/components/card-header/card-header.component.html +4 -0
- package/src/lib/shared/components/card-header/card-header.component.ts +18 -0
- package/src/lib/shared/components/hr-employee-calendar/hr-employee-calendar.component.html +47 -0
- package/src/lib/shared/components/hr-employee-calendar/hr-employee-calendar.component.ts +193 -0
- package/src/lib/shared/components/info-field/info-field.component.html +2 -0
- package/src/lib/shared/components/info-field/info-field.component.ts +20 -0
- package/src/lib/shared/components/widget-card/widget-card-component.html +3 -0
- package/src/lib/shared/components/widget-card/widget-card-component.ts +17 -0
- package/src/lib/shared/pipes/translate.pipe.ts +34 -0
- package/src/lib/shared/services/bank-information-cache.service.ts +29 -0
- package/src/lib/shared/services/common-methods.service.ts +33 -0
- package/src/lib/shared/services/constants.service.ts +12 -0
- package/src/lib/shared/services/entitlements-cache.service.ts +94 -0
- package/src/lib/shared/services/job-information-cache.service.ts +72 -0
- package/src/lib/shared/services/my-team-popup.service.ts +34 -0
- package/src/lib/shared/services/personal-information-cache.service.ts +77 -0
- package/src/lib/shared/services/profile-documents-cache-service.ts +44 -0
- package/src/lib/shared/services/profile-employee-dependents-cach.ts +37 -0
- package/src/lib/shared/services/qualifications-cache.service.ts +45 -0
- package/src/lib/shared/services/translate.service.ts +35 -0
- package/src/lib/shared/types/common.ts +359 -0
- package/src/public-api.ts +35 -0
- package/tsconfig.lib.json +11 -0
- package/tsconfig.lib.prod.json +9 -0
- package/tsconfig.spec.json +8 -0
- package/fesm2022/skysoftware-co-bayan-hr-widgets-ui.mjs +0 -4812
- package/fesm2022/skysoftware-co-bayan-hr-widgets-ui.mjs.map +0 -1
- package/types/skysoftware-co-bayan-hr-widgets-ui.d.ts +0 -1308
|
@@ -0,0 +1,220 @@
|
|
|
1
|
+
import {
|
|
2
|
+
ChangeDetectionStrategy,
|
|
3
|
+
Component,
|
|
4
|
+
OnInit,
|
|
5
|
+
ViewChild,
|
|
6
|
+
computed,
|
|
7
|
+
effect,
|
|
8
|
+
inject,
|
|
9
|
+
input,
|
|
10
|
+
output,
|
|
11
|
+
signal,
|
|
12
|
+
} from '@angular/core';
|
|
13
|
+
import { HRSelfWidgetsService } from '../services/hr-self-widgets.service';
|
|
14
|
+
import {
|
|
15
|
+
CalendarResponse,
|
|
16
|
+
ScheduleCalenderVacation,
|
|
17
|
+
ScheduleRequestsResponse,
|
|
18
|
+
ScheduleVacationTypes,
|
|
19
|
+
} from '../shared/types/common';
|
|
20
|
+
import { HRTranslatePipe } from '../shared/pipes/translate.pipe';
|
|
21
|
+
import { HRConstantsService } from '../shared/services/constants.service';
|
|
22
|
+
import { HREmployeeCalendarComponent } from '../shared/components/hr-employee-calendar/hr-employee-calendar.component';
|
|
23
|
+
import { faCalendarDays } from '@fortawesome/pro-regular-svg-icons';
|
|
24
|
+
import { HRCardHeaderComponent } from '../shared/components/card-header/card-header.component';
|
|
25
|
+
import moment from 'moment';
|
|
26
|
+
|
|
27
|
+
@Component({
|
|
28
|
+
standalone: true,
|
|
29
|
+
selector: 'hr-my-calendar-widget',
|
|
30
|
+
templateUrl: './my-calendar-widget.component.html',
|
|
31
|
+
imports: [HREmployeeCalendarComponent, HRCardHeaderComponent, HRTranslatePipe],
|
|
32
|
+
changeDetection: ChangeDetectionStrategy.OnPush,
|
|
33
|
+
})
|
|
34
|
+
export class MyCalendarWidgetComponent implements OnInit {
|
|
35
|
+
readonly baseUrl = input<string>('');
|
|
36
|
+
readonly headerContainerClass = input<string>('');
|
|
37
|
+
readonly datasource = input<ScheduleRequestsResponse | null>(null);
|
|
38
|
+
readonly isLoadingChanged = output<boolean>();
|
|
39
|
+
|
|
40
|
+
readonly calendarIcon = faCalendarDays;
|
|
41
|
+
|
|
42
|
+
readonly legendContainerClass = input<string>('row mb-2');
|
|
43
|
+
readonly legendRowClass = input<string>('d-flex');
|
|
44
|
+
readonly legendItemClass = input<string>('d-flex align-items-center');
|
|
45
|
+
readonly legendDotClass = input<string>('me-1 circle-sm');
|
|
46
|
+
readonly legendLabelClass = input<string>('me-1 fs-12');
|
|
47
|
+
readonly publicHolidayDotClass = input<string>('bg-accent');
|
|
48
|
+
readonly dayOffDotClass = input<string>('bg-yellow');
|
|
49
|
+
readonly eventsDotClass = input<string>('bg-primary');
|
|
50
|
+
readonly vacationsContainerClass = input<string>('d-flex mt-3');
|
|
51
|
+
readonly vacationsItemClass = input<string>('d-flex align-items-center');
|
|
52
|
+
readonly vacationsIconClass = input<string>('fs-8 me-1');
|
|
53
|
+
readonly calendarContainerClass = input<string>('row mt-2 col-12');
|
|
54
|
+
readonly calendarClass = input<string>('button-boeder-none');
|
|
55
|
+
|
|
56
|
+
private readonly selfWidgetsService = inject(HRSelfWidgetsService);
|
|
57
|
+
private readonly constants = inject(HRConstantsService);
|
|
58
|
+
private readonly translatePipe = inject(HRTranslatePipe);
|
|
59
|
+
|
|
60
|
+
readonly publicHolidayColor = input<string>(this.constants.defaultPublicHolidayColor);
|
|
61
|
+
readonly dayOffColor = input<string>(this.constants.defaultDayOffColor);
|
|
62
|
+
readonly eventsColor = input<string>(this.constants.defaultEventsColor);
|
|
63
|
+
|
|
64
|
+
@ViewChild(HREmployeeCalendarComponent) hrCalendar!: HREmployeeCalendarComponent;
|
|
65
|
+
|
|
66
|
+
readonly minDate: Date;
|
|
67
|
+
readonly maxDate: Date;
|
|
68
|
+
|
|
69
|
+
private readonly baseCalendarData = signal<ScheduleCalenderVacation[]>([]);
|
|
70
|
+
private readonly hrVacations = signal<ScheduleCalenderVacation[]>([]);
|
|
71
|
+
private readonly calendarLoaded = signal(false);
|
|
72
|
+
|
|
73
|
+
readonly scheduleCalenderVacation = computed<ScheduleCalenderVacation[]>(() => {
|
|
74
|
+
if (!this.calendarLoaded()) {
|
|
75
|
+
return [];
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
const pendingVacations: ScheduleCalenderVacation[] =
|
|
79
|
+
this.datasource()?.PendingVacationRequests?.map(v => ({
|
|
80
|
+
VacationType: ScheduleVacationTypes.Vacations,
|
|
81
|
+
Description: v.VacationTypeName,
|
|
82
|
+
Color: v.Color,
|
|
83
|
+
VacationDays: { StartDate: v.StartDate, EndDate: v.EndDate },
|
|
84
|
+
})) ?? [];
|
|
85
|
+
|
|
86
|
+
const mergedVacations = this.mergeConsecutiveVacations(
|
|
87
|
+
[...this.hrVacations(), ...pendingVacations].sort(
|
|
88
|
+
(a, b) => new Date(a.VacationDays.StartDate).getTime() - new Date(b.VacationDays.StartDate).getTime(),
|
|
89
|
+
),
|
|
90
|
+
);
|
|
91
|
+
|
|
92
|
+
const events: ScheduleCalenderVacation[] =
|
|
93
|
+
this.datasource()?.PendingEventRequests?.map(ev => ({
|
|
94
|
+
VacationType: ScheduleVacationTypes.Events,
|
|
95
|
+
Description: ev.Description,
|
|
96
|
+
Color: this.eventsColor(),
|
|
97
|
+
VacationDays: { StartDate: ev.StartDate, EndDate: ev.EndDate },
|
|
98
|
+
})) ?? [];
|
|
99
|
+
|
|
100
|
+
return [...mergedVacations, ...this.baseCalendarData(), ...events];
|
|
101
|
+
});
|
|
102
|
+
|
|
103
|
+
private readonly refreshCalendarEffect = effect(() => {
|
|
104
|
+
if (!this.calendarLoaded()) {
|
|
105
|
+
return;
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
this.scheduleCalenderVacation();
|
|
109
|
+
this.refreshCalendar();
|
|
110
|
+
});
|
|
111
|
+
|
|
112
|
+
constructor() {
|
|
113
|
+
const currentDate = moment().date(1).subtract(1, 'month');
|
|
114
|
+
this.minDate = new Date(currentDate.year(), currentDate.month(), currentDate.date());
|
|
115
|
+
this.maxDate = new Date(this.minDate.getFullYear() + 1, this.minDate.getMonth() + 1, 0);
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
ngOnInit(): void {
|
|
119
|
+
this.loadCalendar();
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
private getCalendar(month: number, year: number, monthsCount: number) {
|
|
123
|
+
return this.selfWidgetsService.getCalendar(this.baseUrl(), month, year, monthsCount);
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
private loadCalendar(): void {
|
|
127
|
+
const currentDate = moment().date(1).subtract(1, 'month');
|
|
128
|
+
const month = currentDate.month() === 0 ? 1 : currentDate.month() + 1;
|
|
129
|
+
const year = currentDate.year();
|
|
130
|
+
|
|
131
|
+
this.isLoadingChanged.emit(true);
|
|
132
|
+
this.getCalendar(month, year, 12).subscribe({
|
|
133
|
+
next: (response: any) => {
|
|
134
|
+
this.isLoadingChanged.emit(false);
|
|
135
|
+
this.mapCalendarData(response.ResponseData as CalendarResponse);
|
|
136
|
+
},
|
|
137
|
+
error: () => {
|
|
138
|
+
this.isLoadingChanged.emit(false);
|
|
139
|
+
},
|
|
140
|
+
});
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
private mapCalendarData(data: CalendarResponse): void {
|
|
144
|
+
this.baseCalendarData.set([
|
|
145
|
+
...data.PublicHolidays.map(ph => ({
|
|
146
|
+
VacationType: ScheduleVacationTypes.PublicHoliday,
|
|
147
|
+
Description: ph.Description,
|
|
148
|
+
Color: this.publicHolidayColor(),
|
|
149
|
+
VacationDays: { StartDate: ph.StartDate, EndDate: ph.EndDate },
|
|
150
|
+
})),
|
|
151
|
+
...data.OffDays.map(od => ({
|
|
152
|
+
VacationType: ScheduleVacationTypes.DaysOff,
|
|
153
|
+
Description: this.translatePipe.transform('DayOff'),
|
|
154
|
+
Color: this.dayOffColor(),
|
|
155
|
+
VacationDays: { StartDate: od, EndDate: od },
|
|
156
|
+
})),
|
|
157
|
+
]);
|
|
158
|
+
|
|
159
|
+
this.hrVacations.set(
|
|
160
|
+
(data.Vacations ?? []).map(v => ({
|
|
161
|
+
VacationType: ScheduleVacationTypes.Vacations,
|
|
162
|
+
Description: v.VacationTypeName,
|
|
163
|
+
Color: v.Color,
|
|
164
|
+
VacationDays: { StartDate: v.StartDate, EndDate: v.EndDate },
|
|
165
|
+
})),
|
|
166
|
+
);
|
|
167
|
+
|
|
168
|
+
this.calendarLoaded.set(true);
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
private refreshCalendar(): void {
|
|
172
|
+
setTimeout(() => {
|
|
173
|
+
if (this.hrCalendar?.calendar) {
|
|
174
|
+
this.hrCalendar.calendar.instance._refresh();
|
|
175
|
+
this.hrCalendar.resetCalenderCurrentDate();
|
|
176
|
+
}
|
|
177
|
+
}, 100);
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
private mergeConsecutiveVacations(vacations: ScheduleCalenderVacation[]): ScheduleCalenderVacation[] {
|
|
181
|
+
if (vacations.length === 0) return [];
|
|
182
|
+
|
|
183
|
+
const grouped = new Map<string, ScheduleCalenderVacation[]>();
|
|
184
|
+
for (const v of vacations) {
|
|
185
|
+
const key = `${v.Description}|${v.Color ?? ''}`;
|
|
186
|
+
if (!grouped.has(key)) grouped.set(key, []);
|
|
187
|
+
grouped.get(key)!.push(v);
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
const result: ScheduleCalenderVacation[] = [];
|
|
191
|
+
|
|
192
|
+
grouped.forEach(items => {
|
|
193
|
+
items.sort((a, b) => new Date(a.VacationDays.StartDate).getTime() - new Date(b.VacationDays.StartDate).getTime());
|
|
194
|
+
|
|
195
|
+
let merged = { ...items[0], VacationDays: { ...items[0].VacationDays } };
|
|
196
|
+
|
|
197
|
+
for (let i = 1; i < items.length; i++) {
|
|
198
|
+
const current = items[i];
|
|
199
|
+
const lastEnd = new Date(merged.VacationDays.EndDate);
|
|
200
|
+
const currentStart = new Date(current.VacationDays.StartDate);
|
|
201
|
+
const diffDays = (currentStart.getTime() - lastEnd.getTime()) / (1000 * 60 * 60 * 24);
|
|
202
|
+
|
|
203
|
+
if (diffDays <= 1) {
|
|
204
|
+
const currentEnd = new Date(current.VacationDays.EndDate);
|
|
205
|
+
if (currentEnd.getTime() > lastEnd.getTime()) {
|
|
206
|
+
merged.VacationDays.EndDate = current.VacationDays.EndDate;
|
|
207
|
+
}
|
|
208
|
+
} else {
|
|
209
|
+
result.push(merged);
|
|
210
|
+
merged = { ...current, VacationDays: { ...current.VacationDays } };
|
|
211
|
+
}
|
|
212
|
+
}
|
|
213
|
+
result.push(merged);
|
|
214
|
+
});
|
|
215
|
+
|
|
216
|
+
return result.sort(
|
|
217
|
+
(a, b) => new Date(a.VacationDays.StartDate).getTime() - new Date(b.VacationDays.StartDate).getTime(),
|
|
218
|
+
);
|
|
219
|
+
}
|
|
220
|
+
}
|
|
@@ -0,0 +1,157 @@
|
|
|
1
|
+
<div [class]="containerClass()">
|
|
2
|
+
<div [class]="cardBodyClass()">
|
|
3
|
+
<div [class]="headerRowClass()">
|
|
4
|
+
<div>
|
|
5
|
+
@if (employeeMainInfo() != null) {
|
|
6
|
+
<div [class]="employeeInfoContainerClass()">
|
|
7
|
+
<bayan-employee-badge
|
|
8
|
+
[badge]="employeeBadge()"
|
|
9
|
+
[badgeClass]="badgeClass()"
|
|
10
|
+
[imageClass]="badgeImageClass()"
|
|
11
|
+
[width]="badgeWidth()"
|
|
12
|
+
[height]="badgeHeight()"
|
|
13
|
+
(employeePhotoError)="handleEmployeePhotoError()"
|
|
14
|
+
></bayan-employee-badge>
|
|
15
|
+
|
|
16
|
+
<div [class]="employeeDetailsClass()">
|
|
17
|
+
<div [class]="employeeNameContainerClass()">
|
|
18
|
+
<div
|
|
19
|
+
[class]="employeeNameClass()"
|
|
20
|
+
data-bs-toggle="tooltip"
|
|
21
|
+
[title]="employeeMainInfo()!.EmployeeNumber + ' | ' + employeeMainInfo()!.EmployeeName"
|
|
22
|
+
>
|
|
23
|
+
{{ employeeMainInfo()!.EmployeeNumber + ' | ' + employeeMainInfo()!.EmployeeName }}
|
|
24
|
+
</div>
|
|
25
|
+
</div>
|
|
26
|
+
@if (employeeMainInfo()!.PositionName != null && employeeMainInfo()!.PositionName != '') {
|
|
27
|
+
<div [class]="employeePositionClass()" data-bs-toggle="tooltip" [title]="employeeMainInfo()!.PositionName">
|
|
28
|
+
{{ employeeMainInfo()!.PositionName }}
|
|
29
|
+
</div>
|
|
30
|
+
}
|
|
31
|
+
@if (employeeMainInfo()!.GradeName != null) {
|
|
32
|
+
<div [class]="employeeGradeClass()" [title]="employeeMainInfo()!.GradeName">
|
|
33
|
+
{{ employeeMainInfo()!.GradeName }}
|
|
34
|
+
</div>
|
|
35
|
+
}
|
|
36
|
+
</div>
|
|
37
|
+
</div>
|
|
38
|
+
}
|
|
39
|
+
</div>
|
|
40
|
+
<div [class]="shortcutsContainerClass()">
|
|
41
|
+
@for (Icon of shortcutsWithUrls(); track Icon; let i = $index) {
|
|
42
|
+
<sky-shortcut-icon
|
|
43
|
+
[shortcut]="Icon"
|
|
44
|
+
[itemClass]="shortcutItemClass()"
|
|
45
|
+
[iconContainerClass]="shortcutIconContainerClass()"
|
|
46
|
+
[iconClass]="shortcutIconClass()"
|
|
47
|
+
[textClass]="shortcutTextClass()"
|
|
48
|
+
(onClicked)="shortcutClicked($event)"
|
|
49
|
+
></sky-shortcut-icon>
|
|
50
|
+
}
|
|
51
|
+
</div>
|
|
52
|
+
</div>
|
|
53
|
+
<div [class]="detailsRowClass()" [ngClass]="{ 'flex-wrap': isMobile() || isTablet() }">
|
|
54
|
+
<div [class]="reportingBlockClass()" [ngClass]="{ 'mb-3': isMobile() }">
|
|
55
|
+
<div [class]="captionLabelClasses() + ' me-5'">
|
|
56
|
+
<div>
|
|
57
|
+
{{ 'ReportingTo' | translate }}
|
|
58
|
+
</div>
|
|
59
|
+
<div [class]="captionLabelValueClass()">
|
|
60
|
+
@if (employeeMainInfo()?.ReportingTo) {
|
|
61
|
+
{{ employeeMainInfo()?.ReportingTo }}
|
|
62
|
+
} @else {
|
|
63
|
+
{{ 'NotAnknown' | translate }}
|
|
64
|
+
}
|
|
65
|
+
</div>
|
|
66
|
+
</div>
|
|
67
|
+
<div [class]="captionLabelClasses()" [ngClass]="{ 'border-end border-1 pe-4': !isMobile() }">
|
|
68
|
+
<div>
|
|
69
|
+
{{ 'ServiceYears' | translate }}
|
|
70
|
+
</div>
|
|
71
|
+
<div [class]="captionLabelValueClass()">
|
|
72
|
+
{{ employeeMainInfo()?.ServiceYears }}
|
|
73
|
+
</div>
|
|
74
|
+
</div>
|
|
75
|
+
</div>
|
|
76
|
+
|
|
77
|
+
<div class="flex-grow-1" [ngClass]="{ ' ms-4': !isMobile() && !isTablet(), 'w-100': isTablet() }">
|
|
78
|
+
<div [class]="vacationBalancesContainerClass()" [ngClass]="{ 'flex-wrap': isMobile(), 'w-100': isTablet() }">
|
|
79
|
+
@for (vacationBalance of employeeMainInfo()?.VacationBalances; track vacationBalance; let i = $index) {
|
|
80
|
+
@if (i <= 2 || employeeMainInfo()?.VacationBalances?.length == 4) {
|
|
81
|
+
<div [class]="vacationBalanceItemClass()" [ngClass]="{ 'mb-2 w-40': isMobile() }">
|
|
82
|
+
<div [class]="vacationBalanceHeaderClass()">
|
|
83
|
+
<div [class]="vacationColorDotClass()">
|
|
84
|
+
<div
|
|
85
|
+
class="rounded rounded-circle"
|
|
86
|
+
style="height: 11px; width: 11px"
|
|
87
|
+
[style.background-color]="vacationBalance.VacationTypeColor"
|
|
88
|
+
></div>
|
|
89
|
+
</div>
|
|
90
|
+
<div [class]="vacationTypeNameClass()">
|
|
91
|
+
{{ vacationBalance.VacationTypeName }}
|
|
92
|
+
</div>
|
|
93
|
+
</div>
|
|
94
|
+
<div [class]="vacationBalanceValueRowClass()">
|
|
95
|
+
<div [class]="vacationColorDotClass()">
|
|
96
|
+
<div class="rounded rounded-circle invisible" style="height: 11px; width: 11px"></div>
|
|
97
|
+
</div>
|
|
98
|
+
<div [class]="vacationBalanceValueClass()">
|
|
99
|
+
{{ vacationBalance.CurrentBalance | number: '1.2-2' }}
|
|
100
|
+
{{ (vacationBalance.CurrentBalance! == 1 ? 'day' : 'days') | translate }}
|
|
101
|
+
</div>
|
|
102
|
+
</div>
|
|
103
|
+
</div>
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
@if (employeeMainInfo()?.VacationBalances && employeeMainInfo()!.VacationBalances!.length > 4) {
|
|
108
|
+
<div [class]="vacationBalanceItemClass()">
|
|
109
|
+
<div [class]="tooltipTriggerLinkClass()" id="otherVacationBalances">
|
|
110
|
+
<div [class]="vacationColorDotClass()">
|
|
111
|
+
<div
|
|
112
|
+
class="rounded rounded-circle"
|
|
113
|
+
style="height: 11px; width: 11px"
|
|
114
|
+
[style.background-color]="defaultVacationBalanceColor()"
|
|
115
|
+
></div>
|
|
116
|
+
</div>
|
|
117
|
+
<div [class]="tooltipTriggerTextClass()">
|
|
118
|
+
+{{ employeeMainInfo()!.VacationBalances!.length - 3 }} {{ 'More' | translate }}
|
|
119
|
+
</div>
|
|
120
|
+
</div>
|
|
121
|
+
<div [class]="vacationBalanceValueRowClass()" style="visibility: hidden">
|
|
122
|
+
<div [class]="vacationColorDotClass()">
|
|
123
|
+
<div class="rounded rounded-circle" style="height: 11px; width: 11px"></div>
|
|
124
|
+
</div>
|
|
125
|
+
<div class="mx-1 fw-medium fs-14 text-dark-gray">{{ 'More' | translate }}</div>
|
|
126
|
+
</div>
|
|
127
|
+
<dx-tooltip [target]="'#otherVacationBalances'" [showEvent]="'mouseenter'" [hideEvent]="'mouseleave'">
|
|
128
|
+
@for (vacationBalance of employeeMainInfo()!.VacationBalances!; track vacationBalance; let i = $index) {
|
|
129
|
+
@if (i > 2) {
|
|
130
|
+
<div [class]="tooltipVacationRowClass()">
|
|
131
|
+
<div [class]="tooltipVacationNameContainerClass()">
|
|
132
|
+
<div [class]="vacationColorDotClass()">
|
|
133
|
+
<div
|
|
134
|
+
class="rounded rounded-circle"
|
|
135
|
+
style="height: 11px; width: 11px"
|
|
136
|
+
[style.background-color]="vacationBalance.VacationTypeColor"
|
|
137
|
+
></div>
|
|
138
|
+
</div>
|
|
139
|
+
<div [class]="tooltipVacationNameClass()">
|
|
140
|
+
{{ vacationBalance.VacationTypeName }}
|
|
141
|
+
</div>
|
|
142
|
+
</div>
|
|
143
|
+
<div>
|
|
144
|
+
{{ vacationBalance.CurrentBalance | number: '1.2-2' }}
|
|
145
|
+
{{ (vacationBalance.CurrentBalance! == 1 ? 'day' : 'days') | translate }}
|
|
146
|
+
</div>
|
|
147
|
+
</div>
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
</dx-tooltip>
|
|
151
|
+
</div>
|
|
152
|
+
}
|
|
153
|
+
</div>
|
|
154
|
+
</div>
|
|
155
|
+
</div>
|
|
156
|
+
</div>
|
|
157
|
+
</div>
|
|
@@ -0,0 +1,179 @@
|
|
|
1
|
+
import { ChangeDetectionStrategy, Component, OnInit, computed, inject, input, output, signal } from '@angular/core';
|
|
2
|
+
import { DxTooltipModule } from 'devextreme-angular';
|
|
3
|
+
import { DecimalPipe, NgClass } from '@angular/common';
|
|
4
|
+
import { HRSelfWidgetsService } from '../services/hr-self-widgets.service';
|
|
5
|
+
import { FontAwesomeModule } from '@fortawesome/angular-fontawesome';
|
|
6
|
+
import { BayanEmployeeBadgeComponent, BayanEmployeeBadgeDTO } from '@skysoftware-co/bayan-components-ui';
|
|
7
|
+
import { SkyShortcutIconComponent, ShortcutIconDTO } from '@skysoftware-co/sky-components-ui';
|
|
8
|
+
import { MyMainDetailsWidgetDetails, MainWidgetShortcut } from '../shared/types/common';
|
|
9
|
+
import { HRConstantsService } from '../shared/services/constants.service';
|
|
10
|
+
import { HRTranslatePipe } from '../shared/pipes/translate.pipe';
|
|
11
|
+
|
|
12
|
+
@Component({
|
|
13
|
+
selector: 'hr-my-main-details-widget',
|
|
14
|
+
standalone: true,
|
|
15
|
+
imports: [
|
|
16
|
+
DxTooltipModule,
|
|
17
|
+
NgClass,
|
|
18
|
+
FontAwesomeModule,
|
|
19
|
+
DecimalPipe,
|
|
20
|
+
BayanEmployeeBadgeComponent,
|
|
21
|
+
SkyShortcutIconComponent,
|
|
22
|
+
HRTranslatePipe,
|
|
23
|
+
],
|
|
24
|
+
providers: [HRTranslatePipe],
|
|
25
|
+
templateUrl: './my-main-details-widget.component.html',
|
|
26
|
+
changeDetection: ChangeDetectionStrategy.OnPush,
|
|
27
|
+
})
|
|
28
|
+
export class MyMainDetailsWidgetComponent implements OnInit {
|
|
29
|
+
private readonly selfWidgetsService = inject(HRSelfWidgetsService);
|
|
30
|
+
private readonly constants = inject(HRConstantsService);
|
|
31
|
+
private readonly translatePipe = inject(HRTranslatePipe);
|
|
32
|
+
|
|
33
|
+
readonly employeeMainInfo = signal<MyMainDetailsWidgetDetails | null>(null);
|
|
34
|
+
|
|
35
|
+
readonly onShortcutClicked = output<ShortcutIconDTO>();
|
|
36
|
+
readonly isLoadingChanged = output<boolean>();
|
|
37
|
+
|
|
38
|
+
readonly badgeClass = input<string>('badge employee-rounded-badge-xl fs-5');
|
|
39
|
+
readonly badgeImageClass = input<string>('rounded-circle shadow-lg');
|
|
40
|
+
readonly badgeWidth = input<string>('50px');
|
|
41
|
+
readonly badgeHeight = input<string>('50px');
|
|
42
|
+
readonly employeeInfoContainerClass = input<string>('d-flex align-content-center');
|
|
43
|
+
readonly employeeDetailsClass = input<string>('ms-3');
|
|
44
|
+
readonly employeeNameContainerClass = input<string>('d-flex align-items-center');
|
|
45
|
+
readonly employeeNameClass = input<string>('fs-14 text-dark-gray fw-medium text-ellipsis-one-line');
|
|
46
|
+
readonly employeePositionClass = input<string>('fs-12 fw-normal text-dark-gray text-ellipsis-one-line mb-1');
|
|
47
|
+
readonly employeeGradeClass = input<string>('fs-12 text-dark-gray');
|
|
48
|
+
|
|
49
|
+
readonly containerClass = input<string>('card rounded rounded-4 card-shadow p-16 border-top-0 mb-4');
|
|
50
|
+
readonly cardBodyClass = input<string>('card-body p-4');
|
|
51
|
+
readonly headerRowClass = input<string>('d-md-flex justify-content-between align-items-center mt-2 mb-3');
|
|
52
|
+
|
|
53
|
+
readonly shortcutsContainerClass = input<string>(
|
|
54
|
+
'd-flex justify-content-md-end justify-content-sm-start fs-12 fw-normal text-secondary mt-3 mt-md-0',
|
|
55
|
+
);
|
|
56
|
+
readonly shortcutItemClass = input<string>('d-flex flex-column align-items-center mx-2 wp-60');
|
|
57
|
+
readonly shortcutIconContainerClass = input<string>(
|
|
58
|
+
'd-flex justify-content-center align-items-center rounded-circle-40 cursor-pointer',
|
|
59
|
+
);
|
|
60
|
+
readonly shortcutIconClass = input<string>('fs-4');
|
|
61
|
+
readonly shortcutTextClass = input<string>('text-center mt-1');
|
|
62
|
+
|
|
63
|
+
readonly detailsRowClass = input<string>('d-flex mt-4');
|
|
64
|
+
|
|
65
|
+
readonly reportingBlockClass = input<string>('d-flex text-secondary align-items-center mb-2 mx-2');
|
|
66
|
+
readonly captionLabelClasses = input<string>('d-flex flex-column align-self-start fs-14 text-dark-gray');
|
|
67
|
+
readonly captionLabelValueClass = input<string>('fw-medium mt-2');
|
|
68
|
+
|
|
69
|
+
readonly vacationBalancesContainerClass = input<string>('d-flex text-secondary align-items-center mb-2');
|
|
70
|
+
readonly vacationBalanceItemClass = input<string>('d-flex flex-column me-4');
|
|
71
|
+
readonly vacationBalanceHeaderClass = input<string>('d-flex align-items-center');
|
|
72
|
+
readonly vacationColorDotClass = input<string>('vacation-color-container-sm');
|
|
73
|
+
readonly vacationTypeNameClass = input<string>('mx-2 fs-14 fw-normal text-dark-gray');
|
|
74
|
+
readonly vacationBalanceValueRowClass = input<string>('d-flex mt-2');
|
|
75
|
+
readonly vacationBalanceValueClass = input<string>('mx-2 fw-medium fs-14 text-dark-gray');
|
|
76
|
+
|
|
77
|
+
readonly tooltipTriggerLinkClass = input<string>('d-flex align-items-center cursor-pointer');
|
|
78
|
+
readonly tooltipTriggerTextClass = input<string>('mx-2 fs-14 text-dark-gray');
|
|
79
|
+
|
|
80
|
+
readonly tooltipVacationRowClass = input<string>('d-flex align-items-center justify-content-around fs-12 mb-2');
|
|
81
|
+
readonly tooltipVacationNameContainerClass = input<string>('d-flex flex-grow-1 align-items-center me-5');
|
|
82
|
+
readonly tooltipVacationNameClass = input<string>('mx-2');
|
|
83
|
+
|
|
84
|
+
readonly defaultVacationBalanceColor = input<string>(this.constants.defaultVacationBalanceColor);
|
|
85
|
+
|
|
86
|
+
readonly defaultVacationColor = input<string>(this.constants.defaultVacationColor);
|
|
87
|
+
|
|
88
|
+
readonly baseUrl = input<string>('');
|
|
89
|
+
|
|
90
|
+
readonly employeeBadge = signal<BayanEmployeeBadgeDTO>({
|
|
91
|
+
EmployeePhotoKey: null,
|
|
92
|
+
EmployeePhotoFailed: false,
|
|
93
|
+
EmployeeNameInitials: '',
|
|
94
|
+
});
|
|
95
|
+
|
|
96
|
+
readonly isMobile = input<boolean>(false);
|
|
97
|
+
readonly isTablet = input<boolean>(false);
|
|
98
|
+
readonly shortcuts = input<ShortcutIconDTO[]>([]);
|
|
99
|
+
|
|
100
|
+
readonly shortcutsWithUrls = computed<ShortcutIconDTO[]>(() => {
|
|
101
|
+
const employeeMainInfo = this.employeeMainInfo();
|
|
102
|
+
return this.shortcuts().map(item => {
|
|
103
|
+
const translated: ShortcutIconDTO = {
|
|
104
|
+
...item,
|
|
105
|
+
title: this.translatePipe.transform(item.title),
|
|
106
|
+
};
|
|
107
|
+
|
|
108
|
+
if (translated.shortcutId === MainWidgetShortcut.Attendance && employeeMainInfo?.AttendanceUrl != null) {
|
|
109
|
+
return { ...translated, navigateUrl: [employeeMainInfo.AttendanceUrl] };
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
if (
|
|
113
|
+
translated.shortcutId === MainWidgetShortcut.VacationStatement &&
|
|
114
|
+
employeeMainInfo?.VacationStatementUrl != null
|
|
115
|
+
) {
|
|
116
|
+
return { ...translated, navigateUrl: [employeeMainInfo.VacationStatementUrl] };
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
return translated;
|
|
120
|
+
});
|
|
121
|
+
});
|
|
122
|
+
|
|
123
|
+
ngOnInit(): void {
|
|
124
|
+
this.loadEmployeeMainInfo();
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
loadEmployeeMainInfo() {
|
|
128
|
+
this.isLoadingChanged.emit(true);
|
|
129
|
+
|
|
130
|
+
this.getEmployeeMainDetails().subscribe({
|
|
131
|
+
next: (data: any) => {
|
|
132
|
+
const responses = data.ResponseData;
|
|
133
|
+
const vacationBalances = responses.VacationBalances.map((v: any) => ({
|
|
134
|
+
...v,
|
|
135
|
+
VacationTypeColor: v.VacationTypeColor ?? this.defaultVacationColor(),
|
|
136
|
+
}));
|
|
137
|
+
|
|
138
|
+
const employeeMainInfo: MyMainDetailsWidgetDetails = {
|
|
139
|
+
EmployeeNumber: responses.EmployeeNumber,
|
|
140
|
+
EmployeeName: responses.EmployeeName,
|
|
141
|
+
EmployeeNameInitials: responses.EmployeeNameInitials,
|
|
142
|
+
PositionName: responses.PositionName,
|
|
143
|
+
GradeName: responses.GradeName,
|
|
144
|
+
PhotoPath: responses.PhotoPath,
|
|
145
|
+
ReportingTo: responses.ReportingToEmployeeName,
|
|
146
|
+
ServiceYears: `${responses.ServicePeriod.Years} ${this.translatePipe.transform('Years')} ${responses.ServicePeriod.Months} ${this.translatePipe.transform('Months')}`,
|
|
147
|
+
VacationBalances: vacationBalances,
|
|
148
|
+
AttendanceUrl: responses.AttendanceReportUrl,
|
|
149
|
+
VacationStatementUrl: responses.VacationStatementReportUrl,
|
|
150
|
+
};
|
|
151
|
+
this.employeeMainInfo.set(employeeMainInfo);
|
|
152
|
+
|
|
153
|
+
this.employeeBadge.set({
|
|
154
|
+
EmployeePhotoKey: employeeMainInfo.PhotoPath || null,
|
|
155
|
+
EmployeeNameInitials: employeeMainInfo.EmployeeNameInitials || '',
|
|
156
|
+
EmployeePhotoFailed: false,
|
|
157
|
+
});
|
|
158
|
+
|
|
159
|
+
this.isLoadingChanged.emit(false);
|
|
160
|
+
},
|
|
161
|
+
error: (error: any) => {
|
|
162
|
+
this.isLoadingChanged.emit(false);
|
|
163
|
+
if (error.status == 401) return;
|
|
164
|
+
},
|
|
165
|
+
});
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
shortcutClicked(icon: ShortcutIconDTO) {
|
|
169
|
+
this.onShortcutClicked.emit(icon);
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
handleEmployeePhotoError() {
|
|
173
|
+
this.employeeBadge.update(badge => ({ ...badge, EmployeePhotoFailed: true }));
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
getEmployeeMainDetails() {
|
|
177
|
+
return this.selfWidgetsService.getMainDetails(this.baseUrl());
|
|
178
|
+
}
|
|
179
|
+
}
|
|
@@ -0,0 +1,131 @@
|
|
|
1
|
+
<dx-popup
|
|
2
|
+
[visible]="popupVisible()"
|
|
3
|
+
[height]="height()"
|
|
4
|
+
[minHeight]="'40%'"
|
|
5
|
+
[maxHeight]="'70%'"
|
|
6
|
+
[width]="width()"
|
|
7
|
+
contentTemplate="popup-content"
|
|
8
|
+
[showCloseButton]="false"
|
|
9
|
+
shadingColor="rgba(0,0,0,0.4)"
|
|
10
|
+
titleTemplate="title"
|
|
11
|
+
[showTitle]="true"
|
|
12
|
+
(onHidden)="onHidden()"
|
|
13
|
+
>
|
|
14
|
+
<div *dxTemplate="let data of 'title'">
|
|
15
|
+
<div class="d-flex justify-content-between align-items-center my-0">
|
|
16
|
+
<p class="fs-16 fw-meduim text-ellipsis-one-line">
|
|
17
|
+
<span class="text-dark-gray">{{ popupTitle ? (popupTitle | translate) : ('NextWeekVacationInsights' | translate) }}</span>
|
|
18
|
+
<span class="mx-2 text-primary">({{ getPopupTitle() | translate }})</span>
|
|
19
|
+
</p>
|
|
20
|
+
<div class="py-2" (click)="onPopupClose()">
|
|
21
|
+
<fa-icon [icon]="xMarkIcon" class="fs-18 text-dark-gray cursor-pointer"></fa-icon>
|
|
22
|
+
</div>
|
|
23
|
+
</div>
|
|
24
|
+
</div>
|
|
25
|
+
|
|
26
|
+
<div *dxTemplate="let d of 'popup-content'">
|
|
27
|
+
<div class="mb-2 d-flex justify-content-end">
|
|
28
|
+
<dx-text-box
|
|
29
|
+
[width]="'250px'"
|
|
30
|
+
mode="search"
|
|
31
|
+
[value]="searchValue()"
|
|
32
|
+
[placeholder]="'Search...' | translate"
|
|
33
|
+
(onValueChanged)="onSearchValueChanged($event)"
|
|
34
|
+
></dx-text-box>
|
|
35
|
+
</div>
|
|
36
|
+
@if (dataSource()) {
|
|
37
|
+
<dx-data-grid
|
|
38
|
+
class="popup-data-grid"
|
|
39
|
+
[dataSource]="dataSource()"
|
|
40
|
+
[showBorders]="false"
|
|
41
|
+
[showRowLines]="false"
|
|
42
|
+
[showColumnLines]="false"
|
|
43
|
+
[columnAutoWidth]="true"
|
|
44
|
+
[wordWrapEnabled]="true"
|
|
45
|
+
[height]="gridHeight()"
|
|
46
|
+
[allowColumnReordering]="false"
|
|
47
|
+
[remoteOperations]="{ paging: true }"
|
|
48
|
+
>
|
|
49
|
+
<dxo-data-grid-sorting mode="none"></dxo-data-grid-sorting>
|
|
50
|
+
|
|
51
|
+
<dxo-data-grid-scrolling
|
|
52
|
+
mode="infinite"
|
|
53
|
+
[useNative]="false"
|
|
54
|
+
[scrollByContent]="true"
|
|
55
|
+
[scrollByThumb]="true"
|
|
56
|
+
showScrollbar="always"
|
|
57
|
+
></dxo-data-grid-scrolling>
|
|
58
|
+
|
|
59
|
+
<dxo-data-grid-paging [enabled]="true" [pageSize]="pageSize()"></dxo-data-grid-paging>
|
|
60
|
+
|
|
61
|
+
<dxi-data-grid-column
|
|
62
|
+
caption="{{ 'Employee' | translate }}"
|
|
63
|
+
dataField="EmployeeName"
|
|
64
|
+
cellTemplate="employeeCellTemplate"
|
|
65
|
+
[minWidth]="250"
|
|
66
|
+
></dxi-data-grid-column>
|
|
67
|
+
|
|
68
|
+
@if (popupType() === VacationPopupType.Upcoming) {
|
|
69
|
+
<dxi-data-grid-column
|
|
70
|
+
caption="{{ 'StartDate' | translate }}"
|
|
71
|
+
dataField="VacationStartDate"
|
|
72
|
+
dataType="date"
|
|
73
|
+
format="dd/MM/yyyy"
|
|
74
|
+
[width]="120"
|
|
75
|
+
alignment="left"
|
|
76
|
+
></dxi-data-grid-column>
|
|
77
|
+
<dxi-data-grid-column
|
|
78
|
+
caption="{{ 'EndDate' | translate }}"
|
|
79
|
+
dataField="VacationEndDate"
|
|
80
|
+
dataType="date"
|
|
81
|
+
format="dd/MM/yyyy"
|
|
82
|
+
[width]="120"
|
|
83
|
+
alignment="left"
|
|
84
|
+
></dxi-data-grid-column>
|
|
85
|
+
} @else {
|
|
86
|
+
<dxi-data-grid-column
|
|
87
|
+
caption="{{ 'ReturnDate' | translate }}"
|
|
88
|
+
dataField="ReturnDate"
|
|
89
|
+
dataType="date"
|
|
90
|
+
format="dd/MM/yyyy"
|
|
91
|
+
[width]="120"
|
|
92
|
+
alignment="left"
|
|
93
|
+
></dxi-data-grid-column>
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
<div *dxTemplate="let cell of 'employeeCellTemplate'">
|
|
97
|
+
<div class="d-flex align-items-center">
|
|
98
|
+
<bayan-employee-badge
|
|
99
|
+
[badge]="getEmployeeBadge(cell.data)"
|
|
100
|
+
badgeClass="badge employee-rounded-badge-xl fs-6"
|
|
101
|
+
imageClass="rounded-circle"
|
|
102
|
+
[width]="'40px'"
|
|
103
|
+
[height]="'40px'"
|
|
104
|
+
(employeePhotoError)="handleEmployeePhotoError(cell.data)"
|
|
105
|
+
></bayan-employee-badge>
|
|
106
|
+
<div class="d-flex flex-column ms-1">
|
|
107
|
+
<div class="d-flex flex-row ms-2">
|
|
108
|
+
@if (showProperty()) {
|
|
109
|
+
<span
|
|
110
|
+
class="property-badge cursor-pointer me-1"
|
|
111
|
+
[title]="cell.data.PropertyName"
|
|
112
|
+
[innerHTML]="cell.data.PropertySymbol"
|
|
113
|
+
></span>
|
|
114
|
+
}
|
|
115
|
+
<span
|
|
116
|
+
class="text-ellipsis-one-line fs-14 text-dark-gray fw-normal"
|
|
117
|
+
[title]="cell.data.EmployeeNumber + ' | ' + cell.data.EmployeeName"
|
|
118
|
+
[innerHTML]="cell.data.EmployeeNumber + ' | ' + cell.data.EmployeeName | highlight: searchValue()"
|
|
119
|
+
></span>
|
|
120
|
+
</div>
|
|
121
|
+
<p
|
|
122
|
+
class="ms-2 mt-1 text-ellipsis-one-line fs-12 text-dark-gray fw-normal mb-0"
|
|
123
|
+
[innerHTML]="cell.data.EmployeeAdminUnitName | highlight: searchValue()"
|
|
124
|
+
></p>
|
|
125
|
+
</div>
|
|
126
|
+
</div>
|
|
127
|
+
</div>
|
|
128
|
+
</dx-data-grid>
|
|
129
|
+
}
|
|
130
|
+
</div>
|
|
131
|
+
</dx-popup>
|