aril 1.0.39 → 1.0.41

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 (59) hide show
  1. package/esm2022/http/src/serviceStateMethods.mjs +6 -2
  2. package/esm2022/theme/layout/app/favorite-pages/favorite-pages-sidebar.component.mjs +211 -0
  3. package/esm2022/theme/layout/app/favorite-pages/favorite-pages.service.mjs +55 -0
  4. package/esm2022/theme/layout/app/favorite-pages/modals/add-edit-favorite-modal/add-edit-favorite-modal.component.mjs +129 -0
  5. package/esm2022/theme/layout/app/history/history-sidebar.component.mjs +128 -0
  6. package/esm2022/theme/layout/app/history/history.service.mjs +146 -0
  7. package/esm2022/theme/layout/app/layout/app.layout.component.mjs +9 -3
  8. package/esm2022/theme/layout/app/profileSidebar/app.profilesidebar.component.mjs +100 -8
  9. package/esm2022/theme/layout/app/profileSidebar/modals/change-password-modal/change-password-modal.component.mjs +142 -0
  10. package/esm2022/theme/layout/app/profileSidebar/modals/edit-profile-modal/edit-profile-modal.component.mjs +123 -0
  11. package/esm2022/theme/layout/app/profileSidebar/profile.service.mjs +42 -0
  12. package/esm2022/theme/layout/app/site-map/site-map-sidebar.component.mjs +161 -0
  13. package/esm2022/theme/layout/app/topbar/app.topbar.component.mjs +23 -5
  14. package/esm2022/theme/layout/service/app.layout.service.mjs +13 -1
  15. package/fesm2022/aril-http.mjs +5 -1
  16. package/fesm2022/aril-http.mjs.map +1 -1
  17. package/fesm2022/aril-theme-layout.mjs +1197 -75
  18. package/fesm2022/aril-theme-layout.mjs.map +1 -1
  19. package/package.json +84 -83
  20. package/theme/layout/app/favorite-pages/favorite-pages-sidebar.component.d.ts +42 -0
  21. package/theme/layout/app/favorite-pages/favorite-pages-sidebar.component.html +106 -0
  22. package/theme/layout/app/favorite-pages/favorite-pages-sidebar.component.scss +181 -0
  23. package/theme/layout/app/favorite-pages/favorite-pages-sidebar.component.ts +253 -0
  24. package/theme/layout/app/favorite-pages/favorite-pages.service.d.ts +54 -0
  25. package/theme/layout/app/favorite-pages/favorite-pages.service.ts +87 -0
  26. package/theme/layout/app/favorite-pages/modals/add-edit-favorite-modal/add-edit-favorite-modal.component.d.ts +36 -0
  27. package/theme/layout/app/favorite-pages/modals/add-edit-favorite-modal/add-edit-favorite-modal.component.html +27 -0
  28. package/theme/layout/app/favorite-pages/modals/add-edit-favorite-modal/add-edit-favorite-modal.component.ts +165 -0
  29. package/theme/layout/app/history/history-sidebar.component.d.ts +30 -0
  30. package/theme/layout/app/history/history-sidebar.component.html +88 -0
  31. package/theme/layout/app/history/history-sidebar.component.scss +191 -0
  32. package/theme/layout/app/history/history-sidebar.component.ts +139 -0
  33. package/theme/layout/app/history/history.service.d.ts +36 -0
  34. package/theme/layout/app/history/history.service.ts +182 -0
  35. package/theme/layout/app/layout/app.layout.component.html +3 -0
  36. package/theme/layout/app/layout/app.layout.component.ts +7 -1
  37. package/theme/layout/app/profileSidebar/app.profilesidebar.component.d.ts +17 -2
  38. package/theme/layout/app/profileSidebar/app.profilesidebar.component.html +107 -135
  39. package/theme/layout/app/profileSidebar/app.profilesidebar.component.scss +152 -0
  40. package/theme/layout/app/profileSidebar/app.profilesidebar.component.ts +114 -7
  41. package/theme/layout/app/profileSidebar/modals/change-password-modal/change-password-modal.component.d.ts +30 -0
  42. package/theme/layout/app/profileSidebar/modals/change-password-modal/change-password-modal.component.html +46 -0
  43. package/theme/layout/app/profileSidebar/modals/change-password-modal/change-password-modal.component.scss +28 -0
  44. package/theme/layout/app/profileSidebar/modals/change-password-modal/change-password-modal.component.ts +178 -0
  45. package/theme/layout/app/profileSidebar/modals/edit-profile-modal/edit-profile-modal.component.d.ts +27 -0
  46. package/theme/layout/app/profileSidebar/modals/edit-profile-modal/edit-profile-modal.component.html +76 -0
  47. package/theme/layout/app/profileSidebar/modals/edit-profile-modal/edit-profile-modal.component.ts +141 -0
  48. package/theme/layout/app/profileSidebar/profile.service.d.ts +67 -0
  49. package/theme/layout/app/profileSidebar/profile.service.ts +89 -0
  50. package/theme/layout/app/site-map/site-map-sidebar.component.d.ts +37 -0
  51. package/theme/layout/app/site-map/site-map-sidebar.component.html +118 -0
  52. package/theme/layout/app/site-map/site-map-sidebar.component.scss +189 -0
  53. package/theme/layout/app/site-map/site-map-sidebar.component.ts +189 -0
  54. package/theme/layout/app/topbar/app.topbar.component.d.ts +7 -1
  55. package/theme/layout/app/topbar/app.topbar.component.html +37 -17
  56. package/theme/layout/app/topbar/app.topbar.component.scss +188 -12
  57. package/theme/layout/app/topbar/app.topbar.component.ts +29 -7
  58. package/theme/layout/service/app.layout.service.d.ts +6 -0
  59. package/theme/layout/service/app.layout.service.ts +19 -1
