@skysoftware-co/bayan-hr-widgets-ui 2.0.18 → 2.0.20
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 +109 -0
- package/src/lib/my-team-subordinates-popup-widget/components/my-team-subordinates-popup/my-team-popup.component.ts +297 -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 -4785
- package/fesm2022/skysoftware-co-bayan-hr-widgets-ui.mjs.map +0 -1
- package/types/skysoftware-co-bayan-hr-widgets-ui.d.ts +0 -1305
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { CommonModule } from '@angular/common';
|
|
2
|
+
import { Component, Input } from '@angular/core';
|
|
3
|
+
import { HRTranslatePipe } from '../../../../shared/pipes/translate.pipe';
|
|
4
|
+
import { WidgetCardComponent } from '../../../../shared/components/widget-card/widget-card-component';
|
|
5
|
+
|
|
6
|
+
@Component({
|
|
7
|
+
selector: 'hr-ticket-card',
|
|
8
|
+
standalone: true,
|
|
9
|
+
imports: [CommonModule, HRTranslatePipe, WidgetCardComponent],
|
|
10
|
+
templateUrl: './ticket-card.component.html',
|
|
11
|
+
})
|
|
12
|
+
export class HRTicketCardComponent {
|
|
13
|
+
@Input({ required: true }) name: string | null = '';
|
|
14
|
+
@Input() typeName: string | null = '';
|
|
15
|
+
@Input() entitlementText: string = '';
|
|
16
|
+
@Input() ticketClassName: string | null = '';
|
|
17
|
+
@Input() ticketSectorName: string | null = '';
|
|
18
|
+
@Input() isDependent: boolean = false;
|
|
19
|
+
|
|
20
|
+
@Input() cardClass: string = 'p-3 card-shadow border border-1 h-100 rounded rounded-2';
|
|
21
|
+
@Input() cardHeight: number = 135;
|
|
22
|
+
@Input() nameClass: string = 'text-dark fs-16';
|
|
23
|
+
@Input() subtitleClass: string = 'field-secondary-label-sm mb-3';
|
|
24
|
+
@Input() labelClass: string = 'text-secondary';
|
|
25
|
+
@Input() valueClass: string = 'text-dark-gray mx-1';
|
|
26
|
+
}
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
@if (hasData()) {
|
|
2
|
+
<sky-section-divider
|
|
3
|
+
[fontAwesomeIcon]="ticketsIcon()"
|
|
4
|
+
[text]="sectionTitle() | translate | uppercase"
|
|
5
|
+
[iconClass]="headerIconClass()"
|
|
6
|
+
[textClass]="headerTextClass()"
|
|
7
|
+
[dividerClass]="headerDividerClass()"
|
|
8
|
+
></sky-section-divider>
|
|
9
|
+
|
|
10
|
+
@let details = ticketDetails();
|
|
11
|
+
@if (details) {
|
|
12
|
+
@let employeeDetails = details.EmployeeTicketDetails;
|
|
13
|
+
@if (!employeeDetails && details.DependentTicketDetails?.length == 0) {
|
|
14
|
+
<sky-empty-design-card
|
|
15
|
+
[containerClass]="emptyStateContainerClass()"
|
|
16
|
+
[cardBodyClass]="''"
|
|
17
|
+
[cardBodyContainerClass]="''"
|
|
18
|
+
[visibleIcon]="false"
|
|
19
|
+
[visibleQuickAction]="false"
|
|
20
|
+
[emptyTextClass]="emptyStateTextClass()"
|
|
21
|
+
[emptyText]="'NoTicketEntitlement' | translate"
|
|
22
|
+
></sky-empty-design-card>
|
|
23
|
+
} @else {
|
|
24
|
+
<div class="row mb-5">
|
|
25
|
+
@if (employeeDetails) {
|
|
26
|
+
<div [class]="columnClass()" [style.height.px]="cardHeight()">
|
|
27
|
+
<hr-ticket-card
|
|
28
|
+
[name]="employeeDetails.EmployeeFirstName"
|
|
29
|
+
[entitlementText]="getMonthsPerTicketEntitlement(employeeDetails.MonthsPerTicketEntitlement)"
|
|
30
|
+
[ticketClassName]="employeeDetails.TicketClassName"
|
|
31
|
+
[ticketSectorName]="employeeDetails.TicketSectorName"
|
|
32
|
+
[cardClass]="cardClass()"
|
|
33
|
+
[cardHeight]="cardHeight()"
|
|
34
|
+
[nameClass]="nameClass()"
|
|
35
|
+
[subtitleClass]="subtitleClass()"
|
|
36
|
+
[labelClass]="labelClass()"
|
|
37
|
+
[valueClass]="valueClass()"
|
|
38
|
+
></hr-ticket-card>
|
|
39
|
+
</div>
|
|
40
|
+
}
|
|
41
|
+
@for (dependent of details.DependentTicketDetails ?? []; track dependent) {
|
|
42
|
+
<div [class]="columnClass()" [style.height.px]="cardHeight()">
|
|
43
|
+
<hr-ticket-card
|
|
44
|
+
[name]="dependent.DependentName"
|
|
45
|
+
[typeName]="dependent.DependentTypeName"
|
|
46
|
+
[entitlementText]="getMonthsPerTicketEntitlement(dependent.MonthsPerTicketEntitlement)"
|
|
47
|
+
[isDependent]="true"
|
|
48
|
+
[cardClass]="cardClass()"
|
|
49
|
+
[cardHeight]="cardHeight()"
|
|
50
|
+
[nameClass]="nameClass()"
|
|
51
|
+
[subtitleClass]="subtitleClass()"
|
|
52
|
+
></hr-ticket-card>
|
|
53
|
+
</div>
|
|
54
|
+
}
|
|
55
|
+
</div>
|
|
56
|
+
}
|
|
57
|
+
} @else {
|
|
58
|
+
<sky-empty-design-card
|
|
59
|
+
[containerClass]="emptyStateContainerClass()"
|
|
60
|
+
[cardBodyClass]="''"
|
|
61
|
+
[cardBodyContainerClass]="''"
|
|
62
|
+
[visibleIcon]="false"
|
|
63
|
+
[visibleQuickAction]="false"
|
|
64
|
+
[emptyTextClass]="emptyStateTextClass()"
|
|
65
|
+
[emptyText]="isLoading() ? (sectionTitle() | translate) + ' ' + ('IsLoading' | translate) : ('NoTicketEntitlement' | translate)"
|
|
66
|
+
></sky-empty-design-card>
|
|
67
|
+
}
|
|
68
|
+
}
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
import { CommonModule } from '@angular/common';
|
|
2
|
+
import { ChangeDetectionStrategy, Component, OnInit, inject, input, output, signal } from '@angular/core';
|
|
3
|
+
import { HRTranslatePipe } from '../../shared/pipes/translate.pipe';
|
|
4
|
+
import { faTicketsAirline } from '@fortawesome/pro-light-svg-icons';
|
|
5
|
+
import { SkyEmptyDesignCardComponent, SkySectionDividerComponent } from '@skysoftware-co/sky-components-ui';
|
|
6
|
+
import { HRSelfWidgetsService } from '../../services/hr-self-widgets.service';
|
|
7
|
+
import { HRTicketCardComponent } from './components/ticket-card/ticket-card.component';
|
|
8
|
+
import { EntitlementsTicket } from '../../shared/types/common';
|
|
9
|
+
|
|
10
|
+
@Component({
|
|
11
|
+
selector: 'hr-my-profile-ticket-widget',
|
|
12
|
+
standalone: true,
|
|
13
|
+
imports: [
|
|
14
|
+
CommonModule,
|
|
15
|
+
HRTranslatePipe,
|
|
16
|
+
SkySectionDividerComponent,
|
|
17
|
+
SkyEmptyDesignCardComponent,
|
|
18
|
+
HRTicketCardComponent,
|
|
19
|
+
],
|
|
20
|
+
providers: [HRTranslatePipe],
|
|
21
|
+
templateUrl: './my-profile-ticket-widget.component.html',
|
|
22
|
+
changeDetection: ChangeDetectionStrategy.OnPush,
|
|
23
|
+
})
|
|
24
|
+
export class MyProfileTicketWidgetComponent implements OnInit {
|
|
25
|
+
readonly baseUrl = input.required<string>();
|
|
26
|
+
readonly sectionTitle = input<string>('Tickets');
|
|
27
|
+
readonly ticketsIcon = input(faTicketsAirline);
|
|
28
|
+
|
|
29
|
+
readonly headerIconClass = input<string>('primary-icon-xl');
|
|
30
|
+
readonly headerTextClass = input<string>('mt-2 field-secondary-label-lg');
|
|
31
|
+
readonly headerDividerClass = input<string>('flex-grow-1 ms-2');
|
|
32
|
+
readonly emptyStateContainerClass = input<string>(
|
|
33
|
+
'd-flex flex-column justify-content-center align-items-center my-5',
|
|
34
|
+
);
|
|
35
|
+
readonly emptyStateTextClass = input<string>('field-secondary-label-md');
|
|
36
|
+
readonly columnClass = input<string>('col-lg-4 col-6 mt-4');
|
|
37
|
+
readonly cardHeight = input<number>(135);
|
|
38
|
+
readonly cardClass = input<string>('p-3 card-shadow border border-1 h-100 rounded rounded-2');
|
|
39
|
+
readonly nameClass = input<string>('text-dark fs-16');
|
|
40
|
+
readonly subtitleClass = input<string>('field-secondary-label-sm mb-3');
|
|
41
|
+
readonly labelClass = input<string>('fs-12 text-secondary');
|
|
42
|
+
readonly valueClass = input<string>('fs-12 text-dark-gray mx-1');
|
|
43
|
+
|
|
44
|
+
readonly isLoadingChanged = output<boolean>();
|
|
45
|
+
readonly errorOccurred = output<string>();
|
|
46
|
+
|
|
47
|
+
readonly ticketDetails = signal<EntitlementsTicket | null>(null);
|
|
48
|
+
readonly isLoading = signal(true);
|
|
49
|
+
readonly hasData = signal(true);
|
|
50
|
+
|
|
51
|
+
private readonly selfWidgetsService = inject(HRSelfWidgetsService);
|
|
52
|
+
private readonly translatePipe = inject(HRTranslatePipe);
|
|
53
|
+
|
|
54
|
+
ngOnInit(): void {
|
|
55
|
+
if (!this.baseUrl()) {
|
|
56
|
+
this.isLoading.set(false);
|
|
57
|
+
return;
|
|
58
|
+
}
|
|
59
|
+
this.loadData();
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
private loadData(): void {
|
|
63
|
+
this.isLoadingChanged.emit(true);
|
|
64
|
+
this.selfWidgetsService.getEntitlementsTicket(this.baseUrl()).subscribe({
|
|
65
|
+
next: data => {
|
|
66
|
+
this.ticketDetails.set(data);
|
|
67
|
+
this.isLoading.set(false);
|
|
68
|
+
const details = this.ticketDetails();
|
|
69
|
+
this.hasData.set(!!details?.EmployeeTicketDetails || (details?.DependentTicketDetails?.length ?? 0) > 0);
|
|
70
|
+
this.isLoadingChanged.emit(false);
|
|
71
|
+
},
|
|
72
|
+
error: error => {
|
|
73
|
+
this.ticketDetails.set(null);
|
|
74
|
+
this.isLoading.set(false);
|
|
75
|
+
this.hasData.set(false);
|
|
76
|
+
this.errorOccurred.emit(error?.error?.ResponseData?.Errors?.[0]?.Message);
|
|
77
|
+
this.isLoadingChanged.emit(false);
|
|
78
|
+
},
|
|
79
|
+
});
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
getMonthsPerTicketEntitlement(monthsPerTicketEntitlement: number | null): string {
|
|
83
|
+
if (monthsPerTicketEntitlement != null && monthsPerTicketEntitlement != 0) {
|
|
84
|
+
if (monthsPerTicketEntitlement > 1) {
|
|
85
|
+
const template = this.translatePipe.transform('TicketEvery{{value}}Months');
|
|
86
|
+
return template.replace('{{value}}', String(monthsPerTicketEntitlement));
|
|
87
|
+
} else {
|
|
88
|
+
const template = this.translatePipe.transform('TicketEvery{{value}}Month');
|
|
89
|
+
return template.replace('{{value}}', String(monthsPerTicketEntitlement));
|
|
90
|
+
}
|
|
91
|
+
} else return this.translatePipe.transform('NotEntitled');
|
|
92
|
+
}
|
|
93
|
+
}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
<sky-section-divider
|
|
2
|
+
[fontAwesomeIcon]="vacationsIcon()"
|
|
3
|
+
[text]="sectionTitle() | translate | uppercase"
|
|
4
|
+
[iconClass]="headerIconClass()"
|
|
5
|
+
[textClass]="headerTextClass()"
|
|
6
|
+
[dividerClass]="headerDividerClass()"
|
|
7
|
+
></sky-section-divider>
|
|
8
|
+
|
|
9
|
+
@if (vacationEntitlements().length > 0) {
|
|
10
|
+
<div [class]="rowClass()">
|
|
11
|
+
<div [class]="labelClass()" [ngClass]="labelColumnClass()">{{ 'Type' | translate }}</div>
|
|
12
|
+
<div [class]="labelClass()" [ngClass]="valueColumnClass()">{{ 'Entitlement' | translate }}</div>
|
|
13
|
+
@for (vacationEntitlement of vacationEntitlements(); track vacationEntitlement) {
|
|
14
|
+
<div [class]="valueClass()" [ngClass]="labelColumnClass()">
|
|
15
|
+
{{ vacationEntitlement.VacationTypeName }}
|
|
16
|
+
</div>
|
|
17
|
+
<div [class]="valueClass()" [ngClass]="valueColumnClass()">
|
|
18
|
+
{{ vacationEntitlement.EntitlementDays }}
|
|
19
|
+
</div>
|
|
20
|
+
}
|
|
21
|
+
</div>
|
|
22
|
+
} @else {
|
|
23
|
+
<sky-empty-design-card
|
|
24
|
+
[containerClass]="emptyStateContainerClass()"
|
|
25
|
+
[cardBodyClass]="''"
|
|
26
|
+
[cardBodyContainerClass]="''"
|
|
27
|
+
[visibleIcon]="false"
|
|
28
|
+
[visibleQuickAction]="false"
|
|
29
|
+
[emptyTextClass]="emptyStateTextClass()"
|
|
30
|
+
[emptyText]="
|
|
31
|
+
isLoading() ? (sectionTitle() | translate) + ' ' + ('IsLoading' | translate) : ('There\'sNoInformationInThisSectionYet' | translate)
|
|
32
|
+
"
|
|
33
|
+
></sky-empty-design-card>
|
|
34
|
+
}
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
import { CommonModule } from '@angular/common';
|
|
2
|
+
import { ChangeDetectionStrategy, Component, OnInit, inject, input, output, signal } from '@angular/core';
|
|
3
|
+
import { HRTranslatePipe } from '../../shared/pipes/translate.pipe';
|
|
4
|
+
import { faIslandTropical } from '@fortawesome/pro-light-svg-icons';
|
|
5
|
+
import { SkyEmptyDesignCardComponent, SkySectionDividerComponent } from '@skysoftware-co/sky-components-ui';
|
|
6
|
+
import { HRSelfWidgetsService } from '../../services/hr-self-widgets.service';
|
|
7
|
+
import { EntitlementsVacation } from '../../shared/types/common';
|
|
8
|
+
|
|
9
|
+
@Component({
|
|
10
|
+
selector: 'hr-my-profile-vacations-widget',
|
|
11
|
+
standalone: true,
|
|
12
|
+
imports: [CommonModule, HRTranslatePipe, SkySectionDividerComponent, SkyEmptyDesignCardComponent],
|
|
13
|
+
templateUrl: './my-profile-vacations-widget.component.html',
|
|
14
|
+
changeDetection: ChangeDetectionStrategy.OnPush,
|
|
15
|
+
})
|
|
16
|
+
export class MyProfileVacationsWidgetComponent implements OnInit {
|
|
17
|
+
readonly baseUrl = input.required<string>();
|
|
18
|
+
readonly sectionTitle = input<string>('Vacations');
|
|
19
|
+
readonly vacationsIcon = input(faIslandTropical);
|
|
20
|
+
|
|
21
|
+
readonly headerIconClass = input<string>('primary-icon-xl');
|
|
22
|
+
readonly headerTextClass = input<string>('mt-2 field-secondary-label-lg');
|
|
23
|
+
readonly headerDividerClass = input<string>('flex-grow-1 ms-2');
|
|
24
|
+
readonly rowClass = input<string>('row mt-4');
|
|
25
|
+
readonly labelClass = input<string>('field-secondary-label-sm');
|
|
26
|
+
readonly valueClass = input<string>('fs-14 fw-meduim mt-2');
|
|
27
|
+
readonly labelColumnClass = input<string>('col-6');
|
|
28
|
+
readonly valueColumnClass = input<string>('col-6');
|
|
29
|
+
readonly emptyStateContainerClass = input<string>(
|
|
30
|
+
'd-flex flex-column justify-content-center align-items-center my-5',
|
|
31
|
+
);
|
|
32
|
+
readonly emptyStateTextClass = input<string>('field-secondary-label-md');
|
|
33
|
+
|
|
34
|
+
readonly isLoadingChanged = output<boolean>();
|
|
35
|
+
readonly errorOccurred = output<string>();
|
|
36
|
+
|
|
37
|
+
readonly vacationEntitlements = signal<EntitlementsVacation[]>([]);
|
|
38
|
+
readonly isLoading = signal(true);
|
|
39
|
+
|
|
40
|
+
private readonly selfWidgetsService = inject(HRSelfWidgetsService);
|
|
41
|
+
|
|
42
|
+
ngOnInit(): void {
|
|
43
|
+
if (!this.baseUrl()) {
|
|
44
|
+
this.isLoading.set(false);
|
|
45
|
+
return;
|
|
46
|
+
}
|
|
47
|
+
this.loadData();
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
private loadData(): void {
|
|
51
|
+
this.isLoadingChanged.emit(true);
|
|
52
|
+
this.selfWidgetsService.getEntitlementsVacations(this.baseUrl()).subscribe({
|
|
53
|
+
next: data => {
|
|
54
|
+
this.vacationEntitlements.set(data ?? []);
|
|
55
|
+
this.isLoading.set(false);
|
|
56
|
+
this.isLoadingChanged.emit(false);
|
|
57
|
+
},
|
|
58
|
+
error: error => {
|
|
59
|
+
this.vacationEntitlements.set([]);
|
|
60
|
+
this.isLoading.set(false);
|
|
61
|
+
this.errorOccurred.emit(error?.error?.ResponseData?.Errors?.[0]?.Message);
|
|
62
|
+
this.isLoadingChanged.emit(false);
|
|
63
|
+
},
|
|
64
|
+
});
|
|
65
|
+
}
|
|
66
|
+
}
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
import { ChangeDetectionStrategy, Component, effect, input, output } from '@angular/core';
|
|
2
|
+
import { NgClass } from '@angular/common';
|
|
3
|
+
import { FontAwesomeModule } from '@fortawesome/angular-fontawesome';
|
|
4
|
+
import { faChevronDown } from '@fortawesome/pro-solid-svg-icons';
|
|
5
|
+
import { BayanEmployeeBadgeComponent, BayanEmployeeBadgeDTO } from '@skysoftware-co/bayan-components-ui';
|
|
6
|
+
import { HighlightPipe, isRTL } from '@skysoftware-co/sky-components-ui';
|
|
7
|
+
import { EmployeeMainInfo } from '../../../shared/types/common';
|
|
8
|
+
|
|
9
|
+
@Component({
|
|
10
|
+
selector: 'app-employee-main-info-card',
|
|
11
|
+
standalone: true,
|
|
12
|
+
imports: [FontAwesomeModule, NgClass, BayanEmployeeBadgeComponent, HighlightPipe],
|
|
13
|
+
templateUrl: './employee-main-info-card.component.html',
|
|
14
|
+
changeDetection: ChangeDetectionStrategy.OnPush,
|
|
15
|
+
})
|
|
16
|
+
export class EmployeeMainInfoCardComponent {
|
|
17
|
+
readonly employeeMainInfo = input<EmployeeMainInfo | null>(null);
|
|
18
|
+
readonly searchValue = input<string>('');
|
|
19
|
+
|
|
20
|
+
readonly badgeClass = input<string>('badge employee-rounded-badge-xl fs-5');
|
|
21
|
+
readonly badgeImageClass = input<string>('rounded-circle');
|
|
22
|
+
readonly badgeWidth = input<string>('50px');
|
|
23
|
+
readonly badgeHeight = input<string>('50px');
|
|
24
|
+
readonly employeeInfoContainerClass = input<string>('d-flex align-content-center');
|
|
25
|
+
readonly employeeDetailsClass = input<string>('ms-3');
|
|
26
|
+
readonly employeeNameContainerClass = input<string>('d-flex align-items-center');
|
|
27
|
+
readonly employeeNameClass = input<string>('fs-13 text-dark-gray fw-medium text-ellipsis-one-line');
|
|
28
|
+
readonly employeePositionClass = input<string>('fs-12 fw-normal text-dark-gray text-ellipsis-one-line mb-1');
|
|
29
|
+
readonly employeeGradeClass = input<string>('fs-12 text-dark-gray');
|
|
30
|
+
|
|
31
|
+
readonly showGrade = input<boolean>(false);
|
|
32
|
+
readonly showPropertySymbol = input<boolean>(true);
|
|
33
|
+
readonly showChangeEmployeeButton = input<boolean>(false);
|
|
34
|
+
readonly alignCenter = input<boolean>(true);
|
|
35
|
+
|
|
36
|
+
readonly ChangeEmployeeButtonHandler = output<void>();
|
|
37
|
+
readonly isRTL = isRTL();
|
|
38
|
+
employeeBadge: BayanEmployeeBadgeDTO = {
|
|
39
|
+
EmployeePhotoKey: null,
|
|
40
|
+
EmployeePhotoFailed: false,
|
|
41
|
+
EmployeeNameInitials: '',
|
|
42
|
+
};
|
|
43
|
+
|
|
44
|
+
dropDownIcon = faChevronDown;
|
|
45
|
+
faildToLoadEmployeePhoto = false;
|
|
46
|
+
|
|
47
|
+
constructor() {
|
|
48
|
+
effect(() => {
|
|
49
|
+
const info = this.employeeMainInfo();
|
|
50
|
+
if (info) {
|
|
51
|
+
this.employeeBadge.EmployeePhotoKey = info.PhotoKey || null;
|
|
52
|
+
this.employeeBadge.EmployeeNameInitials = info.EmployeeNameInitials || '';
|
|
53
|
+
this.employeeBadge.EmployeePhotoFailed = false;
|
|
54
|
+
}
|
|
55
|
+
});
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
convertEmployee() {
|
|
59
|
+
this.ChangeEmployeeButtonHandler.emit();
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
handleEmployeePhotoError() {
|
|
63
|
+
this.employeeBadge.EmployeePhotoFailed = true;
|
|
64
|
+
}
|
|
65
|
+
}
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
@if (employeeMainInfo(); as info) {
|
|
2
|
+
<div [class]="employeeInfoContainerClass()" [ngClass]="{ 'align-items-center': alignCenter() }">
|
|
3
|
+
<bayan-employee-badge
|
|
4
|
+
[badge]="employeeBadge"
|
|
5
|
+
[badgeClass]="badgeClass()"
|
|
6
|
+
[imageClass]="badgeImageClass()"
|
|
7
|
+
[width]="badgeWidth()"
|
|
8
|
+
[height]="badgeHeight()"
|
|
9
|
+
(employeePhotoError)="handleEmployeePhotoError()"
|
|
10
|
+
></bayan-employee-badge>
|
|
11
|
+
|
|
12
|
+
<div [class]="employeeDetailsClass()">
|
|
13
|
+
<div [class]="employeeNameContainerClass()">
|
|
14
|
+
<div
|
|
15
|
+
[class]="employeeNameClass()"
|
|
16
|
+
data-bs-toggle="tooltip"
|
|
17
|
+
[title]="info.EmployeeNumber + ' | ' + info.EmployeeName"
|
|
18
|
+
[innerHTML]="info.EmployeeNumber + ' | ' + info.EmployeeName | highlight: searchValue()"
|
|
19
|
+
></div>
|
|
20
|
+
@if (showChangeEmployeeButton()) {
|
|
21
|
+
<button type="button" class="border-0 ms-2 bg-none" (click)="convertEmployee()">
|
|
22
|
+
<fa-icon [icon]="dropDownIcon" class="text-primary fs-5"></fa-icon>
|
|
23
|
+
</button>
|
|
24
|
+
}
|
|
25
|
+
</div>
|
|
26
|
+
@if (info.PositionName != null && info.PositionName != '') {
|
|
27
|
+
<div [class]="employeePositionClass()" data-bs-toggle="tooltip" [title]="info.PositionName">
|
|
28
|
+
<span [innerHTML]="info.PositionName | highlight: searchValue()"></span>
|
|
29
|
+
</div>
|
|
30
|
+
}
|
|
31
|
+
@if (showGrade() && info.GradeName != null) {
|
|
32
|
+
<div [class]="employeeGradeClass()" [title]="info.GradeName">
|
|
33
|
+
<span [innerHTML]="info.GradeName"></span>
|
|
34
|
+
</div>
|
|
35
|
+
}
|
|
36
|
+
<div
|
|
37
|
+
class="d-flex text-dark-gray mb-0"
|
|
38
|
+
data-bs-toggle="tooltip"
|
|
39
|
+
[title]="showPropertySymbol() ? info.PropertySymbol + ' | ' + info.AdminUnitName : info.AdminUnitName"
|
|
40
|
+
>
|
|
41
|
+
<div class="fs-12">
|
|
42
|
+
@if (showPropertySymbol()) {
|
|
43
|
+
<span class="property-badge cursor-pointer me-1" title="{{ info.PropertyName }}">
|
|
44
|
+
<span [innerHTML]="info.PropertySymbol"></span>
|
|
45
|
+
</span>
|
|
46
|
+
}
|
|
47
|
+
<span
|
|
48
|
+
class="fw-normal ms-1"
|
|
49
|
+
[ngClass]="{ 'me-1': isRTL && showPropertySymbol(), 'ms-1': !isRTL && showPropertySymbol() }"
|
|
50
|
+
[title]="info.AdminUnitName"
|
|
51
|
+
[innerHTML]="info.AdminUnitName | highlight: searchValue()"
|
|
52
|
+
></span>
|
|
53
|
+
</div>
|
|
54
|
+
</div>
|
|
55
|
+
</div>
|
|
56
|
+
</div>
|
|
57
|
+
}
|
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
<dx-popup
|
|
2
|
+
[visible]="isPopupVisible()"
|
|
3
|
+
[width]="'755px'"
|
|
4
|
+
[height]="'680px'"
|
|
5
|
+
[showCloseButton]="true"
|
|
6
|
+
[showTitle]="true"
|
|
7
|
+
[title]="'MyTeam' | translate"
|
|
8
|
+
shadingColor="rgba(0,0,0,0.4)"
|
|
9
|
+
(onShowing)="loadPage(true)"
|
|
10
|
+
(onHiding)="closePopup()"
|
|
11
|
+
>
|
|
12
|
+
<ng-template #loadingIndicatorTemplate>
|
|
13
|
+
<div [class]="loadingContainerClass()">
|
|
14
|
+
<dx-load-indicator [visible]="true" [class]="loadingIndicatorClass()"></dx-load-indicator>
|
|
15
|
+
</div>
|
|
16
|
+
</ng-template>
|
|
17
|
+
|
|
18
|
+
<ng-template #employeeCardTemplate let-employee>
|
|
19
|
+
<div [class]="employeeCardClass()" [style.height]="employeeCardHeight()">
|
|
20
|
+
<div [class]="employeeRowClass()">
|
|
21
|
+
<div [class]="employeeInfoColumnClass()">
|
|
22
|
+
<app-employee-main-info-card
|
|
23
|
+
[employeeMainInfo]="toEmployeeMainInfo(employee)"
|
|
24
|
+
[searchValue]="searchValue()"
|
|
25
|
+
[showGrade]="showGrade()"
|
|
26
|
+
[showPropertySymbol]="showPropertySymbol()"
|
|
27
|
+
[showChangeEmployeeButton]="false"
|
|
28
|
+
></app-employee-main-info-card>
|
|
29
|
+
</div>
|
|
30
|
+
<div [class]="contactColumnClass()">
|
|
31
|
+
<div [class]="contactContainerClass()">
|
|
32
|
+
<span [class]="contactTitleClass()">{{ 'ContactInfo' | translate }}:</span>
|
|
33
|
+
<span [class]="contactRowClass()">
|
|
34
|
+
<fa-icon [icon]="emailIcon()" [class]="contactIconClass()"></fa-icon>
|
|
35
|
+
@if (hasEmployeeEmail(employee)) {
|
|
36
|
+
<a
|
|
37
|
+
[class]="emailTextClass()"
|
|
38
|
+
[href]="'mailto:' + getEmployeeEmailDisplay(employee)"
|
|
39
|
+
[title]="getEmployeeEmailDisplay(employee)"
|
|
40
|
+
[innerHTML]="getEmployeeEmailDisplay(employee)"
|
|
41
|
+
></a>
|
|
42
|
+
} @else {
|
|
43
|
+
<span [class]="emailPlaceholderClass()">-</span>
|
|
44
|
+
}
|
|
45
|
+
</span>
|
|
46
|
+
<span [class]="contactRowClass()">
|
|
47
|
+
<fa-icon [icon]="phoneIcon()" [class]="contactIconClass()"></fa-icon>
|
|
48
|
+
<span [title]="getEmployeePhoneDisplay(employee)" [innerHTML]="getEmployeePhoneDisplay(employee)"></span>
|
|
49
|
+
</span>
|
|
50
|
+
</div>
|
|
51
|
+
</div>
|
|
52
|
+
</div>
|
|
53
|
+
</div>
|
|
54
|
+
</ng-template>
|
|
55
|
+
|
|
56
|
+
<div [class]="headerRowClass()">
|
|
57
|
+
<div [class]="switchContainerClass()">
|
|
58
|
+
<input
|
|
59
|
+
[class]="switchInputClass()"
|
|
60
|
+
type="checkbox"
|
|
61
|
+
role="switch"
|
|
62
|
+
id="myTeamDirectOnlySwitch"
|
|
63
|
+
[checked]="showAllSubordinates()"
|
|
64
|
+
(change)="onToggleChange($event)"
|
|
65
|
+
/>
|
|
66
|
+
<label [class]="switchLabelClass()" for="myTeamDirectOnlySwitch">
|
|
67
|
+
{{ 'ShowAllSubordinates' | translate }}
|
|
68
|
+
</label>
|
|
69
|
+
</div>
|
|
70
|
+
<dx-text-box
|
|
71
|
+
[value]="searchValue()"
|
|
72
|
+
[placeholder]="'Search...' | translate"
|
|
73
|
+
[width]="'250px'"
|
|
74
|
+
mode="search"
|
|
75
|
+
(onValueChanged)="onSearchChanged($event.value)"
|
|
76
|
+
></dx-text-box>
|
|
77
|
+
</div>
|
|
78
|
+
|
|
79
|
+
<dx-scroll-view
|
|
80
|
+
#dataScrollView
|
|
81
|
+
[height]="500"
|
|
82
|
+
[width]="'100%'"
|
|
83
|
+
[elementAttr]="{ class: scrollViewClass() }"
|
|
84
|
+
[scrollByContent]="true"
|
|
85
|
+
[scrollByThumb]="true"
|
|
86
|
+
[showScrollbar]="'always'"
|
|
87
|
+
[bounceEnabled]="false"
|
|
88
|
+
(onReachBottom)="onReachBottom($event)"
|
|
89
|
+
>
|
|
90
|
+
<div [class]="groupedListClass()">
|
|
91
|
+
@if (isDataLoading()) {
|
|
92
|
+
<ng-container *ngTemplateOutlet="loadingIndicatorTemplate"></ng-container>
|
|
93
|
+
} @else if (items().length === 0) {
|
|
94
|
+
<div [class]="emptyStateClass()">
|
|
95
|
+
{{ 'NoDataToDisplay' | translate }}
|
|
96
|
+
</div>
|
|
97
|
+
} @else {
|
|
98
|
+
@for (group of items(); track group.adminUnitName) {
|
|
99
|
+
@if (showAllSubordinates()) {
|
|
100
|
+
<div [class]="groupHeaderClass()" [innerHTML]="group.adminUnitName | highlight: searchValue()"></div>
|
|
101
|
+
}
|
|
102
|
+
@for (emp of group.employees; track emp.EmployeeNumber) {
|
|
103
|
+
<ng-container *ngTemplateOutlet="employeeCardTemplate; context: { $implicit: emp }"></ng-container>
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
</div>
|
|
108
|
+
</dx-scroll-view>
|
|
109
|
+
</dx-popup>
|