@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,119 @@
1
+ import { CommonModule } from '@angular/common';
2
+ import { ChangeDetectionStrategy, Component, ViewChild, effect, inject, input, output, signal } from '@angular/core';
3
+ import { HRTranslatePipe } from '../../../shared/pipes/translate.pipe';
4
+ import { DxDataGridComponent, DxDataGridModule, DxPopupModule, DxTextBoxModule } from 'devextreme-angular';
5
+ import { FontAwesomeModule } from '@fortawesome/angular-fontawesome';
6
+ import { faXmark } from '@fortawesome/pro-light-svg-icons';
7
+ import { BayanEmployeeBadgeComponent, BayanEmployeeBadgeDTO } from '@skysoftware-co/bayan-components-ui';
8
+ import { HttpClient, HttpParams } from '@angular/common/http';
9
+ import CustomStore from 'devextreme/data/custom_store';
10
+ import { lastValueFrom } from 'rxjs';
11
+ import { VacationPopupType } from '../../../shared/types/common';
12
+ import { HighlightPipe } from '@skysoftware-co/sky-components-ui';
13
+
14
+ @Component({
15
+ selector: 'hr-next-week-vacation-insights-popup',
16
+ standalone: true,
17
+ imports: [
18
+ DxPopupModule,
19
+ HRTranslatePipe,
20
+ CommonModule,
21
+ FontAwesomeModule,
22
+ DxDataGridModule,
23
+ BayanEmployeeBadgeComponent,
24
+ DxTextBoxModule,
25
+ HighlightPipe,
26
+ ],
27
+ templateUrl: './next-week-vacation-insights-popup.component.html',
28
+ changeDetection: ChangeDetectionStrategy.OnPush,
29
+ })
30
+ export class HRNextWeekVacationInsightsPopupComponent {
31
+ @ViewChild(DxDataGridComponent, { static: false }) dataGrid!: DxDataGridComponent;
32
+
33
+ readonly popupVisible = input<boolean>(false);
34
+ readonly popupType = input<VacationPopupType>(VacationPopupType.Upcoming);
35
+ readonly baseUrl = input<string>('');
36
+ readonly width = input<string>('700px');
37
+ readonly height = input<string>('480px');
38
+ readonly gridHeight = input<string>('320px');
39
+ readonly pageSize = input<number>(20);
40
+ readonly showProperty = input<boolean>(false);
41
+
42
+ readonly closePopupClickHandler = output<void>();
43
+
44
+ popupTitle: string = '';
45
+ popupSubTitle: string = '';
46
+ keyExpr = 'EmployeeNumber';
47
+ VacationPopupType = VacationPopupType;
48
+ readonly dataSource = signal<CustomStore | null>(null);
49
+ xMarkIcon = faXmark;
50
+ readonly searchValue = signal('');
51
+
52
+ private readonly http = inject(HttpClient);
53
+
54
+ private readonly initDataSourceEffect = effect(() => {
55
+ if (this.popupVisible()) {
56
+ this.initDataSource();
57
+ }
58
+ });
59
+
60
+ private initDataSource(): void {
61
+ this.dataSource.set(
62
+ new CustomStore({
63
+ key: this.keyExpr,
64
+ load: loadOptions => {
65
+ const skip = loadOptions.skip ?? 0;
66
+ const pageIndex = Math.floor(skip / this.pageSize()) + 1;
67
+
68
+ let params = new HttpParams()
69
+ .set('ShowDirectSubordinatesOnly', 'false')
70
+ .set('LoadOptions.PageIndex', pageIndex.toString())
71
+ .set('LoadOptions.PageSize', this.pageSize().toString());
72
+
73
+ if (this.searchValue()) {
74
+ params = params.set('LoadOptions.SearchValue', this.searchValue());
75
+ }
76
+
77
+ return lastValueFrom(this.http.get<any>(this.baseUrl(), { params })).then((response: any) => {
78
+ const items = response.ResponseData?.Data ?? [];
79
+ const totalCount = response.ResponseData?.TotalCount ?? 0;
80
+ return { data: items, totalCount };
81
+ });
82
+ },
83
+ }),
84
+ );
85
+ }
86
+
87
+ onSearchValueChanged(e: any): void {
88
+ this.searchValue.set(e.value ?? '');
89
+ this.initDataSource();
90
+ }
91
+
92
+ getPopupTitle(): string {
93
+ return (
94
+ this.popupSubTitle || (this.popupType() === VacationPopupType.Upcoming ? 'UpcomingVacations' : 'ExpectedToReturn')
95
+ );
96
+ }
97
+
98
+ onPopupClose() {
99
+ this.searchValue.set('');
100
+ this.dataSource.set(null);
101
+ this.closePopupClickHandler.emit();
102
+ }
103
+
104
+ onHidden() {
105
+ this.onPopupClose();
106
+ }
107
+
108
+ getEmployeeBadge(item: any): BayanEmployeeBadgeDTO {
109
+ return {
110
+ EmployeePhotoKey: item.PhotoPath || null,
111
+ EmployeePhotoFailed: item.FailedToLoadPhoto || false,
112
+ EmployeeNameInitials: item.EmployeeNameInitials || '',
113
+ };
114
+ }
115
+
116
+ handleEmployeePhotoError(employee: any) {
117
+ employee.FailedToLoadPhoto = true;
118
+ }
119
+ }
@@ -0,0 +1,35 @@
1
+ <div [class]="cardClass()">
2
+ <div class="card-body d-flex flex-column p-0 mb-3">
3
+ <div [class]="titleClass()">
4
+ {{ 'NextWeekVacationInsights' | translate | uppercase }}
5
+ </div>
6
+ <div class="d-flex flex-column mt-3">
7
+ <div [ngClass]="firstRowClass()">
8
+ <sky-widget-section-item
9
+ [data]="upcomingVacationsBadge()"
10
+ [containerClass]="upcomingContainerClass()"
11
+ [valueClass]="upcomingVacationsBadge().Value === 0 ? disabledValueClass() : valueClass()"
12
+ [ngClass]="{ 'pe-none': upcomingVacationsBadge().Value === 0 }"
13
+ (OnWidgetSectionClick)="openPopup(VacationPopupType.Upcoming)"
14
+ ></sky-widget-section-item>
15
+ </div>
16
+ <div [ngClass]="secondRowClass()">
17
+ <sky-widget-section-item
18
+ [data]="expectedToReturnBadge()"
19
+ [containerClass]="expectedContainerClass()"
20
+ [valueClass]="expectedToReturnBadge().Value === 0 ? disabledValueClass() : valueClass()"
21
+ [ngClass]="{ 'pe-none': expectedToReturnBadge().Value === 0 }"
22
+ (OnWidgetSectionClick)="openPopup(VacationPopupType.ExpectedToReturn)"
23
+ ></sky-widget-section-item>
24
+ </div>
25
+ </div>
26
+ </div>
27
+ </div>
28
+
29
+ <hr-next-week-vacation-insights-popup
30
+ [popupVisible]="popupVisible()"
31
+ [popupType]="popupType()"
32
+ [baseUrl]="popupBaseUrl()"
33
+ [showProperty]="showProperty()"
34
+ (closePopupClickHandler)="closePopup()"
35
+ ></hr-next-week-vacation-insights-popup>
@@ -0,0 +1,110 @@
1
+ import { ChangeDetectionStrategy, Component, effect, inject, input, output, signal } from '@angular/core';
2
+ import { CommonModule } from '@angular/common';
3
+ import { FontAwesomeModule } from '@fortawesome/angular-fontawesome';
4
+ import { HRTranslatePipe } from '../shared/pipes/translate.pipe';
5
+ import { SkyWidgetSectionItemComponent, SkyWidgetSectionItem } from '@skysoftware-co/sky-components-ui';
6
+ import { faPlaneDeparture, faPlaneArrival } from '@fortawesome/pro-solid-svg-icons';
7
+ import { HRSelfWidgetsService } from '../services/hr-self-widgets.service';
8
+ import { HRNextWeekVacationInsightsPopupComponent } from './components/next-week-vacation-insights-popup/next-week-vacation-insights-popup.component';
9
+ import { VacationPopupType } from '../shared/types/common';
10
+
11
+ @Component({
12
+ selector: 'hr-my-next-week-vacation-insights-widget',
13
+ standalone: true,
14
+ imports: [
15
+ CommonModule,
16
+ HRTranslatePipe,
17
+ FontAwesomeModule,
18
+ SkyWidgetSectionItemComponent,
19
+ HRNextWeekVacationInsightsPopupComponent,
20
+ ],
21
+ providers: [HRTranslatePipe],
22
+ templateUrl: './my-next-week-vacation-insights-widget.component.html',
23
+ changeDetection: ChangeDetectionStrategy.OnPush,
24
+ })
25
+ export class MyNextWeekVacationInsightsWidgetComponent {
26
+ readonly baseUrl = input<string>('');
27
+ readonly showProperty = input<boolean>(false);
28
+ readonly cardClass = input<string>('card rounded rounded-4 card-shadow border-top-0 h-100 p-4');
29
+ readonly titleClass = input<string>('table-header-lg fw-meduim mb-3 mt-2');
30
+ readonly valueClass = input<string>('fs-24 mt-1 link-dark hover-primary text-decoration-none');
31
+ readonly disabledValueClass = input<string>('fs-24 mt-1 text-muted pe-none text-decoration-none');
32
+ readonly upcomingContainerClass = input<string>('border-start border-5 mb-4');
33
+ readonly expectedContainerClass = input<string>('border-start border-5');
34
+ readonly firstRowClass = input<string>('mb-4');
35
+ readonly secondRowClass = input<string>('mt-3');
36
+ readonly isLoadingChanged = output<boolean>();
37
+
38
+ readonly popupVisible = signal(false);
39
+ readonly popupType = signal<VacationPopupType>(VacationPopupType.Upcoming);
40
+ readonly popupBaseUrl = signal('');
41
+ VacationPopupType = VacationPopupType;
42
+
43
+ readonly upcomingVacationsBadge = signal<SkyWidgetSectionItem>({
44
+ Id: 1,
45
+ Title: '',
46
+ Value: 0,
47
+ Icon: faPlaneDeparture,
48
+ });
49
+ readonly expectedToReturnBadge = signal<SkyWidgetSectionItem>({
50
+ Id: 2,
51
+ Title: '',
52
+ Value: 0,
53
+ Icon: faPlaneArrival,
54
+ });
55
+
56
+ private readonly selfWidgetsService = inject(HRSelfWidgetsService);
57
+ private readonly translatePipe = inject(HRTranslatePipe);
58
+
59
+ private readonly loadVacationSummaryEffect = effect(() => {
60
+ const baseUrl = this.baseUrl();
61
+ this.initBadges(0, 0);
62
+ this.loadVacationSummary(baseUrl);
63
+ });
64
+
65
+ private loadVacationSummary(baseUrl: string): void {
66
+ this.isLoadingChanged.emit(true);
67
+ this.selfWidgetsService.getVacationSummary(baseUrl).subscribe({
68
+ next: response => {
69
+ const data = response.ResponseData;
70
+ this.initBadges(data.UpcomingVacationsCount, data.ExpectedToReturnCount);
71
+ this.isLoadingChanged.emit(false);
72
+ },
73
+ error: () => {
74
+ this.isLoadingChanged.emit(false);
75
+ },
76
+ });
77
+ }
78
+
79
+ openPopup(type: VacationPopupType): void {
80
+ if (type === VacationPopupType.Upcoming && this.upcomingVacationsBadge()?.Value === 0) return;
81
+ if (type === VacationPopupType.ExpectedToReturn && this.expectedToReturnBadge()?.Value === 0) return;
82
+
83
+ this.popupType.set(type);
84
+ if (type === VacationPopupType.Upcoming) {
85
+ this.popupBaseUrl.set(`${this.baseUrl()}/hr/widgets/me/team/next-week-vacation-insights/upcoming-vacations`);
86
+ } else {
87
+ this.popupBaseUrl.set(`${this.baseUrl()}/hr/widgets/me/team/next-week-vacation-insights/expected-to-return`);
88
+ }
89
+ this.popupVisible.set(true);
90
+ }
91
+
92
+ closePopup(): void {
93
+ this.popupVisible.set(false);
94
+ }
95
+
96
+ private initBadges(upcomingVacations: number, expectedToReturn: number): void {
97
+ this.upcomingVacationsBadge.set({
98
+ Id: 1,
99
+ Title: this.translatePipe.transform('UpcomingVacations'),
100
+ Value: upcomingVacations,
101
+ Icon: faPlaneDeparture,
102
+ });
103
+ this.expectedToReturnBadge.set({
104
+ Id: 2,
105
+ Title: this.translatePipe.transform('ExpectedToReturn'),
106
+ Value: expectedToReturn,
107
+ Icon: faPlaneArrival,
108
+ });
109
+ }
110
+ }
@@ -0,0 +1,57 @@
1
+ <sky-section-divider
2
+ [fontAwesomeIcon]="addressIcon()"
3
+ [text]="sectionTitle() | translate | uppercase"
4
+ [iconClass]="headerIconClass()"
5
+ [textClass]="headerTextClass()"
6
+ [dividerClass]="headerDividerClass()"
7
+ ></sky-section-divider>
8
+
9
+ @if (personalInfoAddressDetails()) {
10
+ <div [ngClass]="rowClass()">
11
+ <div [ngClass]="columnClass()">
12
+ <hr-info-field
13
+ [labelKey]="'Address'"
14
+ [value]="personalInfoAddressDetails()!.Address"
15
+ [labelClass]="labelClass()"
16
+ [valueClass]="valueClass()"
17
+ ></hr-info-field>
18
+ </div>
19
+
20
+ <div [ngClass]="columnClass()">
21
+ <hr-info-field
22
+ [labelKey]="'City'"
23
+ [value]="personalInfoAddressDetails()!.City"
24
+ [labelClass]="labelClass()"
25
+ [valueClass]="valueClass()"
26
+ ></hr-info-field>
27
+ </div>
28
+
29
+ <div [ngClass]="responsiveTopSpacingColumnClass()">
30
+ <hr-info-field
31
+ [labelKey]="'P.OBox'"
32
+ [value]="personalInfoAddressDetails()!.POBox"
33
+ [labelClass]="labelClass()"
34
+ [valueClass]="valueClass()"
35
+ ></hr-info-field>
36
+ </div>
37
+
38
+ <div [ngClass]="topSpacingBottomSpacingColumnClass()">
39
+ <hr-info-field
40
+ [labelKey]="'PostalCode'"
41
+ [value]="personalInfoAddressDetails()!.PostalCode"
42
+ [labelClass]="labelClass()"
43
+ [valueClass]="valueClass()"
44
+ ></hr-info-field>
45
+ </div>
46
+ </div>
47
+ } @else {
48
+ <sky-empty-design-card
49
+ [containerClass]="emptyStateContainerClass()"
50
+ [cardBodyClass]="''"
51
+ [cardBodyContainerClass]="''"
52
+ [visibleIcon]="false"
53
+ [visibleQuickAction]="false"
54
+ [emptyTextClass]="emptyStateTextClass()"
55
+ [emptyText]="isLoading() ? (sectionTitle() | translate) + ' ' + ('IsLoading' | translate) : ('ThereIsNoAddressYet' | translate)"
56
+ ></sky-empty-design-card>
57
+ }
@@ -0,0 +1,70 @@
1
+ import { CommonModule } from '@angular/common';
2
+ import { ChangeDetectionStrategy, Component, OnInit, inject, input, output, signal } from '@angular/core';
3
+ import { faHouse } from '@fortawesome/pro-light-svg-icons';
4
+ import { HRTranslatePipe } from '../../shared/pipes/translate.pipe';
5
+ import { SkyEmptyDesignCardComponent, SkySectionDividerComponent } from '@skysoftware-co/sky-components-ui';
6
+ import { PersonalInfoAddressDetails } from '../../shared/types/common';
7
+ import { HRSelfWidgetsService } from '../../services/hr-self-widgets.service';
8
+ import { HRInfoFieldComponent } from '../../shared/components/info-field/info-field.component';
9
+
10
+ @Component({
11
+ selector: 'hr-my-profile-address-widget',
12
+ standalone: true,
13
+ imports: [
14
+ CommonModule,
15
+ HRTranslatePipe,
16
+ SkySectionDividerComponent,
17
+ SkyEmptyDesignCardComponent,
18
+ HRInfoFieldComponent,
19
+ ],
20
+ templateUrl: './my-profile-address-widget.component.html',
21
+ changeDetection: ChangeDetectionStrategy.OnPush,
22
+ })
23
+ export class MyProfileAddressWidgetComponent implements OnInit {
24
+ readonly personalInfoAddressDetails = signal<PersonalInfoAddressDetails | null>(null);
25
+ readonly isLoading = signal(true);
26
+ readonly baseUrl = input.required<string>();
27
+ readonly headerIconClass = input<string>('primary-icon-xl');
28
+ readonly headerTextClass = input<string>('fs-16 mt-2 text-secondary');
29
+ readonly headerDividerClass = input<string>('flex-grow-1 ms-2');
30
+ readonly rowClass = input<string>('row mt-4');
31
+ readonly columnClass = input<string>('col-md-4 col-6');
32
+ readonly responsiveTopSpacingColumnClass = input<string>('col-md-4 col-6 mt-md-0 mt-4');
33
+ readonly topSpacingBottomSpacingColumnClass = input<string>('col-md-4 col-6 mt-4 mb-5');
34
+ readonly labelClass = input<string>('field-secondary-label-sm');
35
+ readonly valueClass = input<string>('fs-14 fw-medium text-ellipsis-one-line');
36
+ readonly emptyStateContainerClass = input<string>(
37
+ 'd-flex flex-column justify-content-center align-items-center my-5',
38
+ );
39
+ readonly emptyStateTextClass = input<string>('field-secondary-label-md');
40
+
41
+ readonly addressIcon = input(faHouse);
42
+ readonly sectionTitle = input('address');
43
+ readonly isLoadingChanged = output<boolean>();
44
+ readonly errorOccurred = output<string>();
45
+
46
+ private readonly hrSelfWidgetsService = inject(HRSelfWidgetsService);
47
+
48
+ ngOnInit(): void {
49
+ if (!this.baseUrl()) {
50
+ this.isLoading.set(false);
51
+ return;
52
+ }
53
+
54
+ this.isLoadingChanged.emit(true);
55
+
56
+ this.hrSelfWidgetsService.getPersonalInfoAddressDetails(this.baseUrl()).subscribe({
57
+ next: response => {
58
+ this.isLoading.set(false);
59
+ this.isLoadingChanged.emit(false);
60
+ this.personalInfoAddressDetails.set(response);
61
+ },
62
+ error: error => {
63
+ this.isLoading.set(false);
64
+ this.isLoadingChanged.emit(false);
65
+ this.personalInfoAddressDetails.set(null);
66
+ this.errorOccurred.emit(error.error.ResponseData.Errors[0].Message);
67
+ },
68
+ });
69
+ }
70
+ }
@@ -0,0 +1,101 @@
1
+ @if (sectionHeaderVisibility()) {
2
+ <sky-section-divider
3
+ [fontAwesomeIcon]="bankInformationIcon()"
4
+ [text]="sectionTitle() | translate | uppercase"
5
+ [iconClass]="headerIconClass()"
6
+ [textClass]="headerTextClass()"
7
+ [dividerClass]="headerDividerClass()"
8
+ ></sky-section-divider>
9
+ }
10
+ @if (employeeBankInformation().length > 0) {
11
+ @for (bankInfo of employeeBankInformation(); track bankInfo) {
12
+ <div [class]="cardClass()">
13
+ @if (bankInfo.IsMainBank && employeeBankInformation().length > 1) {
14
+ <div [class]="mainBadgeClass()" style="padding-top: 2px" [style.margin-left]="!isRTL() ? '-6px' : 'unset'">
15
+ <span [class]="mainBadgeTextClass()">{{ 'MainBank' | translate }}</span>
16
+ </div>
17
+
18
+ <div
19
+ [class]="triangleClass()"
20
+ [style.margin-left]="!isRTL() ? '-6px' : 'unset'"
21
+ [style.margin-right]="isRTL() ? '-5px' : '20px'"
22
+ [style.margin-top]="!isRTL() ? '7px' : '4px'"
23
+ >
24
+ <svg viewBox="4 2 16 16" class="status-badge-triangle" fill="#e67e0f">
25
+ <path
26
+ d="m3.86 8.753 5.482 4.796c.646.566 1.658.106 1.658-.753V3.204a1 1 0 0 0-1.659-.753l-5.48 4.796a1 1 0 0 0 0 1.506z"
27
+ ></path>
28
+ </svg>
29
+ </div>
30
+ }
31
+
32
+ <div [ngClass]="[rowClass(), bankInfo.IsMainBank ? rowMainPtClass() : rowNormalPtClass()]">
33
+ <div [class]="columnClass()">
34
+ <hr-info-field
35
+ [labelKey]="'Bank'"
36
+ [value]="bankInfo.BankName"
37
+ [labelClass]="labelClass()"
38
+ [valueClass]="valueClass()"
39
+ ></hr-info-field>
40
+ </div>
41
+
42
+ <div [class]="columnClass()">
43
+ <hr-info-field
44
+ [labelKey]="'Branch'"
45
+ [value]="bankInfo.BranchName"
46
+ [labelClass]="labelClass()"
47
+ [valueClass]="valueClass()"
48
+ ></hr-info-field>
49
+ </div>
50
+
51
+ <div [class]="responsiveTopSpacingColClass()">
52
+ <hr-info-field
53
+ [labelKey]="'IBAN'"
54
+ [value]="bankInfo.IBAN"
55
+ [labelClass]="labelClass()"
56
+ [valueClass]="valueClass()"
57
+ ></hr-info-field>
58
+ </div>
59
+
60
+ <div [class]="topSpacingColClass()">
61
+ <hr-info-field
62
+ [labelKey]="'AccountNumber'"
63
+ [value]="bankInfo.AccountNumber"
64
+ [labelClass]="labelClass()"
65
+ [valueClass]="valueClass()"
66
+ ></hr-info-field>
67
+ </div>
68
+
69
+ <div [class]="topSpacingColClass()">
70
+ <hr-info-field
71
+ [labelKey]="'Beneficiary'"
72
+ [value]="bankInfo.Beneficiary"
73
+ [labelClass]="labelClass()"
74
+ [valueClass]="valueClass()"
75
+ ></hr-info-field>
76
+ </div>
77
+
78
+ @if (bankInfo.TransferAmount != null) {
79
+ <div [class]="topSpacingColClass()">
80
+ <hr-info-field
81
+ [labelKey]="'TransferAmount'"
82
+ [value]="formatAmount(bankInfo.TransferAmount) + ' (' + currencyCode() + ')'"
83
+ [labelClass]="labelClass()"
84
+ [valueClass]="valueClass()"
85
+ ></hr-info-field>
86
+ </div>
87
+ }
88
+ </div>
89
+ </div>
90
+ }
91
+ } @else {
92
+ <sky-empty-design-card
93
+ [visibleIcon]="false"
94
+ [visibleQuickAction]="false"
95
+ [containerClass]="emptyStateContainerClass()"
96
+ [cardBodyClass]="''"
97
+ [cardBodyContainerClass]="''"
98
+ [emptyTextClass]="emptyStateTextClass()"
99
+ [emptyText]="isLoading() ? (sectionTitle() | translate) + ' ' + ('IsLoading' | translate) : ('ThereIsNoBankYet' | translate)"
100
+ ></sky-empty-design-card>
101
+ }
@@ -0,0 +1,89 @@
1
+ import { ChangeDetectionStrategy, Component, OnInit, computed, inject, input, output, signal } from '@angular/core';
2
+ import { CommonModule } from '@angular/common';
3
+ import { faMoneyCheckDollarPen } from '@fortawesome/pro-light-svg-icons';
4
+ import { MyBankInfo } from '../../shared/types/common';
5
+ import { HRTranslatePipe } from '../../shared/pipes/translate.pipe';
6
+ import { SkyEmptyDesignCardComponent, SkySectionDividerComponent } from '@skysoftware-co/sky-components-ui';
7
+ import { HRCommonMethodsService } from '../../shared/services/common-methods.service';
8
+ import { HRSelfWidgetsService } from '../../services/hr-self-widgets.service';
9
+ import { HRInfoFieldComponent } from '../../shared/components/info-field/info-field.component';
10
+
11
+ @Component({
12
+ selector: 'hr-my-profile-bank-info-widget',
13
+ standalone: true,
14
+ imports: [
15
+ CommonModule,
16
+ HRTranslatePipe,
17
+ SkySectionDividerComponent,
18
+ SkyEmptyDesignCardComponent,
19
+ HRInfoFieldComponent,
20
+ ],
21
+ templateUrl: './my-profile-bank-info-widget.component.html',
22
+ changeDetection: ChangeDetectionStrategy.OnPush,
23
+ })
24
+ export class MyProfileBankInfoWidgetComponent implements OnInit {
25
+ readonly isLoading = signal(true);
26
+
27
+ private readonly commonMethodsService = inject(HRCommonMethodsService);
28
+ private readonly hrSelfWidgetsService = inject(HRSelfWidgetsService);
29
+
30
+ ngOnInit(): void {
31
+ this.isLoadingChanged.emit(true);
32
+ this.hrSelfWidgetsService.getBankInformation(this.baseUrl()).subscribe({
33
+ next: response => {
34
+ this.isLoading.set(false);
35
+ this.employeeBankInformation.set(response ?? []);
36
+ this.isLoadingChanged.emit(false);
37
+ },
38
+ error: error => {
39
+ this.isLoading.set(false);
40
+ this.employeeBankInformation.set([]);
41
+ this.isLoadingChanged.emit(false);
42
+ this.errorOccurred.emit(error.error.ResponseData.Errors[0].Message);
43
+ },
44
+ });
45
+ }
46
+ readonly employeeBankInformation = signal<MyBankInfo[]>([]);
47
+ readonly currencyCode = input<string>('');
48
+ readonly currencyDecimals = input<number>(2);
49
+
50
+ readonly headerIconClass = input<string>('primary-icon-xl');
51
+ readonly headerTextClass = input<string>('mt-2 field-secondary-label-lg');
52
+ readonly headerDividerClass = input<string>('flex-grow-1 ms-2');
53
+
54
+ readonly cardClass = input<string>('mt-4 card-shadow position-relative');
55
+ readonly mainBadgeClass = input<string>('position-absolute text-center top-0 mt-3 start-0 bg-primary status-badge');
56
+ readonly mainBadgeTextClass = input<string>('mx-1 fs-12 text-white');
57
+ readonly triangleClass = input<string>('position-absolute start-0 top-0');
58
+ readonly rowClass = input<string>('row px-4 pb-3');
59
+ readonly rowMainPtClass = input<string>('pt-5');
60
+ readonly rowNormalPtClass = input<string>('pt-3');
61
+ readonly columnClass = input<string>('col-md-4 col-6');
62
+ readonly responsiveTopSpacingColClass = input<string>('col-md-4 col-6 mt-md-0 mt-4');
63
+ readonly topSpacingColClass = input<string>('col-md-4 col-6 mt-4');
64
+ readonly labelClass = input<string>('field-secondary-label-sm');
65
+ readonly valueClass = input<string>('table-cell-md text-ellipsis-one-line');
66
+ readonly emptyStateContainerClass = input<string>(
67
+ 'd-flex flex-column justify-content-center align-items-center my-5',
68
+ );
69
+ readonly emptyStateTextClass = input<string>('field-secondary-label-md');
70
+
71
+ readonly bankInformationIcon = input(faMoneyCheckDollarPen);
72
+ readonly sectionHeaderVisibility = input(true);
73
+ readonly sectionTitle = input('BankInformation');
74
+ readonly language = input('en');
75
+ readonly baseUrl = input.required<string>();
76
+
77
+ readonly errorOccurred = output<string>();
78
+
79
+ readonly isRTL = computed(() => this.language() === 'ar');
80
+
81
+ readonly isLoadingChanged = output<boolean>();
82
+
83
+ formatAmount(value: number | null | undefined): string {
84
+ if (value == null) {
85
+ return '-';
86
+ }
87
+ return this.commonMethodsService.currencyDecimalFormat(value, this.currencyDecimals()) || '-';
88
+ }
89
+ }
@@ -0,0 +1,89 @@
1
+ <sky-section-divider
2
+ [fontAwesomeIcon]="contactIcon()"
3
+ [text]="sectionTitle() | translate | uppercase"
4
+ [iconClass]="headerIconClass()"
5
+ [textClass]="headerTextClass()"
6
+ [dividerClass]="headerDividerClass()"
7
+ ></sky-section-divider>
8
+
9
+ @if (employeePersonalInfoContactDetails()) {
10
+ <div [ngClass]="rowClass()">
11
+ <div [ngClass]="columnClass()">
12
+ <hr-info-field
13
+ [labelKey]="'MobileNumber'"
14
+ [value]="employeePersonalInfoContactDetails()!.MobileNumber"
15
+ [labelClass]="labelClass()"
16
+ [valueClass]="valueClass()"
17
+ ></hr-info-field>
18
+ <div class="mt-4">
19
+ <hr-info-field
20
+ [labelKey]="'Email'"
21
+ [value]="employeePersonalInfoContactDetails()!.Email"
22
+ [labelClass]="labelClass()"
23
+ [valueClass]="valueClass()"
24
+ ></hr-info-field>
25
+ </div>
26
+ </div>
27
+ <div [ngClass]="columnClass()">
28
+ <hr-info-field
29
+ [labelKey]="'HomePhone'"
30
+ [value]="employeePersonalInfoContactDetails()!.HomePhone"
31
+ [labelClass]="labelClass()"
32
+ [valueClass]="valueClass()"
33
+ ></hr-info-field>
34
+ <div class="mt-4">
35
+ <hr-info-field
36
+ [labelKey]="'BusinessEmail'"
37
+ [value]="employeePersonalInfoContactDetails()!.BusinessEmail"
38
+ [labelClass]="labelClass()"
39
+ [valueClass]="valueClass()"
40
+ ></hr-info-field>
41
+ </div>
42
+ </div>
43
+ </div>
44
+ @if (showEmergencyContact()) {
45
+ <div [ngClass]="rowClass()">
46
+ <div class="col-12">
47
+ <div [ngClass]="emergencyContactLabelClass()">&#x2022; {{ 'EmergencyContact' | translate }}</div>
48
+ </div>
49
+ </div>
50
+ <div [ngClass]="emergencyContactRowClass()">
51
+ <div [ngClass]="emergencyContactColumnClass()">
52
+ <hr-info-field
53
+ [labelKey]="'Name'"
54
+ [value]="
55
+ employeePersonalInfoContactDetails()!.EmergencyContact?.Name || employeePersonalInfoContactDetails()!.EmergencyContactLegacy
56
+ "
57
+ [labelClass]="labelClass()"
58
+ [valueClass]="valueClass()"
59
+ ></hr-info-field>
60
+ </div>
61
+ <div [ngClass]="emergencyContactColumnClass()">
62
+ <hr-info-field
63
+ [labelKey]="'Relation'"
64
+ [value]="employeePersonalInfoContactDetails()!.EmergencyContact?.Relation"
65
+ [labelClass]="labelClass()"
66
+ [valueClass]="valueClass()"
67
+ ></hr-info-field>
68
+ </div>
69
+ <div [ngClass]="emergencyContactResponsiveColumnClass()">
70
+ <hr-info-field
71
+ [labelKey]="'Phone'"
72
+ [value]="employeePersonalInfoContactDetails()!.EmergencyContact?.PhoneNumber"
73
+ [labelClass]="labelClass()"
74
+ [valueClass]="valueClass()"
75
+ ></hr-info-field>
76
+ </div>
77
+ </div>
78
+ }
79
+ } @else {
80
+ <sky-empty-design-card
81
+ [containerClass]="emptyStateContainerClass()"
82
+ [cardBodyClass]="''"
83
+ [cardBodyContainerClass]="''"
84
+ [visibleIcon]="false"
85
+ [visibleQuickAction]="false"
86
+ [emptyTextClass]="emptyStateTextClass()"
87
+ [emptyText]="isLoading() ? (sectionTitle() | translate) + ' ' + ('IsLoading' | translate) : ('ThereIsNoContactYet' | translate)"
88
+ ></sky-empty-design-card>
89
+ }