@@ -0,0 +1,88 @@
1
+ <p-sidebar
2
+ [(visible)]="visible"
3
+ position="right"
4
+ [transitionOptions]="'.3s cubic-bezier(0, 0, 0.2, 1)'"
5
+ styleClass="layout-history-sidebar w-full sm:w-30rem"
6
+ *transloco="let t; read: 'history'">
7
+ <ng-template pTemplate="header">
8
+ <div class="flex align-items-center justify-content-between w-full">
9
+ <div class="flex align-items-center">
10
+ <i class="pi pi-history text-primary text-xl"></i>
11
+ <span class="font-bold text-lg">{{ t('pageHistory') }}</span>
12
+ </div>
13
+ </div>
14
+ </ng-template>
15
+
16
+ <div class="history-content">
17
+ @if (history().length > 0) {
18
+ <div class="search-section">
19
+ <div class="search-input-container">
20
+ <aril-text
21
+ class="w-full"
22
+ [placeholder]="t('searchHistory')"
23
+ [(ngModel)]="searchTerm"
24
+ (ngModelChange)="onSearchChange()">
25
+ </aril-text>
26
+
27
+ <aril-button
28
+ icon="TRASH"
29
+ color="danger"
30
+ size="sm"
31
+ class="ml-1"
32
+ [pTooltip]="t('confirmClearAll')"
33
+ tooltipPosition="left"
34
+ (clickEvent)="clearAllHistory($event)">
35
+ </aril-button>
36
+ </div>
37
+ </div>
38
+ }
39
+
40
+ @if (filteredHistory().length > 0) {
41
+ <div class="history-list">
42
+ <p-scrollPanel [style]="{ width: '100%', height: '100%' }">
43
+ <div class="history-items">
44
+ @for (item of filteredHistory(); track trackByItemId($index, item)) {
45
+ <div class="history-item" (click)="navigateToItem(item)">
46
+ <div class="item-content">
47
+ <div class="item-header">
48
+ <div class="item-title">
49
+ <i class="pi pi-external-link text-primary mr-2"></i>
50
+ <div class="title-info">
51
+ <span class="title-text">{{ getLocalizedTitle(item) }}</span>
52
+ <span class="route-text">{{ item.url }}</span>
53
+ </div>
54
+ </div>
55
+ </div>
56
+ </div>
57
+ </div>
58
+ }
59
+ </div>
60
+ </p-scrollPanel>
61
+ </div>
62
+ } @else {
63
+ <div class="empty-state">
64
+ <div class="empty-content">
65
+ <i class="pi pi-history empty-icon"></i>
66
+ <h3 class="empty-title">
67
+ {{ searchTerm() ? t('noSearchResults') : t('noHistory') }}
68
+ </h3>
69
+ <p class="empty-message">
70
+ {{ searchTerm() ? t('tryDifferentKeywords') : t('startBrowsing') }}
71
+ </p>
72
+ @if (searchTerm()) {
73
+ <aril-button
74
+ [label]="t('clearSearch')"
75
+ icon="TIMES"
76
+ color="secondary"
77
+ [outlined]="true"
78
+ size="sm"
79
+ (clickEvent)="searchTerm.set(''); onSearchChange()">
80
+ </aril-button>
81
+ }
82
+ </div>
83
+ </div>
84
+ }
85
+ </div>
86
+
87
+ <p-confirmDialog></p-confirmDialog>
88
+ </p-sidebar>
@@ -0,0 +1,191 @@
1
+ :host ::ng-deep {
2
+ .layout-history-sidebar {
3
+ .p-sidebar-content {
4
+ padding: 0;
5
+ background: var(--surface-ground);
6
+ }
7
+ .p-sidebar-header {
8
+ background: var(--primary-color);
9
+ color: var(--primary-color-text);
10
+ border-bottom: 1px solid var(--primary-600);
11
+ padding: 1rem 0.5rem;
12
+
13
+ i {
14
+ color: var(--primary-color-text);
15
+ font-size: 1.1rem;
16
+ }
17
+
18
+ span {
19
+ font-size: 1.1rem;
20
+ font-weight: 600;
21
+ color: var(--primary-color-text);
22
+ }
23
+ }
24
+ }
25
+ }
26
+
27
+ .history-content {
28
+ display: flex;
29
+ flex-direction: column;
30
+ height: 92vh;
31
+ background: var(--surface-0);
32
+ }
33
+
34
+ .search-section {
35
+ padding: 1rem;
36
+ border-bottom: 1px solid var(--surface-border);
37
+ background: var(--surface-0);
38
+ width: 100%;
39
+ }
40
+
41
+ .search-input-container {
42
+ display: flex;
43
+ align-items: center;
44
+ justify-content: space-between;
45
+ width: 100%;
46
+ }
47
+
48
+ // History List
49
+ .history-list {
50
+ flex: 1;
51
+ overflow: hidden;
52
+ }
53
+
54
+ .history-items {
55
+ padding: 0.5rem;
56
+ }
57
+
58
+ .history-item {
59
+ background: var(--surface-0);
60
+ border: 1px solid var(--surface-border);
61
+ border-radius: 8px;
62
+ margin-bottom: 0.5rem;
63
+ cursor: pointer;
64
+ transition: all 0.2s ease;
65
+ position: relative;
66
+ overflow: hidden;
67
+
68
+ &:hover {
69
+ border-color: var(--primary-200);
70
+ background: var(--primary-50);
71
+ transform: translateY(-1px);
72
+ box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
73
+ .remove-btn {
74
+ opacity: 1;
75
+ }
76
+ }
77
+ &:last-child {
78
+ margin-bottom: 0;
79
+ }
80
+ }
81
+
82
+ .item-content {
83
+ padding: 1rem 0.75rem;
84
+ }
85
+
86
+ .item-header {
87
+ display: flex;
88
+ align-items: center;
89
+ justify-content: space-between;
90
+ }
91
+
92
+ .item-title {
93
+ display: flex;
94
+ align-items: center;
95
+ flex: 1;
96
+ min-width: 0;
97
+
98
+ .title-info {
99
+ display: flex;
100
+ flex-direction: column;
101
+ flex: 1;
102
+ min-width: 0;
103
+ }
104
+
105
+ .title-text {
106
+ font-weight: 600;
107
+ color: var(--text-color);
108
+ font-size: 1rem;
109
+ line-height: 1.3;
110
+ overflow: hidden;
111
+ text-overflow: ellipsis;
112
+ white-space: nowrap;
113
+ }
114
+
115
+ .route-text {
116
+ font-size: 0.75rem;
117
+ color: var(--text-color-secondary);
118
+ font-weight: 400;
119
+ line-height: 1.2;
120
+ margin-top: 0.25rem;
121
+ overflow: hidden;
122
+ text-overflow: ellipsis;
123
+ white-space: nowrap;
124
+ opacity: 0.8;
125
+ }
126
+ }
127
+
128
+ .empty-state {
129
+ flex: 1;
130
+ display: flex;
131
+ align-items: center;
132
+ justify-content: center;
133
+ padding: 2rem;
134
+ }
135
+
136
+ .empty-content {
137
+ text-align: center;
138
+ max-width: 300px;
139
+ }
140
+
141
+ .empty-icon {
142
+ font-size: 3rem;
143
+ color: var(--text-color-secondary);
144
+ margin-bottom: 1rem;
145
+ opacity: 0.5;
146
+ }
147
+
148
+ .empty-title {
149
+ font-size: 1.1rem;
150
+ font-weight: 600;
151
+ color: var(--text-color);
152
+ margin-bottom: 0.5rem;
153
+ }
154
+
155
+ .empty-message {
156
+ font-size: 0.9rem;
157
+ color: var(--text-color-secondary);
158
+ line-height: 1.4;
159
+ margin-bottom: 1.5rem;
160
+ }
161
+
162
+ @media (max-width: 768px) {
163
+ .history-content {
164
+ height: calc(100vh - 3.5rem);
165
+ }
166
+
167
+ .search-section {
168
+ padding: 0.75rem;
169
+ }
170
+
171
+ .item-content {
172
+ padding: 0.5rem;
173
+ }
174
+
175
+ .item-title .title-text {
176
+ font-size: 0.85rem;
177
+ }
178
+ }
179
+
180
+ // Custom Scrollbar
181
+ :host ::ng-deep {
182
+ .p-scrollpanel-bar-y {
183
+ background: var(--primary-200);
184
+ width: 4px;
185
+ border-radius: 2px;
186
+ }
187
+
188
+ .p-scrollpanel-bar-y:hover {
189
+ background: var(--primary-300);
190
+ }
191
+ }
@@ -0,0 +1,139 @@
1
+ import { CommonModule } from '@angular/common';
2
+ import { Component, OnDestroy, OnInit, signal } from '@angular/core';
3
+ import { FormsModule } from '@angular/forms';
4
+
5
+ import { ConfirmationService, MessageService } from 'primeng/api';
6
+ import { BadgeModule } from 'primeng/badge';
7
+ import { ConfirmDialogModule } from 'primeng/confirmdialog';
8
+ import { InputTextModule } from 'primeng/inputtext';
9
+ import { ScrollPanelModule } from 'primeng/scrollpanel';
10
+ import { SidebarModule } from 'primeng/sidebar';
11
+ import { TooltipModule } from 'primeng/tooltip';
12
+
13
+ import { TranslocoModule, TranslocoService } from '@ngneat/transloco';
14
+ import { Subject, takeUntil } from 'rxjs';
15
+
16
+ import { ButtonComponent } from 'aril/ui/button';
17
+ import { TextComponent } from 'aril/ui/text';
18
+
19
+ import { LayoutService } from '../../service/app.layout.service';
20
+ import { HistoryItem, HistoryService } from './history.service';
21
+
22
+ @Component({
23
+ standalone: true,
24
+ selector: 'app-history-sidebar',
25
+ imports: [
26
+ CommonModule,
27
+ FormsModule,
28
+ SidebarModule,
29
+ ButtonComponent,
30
+ InputTextModule,
31
+ ScrollPanelModule,
32
+ ConfirmDialogModule,
33
+ TooltipModule,
34
+ BadgeModule,
35
+ TranslocoModule,
36
+ TextComponent
37
+ ],
38
+ templateUrl: './history-sidebar.component.html',
39
+ styleUrls: ['./history-sidebar.component.scss'],
40
+ providers: [ConfirmationService]
41
+ })
42
+ export class HistorySidebarComponent implements OnInit, OnDestroy {
43
+ history = signal<HistoryItem[]>([]);
44
+ filteredHistory = signal<HistoryItem[]>([]);
45
+ searchTerm = signal<string>('');
46
+
47
+ private destroy$ = new Subject<void>();
48
+
49
+ constructor(
50
+ public layoutService: LayoutService,
51
+ private historyService: HistoryService,
52
+ private confirmationService: ConfirmationService,
53
+ private messageService: MessageService,
54
+ private translocoService: TranslocoService
55
+ ) {}
56
+
57
+ ngOnInit(): void {
58
+ this.historyService.history$.pipe(takeUntil(this.destroy$)).subscribe((history) => {
59
+ this.history.set(history);
60
+ this.applyFilter();
61
+ });
62
+ }
63
+
64
+ ngOnDestroy(): void {
65
+ this.destroy$.next();
66
+ this.destroy$.complete();
67
+ }
68
+
69
+ get visible(): boolean {
70
+ return this.layoutService.state.historySidebarVisible;
71
+ }
72
+
73
+ set visible(value: boolean) {
74
+ this.layoutService.state.historySidebarVisible = value;
75
+ }
76
+
77
+ onSearchChange(): void {
78
+ this.applyFilter();
79
+ }
80
+
81
+ private applyFilter(): void {
82
+ const searchTerm = this.searchTerm();
83
+ if (!searchTerm.trim()) {
84
+ this.filteredHistory.set(this.history());
85
+ } else {
86
+ const filtered = this.historyService.getHistoryItemsBySearchTerm(searchTerm);
87
+ this.filteredHistory.set(filtered);
88
+ }
89
+ }
90
+
91
+ navigateToItem(item: HistoryItem): void {
92
+ this.historyService.navigateToHistoryItem(item);
93
+ this.visible = false;
94
+ }
95
+
96
+ clearAllHistory(event: Event): void {
97
+ this.confirmationService.confirm({
98
+ target: event.target as EventTarget,
99
+ message: this.translocoService.translate('history.confirmClearAllMessage'),
100
+ header: this.translocoService.translate('history.deleteConfirmation'),
101
+ icon: 'pi pi-info-circle',
102
+ acceptLabel: this.translocoService.translate('history.acceptButtonLabel'),
103
+ rejectLabel: this.translocoService.translate('history.rejectButtonLabel'),
104
+ acceptButtonStyleClass: 'p-button-success',
105
+ rejectButtonStyleClass: 'p-button-danger p-button-outlined',
106
+ accept: () => {
107
+ this.historyService.clearHistory();
108
+ this.messageService.add({
109
+ severity: 'success',
110
+ summary: this.translocoService.translate('history.acceptButtonLabel'),
111
+ detail: this.translocoService.translate('history.clearAll')
112
+ });
113
+ }
114
+ });
115
+ }
116
+
117
+ trackByItemId(index: number, item: HistoryItem) {
118
+ return item.id || index;
119
+ }
120
+
121
+ getLocalizedTitle(item: HistoryItem): string {
122
+ const currentLang = this.translocoService.getActiveLang() as 'tr' | 'en';
123
+
124
+ // Use multiLanguageTitle if available
125
+ if (item.multiLanguageTitle) {
126
+ const localizedTitle = item.multiLanguageTitle[currentLang];
127
+ if (localizedTitle) {
128
+ return localizedTitle;
129
+ }
130
+ // Fallback to Turkish if current language not available
131
+ if (item.multiLanguageTitle.tr) {
132
+ return item.multiLanguageTitle.tr;
133
+ }
134
+ }
135
+
136
+ // Fallback to original title
137
+ return item.title;
138
+ }
139
+ }
@@ -0,0 +1,36 @@
1
+ import { Observable } from 'rxjs';
2
+ import * as i0 from "@angular/core";
3
+ export interface HistoryItem {
4
+ id: string;
5
+ title: string;
6
+ multiLanguageTitle?: {
7
+ tr?: string;
8
+ en?: string;
9
+ };
10
+ url: string;
11
+ timestamp: number;
12
+ }
13
+ export declare class HistoryService {
14
+ private readonly STORAGE_KEY;
15
+ private readonly MAX_HISTORY_SIZE;
16
+ private historySubject;
17
+ history$: Observable<HistoryItem[]>;
18
+ private excludedPaths;
19
+ private router;
20
+ private translocoService;
21
+ constructor();
22
+ private initializeRouterTracking;
23
+ private addToHistory;
24
+ private shouldExcludeUrl;
25
+ private findMenuItemByPath;
26
+ private findMenuItemRecursive;
27
+ private generateId;
28
+ private loadHistoryFromStorage;
29
+ private saveHistoryToStorage;
30
+ clearHistory(): void;
31
+ navigateToHistoryItem(item: HistoryItem): void;
32
+ private getHistoryFromStorage;
33
+ getHistoryItemsBySearchTerm(searchTerm: string): HistoryItem[];
34
+ static ɵfac: i0.ɵɵFactoryDeclaration<HistoryService, never>;
35
+ static ɵprov: i0.ɵɵInjectableDeclaration<HistoryService>;
36
+ }
@@ -0,0 +1,182 @@
1
+ import { Injectable, inject } from '@angular/core';
2
+ import { Router, NavigationEnd } from '@angular/router';
3
+ import { BehaviorSubject, Observable } from 'rxjs';
4
+ import { filter, map } from 'rxjs/operators';
5
+ import { TranslocoService } from '@ngneat/transloco';
6
+
7
+ import { PluginMenuItem } from 'aril/boot/config/apps';
8
+
9
+ export interface HistoryItem {
10
+ id: string;
11
+ title: string;
12
+ multiLanguageTitle?: {
13
+ tr?: string;
14
+ en?: string;
15
+ };
16
+ url: string;
17
+ timestamp: number;
18
+ }
19
+
20
+ @Injectable({
21
+ providedIn: 'root'
22
+ })
23
+ export class HistoryService {
24
+ private readonly STORAGE_KEY = 'page_history';
25
+ private readonly MAX_HISTORY_SIZE = 20;
26
+
27
+ private historySubject = new BehaviorSubject<HistoryItem[]>([]);
28
+ public history$: Observable<HistoryItem[]> = this.historySubject.asObservable();
29
+
30
+ // Excluded paths that shouldn't be tracked
31
+ private excludedPaths = ['/login', '/logout', '/error', '/not-found', '/unauthorized'];
32
+
33
+ private router = inject(Router);
34
+ private translocoService = inject(TranslocoService);
35
+
36
+ constructor() {
37
+ this.loadHistoryFromStorage();
38
+ this.initializeRouterTracking();
39
+ }
40
+
41
+ private initializeRouterTracking(): void {
42
+ this.router.events
43
+ .pipe(
44
+ filter((event) => event instanceof NavigationEnd),
45
+ map((event) => event as NavigationEnd)
46
+ )
47
+ .subscribe((event: NavigationEnd) => {
48
+ this.addToHistory(event.urlAfterRedirects || event.url);
49
+ });
50
+ }
51
+
52
+ private addToHistory(url: string): void {
53
+ // Skip if URL should be excluded
54
+ if (this.shouldExcludeUrl(url)) {
55
+ return;
56
+ }
57
+
58
+ const menuItem = this.findMenuItemByPath(url);
59
+ const multiLanguageTitle: { tr?: string; en?: string } = {};
60
+
61
+ // Get titles for both languages if menu item exists
62
+ if (menuItem) {
63
+ multiLanguageTitle.tr = menuItem.label['tr'];
64
+ multiLanguageTitle.en = menuItem.label['en'];
65
+ } else {
66
+ // Fallback for pages not in menu
67
+ multiLanguageTitle.tr = 'Bilinmeyen Sayfa';
68
+ multiLanguageTitle.en = 'Unknown Page';
69
+ }
70
+
71
+ const currentLang = this.translocoService.getActiveLang() as 'tr' | 'en';
72
+ const title = multiLanguageTitle[currentLang] || multiLanguageTitle.tr || 'Unknown Page';
73
+ const timestamp = Date.now();
74
+ const id = this.generateId(url, timestamp);
75
+
76
+ const newItem: HistoryItem = {
77
+ id,
78
+ title,
79
+ multiLanguageTitle,
80
+ url,
81
+ timestamp
82
+ };
83
+
84
+ let history = this.getHistoryFromStorage();
85
+ history = history.filter((item) => item.url !== url);
86
+ history.unshift(newItem);
87
+
88
+ // Limit history size
89
+ if (history.length > this.MAX_HISTORY_SIZE) {
90
+ history = history.slice(0, this.MAX_HISTORY_SIZE);
91
+ }
92
+
93
+ this.saveHistoryToStorage(history);
94
+ this.historySubject.next(history);
95
+ }
96
+
97
+ private shouldExcludeUrl(url: string): boolean {
98
+ return this.excludedPaths.some((excludedPath) => url.startsWith(excludedPath));
99
+ }
100
+
101
+ private findMenuItemByPath(path: string): PluginMenuItem | null {
102
+ const menuItems = (<any>globalThis).hostMenuItems?.() || [];
103
+
104
+ // Special handling for home page route
105
+ if (path === '/' || path === '') {
106
+ return menuItems.find((item: PluginMenuItem) => item.routerLink === '/') || null;
107
+ }
108
+
109
+ // Remove leading slash if present for other routes
110
+ const cleanPath = path.startsWith('/') ? path.substring(1) : path;
111
+ return this.findMenuItemRecursive(menuItems, cleanPath);
112
+ }
113
+
114
+ private findMenuItemRecursive(items: PluginMenuItem[], path: string): PluginMenuItem | null {
115
+ for (const item of items) {
116
+ if (item.routerLink === path) {
117
+ return item;
118
+ }
119
+
120
+ if (item.routerLink && path.startsWith(item.routerLink + '/')) {
121
+ return item;
122
+ }
123
+
124
+ if (item.items) {
125
+ const found = this.findMenuItemRecursive(item.items, path);
126
+ if (found) {
127
+ return found;
128
+ }
129
+ }
130
+ }
131
+
132
+ return null;
133
+ }
134
+
135
+ private generateId(url: string, timestamp: number): string {
136
+ return `${url.replace(/[^a-zA-Z0-9]/g, '_')}_${timestamp}`;
137
+ }
138
+
139
+ private loadHistoryFromStorage(): void {
140
+ const history = this.getHistoryFromStorage();
141
+ this.historySubject.next(history);
142
+ }
143
+
144
+ private saveHistoryToStorage(history: HistoryItem[]): void {
145
+ try {
146
+ localStorage.setItem(this.STORAGE_KEY, JSON.stringify(history));
147
+ } catch (error) {
148
+ console.warn('Failed to save navigation history to localStorage:', error);
149
+ }
150
+ }
151
+
152
+ public clearHistory(): void {
153
+ localStorage.removeItem(this.STORAGE_KEY);
154
+ this.historySubject.next([]);
155
+ }
156
+
157
+ public navigateToHistoryItem(item: HistoryItem): void {
158
+ this.router.navigate([item.url]);
159
+ }
160
+
161
+ private getHistoryFromStorage(): HistoryItem[] {
162
+ try {
163
+ const stored = localStorage.getItem(this.STORAGE_KEY);
164
+ return stored ? JSON.parse(stored) : [];
165
+ } catch (error) {
166
+ console.warn('Failed to load navigation history from localStorage:', error);
167
+ return [];
168
+ }
169
+ }
170
+
171
+ public getHistoryItemsBySearchTerm(searchTerm: string): HistoryItem[] {
172
+ const history = this.getHistoryFromStorage();
173
+ const lowerSearchTerm = searchTerm.toLowerCase();
174
+ const currentLang = this.translocoService.getActiveLang() as 'tr' | 'en';
175
+
176
+ return history.filter((item) => {
177
+ // Search in current language title
178
+ const currentTitle = item.multiLanguageTitle?.[currentLang] || item.title;
179
+ return currentTitle.toLowerCase().includes(lowerSearchTerm) || item.url.toLowerCase().includes(lowerSearchTerm);
180
+ });
181
+ }
182
+ }
@@ -8,6 +8,9 @@
8
8
  </div>
