@skysoftware-co/bayan-core-widgets-ui 0.0.3 → 0.0.6

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 (60) hide show
  1. package/README.md +2 -2
  2. package/ng-package.json +7 -0
  3. package/package.json +5 -1
  4. package/src/assets/i18n/ar.json +725 -0
  5. package/src/assets/i18n/en.json +683 -0
  6. package/src/assets/i18n/fr.json +687 -0
  7. package/src/lib/shared/common-methods/navigation.utils.ts +21 -0
  8. package/src/lib/shared/menu.dtos.ts +107 -0
  9. package/src/lib/shared/menu.service.ts +157 -0
  10. package/src/lib/top-menu-widget/components/about-dialog-widget/about-dialog-widget.component.html +37 -0
  11. package/src/lib/top-menu-widget/components/about-dialog-widget/about-dialog-widget.component.ts +68 -0
  12. package/src/lib/top-menu-widget/components/change-password-widget/change-password-widget.component.html +56 -0
  13. package/src/lib/top-menu-widget/components/change-password-widget/change-password-widget.component.ts +158 -0
  14. package/src/lib/top-menu-widget/components/global-search-widget/global-search-widget.component.html +39 -0
  15. package/src/lib/top-menu-widget/components/global-search-widget/global-search-widget.component.ts +153 -0
  16. package/src/lib/top-menu-widget/components/item-widget/item-widget.component.html +39 -0
  17. package/src/lib/top-menu-widget/components/item-widget/item-widget.component.ts +95 -0
  18. package/src/lib/top-menu-widget/components/notifications-widget/notifications-widget.component.html +10 -0
  19. package/src/lib/top-menu-widget/components/notifications-widget/notifications-widget.component.ts +89 -0
  20. package/src/lib/top-menu-widget/components/settings-widget/settings-widget.component.html +119 -0
  21. package/src/lib/top-menu-widget/components/settings-widget/settings-widget.component.ts +233 -0
  22. package/src/lib/top-menu-widget/components/user-panel-widget/user-panel-widget.component.html +53 -0
  23. package/src/lib/top-menu-widget/components/user-panel-widget/user-panel-widget.component.ts +140 -0
  24. package/src/lib/top-menu-widget/top-menu-widget.component.html +103 -0
  25. package/src/lib/top-menu-widget/top-menu-widget.component.ts +148 -0
  26. package/src/lib/top-menu-widget/top-menu-widget.models.ts +29 -0
  27. package/src/lib/top-menu-widget/top-menu-widget.styles.css +576 -0
  28. package/{public-api.d.ts → src/public-api.ts} +7 -4
  29. package/tsconfig.lib.json +16 -0
  30. package/tsconfig.lib.prod.json +9 -0
  31. package/tsconfig.spec.json +13 -0
  32. package/fesm2022/skysoftware-co-bayan-core-widgets-ui.mjs +0 -1092
  33. package/fesm2022/skysoftware-co-bayan-core-widgets-ui.mjs.map +0 -1
  34. package/index.d.ts +0 -6
  35. package/lib/shared/common-methods/navigation.utils.d.ts +0 -4
  36. package/lib/shared/common-methods/navigation.utils.d.ts.map +0 -1
  37. package/lib/shared/menu.dtos.d.ts +0 -91
  38. package/lib/shared/menu.dtos.d.ts.map +0 -1
  39. package/lib/shared/menu.service.d.ts +0 -24
  40. package/lib/shared/menu.service.d.ts.map +0 -1
  41. package/lib/top-menu-widget/components/about-dialog-widget/about-dialog-widget.component.d.ts +0 -18
  42. package/lib/top-menu-widget/components/about-dialog-widget/about-dialog-widget.component.d.ts.map +0 -1
  43. package/lib/top-menu-widget/components/change-password-widget/change-password-widget.component.d.ts +0 -30
  44. package/lib/top-menu-widget/components/change-password-widget/change-password-widget.component.d.ts.map +0 -1
  45. package/lib/top-menu-widget/components/global-search-widget/global-search-widget.component.d.ts +0 -59
  46. package/lib/top-menu-widget/components/global-search-widget/global-search-widget.component.d.ts.map +0 -1
  47. package/lib/top-menu-widget/components/item-widget/item-widget.component.d.ts +0 -29
  48. package/lib/top-menu-widget/components/item-widget/item-widget.component.d.ts.map +0 -1
  49. package/lib/top-menu-widget/components/notifications-widget/notifications-widget.component.d.ts +0 -23
  50. package/lib/top-menu-widget/components/notifications-widget/notifications-widget.component.d.ts.map +0 -1
  51. package/lib/top-menu-widget/components/settings-widget/settings-widget.component.d.ts +0 -37
  52. package/lib/top-menu-widget/components/settings-widget/settings-widget.component.d.ts.map +0 -1
  53. package/lib/top-menu-widget/components/user-panel-widget/user-panel-widget.component.d.ts +0 -43
  54. package/lib/top-menu-widget/components/user-panel-widget/user-panel-widget.component.d.ts.map +0 -1
  55. package/lib/top-menu-widget/top-menu-widget.component.d.ts +0 -76
  56. package/lib/top-menu-widget/top-menu-widget.component.d.ts.map +0 -1
  57. package/lib/top-menu-widget/top-menu-widget.models.d.ts +0 -36
  58. package/lib/top-menu-widget/top-menu-widget.models.d.ts.map +0 -1
  59. package/public-api.d.ts.map +0 -1
  60. package/skysoftware-co-bayan-core-widgets-ui.d.ts.map +0 -1
