@skysoftware-co/bayan-hr-widgets-ui 2.0.19 → 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.
Files changed (104) hide show
  1. package/ng-package.json +9 -0
  2. package/package.json +3 -15
  3. package/src/assets/i18n/ar.json +166 -0
  4. package/src/assets/i18n/en.json +166 -0
  5. package/src/assets/i18n/fr.json +166 -0
  6. package/src/lib/my-calendar-widget/my-calendar-widget.component.html +25 -0
  7. package/src/lib/my-calendar-widget/my-calendar-widget.component.ts +220 -0
  8. package/src/lib/my-main-details-widget/my-main-details-widget.component.html +157 -0
  9. package/src/lib/my-main-details-widget/my-main-details-widget.component.ts +179 -0
  10. package/src/lib/my-next-week-vacation-insights-widget/components/next-week-vacation-insights-popup/next-week-vacation-insights-popup.component.html +131 -0
  11. package/src/lib/my-next-week-vacation-insights-widget/components/next-week-vacation-insights-popup/next-week-vacation-insights-popup.component.ts +119 -0
  12. package/src/lib/my-next-week-vacation-insights-widget/my-next-week-vacation-insights-widget.component.html +35 -0
  13. package/src/lib/my-next-week-vacation-insights-widget/my-next-week-vacation-insights-widget.component.ts +110 -0
  14. package/src/lib/my-profile/address-widget/my-profile-address-widget.component.html +57 -0
  15. package/src/lib/my-profile/address-widget/my-profile-address-widget.component.ts +70 -0
  16. package/src/lib/my-profile/bank-info-widget/my-profile-bank-info-widget.component.html +101 -0
  17. package/src/lib/my-profile/bank-info-widget/my-profile-bank-info-widget.component.ts +89 -0
  18. package/src/lib/my-profile/contact-widget/my-profile-contact-widget.component.html +89 -0
  19. package/src/lib/my-profile/contact-widget/my-profile-contact-widget.component.ts +78 -0
  20. package/src/lib/my-profile/contract-widget/my-profile-contract-widget.component.html +63 -0
  21. package/src/lib/my-profile/contract-widget/my-profile-contract-widget.component.ts +73 -0
  22. package/src/lib/my-profile/degrees-widget/my-profile-degrees-widget-component.html +86 -0
  23. package/src/lib/my-profile/degrees-widget/my-profile-degrees-widget-component.ts +98 -0
  24. package/src/lib/my-profile/dependents-documents-widget/my-profile-dependents-documents-widget.html +83 -0
  25. package/src/lib/my-profile/dependents-documents-widget/my-profile-dependents-documents-widget.ts +126 -0
  26. package/src/lib/my-profile/documents-widgets/components/document-card/document-card.component.html +53 -0
  27. package/src/lib/my-profile/documents-widgets/components/document-card/document-card.component.ts +50 -0
  28. package/src/lib/my-profile/documents-widgets/components/document-row/document-row.component.html +48 -0
  29. package/src/lib/my-profile/documents-widgets/components/document-row/document-row.component.ts +44 -0
  30. package/src/lib/my-profile/documents-widgets/components/document-tablet-card/document-tablet-card.component.html +46 -0
  31. package/src/lib/my-profile/documents-widgets/components/document-tablet-card/document-tablet-card.component.ts +47 -0
  32. package/src/lib/my-profile/employee-dependents-widget/my-profile-employee-dependents-component.html +50 -0
  33. package/src/lib/my-profile/employee-dependents-widget/my-profile-employee-dependents-component.ts +63 -0
  34. package/src/lib/my-profile/entitlements-others-widget/my-profile-entitlements-others-widget.component.html +26 -0
  35. package/src/lib/my-profile/entitlements-others-widget/my-profile-entitlements-others-widget.component.ts +66 -0
  36. package/src/lib/my-profile/experiences-widget/my-profile-experiences-widget-component.html +93 -0
  37. package/src/lib/my-profile/experiences-widget/my-profile-experiences-widget-component.ts +102 -0
  38. package/src/lib/my-profile/indemnity-widget/my-profile-indemnity-widget.component.html +49 -0
  39. package/src/lib/my-profile/indemnity-widget/my-profile-indemnity-widget.component.ts +79 -0
  40. package/src/lib/my-profile/job-info-widget/my-profile-job-info-widget.component.html +71 -0
  41. package/src/lib/my-profile/job-info-widget/my-profile-job-info-widget.component.ts +73 -0
  42. package/src/lib/my-profile/languages-widget/my-profile-languages-widget.component.html +23 -0
  43. package/src/lib/my-profile/languages-widget/my-profile-languages-widget.component.ts +70 -0
  44. package/src/lib/my-profile/medical-insurance-widget/components/medical-insurance-card/medical-insurance-card.component.html +18 -0
  45. package/src/lib/my-profile/medical-insurance-widget/components/medical-insurance-card/medical-insurance-card.component.ts +29 -0
  46. package/src/lib/my-profile/medical-insurance-widget/my-profile-medical-insurance-widget.component.html +52 -0
  47. package/src/lib/my-profile/medical-insurance-widget/my-profile-medical-insurance-widget.component.ts +103 -0
  48. package/src/lib/my-profile/official-documents-widget/my-profile-official-documents-widget.html +82 -0
  49. package/src/lib/my-profile/official-documents-widget/my-profile-official-documents-widget.ts +119 -0
  50. package/src/lib/my-profile/other-nationalities-widget/my-profile-other-nationalities-widget.component.html +23 -0
  51. package/src/lib/my-profile/other-nationalities-widget/my-profile-other-nationalities-widget.component.ts +70 -0
  52. package/src/lib/my-profile/personal-info-main-widget/my-profile-personal-info-main-widget.component.html +115 -0
  53. package/src/lib/my-profile/personal-info-main-widget/my-profile-personal-info-main-widget.component.ts +75 -0
  54. package/src/lib/my-profile/salary-widget/my-profile-salary-widget.component.html +37 -0
  55. package/src/lib/my-profile/salary-widget/my-profile-salary-widget.component.ts +85 -0
  56. package/src/lib/my-profile/service-charge-widget/my-profile-service-charge-widget.component.html +16 -0
  57. package/src/lib/my-profile/service-charge-widget/my-profile-service-charge-widget.component.ts +101 -0
  58. package/src/lib/my-profile/ticket-widget/components/ticket-card/ticket-card.component.html +23 -0
  59. package/src/lib/my-profile/ticket-widget/components/ticket-card/ticket-card.component.ts +26 -0
  60. package/src/lib/my-profile/ticket-widget/my-profile-ticket-widget.component.html +68 -0
  61. package/src/lib/my-profile/ticket-widget/my-profile-ticket-widget.component.ts +93 -0
  62. package/src/lib/my-profile/vacations-widget/my-profile-vacations-widget.component.html +34 -0
  63. package/src/lib/my-profile/vacations-widget/my-profile-vacations-widget.component.ts +66 -0
  64. package/src/lib/my-team-subordinates-popup-widget/components/employee-main-info-card/employee-information-card.component.ts +65 -0
  65. package/src/lib/my-team-subordinates-popup-widget/components/employee-main-info-card/employee-main-info-card.component.html +57 -0
  66. package/src/lib/my-team-subordinates-popup-widget/components/my-team-subordinates-popup/my-team-popup.component.html +109 -0
  67. package/src/lib/my-team-subordinates-popup-widget/components/my-team-subordinates-popup/my-team-popup.component.ts +297 -0
  68. package/src/lib/my-upcoming-events-widget/components/event-item/event-item.component.html +53 -0
  69. package/src/lib/my-upcoming-events-widget/components/event-item/event-item.component.ts +42 -0
  70. package/src/lib/my-upcoming-events-widget/components/event-tab-bar/event-tab-bar.component.html +21 -0
  71. package/src/lib/my-upcoming-events-widget/components/event-tab-bar/event-tab-bar.component.ts +44 -0
  72. package/src/lib/my-upcoming-events-widget/components/events-popup/events-popup.component.html +67 -0
  73. package/src/lib/my-upcoming-events-widget/components/events-popup/events-popup.component.ts +74 -0
  74. package/src/lib/my-upcoming-events-widget/my-upcoming-events-widget.component.html +74 -0
  75. package/src/lib/my-upcoming-events-widget/my-upcoming-events-widget.component.ts +199 -0
  76. package/src/lib/services/hr-self-widgets.service.ts +624 -0
  77. package/src/lib/shared/components/card-header/card-header.component.html +4 -0
  78. package/src/lib/shared/components/card-header/card-header.component.ts +18 -0
  79. package/src/lib/shared/components/hr-employee-calendar/hr-employee-calendar.component.html +47 -0
  80. package/src/lib/shared/components/hr-employee-calendar/hr-employee-calendar.component.ts +193 -0
  81. package/src/lib/shared/components/info-field/info-field.component.html +2 -0
  82. package/src/lib/shared/components/info-field/info-field.component.ts +20 -0
  83. package/src/lib/shared/components/widget-card/widget-card-component.html +3 -0
  84. package/src/lib/shared/components/widget-card/widget-card-component.ts +17 -0
  85. package/src/lib/shared/pipes/translate.pipe.ts +34 -0
  86. package/src/lib/shared/services/bank-information-cache.service.ts +29 -0
  87. package/src/lib/shared/services/common-methods.service.ts +33 -0
  88. package/src/lib/shared/services/constants.service.ts +12 -0
  89. package/src/lib/shared/services/entitlements-cache.service.ts +94 -0
  90. package/src/lib/shared/services/job-information-cache.service.ts +72 -0
  91. package/src/lib/shared/services/my-team-popup.service.ts +34 -0
  92. package/src/lib/shared/services/personal-information-cache.service.ts +77 -0
  93. package/src/lib/shared/services/profile-documents-cache-service.ts +44 -0
  94. package/src/lib/shared/services/profile-employee-dependents-cach.ts +37 -0
  95. package/src/lib/shared/services/qualifications-cache.service.ts +45 -0
  96. package/src/lib/shared/services/translate.service.ts +35 -0
  97. package/src/lib/shared/types/common.ts +359 -0
  98. package/src/public-api.ts +35 -0
  99. package/tsconfig.lib.json +11 -0
  100. package/tsconfig.lib.prod.json +9 -0
  101. package/tsconfig.spec.json +8 -0
  102. package/fesm2022/skysoftware-co-bayan-hr-widgets-ui.mjs +0 -4788
  103. package/fesm2022/skysoftware-co-bayan-hr-widgets-ui.mjs.map +0 -1
  104. package/types/skysoftware-co-bayan-hr-widgets-ui.d.ts +0 -1306
@@ -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>