9
9
  </div>
10
10
  <app-profilemenu />
11
+ <app-history-sidebar />
12
+ <app-site-map-sidebar />
13
+ <app-favorite-pages-sidebar />
11
14
  <!--<app-config></app-config>-->
12
15
  <app-chatbot></app-chatbot>
13
16
  <div class="layout-mask"></div>
@@ -13,6 +13,9 @@ import { Subscription, filter } from 'rxjs';
13
13
  import { LayoutService } from '../../service/app.layout.service';
14
14
  import { AppMenuService } from '../../service/app.menu.service';
15
15
  import { AppProfileSidebarComponent } from '../profileSidebar/app.profilesidebar.component';
16
+ import { HistorySidebarComponent } from '../history/history-sidebar.component';
17
+ import { SiteMapSidebarComponent } from '../site-map/site-map-sidebar.component';
18
+ import { FavoritePagesSidebarComponent } from '../favorite-pages/favorite-pages-sidebar.component';
16
19
  import { AppSidebarComponent } from '../sidebar/app.sidebar.component';
17
20
  import { AppTopbarComponent } from '../topbar/app.topbar.component';
18
21
  import { AppChatbotComponent } from '../chatbot/app.chatbot.component';
@@ -31,6 +34,9 @@ import { ExpandableMenuComponent } from '../expandableMenu/expandable-menu.compo
31
34
  ToastModule,