@@ -0,0 +1,153 @@
1
+ import { CommonModule, DOCUMENT } from '@angular/common';
2
+ import { ChangeDetectionStrategy, Component, EventEmitter, Input, OnChanges, Output, SimpleChanges, ViewChild, inject } from '@angular/core';
3
+ import { FontAwesomeModule } from '@fortawesome/angular-fontawesome';
4
+ import {
5
+ faDollar,
6
+ faGraduationCap,
7
+ faGrid,
8
+ faMedal,
9
+ faRightLeft,
10
+ faTools,
11
+ faUsers,
12
+ } from '@fortawesome/pro-solid-svg-icons';
13
+ import { faClock } from '@fortawesome/pro-light-svg-icons';
14
+ import { Router } from '@angular/router';
15
+ import { DxAutocompleteComponent, DxAutocompleteModule } from 'devextreme-angular';
16
+ import { TranslatePipe } from '@skysoftware-co/sky-components-ui';
17
+ import { GlobalSearchMenu } from '../../../shared/menu.dtos';
18
+ import { BayanCoreTopMenuService } from '../../../shared/menu.service';
19
+ import { isExternalNavigation, resolveUrl } from '../../../shared/common-methods/navigation.utils';
20
+
21
+ @Component({
22
+ selector: 'bayan-core-global-search-widget',
23
+ standalone: true,
24
+ imports: [CommonModule, DxAutocompleteModule, FontAwesomeModule, TranslatePipe],
25
+ templateUrl: './global-search-widget.component.html',
26
+ styles: [':host { display: flex; align-items: center; height: 56px; }'],
27
+ styleUrls: ['../../top-menu-widget.styles.css'],
28
+ changeDetection: ChangeDetectionStrategy.OnPush,
29
+ })
30
+ export class BayanCoreGlobalSearchWidgetComponent implements OnChanges {
31
+ private readonly menuService = inject(BayanCoreTopMenuService);
32
+ private readonly document = inject(DOCUMENT);
33
+ private readonly router = inject(Router);
34
+
35
+ @ViewChild('searchAutoComplete') searchAutoComplete?: DxAutocompleteComponent;
36
+
37
+ @Input() baseUrl = '';
38
+ @Input() ActivePropertyChanged = false;
39
+ @Input() ActivePropertyId: number = 0;
40
+ @Input() placeholder = 'Type to search';
41
+
42
+ @Input() searchMode: 'contains' | 'startswith' = 'contains';
43
+ @Input() stylingMode: 'filled' | 'outlined' | 'underlined' = 'filled';
44
+ @Input() searchWrapperClass = 'top-menu-widget__search';
45
+ @Input() searchItemClass = 'top-menu-widget__search-item d-flex flex-column text-decoration-none';
46
+ @Input() searchItemTitleClass = 'top-menu-widget__search-item-title text-light fs-11 mb-1 d-flex align-content-center';
47
+ @Input() searchItemSubtitleClass = 'top-menu-widget__search-item-subtitle text-dark fs-13 ms-2 ps-1';
48
+ @Input() iconClass = 'fs-11 fw-medium me-1';
49
+
50
+ @Output() search = new EventEmitter<string>();
51
+ @Output() itemNavigate = new EventEmitter<GlobalSearchMenu>();
52
+
53
+ dataSource: GlobalSearchMenu[] = [];
54
+ readonly toolsIcon = faTools;
55
+ readonly gridIcon = faGrid;
56
+ readonly creditIcon = faDollar;
57
+ readonly usersIcon = faUsers;
58
+ readonly clockIcon = faClock;
59
+ readonly swapIcon = faRightLeft;
60
+ readonly medalIcon = faMedal;
61
+ readonly graduateIcon = faGraduationCap;
62
+
63
+ ngOnInit(): void {
64
+ this.loadMenus();
65
+ }
66
+
67
+ // Removed duplicate ngOnChanges
68
+
69
+ private loadMenus(): void {
70
+ if (this.baseUrl && this.ActivePropertyId > 0) {
71
+ this.menuService.getGlobalSearchMenus(this.baseUrl, this.ActivePropertyId).subscribe({
72
+ next: (menus) => this.dataSource = menus ?? [],
73
+ error: () => this.dataSource = []
74
+ });
75
+ }
76
+ }
77
+
78
+ ngOnChanges(changes: SimpleChanges): void {
79
+ if (
80
+ changes['ActivePropertyChanged']
81
+ && !changes['ActivePropertyChanged'].firstChange
82
+ && changes['ActivePropertyChanged'].previousValue !== changes['ActivePropertyChanged'].currentValue
83
+ ) {
84
+ this.reset();
85
+ this.loadMenus();
86
+ }
87
+ }
88
+
89
+ onInput(event: { event?: { target?: { value?: string } }; component?: { option: (name: string, value: string) => void } } | any): void {
90
+ const searchTerm = event.event?.target?.value;
91
+ if (typeof searchTerm === 'string' && searchTerm.startsWith(' ')) {
92
+ event.component?.option('value', searchTerm.trim());
93
+ }
94
+ }
95
+
96
+ onEnterKey(event: { event?: { target?: { value?: string } } } | any): void {
97
+ const searchTerm = (event.event?.target?.value ?? '').toString().trim();
98
+ if (!searchTerm) {
99
+ return;
100
+ }
101
+
102
+ const match = this.dataSource.find(
103
+ (item) => item.MenuSubTitle.toLowerCase().trim() === searchTerm.toLowerCase().trim(),
104
+ );
105
+
106
+ if (match) {
107
+ window.location.href = match.MenuUrl;
108
+ this.itemNavigate.emit(match);
109
+ return;
110
+ }
111
+
112
+ this.search.emit(searchTerm);
113
+ }
114
+
115
+ onItemSelected(event: Event, item: GlobalSearchMenu): void {
116
+ event.preventDefault();
117
+ event.stopPropagation();
118
+ if (item.MenuUrl) {
119
+ window.location.href = item.MenuUrl;
120
+ }
121
+ }
122
+
123
+ reset(): void {
124
+ this.searchAutoComplete?.instance?.option('value', '');
125
+ }
126
+
127
+ getText(text: string, isTranslatable = false): string {
128
+ return isTranslatable ? text : text;
129
+ }
130
+
131
+ getIconForClass(iconClass: string) {
132
+ switch (iconClass) {
133
+ case 'icon icon-tools':
134
+ return this.toolsIcon;
135
+ case 'icon icon-grid':
136
+ return this.gridIcon;
137
+ case 'icon icon-credit':
138
+ return this.creditIcon;
139
+ case 'icon icon-users':
140
+ return this.usersIcon;
141
+ case 'icon icon-clock':
142
+ return this.clockIcon;
143
+ case 'icon icon-swap':
144
+ return this.swapIcon;
145
+ case 'icon icon-medal':
146
+ return this.medalIcon;
147
+ case 'icon icon-graduation-cap':
148
+ return this.graduateIcon;
149
+ default:
150
+ return this.toolsIcon;
151
+ }
152
+ }
153
+ }
@@ -0,0 +1,39 @@
1
+ @if (!hasChildren()) {
2
+ <li [class]="navItemClass">
3
+ <a
4
+ [class]="navLinkClass"
5
+ href="#"
6
+ (click)="onItemActivated($event)">
7
+ {{ item.MenuName | translate }}
8
+ </a>
9
+ </li>
10
+ }
11
+
12
+ @if (hasChildren()) {
13
+ <li [class]="dropdownClass" [class.open]="open()">
14
+ <a href="#" [class]="dropdownToggleClass" (click)="onItemActivated($event)">
15
+ {{ item.MenuName | translate }} <span [class]="caretClass"></span>
16
+ </a>
17
+
18
+ @if (open()) {
19
+ <ul [class]="dropdownMenuClass">
20
+ @for (child of item.Children; track child.MenuName) {
21
+ <bayan-core-item-widget
22
+ [baseUrl]="baseUrl"
23
+ [ActivePropertyChanged]="ActivePropertyChanged"
24
+ [item]="child"
25
+ (itemClick)="onChildItemClick($event)"
26
+ [navItemClass]="navItemClass"
27
+ [navLinkClass]="navLinkClass"
28
+ [dropdownClass]="dropdownClass"
29
+ [dropdownOpenClass]="dropdownOpenClass"
30
+ [dropdownToggleClass]="dropdownToggleClass"
31
+ [caretClass]="caretClass"
32
+ [dropdownMenuClass]="dropdownMenuClass"
33
+ >
34
+ </bayan-core-item-widget>
35
+ }
36
+ </ul>
37
+ }
38
+ </li>
39
+ }
@@ -0,0 +1,95 @@
1
+ import { of } from 'rxjs';
2
+ import { CommonModule, DOCUMENT } from '@angular/common';
3
+ import {
4
+ ChangeDetectionStrategy,
5
+ Component,
6
+ ElementRef,
7
+ EventEmitter,
8
+ HostListener,
9
+ Input,
10
+ OnChanges,
11
+ Output,
12
+ SimpleChanges,
13
+ inject,
14
+ signal,
15
+ } from '@angular/core';
16
+ import { Router } from '@angular/router';
17
+ import { TranslatePipe } from '@skysoftware-co/sky-components-ui';
18
+ import { TopMenuShortcut } from '../../../shared/menu.dtos';
19
+ import { isExternalNavigation, resolveUrl } from '../../../shared/common-methods/navigation.utils';
20
+
21
+ @Component({
22
+ selector: 'bayan-core-item-widget',
23
+ standalone: true,
24
+ imports: [CommonModule, TranslatePipe],
25
+ templateUrl: './item-widget.component.html',
26
+ styles: [':host { display: contents; }'],
27
+ styleUrls: ['../../top-menu-widget.styles.css'],
28
+ changeDetection: ChangeDetectionStrategy.OnPush,
29
+ })
30
+ export class BayanCoreItemWidgetComponent implements OnChanges {
31
+ private readonly document = inject(DOCUMENT);
32
+ private readonly router = inject(Router);
33
+
34
+ @Input() baseUrl = '';
35
+ @Input() ActivePropertyChanged = false;
36
+ @Input({ required: true }) item!: TopMenuShortcut;
37
+
38
+ @Input() navItemClass = 'nav-item';
39
+ @Input() navLinkClass = 'nav-link';
40
+ @Input() dropdownClass = 'nav-item dropdown';
41
+ @Input() dropdownOpenClass = 'open';
42
+ @Input() dropdownToggleClass = 'nav-link dropdown-toggle';
43
+ @Input() caretClass = 'caret';
44
+ @Input() dropdownMenuClass = 'dropdown-menu menu-dropdown-panel';
45
+
46
+ @Output() itemClick = new EventEmitter<TopMenuShortcut>();
47
+
48
+ readonly open = signal(false);
49
+
50
+ constructor(private readonly elementRef: ElementRef<HTMLElement>) {}
51
+
52
+ ngOnChanges(changes: SimpleChanges): void {
53
+ if (
54
+ changes['ActivePropertyChanged']
55
+ && !changes['ActivePropertyChanged'].firstChange
56
+ && changes['ActivePropertyChanged'].previousValue !== changes['ActivePropertyChanged'].currentValue
57
+ ) {
58
+ this.open.set(false);
59
+ }
60
+ }
61
+
62
+ @HostListener('document:click', ['$event'])
63
+ onDocumentClick(event: MouseEvent): void {
64
+ const target = event.target as Node | null;
65
+ if (target && !this.elementRef.nativeElement.contains(target)) {
66
+ this.open.set(false);
67
+ }
68
+ }
69
+
70
+ hasChildren(): boolean {
71
+ return (this.item.Children ?? []).length > 0;
72
+ }
73
+
74
+ onItemActivated(event: Event): void {
75
+ event.preventDefault();
76
+
77
+ if (this.hasChildren()) {
78
+ event.stopPropagation();
79
+ this.open.update((value) => !value);
80
+ return;
81
+ }
82
+
83
+ this.itemClick.emit(this.item);
84
+ if (typeof this.item.MenuUrl === 'string' && this.item.MenuName == 'Reports') {
85
+ window.open(this.item.MenuUrl, '_blank');
86
+ } else if (this.item.MenuUrl) {
87
+ window.location.href = this.item.MenuUrl;
88
+ }
89
+ }
90
+
91
+ onChildItemClick(item: TopMenuShortcut): void {
92
+ this.open.set(false);
93
+ this.itemClick.emit(item);
94
+ }
95
+ }
@@ -0,0 +1,10 @@
1
+ <div [class]="wrapperClass">
2
+ <a [class]="linkClass"
3
+ [title]="title | translate"
4
+ (click)="onNotificationClick($event)">
5
+ <fa-icon [class]="iconClass" [icon]="bellIcon"></fa-icon>
6
+ @if ((notificationsSummary().TotalNotificationsCount || 0) > 0) {
7
+ <span [class]="badgeClass">{{ notificationsSummary().TotalNotificationsCount }}</span>
8
+ }
9
+ </a>
10
+ </div>
@@ -0,0 +1,89 @@
1
+ import { CommonModule, DOCUMENT } from '@angular/common';
2
+ import {
3
+ ChangeDetectionStrategy,
4
+ Component,
5
+ Input,
6
+ OnChanges,
7
+ OnInit,
8
+ SimpleChanges,
9
+ inject,
10
+ signal,
11
+ } from '@angular/core';
12
+ import { FontAwesomeModule } from '@fortawesome/angular-fontawesome';
13
+ import { faBell } from '@fortawesome/pro-solid-svg-icons';
14
+ import { TranslatePipe } from '@skysoftware-co/sky-components-ui';
15
+ import { isExternalNavigation, resolveUrl } from '../../../shared/common-methods/navigation.utils';
16
+ import { NotificationsSummary } from '../../../shared/menu.dtos';
17
+ import { BayanCoreTopMenuService } from '../../../shared/menu.service';
18
+
19
+ @Component({
20
+ selector: 'bayan-core-notifications-widget',
21
+ standalone: true,
22
+ imports: [CommonModule, FontAwesomeModule, TranslatePipe],
23
+ templateUrl: './notifications-widget.component.html',
24
+ styles: [':host { display: flex; align-items: center; height: 56px; }'],
25
+ styleUrls: ['../../top-menu-widget.styles.css'],
26
+ changeDetection: ChangeDetectionStrategy.OnPush,
27
+ })
28
+ export class BayanCoreNotificationsWidgetComponent implements OnInit, OnChanges {
29
+ private readonly document = inject(DOCUMENT);
30
+ private readonly topMenuService = inject(BayanCoreTopMenuService);
31
+
32
+ @Input() baseUrl = '';
33
+ @Input() title = 'Notifications';
34
+ @Input() wrapperClass = 'notifications-icon-wrap menu-dropdown-host';
35
+ @Input() linkClass = 'menu-icon-btn cursor-pointer notifications-icon-btn';
36
+ @Input() iconClass = 'fs-6';
37
+ @Input() badgeClass = 'notifications-badge';
38
+
39
+ readonly bellIcon = faBell;
40
+ readonly notificationsSummary = signal<NotificationsSummary>({
41
+ NotificationsUrl: '',
42
+ TotalNotificationsCount: 0,
43
+ });
44
+
45
+ ngOnInit(): void {
46
+ this.loadNotificationsSummary();
47
+ }
48
+
49
+ ngOnChanges(changes: SimpleChanges): void {
50
+ if (changes['baseUrl'] && !changes['baseUrl'].firstChange) {
51
+ this.loadNotificationsSummary();
52
+ }
53
+ }
54
+
55
+ onNotificationClick(event?: Event): void {
56
+ event?.preventDefault();
57
+ const rawNotificationUrl = this.notificationsSummary().NotificationsUrl;
58
+
59
+ if (rawNotificationUrl) {
60
+ this.document.location.href = `${window.location.origin}${rawNotificationUrl}`;
61
+ }
62
+ }
63
+
64
+ private loadNotificationsSummary(): void {
65
+ if (!this.baseUrl) {
66
+ this.resetNotificationsData();
67
+ return;
68
+ }
69
+
70
+ this.topMenuService.getNotificationsSummary(this.baseUrl).subscribe({
71
+ next: (summary) => {
72
+ this.notificationsSummary.set({
73
+ NotificationsUrl: summary.NotificationsUrl,
74
+ TotalNotificationsCount: summary.TotalNotificationsCount,
75
+ });
76
+ },
77
+ error: () => {
78
+ this.resetNotificationsData();
79
+ },
80
+ });
81
+ }
82
+
83
+ private resetNotificationsData(): void {
84
+ this.notificationsSummary.set({
85
+ NotificationsUrl: '',
86
+ TotalNotificationsCount: 0,
87
+ });
88
+ }
89
+ }
@@ -0,0 +1,119 @@
1
+ <div [class]="dropdownHostClass" [class.open]="dropdownOpen()">
2
+ <a href="#" [class]="toggleBtnClass" (click)="toggleDropdown($event)" [title]="'Settings' | translate">
3
+ <fa-icon [icon]="cogIcon" class="fs-6"></fa-icon>
4
+ </a>
5
+
6
+ @if (dropdownOpen()) {
7
+ <ul [class]="menuPanelClass">
8
+ @if (preferences?.UseAlternateNames) {
9
+ <li>
10
+ <a [class]="alternateNamesLinkClass" (click)="onAlternateNamesClick($event)">
11
+ @if (preferences?.UseAlternateNames) {
12
+ <fa-icon [class]="indicatorActiveClass" [icon]="checkIcon"></fa-icon>
13
+ } @else {
14
+ <fa-icon [class]="indicatorInvisibleClass" [icon]="checkIcon"></fa-icon>
15
+ }
16
+ {{ 'DisplayAlternateNames' | translate }}
17
+ </a>
18
+ </li>
19
+ <li><hr class="dropdown-divider"></li>
20
+ }
21
+
22
+ @if (hrBlockState?.UserCanBlockModule) {
23
+ <li>
24
+ @if (hrBlockState?.IsBlocked) {
25
+ <a [class]="alternateNamesLinkClass" (click)="releaseModule(BlockableModule.HumanResources, $event)">
26
+ <fa-icon [class]="indicatorActiveClass" [icon]="checkIcon"></fa-icon>
27
+ {{ 'ReleaseHR' | translate }}
28
+ </a>
29
+ } @else {
30
+ <a [class]="alternateNamesLinkClass" (click)="blockModule(BlockableModule.HumanResources, $event)">
31
+ <fa-icon [class]="indicatorInvisibleClass" [icon]="checkIcon"></fa-icon>
32
+ {{ 'BlockHR' | translate }}
33
+ </a>
34
+ }
35
+ </li>
36
+ }
37
+
38
+ @if (tkBlockState?.UserCanBlockModule) {
39
+ <li>
40
+ @if (tkBlockState?.IsBlocked) {
41
+ <a [class]="alternateNamesLinkClass" (click)="releaseModule(BlockableModule.Timekeeping, $event)">
42
+ <fa-icon [class]="indicatorActiveClass" [icon]="checkIcon"></fa-icon>
43
+ {{ 'ReleaseTK' | translate }}
44
+ </a>
45
+ } @else {
46
+ <a [class]="alternateNamesLinkClass" (click)="blockModule(BlockableModule.Timekeeping, $event)">
47
+ <fa-icon [class]="indicatorInvisibleClass" [icon]="checkIcon"></fa-icon>
48
+ {{ 'BlockTK' | translate }}
49
+ </a>
50
+ }
51
+ </li>
52
+ }
53
+
54
+ @if (hrBlockState?.UserCanBlockModule || tkBlockState?.UserCanBlockModule) {
55
+ <li><hr class="dropdown-divider"></li>
56
+ }
57
+
58
+ <li>
59
+ <span [class]="sectionLabelClass">{{ 'EmployeeNamesMode' | translate }}</span>
60
+ </li>
61
+ <li>
62
+ <a [class]="menuRowClass" (click)="onNameModeClick(EmployeeNamesModeOption.ShortNames, $event); $event.stopPropagation()">
63
+ @if (preferences?.EmployeeNamesMode === EmployeeNamesModeOption.ShortNames) {
64
+ <fa-icon [class]="indicatorClass" [icon]="checkIcon"></fa-icon>
65
+ }
66
+ {{ 'ShortNames' | translate }}
67
+ </a>
68
+ </li>
69
+ <li>
70
+ <a [class]="menuRowClass" (click)="onNameModeClick(EmployeeNamesModeOption.StandardNames, $event); $event.stopPropagation()">
71
+ @if (preferences?.EmployeeNamesMode === EmployeeNamesModeOption.StandardNames) {
72
+ <fa-icon [class]="indicatorClass" [icon]="checkIcon"></fa-icon>
73
+ }
74
+ {{ 'StandardNames' | translate }}
75
+ </a>
76
+ </li>
77
+ <li>
78
+ <a [class]="menuRowClass" (click)="onNameModeClick(EmployeeNamesModeOption.FullNames, $event); $event.stopPropagation()">
79
+ @if (preferences?.EmployeeNamesMode === EmployeeNamesModeOption.FullNames) {
80
+ <fa-icon [class]="indicatorClass" [icon]="checkIcon"></fa-icon>
81
+ }
82
+ {{ 'FullNames' | translate }}
83
+ </a>
84
+ </li>
85
+ <li><hr [class]="dividerClass"></li>
86
+
87
+ <li>
88
+ <a [class]="menuRowClass" (click)="onChangePasswordClick($event)">
89
+ <span [class]="indicatorClass"></span>
90
+ {{ 'ChangePassword' | translate }}
91
+ </a>
92
+ </li>
93
+
94
+ <li><hr [class]="dividerClass"></li>
95
+
96
+ <li>
97
+ <a [class]="menuRowClass" (click)="onOpenAboutClick($event)">
98
+ <fa-icon [class]="indicatorClass" [icon]="infoIcon"></fa-icon>
99
+ {{ 'About' | translate }}
100
+ </a>
101
+ </li>
102
+ </ul>
103
+ }
104
+ </div>
105
+
106
+ <bayan-core-change-password-widget
107
+ [visible]="showChangePassword"
108
+ [config]="changePasswordDialog"
109
+ (visibleChange)="showChangePassword = !!$event">
110
+ </bayan-core-change-password-widget>
111
+
112
+ <bayan-core-about-dialog-widget
113
+ [visible]="showAbout"
114
+ [config]="aboutDialog"
115
+ [licenseUrl]="licenseUrl"
116
+ [releaseNotesUrl]="releaseNotesUrl"
117
+ [supportUrl]="supportUrl"
118
+ (visibleChange)="showAbout = !!$event">
119
+ </bayan-core-about-dialog-widget>