@skysoftware-co/bayan-hr-widgets-ui 2.0.25 → 2.0.27

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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 +108 -0
  67. package/src/lib/my-team-subordinates-popup-widget/components/my-team-subordinates-popup/my-team-popup.component.ts +332 -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 -4812
  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 -1308
@@ -0,0 +1,49 @@
1
+ <sky-section-divider
2
+ [fontAwesomeIcon]="indemnityIcon()"
3
+ [text]="sectionTitle() | translate | uppercase"
4
+ [iconClass]="headerIconClass()"
5
+ [textClass]="headerTextClass()"
6
+ [dividerClass]="headerDividerClass()"
7
+ ></sky-section-divider>
8
+
9
+ @if (indemnityDetails()) {
10
+ <div [class]="rowClass()">
11
+ <div [class]="columnClass()">
12
+ <hr-info-field
13
+ labelKey="IndemnityEligibility"
14
+ [value]="(indemnityDetails()!.IsEligibleForIndemnity ? 'Eligible' : 'NotEligible') | translate"
15
+ [labelClass]="labelClass()"
16
+ [valueClass]="valueClass()"
17
+ ></hr-info-field>
18
+ </div>
19
+ <div [class]="columnClass()">
20
+ <hr-info-field
21
+ labelKey="ServiceYears"
22
+ [value]="'' + (indemnityDetails()!.IndemnityServiceYears ?? '')"
23
+ [labelClass]="labelClass()"
24
+ [valueClass]="valueClass()"
25
+ ></hr-info-field>
26
+ </div>
27
+
28
+ <div [class]="topSpacingColumnClass()">
29
+ <hr-info-field
30
+ labelKey="StartDate"
31
+ [value]="indemnityDetails()!.IndemnityStartDate | date: dateFormat()"
32
+ [labelClass]="labelClass()"
33
+ [valueClass]="valueClass()"
34
+ ></hr-info-field>
35
+ </div>
36
+ </div>
37
+ } @else {
38
+ <sky-empty-design-card
39
+ [containerClass]="emptyStateContainerClass()"
40
+ [cardBodyClass]="''"
41
+ [cardBodyContainerClass]="''"
42
+ [visibleIcon]="false"
43
+ [visibleQuickAction]="false"
44
+ [emptyTextClass]="emptyStateTextClass()"
45
+ [emptyText]="
46
+ isLoading() ? (sectionTitle() | translate) + ' ' + ('IsLoading' | translate) : ('There\'sNoInformationInThisSectionYet' | translate)
47
+ "
48
+ ></sky-empty-design-card>
49
+ }
@@ -0,0 +1,79 @@
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 { faFileSignature } 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 { HRInfoFieldComponent } from '../../shared/components/info-field/info-field.component';
8
+ import { EntitlementsIndemnity } from '../../shared/types/common';
9
+
10
+ @Component({
11
+ selector: 'hr-my-profile-indemnity-widget',
12
+ standalone: true,
13
+ imports: [
14
+ CommonModule,
15
+ HRTranslatePipe,
16
+ SkySectionDividerComponent,
17
+ SkyEmptyDesignCardComponent,
18
+ HRInfoFieldComponent,
19
+ ],
20
+ templateUrl: './my-profile-indemnity-widget.component.html',
21
+ changeDetection: ChangeDetectionStrategy.OnPush,
22
+ })
23
+ export class MyProfileIndemnityWidgetComponent implements OnInit {
24
+ readonly baseUrl = input.required<string>();
25
+ readonly currencyCode = input<string>('');
26
+ readonly currencyDecimals = input<number>(0);
27
+ readonly sectionTitle = input<string>('Indemnity');
28
+ readonly indemnityIcon = input(faFileSignature);
29
+
30
+ readonly headerIconClass = input<string>('primary-icon-xl');
31
+ readonly headerTextClass = input<string>('mt-2 field-secondary-label-lg');
32
+ readonly headerDividerClass = input<string>('flex-grow-1 ms-2');
33
+ readonly rowClass = input<string>('row mt-4');
34
+ readonly columnClass = input<string>('col-6');
35
+ readonly topSpacingColumnClass = input<string>('col-6 mt-4');
36
+ readonly labelClass = input<string>('field-secondary-label-sm');
37
+ readonly valueClass = input<string>('fs-14 fw-meduim');
38
+ readonly dateFormat = input<string>('dd/MM/yyyy');
39
+ readonly emptyStateContainerClass = input<string>(
40
+ 'd-flex flex-column justify-content-center align-items-center my-5',
41
+ );
42
+ readonly emptyStateTextClass = input<string>('field-secondary-label-md');
43
+
44
+ readonly isLoadingChanged = output<boolean>();
45
+ readonly errorOccurred = output<string>();
46
+ readonly hasDataChanged = output<boolean>();
47
+
48
+ readonly indemnityDetails = signal<EntitlementsIndemnity | null>(null);
49
+ readonly isLoading = signal(true);
50
+
51
+ private readonly selfWidgetsService = inject(HRSelfWidgetsService);
52
+
53
+ ngOnInit(): void {
54
+ if (!this.baseUrl()) {
55
+ this.isLoading.set(false);
56
+ return;
57
+ }
58
+ this.loadData();
59
+ }
60
+
61
+ private loadData(): void {
62
+ this.isLoadingChanged.emit(true);
63
+ this.selfWidgetsService.getEntitlementsIndemnity(this.baseUrl()).subscribe({
64
+ next: data => {
65
+ this.indemnityDetails.set(data);
66
+ this.isLoading.set(false);
67
+ this.hasDataChanged.emit(!!this.indemnityDetails());
68
+ this.isLoadingChanged.emit(false);
69
+ },
70
+ error: error => {
71
+ this.indemnityDetails.set(null);
72
+ this.isLoading.set(false);
73
+ this.hasDataChanged.emit(false);
74
+ this.errorOccurred.emit(error?.error?.ResponseData?.Errors?.[0]?.Message);
75
+ this.isLoadingChanged.emit(false);
76
+ },
77
+ });
78
+ }
79
+ }
@@ -0,0 +1,71 @@
1
+ <sky-section-divider
2
+ [fontAwesomeIcon]="mainIcon()"
3
+ [text]="sectionTitle() | translate | uppercase"
4
+ [iconClass]="headerIconClass()"
5
+ [textClass]="headerTextClass()"
6
+ [dividerClass]="headerDividerClass()"
7
+ ></sky-section-divider>
8
+
9
+ @if (jobInformationMain()) {
10
+ <div [ngClass]="rowClass()">
11
+ <div [ngClass]="columnClass()">
12
+ <hr-info-field
13
+ [labelKey]="'AdminUnit'"
14
+ [value]="jobInformationMain()!.AdminUnitName"
15
+ [labelClass]="labelClass()"
16
+ [valueClass]="valueClass()"
17
+ ></hr-info-field>
18
+ </div>
19
+ <div [ngClass]="columnClass()">
20
+ <hr-info-field
21
+ [labelKey]="'Position'"
22
+ [value]="jobInformationMain()!.PositionName"
23
+ [labelClass]="labelClass()"
24
+ [valueClass]="valueClass()"
25
+ ></hr-info-field>
26
+ </div>
27
+ <div [ngClass]="responsiveTopSpacingColumnClass()">
28
+ <hr-info-field
29
+ [labelKey]="'Grade'"
30
+ [value]="jobInformationMain()!.GradeName"
31
+ [labelClass]="labelClass()"
32
+ [valueClass]="valueClass()"
33
+ ></hr-info-field>
34
+ </div>
35
+
36
+ <div [ngClass]="topSpacingBottomMdSpacingColumnClass()">
37
+ <hr-info-field
38
+ [labelKey]="'JoiningDate'"
39
+ [value]="jobInformationMain()!.JoiningDate ? (jobInformationMain()!.JoiningDate | date: 'dd/MM/yyyy') : null"
40
+ [labelClass]="labelClass()"
41
+ [valueClass]="valueClass()"
42
+ ></hr-info-field>
43
+ </div>
44
+ <div [ngClass]="topSpacingBottomMdSpacingColumnClass()">
45
+ <hr-info-field
46
+ [labelKey]="'CorporateJoiningDate'"
47
+ [value]="jobInformationMain()!.CorporateJoiningDate ? (jobInformationMain()!.CorporateJoiningDate | date: 'dd/MM/yyyy') : null"
48
+ [labelClass]="labelClass()"
49
+ [valueClass]="valueClass()"
50
+ ></hr-info-field>
51
+ </div>
52
+ <div [ngClass]="topSpacingBottomSpacingColumnClass()">
53
+ <hr-info-field
54
+ [labelKey]="'Sponsor'"
55
+ [value]="jobInformationMain()!.SponsorName"
56
+ [labelClass]="labelClass()"
57
+ [valueClass]="valueClass()"
58
+ ></hr-info-field>
59
+ </div>
60
+ </div>
61
+ } @else {
62
+ <sky-empty-design-card
63
+ [visibleIcon]="false"
64
+ [visibleQuickAction]="false"
65
+ [containerClass]="emptyStateContainerClass()"
66
+ [cardBodyClass]="''"
67
+ [cardBodyContainerClass]="''"
68
+ [emptyTextClass]="emptyStateTextClass()"
69
+ [emptyText]="isLoading() ? (sectionTitle() | translate) + ' ' + ('IsLoading' | translate) : ('ThereIsNoJobMainYet' | translate)"
70
+ ></sky-empty-design-card>
71
+ }
@@ -0,0 +1,73 @@
1
+ import { CommonModule } from '@angular/common';
2
+ import { ChangeDetectionStrategy, Component, OnInit, inject, input, output, signal } from '@angular/core';
3
+ import { faFileSignature } from '@fortawesome/pro-light-svg-icons';
4
+ import { SkyEmptyDesignCardComponent, SkySectionDividerComponent } from '@skysoftware-co/sky-components-ui';
5
+ import { HRSelfWidgetsService } from '../../services/hr-self-widgets.service';
6
+ import { HRTranslatePipe } from '../../shared/pipes/translate.pipe';
7
+ import { JobInformationMain } from '../../shared/types/common';
8
+ import { HRInfoFieldComponent } from '../../shared/components/info-field/info-field.component';
9
+
10
+ @Component({
11
+ selector: 'hr-my-profile-job-info-widget',
12
+ standalone: true,
13
+ imports: [
14
+ CommonModule,
15
+ HRTranslatePipe,
16
+ SkySectionDividerComponent,
17
+ SkyEmptyDesignCardComponent,
18
+ HRInfoFieldComponent,
19
+ ],
20
+ templateUrl: './my-profile-job-info-widget.component.html',
21
+ changeDetection: ChangeDetectionStrategy.OnPush,
22
+ })
23
+ export class MyProfileJobInfoWidgetComponent implements OnInit {
24
+ readonly jobInformationMain = signal<JobInformationMain | null>(null);
25
+ readonly isLoading = signal(true);
26
+
27
+ readonly baseUrl = input.required<string>();
28
+ readonly headerIconClass = input<string>('primary-icon-xl');
29
+ readonly headerTextClass = input<string>('mt-2 field-secondary-label-lg');
30
+ readonly headerDividerClass = input<string>('flex-grow-1 ms-2');
31
+ readonly rowClass = input<string>('row mt-4');
32
+ readonly columnClass = input<string>('col-md-4 col-6');
33
+ readonly responsiveTopSpacingColumnClass = input<string>('col-md-4 col-6 mt-md-0 mt-4');
34
+ readonly topSpacingBottomMdSpacingColumnClass = input<string>('col-md-4 col-6 mt-4 mb-md-5');
35
+ readonly topSpacingBottomSpacingColumnClass = input<string>('col-md-4 col-6 mt-4 mb-5');
36
+ readonly labelClass = input<string>('field-secondary-label-sm');
37
+ readonly valueClass = input<string>('fs-14 fw-medium text-ellipsis-one-line');
38
+ readonly emptyStateContainerClass = input<string>(
39
+ 'd-flex flex-column justify-content-center align-items-center my-5',
40
+ );
41
+ readonly emptyStateTextClass = input<string>('field-secondary-label-md');
42
+
43
+ readonly mainIcon = input(faFileSignature);
44
+ readonly sectionTitle = input('JobInformation');
45
+
46
+ readonly isLoadingChanged = output<boolean>();
47
+ readonly errorOccurred = output<string>();
48
+
49
+ private readonly hrSelfWidgetsService = inject(HRSelfWidgetsService);
50
+
51
+ ngOnInit(): void {
52
+ if (!this.baseUrl()) {
53
+ this.isLoading.set(false);
54
+ return;
55
+ }
56
+
57
+ this.isLoadingChanged.emit(true);
58
+
59
+ this.hrSelfWidgetsService.getJobInformationMain(this.baseUrl()).subscribe({
60
+ next: response => {
61
+ this.isLoading.set(false);
62
+ this.jobInformationMain.set(response);
63
+ this.isLoadingChanged.emit(false);
64
+ },
65
+ error: error => {
66
+ this.isLoading.set(false);
67
+ this.jobInformationMain.set(null);
68
+ this.isLoadingChanged.emit(false);
69
+ this.errorOccurred.emit(error.error.ResponseData.Errors[0].Message);
70
+ },
71
+ });
72
+ }
73
+ }
@@ -0,0 +1,23 @@
1
+ <sky-section-divider
2
+ [fontAwesomeIcon]="languagesIcon()"
3
+ [text]="sectionTitle() | translate | uppercase"
4
+ [iconClass]="headerIconClass()"
5
+ [textClass]="headerTextClass()"
6
+ [dividerClass]="headerDividerClass()"
7
+ ></sky-section-divider>
8
+
9
+ @if ((languages()?.length ?? 0) > 0) {
10
+ <div [ngClass]="contentTextClass()">
11
+ {{ getLanguages() }}
12
+ </div>
13
+ } @else {
14
+ <sky-empty-design-card
15
+ [visibleIcon]="false"
16
+ [visibleQuickAction]="false"
17
+ [containerClass]="emptyStateContainerClass()"
18
+ [cardBodyClass]="''"
19
+ [cardBodyContainerClass]="''"
20
+ [emptyTextClass]="emptyStateTextClass()"
21
+ [emptyText]="isLoading() ? (sectionTitle() | translate) + ' ' + ('IsLoading' | translate) : ('ThereIsNoLanguagesYet' | translate)"
22
+ ></sky-empty-design-card>
23
+ }
@@ -0,0 +1,70 @@
1
+ import { CommonModule } from '@angular/common';
2
+ import { ChangeDetectionStrategy, Component, OnInit, inject, input, output, signal } from '@angular/core';
3
+ import { faLanguage } 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 { HRSelfWidgetsService } from '../../services/hr-self-widgets.service';
7
+
8
+ @Component({
9
+ selector: 'hr-my-profile-languages-widget',
10
+ standalone: true,
11
+ imports: [CommonModule, HRTranslatePipe, SkySectionDividerComponent, SkyEmptyDesignCardComponent],
12
+ templateUrl: './my-profile-languages-widget.component.html',
13
+ changeDetection: ChangeDetectionStrategy.OnPush,
14
+ })
15
+ export class MyProfileLanguagesWidgetComponent implements OnInit {
16
+ readonly languages = signal<string[] | null>(null);
17
+ readonly isLoading = signal(true);
18
+ readonly baseUrl = input<string>('');
19
+ readonly headerIconClass = input<string>('primary-icon-xl');
20
+ readonly headerTextClass = input<string>('fs-16 mt-2 text-secondary');
21
+ readonly headerDividerClass = input<string>('flex-grow-1 ms-2');
22
+ readonly contentTextClass = input<string>('text-dark-gray fs-14 fw-medium mt-4');
23
+ readonly emptyStateContainerClass = input<string>(
24
+ 'd-flex flex-column justify-content-center align-items-center my-5',
25
+ );
26
+ readonly emptyStateTextClass = input<string>('field-secondary-label-md');
27
+ readonly hasDataChange = output<boolean>();
28
+
29
+ readonly languagesIcon = input(faLanguage);
30
+ readonly sectionTitle = input('languages');
31
+
32
+ readonly isLoadingChanged = output<boolean>();
33
+ readonly errorOccurred = output<string>();
34
+
35
+ private readonly hrSelfWidgetsService = inject(HRSelfWidgetsService);
36
+
37
+ ngOnInit(): void {
38
+ if (!this.baseUrl()) {
39
+ this.isLoading.set(false);
40
+ this.emitHasData();
41
+ return;
42
+ }
43
+
44
+ this.isLoadingChanged.emit(true);
45
+
46
+ this.hrSelfWidgetsService.getPersonalInfoLanguages(this.baseUrl()).subscribe({
47
+ next: response => {
48
+ this.isLoading.set(false);
49
+ this.isLoadingChanged.emit(false);
50
+ this.languages.set(response ?? []);
51
+ this.emitHasData();
52
+ },
53
+ error: error => {
54
+ this.isLoading.set(false);
55
+ this.languages.set([]);
56
+ this.emitHasData();
57
+ this.isLoadingChanged.emit(false);
58
+ this.errorOccurred.emit(error.error.ResponseData.Errors[0].Message);
59
+ },
60
+ });
61
+ }
62
+
63
+ private emitHasData(): void {
64
+ this.hasDataChange.emit((this.languages()?.length ?? 0) > 0);
65
+ }
66
+
67
+ getLanguages(): string {
68
+ return this.languages()?.join(', ') || '-';
69
+ }
70
+ }
@@ -0,0 +1,18 @@
1
+ <hr-widget-card [cardClass]="cardClass" [height]="cardHeight" [contentTemplate]="cardContent"></hr-widget-card>
2
+
3
+ <ng-template #cardContent>
4
+ <p [class]="nameClass" [ngClass]="isDependent ? 'd-flex' : ''">
5
+ @if (isDependent) {
6
+ <span class="text-ellipsis-one-line cursor-pointer" [title]="name">{{ name }}</span>
7
+ <span class="mx-1">({{ typeName }})</span>
8
+ } @else {
9
+ {{ name }} ({{ 'Me' | translate }})
10
+ }
11
+ </p>
12
+ @for (field of fields; track field.labelKey; let last = $last) {
13
+ <p [class.mb-2]="!last">
14
+ <span [class]="labelClass">{{ field.labelKey | translate }}:</span>
15
+ <span [class]="valueClass">{{ field.value || (field.fallbackValue ?? '—') }}</span>
16
+ </p>
17
+ }
18
+ </ng-template>
@@ -0,0 +1,29 @@
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
+ export interface MedicalInsuranceField {
7
+ labelKey: string;
8
+ value: any;
9
+ fallbackValue?: string;
10
+ }
11
+
12
+ @Component({
13
+ selector: 'hr-medical-insurance-card',
14
+ standalone: true,
15
+ imports: [CommonModule, HRTranslatePipe, WidgetCardComponent],
16
+ templateUrl: './medical-insurance-card.component.html',
17
+ })
18
+ export class HRMedicalInsuranceCardComponent {
19
+ @Input({ required: true }) name: string | null = '';
20
+ @Input() typeName: string | null = '';
21
+ @Input() isDependent: boolean = false;
22
+ @Input() fields: MedicalInsuranceField[] = [];
23
+
24
+ @Input() cardClass: string = 'p-3 card-shadow h-100 border border-1 rounded rounded-2';
25
+ @Input() cardHeight: number = 185;
26
+ @Input() nameClass: string = 'text-dark fs-16 mb-2';
27
+ @Input() labelClass: string = 'field-secondary-label-sm';
28
+ @Input() valueClass: string = 'text-dark-gray mx-1';
29
+ }
@@ -0,0 +1,52 @@
1
+ <sky-section-divider
2
+ [fontAwesomeIcon]="medicalInsuranceIcon()"
3
+ [text]="sectionTitle() | translate | uppercase"
4
+ [iconClass]="headerIconClass()"
5
+ [textClass]="headerTextClass()"
6
+ [dividerClass]="headerDividerClass()"
7
+ ></sky-section-divider>
8
+
9
+ @if (medicalInsuranceDetails()) {
10
+ <div class="row mb-5">
11
+ @if (medicalInsuranceDetails()!.EmployeeMedicalInsurance) {
12
+ <div [class]="columnClass()" [style.height.px]="cardHeight()">
13
+ <hr-medical-insurance-card
14
+ [name]="medicalInsuranceDetails()?.EmployeeMedicalInsurance?.EmployeeFirstName || ''"
15
+ [fields]="employeeFields()"
16
+ [cardClass]="cardClass()"
17
+ [cardHeight]="cardHeight()"
18
+ [nameClass]="nameClass()"
19
+ [labelClass]="labelClass()"
20
+ [valueClass]="valueClass()"
21
+ ></hr-medical-insurance-card>
22
+ </div>
23
+ }
24
+ @for (dependent of medicalInsuranceDetails()!.DependentsMedicalInsurance; track dependent) {
25
+ <div [class]="columnClass()" [style.height.px]="cardHeight()">
26
+ <hr-medical-insurance-card
27
+ [name]="dependent.DependentName"
28
+ [typeName]="dependent.DependentTypeName"
29
+ [isDependent]="true"
30
+ [fields]="getDependentFields(dependent)"
31
+ [cardClass]="cardClass()"
32
+ [cardHeight]="cardHeight()"
33
+ [nameClass]="nameClass()"
34
+ [labelClass]="labelClass()"
35
+ [valueClass]="valueClass()"
36
+ ></hr-medical-insurance-card>
37
+ </div>
38
+ }
39
+ </div>
40
+ } @else {
41
+ <sky-empty-design-card
42
+ [containerClass]="emptyStateContainerClass()"
43
+ [cardBodyClass]="''"
44
+ [cardBodyContainerClass]="''"
45
+ [visibleIcon]="false"
46
+ [visibleQuickAction]="false"
47
+ [emptyTextClass]="emptyStateTextClass()"
48
+ [emptyText]="
49
+ isLoading() ? (sectionTitle() | translate) + ' ' + ('IsLoading' | translate) : ('NotCoveredByMedicalInsurance' | translate)
50
+ "
51
+ ></sky-empty-design-card>
52
+ }
@@ -0,0 +1,103 @@
1
+ import { CommonModule, DatePipe } 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 { faNotesMedical } 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 {
8
+ HRMedicalInsuranceCardComponent,
9
+ MedicalInsuranceField,
10
+ } from './components/medical-insurance-card/medical-insurance-card.component';
11
+ import { EntitlementsMedicalInsurance, DependentsMedicalInsurance } from '../../shared/types/common';
12
+
13
+ @Component({
14
+ selector: 'hr-my-profile-medical-insurance-widget',
15
+ standalone: true,
16
+ imports: [
17
+ CommonModule,
18
+ HRTranslatePipe,
19
+ SkySectionDividerComponent,
20
+ SkyEmptyDesignCardComponent,
21
+ HRMedicalInsuranceCardComponent,
22
+ ],
23
+ templateUrl: './my-profile-medical-insurance-widget.component.html',
24
+ changeDetection: ChangeDetectionStrategy.OnPush,
25
+ })
26
+ export class MyProfileMedicalInsuranceWidgetComponent implements OnInit {
27
+ readonly baseUrl = input.required<string>();
28
+ readonly sectionTitle = input<string>('MedicalInsurance');
29
+ readonly medicalInsuranceIcon = input(faNotesMedical);
30
+
31
+ readonly headerIconClass = input<string>('primary-icon-xl');
32
+ readonly headerTextClass = input<string>('mt-2 field-secondary-label-lg');
33
+ readonly headerDividerClass = input<string>('flex-grow-1 ms-2');
34
+ readonly labelClass = input<string>('field-secondary-label-sm');
35
+ readonly valueClass = input<string>('text-dark-gray mx-1');
36
+ readonly columnClass = input<string>('col-lg-4 col-6 mt-4');
37
+ readonly cardHeight = input<number>(185);
38
+ readonly cardClass = input<string>('p-3 card-shadow h-100 border border-1 rounded rounded-2');
39
+ readonly nameClass = input<string>('text-dark fs-16 mb-2');
40
+ readonly dateFormat = input<string>('dd/MM/yyyy');
41
+ readonly emptyStateContainerClass = input<string>(
42
+ 'd-flex flex-column justify-content-center align-items-center my-5',
43
+ );
44
+ readonly emptyStateTextClass = input<string>('field-secondary-label-md');
45
+
46
+ readonly isLoadingChanged = output<boolean>();
47
+ readonly errorOccurred = output<string>();
48
+
49
+ readonly medicalInsuranceDetails = signal<EntitlementsMedicalInsurance | null>(null);
50
+ readonly isLoading = signal(true);
51
+ readonly employeeFields = signal<MedicalInsuranceField[]>([]);
52
+
53
+ private datePipe = new DatePipe('en-US');
54
+
55
+ private readonly selfWidgetsService = inject(HRSelfWidgetsService);
56
+
57
+ ngOnInit(): void {
58
+ if (!this.baseUrl()) {
59
+ this.isLoading.set(false);
60
+ return;
61
+ }
62
+ this.loadData();
63
+ }
64
+
65
+ private loadData(): void {
66
+ this.isLoadingChanged.emit(true);
67
+ this.selfWidgetsService.getEntitlementsMedicalInsurance(this.baseUrl()).subscribe({
68
+ next: data => {
69
+ this.medicalInsuranceDetails.set(data);
70
+ this.buildEmployeeFields();
71
+ this.isLoading.set(false);
72
+ this.isLoadingChanged.emit(false);
73
+ },
74
+ error: error => {
75
+ this.medicalInsuranceDetails.set(null);
76
+ this.isLoading.set(false);
77
+ this.errorOccurred.emit(error?.error?.ResponseData?.Errors?.[0]?.Message);
78
+ this.isLoadingChanged.emit(false);
79
+ },
80
+ });
81
+ }
82
+
83
+ private buildEmployeeFields(): void {
84
+ const details = this.medicalInsuranceDetails();
85
+ if (!details?.EmployeeMedicalInsurance) return;
86
+ const emp = details.EmployeeMedicalInsurance;
87
+ this.employeeFields.set([
88
+ { labelKey: 'Class', value: emp.MedicalInsuranceClassName },
89
+ { labelKey: 'Number', value: emp.MedicalInsuranceNumber },
90
+ { labelKey: 'CoverageDate', value: this.datePipe.transform(emp.CoverageDate, this.dateFormat()) },
91
+ { labelKey: 'TotalEmployeeShare', value: details.TotalEmployeeShare },
92
+ { labelKey: 'TotalEmployerShare', value: details.TotalEmployerShare },
93
+ ]);
94
+ }
95
+
96
+ getDependentFields(dependent: DependentsMedicalInsurance): MedicalInsuranceField[] {
97
+ return [
98
+ { labelKey: 'Class', value: dependent.MedicalInsuranceClassName },
99
+ { labelKey: 'Number', value: dependent.MedicalInsuranceNumber },
100
+ { labelKey: 'CoverageDate', value: this.datePipe.transform(dependent.CoverageDate, this.dateFormat()) },
101
+ ];
102
+ }
103
+ }
@@ -0,0 +1,82 @@
1
+ <sky-section-divider
2
+ [fontAwesomeIcon]="icon()"
3
+ [text]="sectionTitle() | translate | uppercase"
4
+ [iconClass]="headerIconClass()"
5
+ [textClass]="headerTextClass()"
6
+ [dividerClass]="headerDividerClass()"
7
+ ></sky-section-divider>
8
+
9
+ <div class="mt-4">
10
+ @if (documents().length) {
11
+ <div [class]="!(isTablet() || isMobile()) ? cardClass() : ''">
12
+ @if (!(isTablet() || isMobile())) {
13
+ <hr-document-card
14
+ [title]="employeeName() + ' (' + ('Me' | translate) + ')'"
15
+ [documents]="documents()"
16
+ [valueClass]="valueClass()"
17
+ [viewIcon]="viewIcon()"
18
+ [downloadIcon]="downloadIcon()"
19
+ [viewIconClass]="viewIconClass()"
20
+ [downloadIconClass]="downloadIconClass()"
21
+ [titleContainerClass]="titleContainerClass()"
22
+ [titleClass]="titleClass()"
23
+ [labelClass]="labelClass()"
24
+ [rowClass]="rowClass()"
25
+ [dataColClass]="dataColClass()"
26
+ [dataColSpacingClass]="dataColSpacingClass()"
27
+ [dataRowClass]="dataRowClass()"
28
+ [typeColClass]="typeColClass()"
29
+ [numberColClass]="numberColClass()"
30
+ [issueDateColClass]="issueDateColClass()"
31
+ [expiryDateColClass]="expiryDateColClass()"
32
+ [actionsColClass]="actionsColClass()"
33
+ [actionsWrapperClass]="actionsWrapperClass()"
34
+ [downloadContainerClass]="downloadContainerClass()"
35
+ (attachmentView)="onAttachmentView($event)"
36
+ (download)="onDownload($event)"
37
+ ></hr-document-card>
38
+ } @else {
39
+ <div [class]="titleContainerClass()">
40
+ <p [class]="titleClass()">{{ employeeName() }} ({{ 'Me' | translate }})</p>
41
+ </div>
42
+
43
+ <div class="row mx-1">
44
+ @for (doc of documents(); track doc; let odd = $odd) {
45
+ <div class="col-6 mb-2">
46
+ <hr-document-tablet-card
47
+ [doc]="doc"
48
+ [isOdd]="odd"
49
+ [viewIcon]="viewIcon()"
50
+ [downloadIcon]="downloadIcon()"
51
+ [labelClass]="labelClass()"
52
+ [valueClass]="valueClass()"
53
+ [downloadIconClass]="downloadIconClass()"
54
+ [downloadContainerClass]="downloadContainerClass()"
55
+ [downloadCountClass]="tabletDownloadCountClass()"
56
+ [tabletContainerClass]="tabletContainerClass()"
57
+ [tabletCardClass]="tabletCardClass()"
58
+ [cardHeight]="tabletCardHeight()"
59
+ [tabletColWithAttachmentClass]="tabletColWithAttachmentClass()"
60
+ [tabletColWithoutAttachmentClass]="tabletColWithoutAttachmentClass()"
61
+ [tabletActionsColClass]="tabletActionsColClass()"
62
+ [tabletBottomRowSpacingClass]="tabletBottomRowSpacingClass()"
63
+ (view)="onAttachmentView(doc)"
64
+ (download)="onDownload(doc)"
65
+ ></hr-document-tablet-card>
66
+ </div>
67
+ }
68
+ </div>
69
+ }
70
+ </div>
71
+ } @else {
72
+ <sky-empty-design-card
73
+ [visibleIcon]="false"
74
+ [visibleQuickAction]="false"
75
+ [containerClass]="emptyStateContainerClass()"
76
+ [emptyTextClass]="emptyStateTextClass()"
77
+ [emptyText]="
78
+ isLoading() ? (sectionTitle() | translate) + ' ' + ('IsLoading' | translate) : ('ThereAreNoEmployeeDocumentsYet' | translate)
79
+ "
80
+ ></sky-empty-design-card>
81
+ }
82
+ </div>