32
35
  AppTopbarComponent,
33
36
  AppProfileSidebarComponent,
37
+ HistorySidebarComponent,
38
+ SiteMapSidebarComponent,
39
+ FavoritePagesSidebarComponent,
34
40
  AppChatbotComponent,
35
41
  AppSidebarComponent,
36
42
  ExpandableMenuComponent
@@ -174,4 +180,4 @@ export class AppLayoutComponent implements OnDestroy {
174
180
  this.menuOutsideClickListener();
175
181
  }
176
182
  }
177
- }
183
+ }
@@ -1,14 +1,29 @@
1
+ import { OnInit } from '@angular/core';
2
+ import { DialogService } from 'primeng/dynamicdialog';
3
+ import { TranslocoService } from '@ngneat/transloco';
1
4
  import { KeycloakService } from 'keycloak-angular';
2
5
  import { LayoutService } from '../../service/app.layout.service';
6
+ import { ProfileService, UserResponseDTO } from './profile.service';
3
7
  import * as i0 from "@angular/core";
4
- export declare class AppProfileSidebarComponent {
8
+ export declare class AppProfileSidebarComponent implements OnInit {
5
9
  layoutService: LayoutService;
6
10
  private readonly keycloak;
11
+ private readonly profileService;
12
+ private readonly dialogService;
13
+ private readonly translocoService;
7
14
  username: string;
8
- constructor(layoutService: LayoutService, keycloak: KeycloakService);
15
+ userProfile: import("@angular/core").WritableSignal<UserResponseDTO | null>;
16
+ private subjects;
17
+ getUserService: import("@angular/core").Signal<import("../../../../../../dist/http").ServiceResponse<UserResponseDTO> | undefined>;
18
+ constructor(layoutService: LayoutService, keycloak: KeycloakService, profileService: ProfileService, dialogService: DialogService, translocoService: TranslocoService);
19
+ ngOnInit(): void;
20
+ private initializeEffects;
21
+ private loadUserProfile;
9
22
  get visible(): boolean;
10
23
  set visible(_val: boolean);
11
24
  logout(): void;
25
+ editProfile(): void;
26
+ changePassword(): void;
12
27
  static ɵfac: i0.ɵɵFactoryDeclaration<AppProfileSidebarComponent, never>;
13
28
  static ɵcmp: i0.ɵɵComponentDeclaration<AppProfileSidebarComponent, "app-profilemenu", never, {}, {}, never, never, true, never>;
14
29
  }