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,253 @@
1
+ import { CommonModule } from '@angular/common';
2
+ import { Component, OnInit, effect, signal } from '@angular/core';
3
+ import { toSignal } from '@angular/core/rxjs-interop';
4
+
5
+ import { ConfirmationService, MessageService } from 'primeng/api';
6
+ import { ConfirmDialogModule } from 'primeng/confirmdialog';
7
+ import { DialogService, DynamicDialogModule } from 'primeng/dynamicdialog';
8
+ import { PaginatorModule } from 'primeng/paginator';
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, switchMap } from 'rxjs';
15
+
16
+ import { ButtonComponent } from 'aril/ui/button';
17
+
18
+ import { LayoutService } from '../../service/app.layout.service';
19
+ import { FavoritePageResponseDTO, FavoritePagesService } from './favorite-pages.service';
20
+ import { AddEditFavoriteModalComponent } from './modals/add-edit-favorite-modal/add-edit-favorite-modal.component';
21
+
22
+ @Component({
23
+ standalone: true,
24
+ selector: 'app-favorite-pages-sidebar',
25
+ imports: [
26
+ CommonModule,
27
+ SidebarModule,
28
+ ScrollPanelModule,
29
+ ConfirmDialogModule,
30
+ PaginatorModule,
31
+ DynamicDialogModule,
32
+ ButtonComponent,
33
+ TranslocoModule,
34
+ TooltipModule
35
+ ],
36
+ templateUrl: './favorite-pages-sidebar.component.html',
37
+ styleUrls: ['./favorite-pages-sidebar.component.scss'],
38
+ providers: [ConfirmationService, DialogService]
39
+ })
40
+ export class FavoritePagesSidebarComponent implements OnInit {
41
+ favoritePages = signal<FavoritePageResponseDTO[]>([]);
42
+ allFavoritePages = signal<FavoritePageResponseDTO[]>([]);
43
+ isCurrentPageFavorited = signal<boolean>(false);
44
+
45
+ currentPage = signal<number>(1);
46
+ pageSize = signal<number>(10);
47
+ totalItems = signal<number>(0);
48
+ totalPages = signal<number>(0);
49
+
50
+ private subjects = {
51
+ loadAllFavorites: new Subject<void>(),
52
+ deleteFavorite: new Subject<number>()
53
+ };
54
+
55
+ loadAllFavoritesService = toSignal(
56
+ this.subjects.loadAllFavorites.pipe(
57
+ switchMap(() =>
58
+ this.favoritePagesService.filterFavoritePages({
59
+ pageSize: 1000,
60
+ pageNumber: 1,
61
+ sortFieldName: 'label',
62
+ sortDirection: 1
63
+ })
64
+ )
65
+ )
66
+ );
67
+
68
+ deleteFavoriteService = toSignal(
69
+ this.subjects.deleteFavorite.pipe(switchMap((id) => this.favoritePagesService.deleteFavoritePage(id)))
70
+ );
71
+
72
+ constructor(
73
+ public layoutService: LayoutService,
74
+ private favoritePagesService: FavoritePagesService,
75
+ private confirmationService: ConfirmationService,
76
+ private messageService: MessageService,
77
+ private dialogService: DialogService,
78
+ private translocoService: TranslocoService
79
+ ) {
80
+ this.initializeEffects();
81
+ }
82
+
83
+ ngOnInit(): void {
84
+ this.loadFavoritePages();
85
+ this.checkCurrentPageStatus();
86
+ }
87
+
88
+ private initializeEffects(): void {
89
+ effect(
90
+ () => {
91
+ const service = this.loadAllFavoritesService();
92
+ if (service?.response) {
93
+ this.allFavoritePages.set(service.response.result);
94
+ this.totalItems.set(service.response.result.length);
95
+ this.updateClientSidePagination();
96
+ this.checkCurrentPageStatus();
97
+ }
98
+ },
99
+ { allowSignalWrites: true }
100
+ );
101
+
102
+ effect(
103
+ () => {
104
+ const service = this.deleteFavoriteService();
105
+ if (service?.response) {
106
+ this.loadFavoritePages();
107
+ this.messageService.add({
108
+ severity: 'success',
109
+ summary: this.translocoService.translate('favoritePages.success'),
110
+ detail: this.translocoService.translate('favoritePages.deletedSuccessfully'),
111
+ key: 'toast-root'
112
+ });
113
+ }
114
+ },
115
+ { allowSignalWrites: true }
116
+ );
117
+ }
118
+
119
+ get visible(): boolean {
120
+ return this.layoutService.state.favoritePagesSidebarVisible;
121
+ }
122
+
123
+ set visible(value: boolean) {
124
+ this.layoutService.state.favoritePagesSidebarVisible = value;
125
+ if (value) {
126
+ this.checkCurrentPageStatus();
127
+ }
128
+ }
129
+
130
+ private loadFavoritePages(): void {
131
+ this.subjects.loadAllFavorites.next();
132
+ }
133
+
134
+ private updateClientSidePagination(): void {
135
+ const allFavorites = this.allFavoritePages();
136
+ const totalItems = allFavorites.length;
137
+ const pageSize = this.pageSize();
138
+ const currentPage = this.currentPage();
139
+
140
+ const totalPages = Math.ceil(totalItems / pageSize);
141
+ this.totalPages.set(totalPages);
142
+
143
+ const startIndex = (currentPage - 1) * pageSize;
144
+ const endIndex = Math.min(startIndex + pageSize, totalItems);
145
+
146
+ const currentPageData = allFavorites.slice(startIndex, endIndex);
147
+ this.favoritePages.set(currentPageData);
148
+ }
149
+
150
+ private checkCurrentPageStatus(): void {
151
+ const currentPath = this.favoritePagesService.getCurrentRoutePath();
152
+ const allFavorites = this.allFavoritePages();
153
+ const isFound = allFavorites.some((fav) => fav.url === currentPath);
154
+
155
+ this.isCurrentPageFavorited.set(isFound);
156
+ }
157
+
158
+ addCurrentPageToFavorites(): void {
159
+ const currentPath = this.favoritePagesService.getCurrentRoutePath();
160
+
161
+ const ref = this.dialogService.open(AddEditFavoriteModalComponent, {
162
+ header: this.translocoService.translate('favoritePages.addToFavorites'),
163
+ width: '500px',
164
+ modal: true,
165
+ closable: true,
166
+ data: {
167
+ mode: 'add',
168
+ url: currentPath
169
+ }
170
+ });
171
+
172
+ ref.onClose.subscribe((result) => {
173
+ if (result?.status === 'success') {
174
+ this.loadFavoritePages();
175
+ }
176
+ });
177
+ }
178
+
179
+ removeCurrentPageFromFavorites(): void {
180
+ const currentPath = this.favoritePagesService.getCurrentRoutePath();
181
+ const favorites = this.favoritePages();
182
+ const currentFavorite = favorites.find((fav) => fav.url === currentPath);
183
+
184
+ if (currentFavorite) {
185
+ this.confirmationService.confirm({
186
+ message: this.translocoService.translate('favoritePages.confirmDelete'),
187
+ header: this.translocoService.translate('favoritePages.deleteConfirmTitle'),
188
+ icon: 'pi pi-info-circle',
189
+ acceptLabel: this.translocoService.translate('acceptButtonLabel'),
190
+ rejectLabel: this.translocoService.translate('rejectButtonLabel'),
191
+ acceptButtonStyleClass: 'p-button-success',
192
+ rejectButtonStyleClass: 'p-button-danger p-button-outlined',
193
+ accept: () => {
194
+ this.subjects.deleteFavorite.next(currentFavorite.id);
195
+ }
196
+ });
197
+ }
198
+ }
199
+
200
+ editFavorite(favorite: FavoritePageResponseDTO, event: Event): void {
201
+ event.stopPropagation();
202
+
203
+ const ref = this.dialogService.open(AddEditFavoriteModalComponent, {
204
+ header: this.translocoService.translate('favoritePages.editFavorite'),
205
+ width: '500px',
206
+ modal: true,
207
+ closable: true,
208
+ data: {
209
+ mode: 'edit',
210
+ favorite: favorite
211
+ }
212
+ });
213
+
214
+ ref.onClose.subscribe((result) => {
215
+ if (result?.status === 'success') {
216
+ this.loadFavoritePages();
217
+ }
218
+ });
219
+ }
220
+
221
+ deleteFavorite(favorite: FavoritePageResponseDTO, event: Event): void {
222
+ event.stopPropagation();
223
+
224
+ this.confirmationService.confirm({
225
+ target: event.target as EventTarget,
226
+ message: this.translocoService.translate('favoritePages.confirmDelete', { label: favorite.label }),
227
+ header: this.translocoService.translate('favoritePages.deleteConfirmTitle'),
228
+ icon: 'pi pi-info-circle',
229
+ acceptLabel: this.translocoService.translate('acceptButtonLabel'),
230
+ rejectLabel: this.translocoService.translate('rejectButtonLabel'),
231
+ acceptButtonStyleClass: 'p-button-success',
232
+ rejectButtonStyleClass: 'p-button-danger p-button-outlined',
233
+ accept: () => {
234
+ this.subjects.deleteFavorite.next(favorite.id);
235
+ }
236
+ });
237
+ }
238
+
239
+ navigateToFavorite(favorite: FavoritePageResponseDTO): void {
240
+ this.favoritePagesService.navigateToFavoritePage(favorite);
241
+ this.visible = false;
242
+ }
243
+
244
+ trackByFavoriteId(index: number, favorite: FavoritePageResponseDTO): number {
245
+ return favorite.id;
246
+ }
247
+
248
+ onPageChange(event: any): void {
249
+ this.currentPage.set(event.page + 1);
250
+ this.pageSize.set(event.rows);
251
+ this.updateClientSidePagination(); // Update pagination client-side, no API call
252
+ }
253
+ }
@@ -0,0 +1,54 @@
1
+ import { Router } from '@angular/router';
2
+ import { Observable } from 'rxjs';
3
+ import { RestClient, ServiceCallStateMap, ServiceResponse } from 'aril/http';
4
+ import * as i0 from "@angular/core";
5
+ export interface FavoritePageResponseDTO {
6
+ id: number;
7
+ creator: string;
8
+ created: number;
9
+ updater: string;
10
+ updated: number;
11
+ version: number;
12
+ username: string;
13
+ url: string;
14
+ label: string;
15
+ }
16
+ export interface FavoritePageSaveRequestDTO {
17
+ url: string;
18
+ label: string;
19
+ }
20
+ export interface FavoritePageUpdateRequestDTO {
21
+ label: string;
22
+ version: number;
23
+ }
24
+ export interface FavoritePageFilterRequestDTO {
25
+ pageSize?: number;
26
+ pageNumber?: number;
27
+ sortFieldName?: string;
28
+ sortDirection?: number;
29
+ }
30
+ export interface SearchResultDTO<T> {
31
+ resultInfo: {
32
+ totalPage: number;
33
+ totalItem: number;
34
+ };
35
+ result: T[];
36
+ searchAfterValues: any[];
37
+ }
38
+ export declare const favoritePageEndpoints: {
39
+ filter: string;
40
+ favorite: string;
41
+ };
42
+ export declare class FavoritePagesService extends RestClient {
43
+ private router;
44
+ states: ServiceCallStateMap<FavoritePagesService>;
45
+ constructor(router: Router);
46
+ getCurrentRoutePath(): string;
47
+ navigateToFavoritePage(favorite: FavoritePageResponseDTO): void;
48
+ filterFavoritePages(post: FavoritePageFilterRequestDTO): Observable<ServiceResponse<SearchResultDTO<FavoritePageResponseDTO>>>;
49
+ saveFavoritePage(post: FavoritePageSaveRequestDTO): Observable<ServiceResponse<FavoritePageResponseDTO>>;
50
+ updateFavoritePage(id: number, post: FavoritePageUpdateRequestDTO): Observable<ServiceResponse<FavoritePageResponseDTO>>;
51
+ deleteFavoritePage(id: number): Observable<ServiceResponse<boolean>>;
52
+ static ɵfac: i0.ɵɵFactoryDeclaration<FavoritePagesService, never>;
53
+ static ɵprov: i0.ɵɵInjectableDeclaration<FavoritePagesService>;
54
+ }
@@ -0,0 +1,87 @@
1
+ import { Injectable } from '@angular/core';
2
+ import { Router } from '@angular/router';
3
+
4
+ import { Observable } from 'rxjs';
5
+
6
+ import { HTTPMethods, ProxyTypes, RestClient, ServiceCall, ServiceCallStateMap, ServiceResponse } from 'aril/http';
7
+
8
+ export interface FavoritePageResponseDTO {
9
+ id: number;
10
+ creator: string;
11
+ created: number;
12
+ updater: string;
13
+ updated: number;
14
+ version: number;
15
+ username: string;
16
+ url: string;
17
+ label: string;
18
+ }
19
+
20
+ export interface FavoritePageSaveRequestDTO {
21
+ url: string;
22
+ label: string;
23
+ }
24
+
25
+ export interface FavoritePageUpdateRequestDTO {
26
+ label: string;
27
+ version: number;
28
+ }
29
+
30
+ export interface FavoritePageFilterRequestDTO {
31
+ pageSize?: number;
32
+ pageNumber?: number;
33
+ sortFieldName?: string;
34
+ sortDirection?: number; // 1=ASC, 2=DESC
35
+ }
36
+
37
+ export interface SearchResultDTO<T> {
38
+ resultInfo: {
39
+ totalPage: number;
40
+ totalItem: number;
41
+ };
42
+ result: T[];
43
+ searchAfterValues: any[];
44
+ }
45
+
46
+ // API Endpoints
47
+ export const favoritePageEndpoints = {
48
+ filter: 'favorite-pages/filter',
49
+ favorite: 'favorite-pages'
50
+ };
51
+
52
+ @Injectable({ providedIn: 'root' })
53
+ export class FavoritePagesService extends RestClient {
54
+ override states: ServiceCallStateMap<FavoritePagesService> = {};
55
+
56
+ constructor(private router: Router) {
57
+ super();
58
+ }
59
+
60
+ getCurrentRoutePath(): string {
61
+ return this.router.url;
62
+ }
63
+
64
+ navigateToFavoritePage(favorite: FavoritePageResponseDTO): void {
65
+ this.router.navigate([favorite.url]);
66
+ }
67
+
68
+ @ServiceCall(HTTPMethods.POST, ProxyTypes.ClientSide, favoritePageEndpoints.filter)
69
+ filterFavoritePages(post: FavoritePageFilterRequestDTO) {
70
+ return new Observable<ServiceResponse<SearchResultDTO<FavoritePageResponseDTO>>>();
71
+ }
72
+
73
+ @ServiceCall(HTTPMethods.POST, ProxyTypes.ClientSide, favoritePageEndpoints.favorite)
74
+ saveFavoritePage(post: FavoritePageSaveRequestDTO) {
75
+ return new Observable<ServiceResponse<FavoritePageResponseDTO>>();
76
+ }
77
+
78
+ @ServiceCall(HTTPMethods.PUT, ProxyTypes.ClientSide, favoritePageEndpoints.favorite)
79
+ updateFavoritePage(id: number, post: FavoritePageUpdateRequestDTO) {
80
+ return new Observable<ServiceResponse<FavoritePageResponseDTO>>();
81
+ }
82
+
83
+ @ServiceCall(HTTPMethods.DELETE, ProxyTypes.ClientSide, favoritePageEndpoints.favorite)
84
+ deleteFavoritePage(id: number) {
85
+ return new Observable<ServiceResponse<boolean>>();
86
+ }
87
+ }
@@ -0,0 +1,36 @@
1
+ import { OnInit } from '@angular/core';
2
+ import { FormBuilder, FormGroup } from '@angular/forms';
3
+ import { MessageService } from 'primeng/api';
4
+ import { DynamicDialogConfig, DynamicDialogRef } from 'primeng/dynamicdialog';
5
+ import { TranslocoService } from '@ngneat/transloco';
6
+ import { FavoritePageResponseDTO, FavoritePagesService } from '../../favorite-pages.service';
7
+ import * as i0 from "@angular/core";
8
+ interface ModalData {
9
+ mode: 'add' | 'edit';
10
+ url?: string;
11
+ favorite?: FavoritePageResponseDTO;
12
+ }
13
+ export declare class AddEditFavoriteModalComponent implements OnInit {
14
+ private readonly formBuilder;
15
+ private readonly dialogRef;
16
+ private readonly dialogConfig;
17
+ private readonly favoritePagesService;
18
+ private readonly messageService;
19
+ private readonly translocoService;
20
+ favoriteForm: FormGroup;
21
+ modalData: ModalData;
22
+ private subjects;
23
+ saveFavoriteService: import("@angular/core").Signal<import("../../../../../../../../dist/http").ServiceResponse<FavoritePageResponseDTO> | undefined>;
24
+ updateFavoriteService: import("@angular/core").Signal<import("../../../../../../../../dist/http").ServiceResponse<FavoritePageResponseDTO> | undefined>;
25
+ constructor(formBuilder: FormBuilder, dialogRef: DynamicDialogRef, dialogConfig: DynamicDialogConfig, favoritePagesService: FavoritePagesService, messageService: MessageService, translocoService: TranslocoService);
26
+ ngOnInit(): void;
27
+ private initializeEffects;
28
+ private initializeForm;
29
+ get isAddMode(): boolean;
30
+ get isEditMode(): boolean;
31
+ submit(): void;
32
+ cancel(): void;
33
+ static ɵfac: i0.ɵɵFactoryDeclaration<AddEditFavoriteModalComponent, never>;
34
+ static ɵcmp: i0.ɵɵComponentDeclaration<AddEditFavoriteModalComponent, "ng-component", never, {}, {}, never, never, true, never>;
35
+ }
36
+ export {};
@@ -0,0 +1,27 @@
1
+ <div *transloco="let t; read: 'favoritePages'">
2
+ <aril-form [formGroup]="favoriteForm">
3
+ <aril-field [label]="t('label')" [cols]="{ xl: 12, lg: 12, md: 12, sm: 12 }" [markAsRequired]="true">
4
+ <aril-text formControlName="label" [placeholder]="t('labelPlaceholder')"> </aril-text>
5
+ </aril-field>
6
+
7
+ <aril-field [label]="t('path')" [cols]="{ xl: 12, lg: 12, md: 12, sm: 12 }">
8
+ <aril-text formControlName="url"> </aril-text>
9
+ </aril-field>
10
+
11
+ <div class="col-12 flex justify-content-end mt-4 gap-2">
12
+ <aril-button
13
+ color="danger"
14
+ [label]="t('cancel')"
15
+ [outlined]="true"
16
+ icon="TIMES"
17
+ (clickEvent)="cancel()">
18
+ </aril-button>
19
+ <aril-form-submit
20
+ [label]="t('save')"
21
+ color="success"
22
+ icon="CHECK"
23
+ [formGroup]="favoriteForm"
24
+ (validEvent)="submit()" />
25
+ </div>
26
+ </aril-form>
27
+ </div>
@@ -0,0 +1,165 @@
1
+ import { CommonModule } from '@angular/common';
2
+ import { Component, OnInit, effect } from '@angular/core';
3
+ import { toSignal } from '@angular/core/rxjs-interop';
4
+ import { FormBuilder, FormGroup, FormsModule, ReactiveFormsModule, Validators } from '@angular/forms';
5
+
6
+ import { MessageService } from 'primeng/api';
7
+ import { DynamicDialogConfig, DynamicDialogRef } from 'primeng/dynamicdialog';
8
+
9
+ import { TranslocoModule, TranslocoService } from '@ngneat/transloco';
10
+ import { Subject, switchMap } from 'rxjs';
11
+
12
+ import { ButtonComponent } from 'aril/ui/button';
13
+ import { FieldComponent } from 'aril/ui/field';
14
+ import { ARiLFormModule } from 'aril/ui/form';
15
+ import { TextComponent } from 'aril/ui/text';
16
+
17
+ import {
18
+ FavoritePageResponseDTO,
19
+ FavoritePageSaveRequestDTO,
20
+ FavoritePageUpdateRequestDTO,
21
+ FavoritePagesService
22
+ } from '../../favorite-pages.service';
23
+
24
+ interface ModalData {
25
+ mode: 'add' | 'edit';
26
+ url?: string; // For add mode
27
+ favorite?: FavoritePageResponseDTO; // For edit mode
28
+ }
29
+
30
+ @Component({
31
+ standalone: true,
32
+ imports: [
33
+ CommonModule,
34
+ ReactiveFormsModule,
35
+ FormsModule,
36
+ ARiLFormModule,
37
+ FieldComponent,
38
+ TextComponent,
39
+ ButtonComponent,
40
+ TranslocoModule
41
+ ],
42
+ templateUrl: './add-edit-favorite-modal.component.html'
43
+ })
44
+ export class AddEditFavoriteModalComponent implements OnInit {
45
+ favoriteForm!: FormGroup;
46
+ modalData: ModalData;
47
+
48
+ private subjects = {
49
+ saveFavorite: new Subject<FavoritePageSaveRequestDTO>(),
50
+ updateFavorite: new Subject<FavoritePageUpdateRequestDTO>()
51
+ };
52
+
53
+ saveFavoriteService = toSignal(
54
+ this.subjects.saveFavorite.pipe(switchMap((data) => this.favoritePagesService.saveFavoritePage(data)))
55
+ );
56
+
57
+ updateFavoriteService = toSignal(
58
+ this.subjects.updateFavorite.pipe(
59
+ switchMap((data) => this.favoritePagesService.updateFavoritePage(this.modalData.favorite?.id as number, data))
60
+ )
61
+ );
62
+
63
+ constructor(
64
+ private readonly formBuilder: FormBuilder,
65
+ private readonly dialogRef: DynamicDialogRef,
66
+ private readonly dialogConfig: DynamicDialogConfig,
67
+ private readonly favoritePagesService: FavoritePagesService,
68
+ private readonly messageService: MessageService,
69
+ private readonly translocoService: TranslocoService
70
+ ) {
71
+ this.modalData = this.dialogConfig.data;
72
+ this.initializeEffects();
73
+ this.initializeForm();
74
+ }
75
+
76
+ ngOnInit(): void {
77
+ if (!this.modalData || !['add', 'edit'].includes(this.modalData.mode)) {
78
+ this.dialogRef.close('error');
79
+ }
80
+ }
81
+
82
+ private initializeEffects(): void {
83
+ // Save favorite effect
84
+ effect(
85
+ () => {
86
+ const service = this.saveFavoriteService();
87
+ if (service?.response) {
88
+ this.messageService.add({
89
+ severity: 'success',
90
+ summary: this.translocoService.translate('favoritePages.success'),
91
+ detail: this.translocoService.translate('favoritePages.saveSuccessfully'),
92
+ key: 'toast-root'
93
+ });
94
+ this.dialogRef.close({ status: 'success', data: service.response });
95
+ }
96
+ },
97
+ { allowSignalWrites: true }
98
+ );
99
+
100
+ // Update favorite effect
101
+ effect(
102
+ () => {
103
+ const service = this.updateFavoriteService();
104
+ if (service?.response) {
105
+ this.messageService.add({
106
+ severity: 'success',
107
+ summary: this.translocoService.translate('favoritePages.success'),
108
+ detail: this.translocoService.translate('favoritePages.updatedSuccessfully'),
109
+ key: 'toast-root'
110
+ });
111
+ this.dialogRef.close({ status: 'success', data: service.response });
112
+ }
113
+ },
114
+ { allowSignalWrites: true }
115
+ );
116
+ }
117
+
118
+ private initializeForm(): void {
119
+ if (this.modalData.mode === 'add') {
120
+ this.favoriteForm = this.formBuilder.group({
121
+ label: ['', [Validators.required, Validators.minLength(1), Validators.maxLength(100)]],
122
+ url: [{ value: this.modalData.url || '', disabled: true }]
123
+ });
124
+ } else if (this.modalData.mode === 'edit' && this.modalData.favorite) {
125
+ this.favoriteForm = this.formBuilder.group({
126
+ label: [
127
+ this.modalData.favorite.label,
128
+ [Validators.required, Validators.minLength(1), Validators.maxLength(100)]
129
+ ],
130
+ url: [{ value: this.modalData.favorite.url, disabled: true }]
131
+ });
132
+ }
133
+ }
134
+
135
+ get isAddMode(): boolean {
136
+ return this.modalData.mode === 'add';
137
+ }
138
+
139
+ get isEditMode(): boolean {
140
+ return this.modalData.mode === 'edit';
141
+ }
142
+
143
+ submit(): void {
144
+ const formValue = this.favoriteForm.value;
145
+
146
+ if (this.isAddMode) {
147
+ const saveRequest: FavoritePageSaveRequestDTO = {
148
+ url: this.modalData.url!,
149
+ label: formValue.label.trim()
150
+ };
151
+ this.subjects.saveFavorite.next(saveRequest);
152
+ } else if (this.isEditMode && this.modalData.favorite) {
153
+ const updateRequest: any = {
154
+ label: formValue.label.trim(),
155
+ url: this.modalData.url!,
156
+ version: this.modalData.favorite.version
157
+ };
158
+ this.subjects.updateFavorite.next(updateRequest);
159
+ }
160
+ }
161
+
162
+ cancel(): void {
163
+ this.dialogRef.close('cancel');
164
+ }
165
+ }
@@ -0,0 +1,30 @@
1
+ import { OnDestroy, OnInit } from '@angular/core';
2
+ import { ConfirmationService, MessageService } from 'primeng/api';
3
+ import { TranslocoService } from '@ngneat/transloco';
4
+ import { LayoutService } from '../../service/app.layout.service';
5
+ import { HistoryItem, HistoryService } from './history.service';
6
+ import * as i0 from "@angular/core";
7
+ export declare class HistorySidebarComponent implements OnInit, OnDestroy {
8
+ layoutService: LayoutService;
9
+ private historyService;
10
+ private confirmationService;
11
+ private messageService;
12
+ private translocoService;
13
+ history: import("@angular/core").WritableSignal<HistoryItem[]>;
14
+ filteredHistory: import("@angular/core").WritableSignal<HistoryItem[]>;
15
+ searchTerm: import("@angular/core").WritableSignal<string>;
16
+ private destroy$;
17
+ constructor(layoutService: LayoutService, historyService: HistoryService, confirmationService: ConfirmationService, messageService: MessageService, translocoService: TranslocoService);
18
+ ngOnInit(): void;
19
+ ngOnDestroy(): void;
20
+ get visible(): boolean;
21
+ set visible(value: boolean);
22
+ onSearchChange(): void;
23
+ private applyFilter;
24
+ navigateToItem(item: HistoryItem): void;
25
+ clearAllHistory(event: Event): void;
26
+ trackByItemId(index: number, item: HistoryItem): string | number;
27
+ getLocalizedTitle(item: HistoryItem): string;
28
+ static ɵfac: i0.ɵɵFactoryDeclaration<HistorySidebarComponent, never>;
29
+ static ɵcmp: i0.ɵɵComponentDeclaration<HistorySidebarComponent, "app-history-sidebar", never, {}, {}, never, never, true, never>;
30
+ }