@flusys/ng-shared 1.0.0-rc → 1.0.0

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.
@@ -1,6 +1,6 @@
1
- import * as _angular_core from '@angular/core';
2
- import { Signal, Injector, ResourceRef, model, ElementRef, InjectionToken, DestroyRef } from '@angular/core';
3
1
  import { Observable } from 'rxjs';
2
+ import * as _angular_core from '@angular/core';
3
+ import { Signal, Injector, ResourceRef, model, ElementRef, DestroyRef, InjectionToken } from '@angular/core';
4
4
  import * as i1 from '@angular/common';
5
5
  import * as i2 from '@angular/forms';
6
6
  import { ControlValueAccessor } from '@angular/forms';
@@ -46,10 +46,9 @@ import * as i36 from 'primeng/tooltip';
46
46
  import * as i37 from 'primeng/treetable';
47
47
  import * as _flusys_ng_shared from '@flusys/ng-shared';
48
48
  import { HttpClient, HttpParams, HttpHeaders } from '@angular/common/http';
49
- import * as _flusys_ng_core from '@flusys/ng-core';
50
- import { ApiLoaderService } from '@flusys/ng-core';
51
49
  import { FormValueControl } from '@angular/forms/signals';
52
50
  import { MessageService, ConfirmationService } from 'primeng/api';
51
+ import * as _flusys_ng_core from '@flusys/ng-core';
53
52
 
54
53
  /**
55
54
  * Centralized Permission Codes
@@ -232,43 +231,6 @@ declare const PERMISSIONS: {
232
231
  };
233
232
  type PermissionCode = (typeof PERMISSIONS)[keyof typeof PERMISSIONS][keyof (typeof PERMISSIONS)[keyof typeof PERMISSIONS]];
234
233
 
235
- /**
236
- * Auth State Provider Interface
237
- *
238
- * Abstracts auth state access for feature packages (form-builder, etc.)
239
- * that need to check authentication status without depending on ng-auth directly.
240
- *
241
- * @example
242
- * // In form-builder component
243
- * class PublicFormPageComponent {
244
- * private readonly authStateProvider = inject(AUTH_STATE_PROVIDER);
245
- *
246
- * ngOnInit() {
247
- * this.authStateProvider.initialize().subscribe({
248
- * next: () => this.checkFormAccess(),
249
- * error: () => this.checkFormAccess(),
250
- * });
251
- * }
252
- *
253
- * checkAccess() {
254
- * if (this.authStateProvider.isAuthenticated()) {
255
- * // User is logged in
256
- * }
257
- * }
258
- * }
259
- */
260
- interface IAuthStateProvider {
261
- /**
262
- * Signal indicating if user is currently authenticated
263
- */
264
- isAuthenticated: Signal<boolean>;
265
- /**
266
- * Initialize auth state (restore session from cookies/storage)
267
- * Call this before checking isAuthenticated for users returning after login
268
- */
269
- initialize(): Observable<void>;
270
- }
271
-
272
234
  /**
273
235
  * Base entity interface - matches backend Identity entity
274
236
  */
@@ -326,6 +288,61 @@ interface ILoggedUserInfo {
326
288
  companyLogoId?: string;
327
289
  branchLogoId?: string;
328
290
  }
291
+ /**
292
+ * Simple dropdown item for select components
293
+ */
294
+ interface IDropDown {
295
+ label: string;
296
+ value: string;
297
+ }
298
+ /**
299
+ * Delete operation types
300
+ * - 'delete': Soft delete (sets deletedAt timestamp)
301
+ * - 'restore': Restore soft-deleted item (clears deletedAt)
302
+ * - 'permanent': Permanently delete from database
303
+ */
304
+ type DeleteType = 'delete' | 'restore' | 'permanent';
305
+ /**
306
+ * Delete request payload - matches backend DeleteDto
307
+ */
308
+ interface IDeleteData {
309
+ /** Single ID or array of IDs to delete */
310
+ id: string | string[];
311
+ /** Type of delete operation */
312
+ type: DeleteType;
313
+ }
314
+ /** Action node - checks a single permission */
315
+ interface IActionNode {
316
+ type: 'action';
317
+ actionId: string;
318
+ }
319
+ /** Group node - combines children with AND/OR logic */
320
+ interface IGroupNode {
321
+ type: 'group';
322
+ operator: 'AND' | 'OR';
323
+ children: ILogicNode[];
324
+ }
325
+ /** Permission logic tree (discriminated union of action/group) */
326
+ type ILogicNode = IActionNode | IGroupNode;
327
+
328
+ interface IPagination {
329
+ pageSize: number;
330
+ currentPage: number;
331
+ }
332
+ interface ISort {
333
+ [key: string]: 'ASC' | 'DESC';
334
+ }
335
+ interface IFilter {
336
+ [key: string]: string | number | boolean | null | undefined | string[] | number[];
337
+ }
338
+ interface IFilterData {
339
+ filter?: IFilter;
340
+ pagination?: IPagination;
341
+ select?: string[];
342
+ sort?: ISort;
343
+ withDeleted?: boolean;
344
+ extraKey?: string[];
345
+ }
329
346
 
330
347
  /**
331
348
  * Request metadata added by backend ResponseMetaInterceptor
@@ -467,156 +484,6 @@ interface IFileData {
467
484
  createdAt: Date;
468
485
  }
469
486
 
470
- /**
471
- * Company basic info for dropdowns
472
- */
473
- interface ICompanyBasicInfo {
474
- id: string;
475
- name: string;
476
- slug?: string;
477
- }
478
- interface ICompanyApiProvider {
479
- /**
480
- * Get list of companies with pagination
481
- */
482
- getCompanies(filter?: {
483
- page?: number;
484
- pageSize?: number;
485
- search?: string;
486
- }): Observable<IListResponse<ICompanyBasicInfo>>;
487
- }
488
-
489
- /**
490
- * Delete operation types
491
- * - 'delete': Soft delete (sets deletedAt timestamp)
492
- * - 'restore': Restore soft-deleted item (clears deletedAt)
493
- * - 'permanent': Permanently delete from database
494
- */
495
- type DeleteType = 'delete' | 'restore' | 'permanent';
496
- /**
497
- * Delete request payload - matches backend DeleteDto
498
- */
499
- interface IDeleteData {
500
- /** Single ID or array of IDs to delete */
501
- id: string | string[];
502
- /** Type of delete operation */
503
- type: DeleteType;
504
- }
505
-
506
- interface IDropDown {
507
- label: string;
508
- value: string;
509
- }
510
-
511
- interface IPagination {
512
- pageSize: number;
513
- currentPage: number;
514
- }
515
- interface ISort {
516
- [key: string]: 'ASC' | 'DESC';
517
- }
518
- interface IFilter {
519
- [key: string]: string | number | boolean | null | undefined | string[] | number[];
520
- }
521
- interface IFilterData {
522
- filter?: IFilter;
523
- pagination?: IPagination;
524
- select?: string[];
525
- sort?: ISort;
526
- withDeleted?: boolean;
527
- extraKey?: string[];
528
- }
529
-
530
- /** Action node - checks a single permission */
531
- interface IActionNode {
532
- type: 'action';
533
- actionId: string;
534
- }
535
- /** Group node - combines children with AND/OR logic */
536
- interface IGroupNode {
537
- type: 'group';
538
- operator: 'AND' | 'OR';
539
- children: ILogicNode[];
540
- }
541
- /** Permission logic tree (discriminated union of action/group) */
542
- type ILogicNode = IActionNode | IGroupNode;
543
-
544
- /**
545
- * User Permission Provider Interface
546
- *
547
- * Abstracts user permission data access operations.
548
- * Implemented by auth package, used by IAM for user permission queries.
549
- *
550
- * @example
551
- * // In IAM component
552
- * class UserActionSelectorComponent {
553
- * private readonly userPermissionProvider = inject(USER_PERMISSION_PROVIDER);
554
- *
555
- * async loadUserBranches(userId: string) {
556
- * const response = await this.userPermissionProvider
557
- * .getUserBranchPermissions(userId, '')
558
- * .toPromise();
559
- * this.branches.set(response?.data ?? []);
560
- * }
561
- * }
562
- */
563
- interface IUserPermissionProvider {
564
- /**
565
- * Get user's branch permissions
566
- */
567
- getUserBranchPermissions(userId: string): Observable<ISingleResponse<any>>;
568
- }
569
-
570
- /**
571
- * User data for dropdowns and selectors
572
- */
573
- interface IUserBasicInfo {
574
- id: string;
575
- name: string;
576
- email: string;
577
- }
578
- /**
579
- * User Provider Interface
580
- *
581
- * Abstracts user data access for IAM and other feature packages.
582
- * Implemented by auth package, used by IAM for user selection in permission assignment.
583
- *
584
- * @example
585
- * // In IAM component
586
- * class UserActionSelectorComponent {
587
- * private readonly userProvider = inject(USER_PROVIDER);
588
- *
589
- * loadUsers() {
590
- * this.userProvider.getUsers({ page: 0, pageSize: 50 }).subscribe(users => {
591
- * this.users.set(users.data);
592
- * });
593
- * }
594
- * }
595
- */
596
- interface IUserProvider {
597
- /**
598
- * Get list of users with pagination
599
- * @param filter Optional filter (page, pageSize, search, etc.)
600
- */
601
- getUsers(filter?: {
602
- page?: number;
603
- pageSize?: number;
604
- search?: string;
605
- companyId?: string;
606
- branchId?: string;
607
- isActive?: boolean;
608
- }): Observable<IListResponse<IUserBasicInfo>>;
609
- }
610
-
611
- /** Filter params passed to loadUsers function */
612
- interface IUserSelectFilter {
613
- page: number;
614
- pageSize: number;
615
- search: string;
616
- }
617
- /** Function type for loading users */
618
- type LoadUsersFn = (filter: IUserSelectFilter) => Observable<IListResponse<IUserBasicInfo>>;
619
-
620
487
  /**
621
488
  * Basic file info for selectors and displays
622
489
  */
@@ -697,6 +564,79 @@ declare function getFileIconClass(contentType: string): string;
697
564
  */
698
565
  declare function formatFileSize(sizeInKb: string | number): string;
699
566
 
567
+ /**
568
+ * Auth State Provider Interface
569
+ *
570
+ * Abstracts auth state access for feature packages (form-builder, etc.)
571
+ * that need to check authentication status without depending on ng-auth directly.
572
+ */
573
+ interface IAuthStateProvider {
574
+ /** Signal indicating if user is currently authenticated */
575
+ isAuthenticated: Signal<boolean>;
576
+ /** Initialize auth state (restore session from cookies/storage) */
577
+ initialize(): Observable<void>;
578
+ }
579
+ /**
580
+ * User data for dropdowns and selectors
581
+ */
582
+ interface IUserBasicInfo {
583
+ id: string;
584
+ name: string;
585
+ email: string;
586
+ }
587
+ /**
588
+ * User Provider Interface - Abstracts user data access for IAM and other feature packages.
589
+ */
590
+ interface IUserProvider {
591
+ getUsers(filter?: {
592
+ page?: number;
593
+ pageSize?: number;
594
+ search?: string;
595
+ companyId?: string;
596
+ branchId?: string;
597
+ isActive?: boolean;
598
+ }): Observable<IListResponse<IUserBasicInfo>>;
599
+ }
600
+ /** Filter params passed to loadUsers function */
601
+ interface IUserSelectFilter {
602
+ page: number;
603
+ pageSize: number;
604
+ search: string;
605
+ }
606
+ /** Function type for loading users */
607
+ type LoadUsersFn = (filter: IUserSelectFilter) => Observable<IListResponse<IUserBasicInfo>>;
608
+ /**
609
+ * User branch permission data
610
+ */
611
+ interface IUserBranchPermission {
612
+ branchId: string;
613
+ branchName: string;
614
+ companyId: string;
615
+ }
616
+ /**
617
+ * User Permission Provider Interface - Abstracts user permission data access operations.
618
+ */
619
+ interface IUserPermissionProvider {
620
+ getUserBranchPermissions(userId: string): Observable<ISingleResponse<IUserBranchPermission[]>>;
621
+ }
622
+ /**
623
+ * Company basic info for dropdowns
624
+ */
625
+ interface ICompanyBasicInfo {
626
+ id: string;
627
+ name: string;
628
+ slug?: string;
629
+ }
630
+ /**
631
+ * Company API Provider Interface
632
+ */
633
+ interface ICompanyApiProvider {
634
+ getCompanies(filter?: {
635
+ page?: number;
636
+ pageSize?: number;
637
+ search?: string;
638
+ }): Observable<IListResponse<ICompanyBasicInfo>>;
639
+ }
700
640
  /**
701
641
  * User role info for profile display
702
642
  */
@@ -715,89 +655,39 @@ interface IProfileActionInfo {
715
655
  description?: string | null;
716
656
  }
717
657
  /**
718
- * Profile Permission Provider Interface
719
- *
720
- * Abstracts permission data access for profile page.
721
- * Implemented by ng-iam, consumed by ng-auth profile page.
722
- * Optional injection - if not provided, permissions section is hidden.
723
- *
724
- * @example
725
- * // In profile component
726
- * private readonly permissionProvider = inject(PROFILE_PERMISSION_PROVIDER, { optional: true });
727
- *
728
- * ngOnInit() {
729
- * if (this.permissionProvider) {
730
- * this.loadPermissions();
731
- * }
732
- * }
658
+ * Profile Permission Provider Interface - Abstracts permission data access for profile page.
733
659
  */
734
660
  interface IProfilePermissionProvider {
735
- /**
736
- * Get user's assigned roles
737
- * @param userId User ID
738
- * @param branchId Optional branch ID for branch-scoped roles
739
- */
740
661
  getUserRoles(userId: string, branchId?: string): Observable<ISingleResponse<IProfileRoleInfo[]>>;
741
- /**
742
- * Get user's direct actions
743
- * @param userId User ID
744
- * @param branchId Optional branch ID for branch-scoped actions
745
- */
746
662
  getUserActions(userId: string, branchId?: string): Observable<ISingleResponse<IProfileActionInfo[]>>;
747
663
  }
748
-
749
664
  /**
750
665
  * Uploaded file result with file manager ID
751
666
  */
752
667
  interface IProfileUploadResult {
753
- /** File manager ID (UUID) for storing in profilePictureId */
754
668
  id: string;
755
- /** Original file name */
756
669
  name: string;
757
- /** Storage key/path */
758
670
  key: string;
759
- /** File size in bytes */
760
671
  size: number;
761
- /** MIME type */
762
672
  contentType: string;
763
673
  }
764
674
  /**
765
675
  * Profile Upload Options
766
676
  */
767
677
  interface IProfileUploadOptions {
768
- /** Folder path for organizing uploads */
769
678
  folderPath?: string;
770
- /** Enable image compression */
771
679
  compress?: boolean;
772
- /** Max width for image compression */
773
680
  maxWidth?: number;
774
- /** Max height for image compression */
775
681
  maxHeight?: number;
776
682
  }
777
683
  /**
778
- * Profile Upload Provider Interface
779
- *
780
- * Provides file upload functionality for profile pictures.
781
- * Implemented by ng-storage, consumed by ng-auth profile page.
782
- *
783
- * This interface enables ng-auth to use storage functionality
784
- * without directly depending on ng-storage package.
684
+ * Profile Upload Provider Interface - Provides file upload functionality for profile pictures.
785
685
  */
786
686
  interface IProfileUploadProvider {
787
- /**
788
- * Upload profile picture and register in file manager
789
- * Returns file manager ID (UUID) for storing in user.profilePictureId
790
- *
791
- * @param file - File to upload
792
- * @param options - Upload options (compression, folder, etc.)
793
- * @returns Observable with upload result including file manager ID
794
- */
795
687
  uploadProfilePicture(file: File, options?: IProfileUploadOptions): Observable<ISingleResponse<IProfileUploadResult>>;
796
688
  }
797
-
798
689
  /**
799
690
  * Base user interface for list operations
800
- * Extends this with app-specific user fields
801
691
  */
802
692
  interface IUserListItem {
803
693
  id: string;
@@ -808,136 +698,53 @@ interface IUserListItem {
808
698
  }
809
699
  /**
810
700
  * User list action definition
811
- * @template T User type, defaults to IUserListItem
812
701
  */
813
702
  interface IUserListAction<T = IUserListItem> {
814
- /** Unique action identifier */
815
703
  id: string;
816
- /** Display label */
817
704
  label: string;
818
- /** PrimeNG icon class (e.g., 'pi pi-pencil') */
819
705
  icon?: string;
820
- /** Severity for styling (e.g., 'primary', 'danger', 'warning') */
821
706
  severity?: 'primary' | 'secondary' | 'success' | 'info' | 'warn' | 'danger' | 'help' | 'contrast';
822
- /** Permission code required (checked via hasPermission) */
823
707
  permission?: string;
824
- /** Tooltip text */
825
708
  tooltip?: string;
826
- /** Whether action is disabled */
827
709
  disabled?: boolean | ((user: T) => boolean);
828
- /** Whether action is visible */
829
710
  visible?: boolean | ((user: T) => boolean);
830
711
  }
831
712
  /**
832
713
  * Extra column definition for user list
833
714
  */
834
715
  interface IUserListColumn {
835
- /** Column field name */
836
716
  field: string;
837
- /** Column header label */
838
717
  header: string;
839
- /** Column width */
840
718
  width?: string;
841
- /** Whether column is sortable */
842
719
  sortable?: boolean;
843
- /** Whether column is filterable */
844
720
  filterable?: boolean;
845
- /** Custom template type for rendering */
846
721
  templateType?: 'text' | 'badge' | 'date' | 'boolean' | 'custom';
847
722
  }
848
- /**
849
- * User List Provider Interface
850
- *
851
- * Allows consuming applications to extend user list pages with:
852
- * - Extra columns
853
- * - Extra row actions
854
- * - Extra toolbar actions
855
- * - Custom data enrichment
856
- *
857
- * This follows the Provider Interface Pattern:
858
- * - ng-shared defines the interface (this file)
859
- * - Consuming apps (via ng-iam or app-specific) implement the interface
860
- * - ng-auth user list optionally injects and uses the implementation
861
- *
862
- * @template T User type, defaults to IUserListItem
863
- *
864
- * @example
865
- * // In app.config.ts
866
- * providers: [
867
- * { provide: USER_LIST_PROVIDER, useClass: MyUserListProvider },
868
- * ]
869
- *
870
- * // Implementation
871
- * @Injectable({ providedIn: 'root' })
872
- * export class MyUserListProvider implements IUserListProvider {
873
- * getExtraRowActions() {
874
- * return [
875
- * { id: 'assign-role', label: 'Assign Role', icon: 'pi pi-users' },
876
- * ];
877
- * }
878
- * }
879
- */
880
- interface IUserListProvider<T extends IUserListItem = IUserListItem> {
881
- /**
882
- * Get extra columns to display in user list
883
- * @returns Array of extra column definitions
884
- */
885
- getExtraColumns?(): IUserListColumn[];
886
- /**
887
- * Get extra row-level actions (per-user actions)
888
- * Displayed in actions column for each row
889
- * @returns Array of action definitions
890
- */
891
- getExtraRowActions?(): IUserListAction<T>[];
892
- /**
893
- * Get extra toolbar actions
894
- * Displayed in toolbar above the list
895
- * @returns Array of action definitions
896
- */
897
- getExtraToolbarActions?(): IUserListAction<T>[];
898
- /**
899
- * Handle row action click
900
- * @param actionId Action identifier
901
- * @param user User data from the row
902
- */
903
- onRowAction?(actionId: string, user: T): void;
904
- /**
905
- * Handle toolbar action click
906
- * @param actionId Action identifier
907
- * @param selectedUsers Currently selected users (for bulk actions)
908
- */
909
- onToolbarAction?(actionId: string, selectedUsers: T[]): void;
910
- /**
911
- * Enrich user list data with extra fields
912
- * Called after data is loaded from API
913
- * @param users List of users from API
914
- * @returns Observable of enriched users
915
- */
916
- enrichListData?(users: T[]): Observable<T[]>;
917
- /**
918
- * Get extra filters for user list
919
- * @returns Array of filter definitions
920
- */
921
- getExtraFilters?(): IUserListFilter[];
922
- }
923
723
  /**
924
724
  * Extra filter definition for user list
925
725
  */
926
726
  interface IUserListFilter {
927
- /** Filter field name */
928
727
  field: string;
929
- /** Filter label */
930
728
  label: string;
931
- /** Filter type */
932
729
  type: 'text' | 'dropdown' | 'multiselect' | 'date' | 'boolean';
933
- /** Options for dropdown/multiselect */
934
730
  options?: {
935
731
  label: string;
936
732
  value: string | number | boolean;
937
733
  }[];
938
- /** Placeholder text */
939
734
  placeholder?: string;
940
735
  }
736
+ /**
737
+ * User List Provider Interface - Allows apps to extend user list pages.
738
+ */
739
+ interface IUserListProvider<T extends IUserListItem = IUserListItem> {
740
+ getExtraColumns?(): IUserListColumn[];
741
+ getExtraRowActions?(): IUserListAction<T>[];
742
+ getExtraToolbarActions?(): IUserListAction<T>[];
743
+ onRowAction?(actionId: string, user: T): void;
744
+ onToolbarAction?(actionId: string, selectedUsers: T[]): void;
745
+ enrichListData?(users: T[]): Observable<T[]>;
746
+ getExtraFilters?(): IUserListFilter[];
747
+ }
941
748
 
942
749
  declare enum ContactTypeEnum {
943
750
  PHONE = 1,
@@ -959,15 +766,6 @@ declare class CookieService {
959
766
  static ɵprov: _angular_core.ɵɵInjectableDeclaration<CookieService>;
960
767
  }
961
768
 
962
- /**
963
- * Request DTO for fetching file URLs
964
- */
965
- interface GetFilesRequestDto {
966
- id: string;
967
- }
968
- /**
969
- * Response DTO with file information including URL
970
- */
971
769
  interface FilesResponseDto {
972
770
  id: string;
973
771
  name: string;
@@ -976,116 +774,47 @@ interface FilesResponseDto {
976
774
  }
977
775
  /**
978
776
  * Service to fetch file URLs from the backend.
979
- * Uses POST /file-manager/get-files endpoint which:
980
- * - Handles presigned URLs for cloud storage (AWS S3, Azure)
981
- * - Auto-refreshes expired URLs
982
- * - Validates file access permissions
983
- * - Works with all storage providers (Local, S3, Azure, SFTP)
777
+ * Handles presigned URLs for cloud storage, auto-refresh, and caching.
984
778
  */
985
779
  declare class FileUrlService {
986
780
  private readonly http;
987
781
  private readonly appConfig;
988
- /** Cache of file URLs by file ID */
989
- private readonly urlCache;
990
- /**
991
- * Get file URL by ID from cache (reactive signal)
992
- */
782
+ private readonly _cache;
783
+ readonly cache: Signal<Map<string, FilesResponseDto>>;
784
+ /** Get file URL by ID from cache (synchronous) */
993
785
  getFileUrl(fileId: string | null | undefined): string | null;
994
- /**
995
- * Get file URL signal (computed from cache)
996
- */
997
- fileUrlSignal(fileId: string | null | undefined): _angular_core.Signal<string | null>;
998
- /**
999
- * Fetch file URLs from backend and update cache.
1000
- * Skips IDs already in cache to prevent duplicate calls.
1001
- * Returns Observable of fetched files (including cached ones).
1002
- */
786
+ /** Get file URL as computed signal */
787
+ fileUrlSignal(fileId: string | null | undefined): Signal<string | null>;
788
+ /** Fetch file URLs from backend and update cache */
1003
789
  fetchFileUrls(fileIds: string[], forceRefresh?: boolean): Observable<FilesResponseDto[]>;
1004
- /**
1005
- * Fetch a single file URL.
1006
- * Uses cache if available to prevent duplicate calls.
1007
- * Returns Observable of file info or null if not found.
1008
- */
790
+ /** Fetch single file URL (delegates to fetchFileUrls) */
1009
791
  fetchSingleFileUrl(fileId: string, forceRefresh?: boolean): Observable<FilesResponseDto | null>;
1010
- /**
1011
- * Clear the URL cache.
1012
- * Useful on logout or when switching contexts.
1013
- */
792
+ /** Clear entire cache */
1014
793
  clearCache(): void;
1015
- /**
1016
- * Remove specific file from cache.
1017
- */
794
+ /** Remove specific file from cache */
1018
795
  removeFromCache(fileId: string): void;
796
+ private addToCache;
797
+ private getFromCache;
1019
798
  static ɵfac: _angular_core.ɵɵFactoryDeclaration<FileUrlService, never>;
1020
799
  static ɵprov: _angular_core.ɵɵInjectableDeclaration<FileUrlService>;
1021
800
  }
1022
801
 
1023
802
  /**
1024
- * Permission Validator Service
1025
- *
1026
- * Centralized service for permission validation across all packages.
1027
- * Provides signal-based state management and reactive permission checking.
1028
- *
1029
- * Features:
1030
- * - Signal-based permission storage
1031
- * - Individual permission checks
1032
- * - Permission change detection
1033
- * - Reactive permission state updates
1034
- *
1035
- * Usage:
1036
- * ```typescript
1037
- * // In component
1038
- * readonly permissionValidator = inject(PermissionValidatorService);
1039
- *
1040
- * // Set permissions (typically from auth/IAM)
1041
- * this.permissionValidator.setPermissions(['user.view', 'user.create']);
1042
- *
1043
- * // Or set wildcard for no-IAM mode
1044
- * this.permissionValidator.setPermissions(['*']);
1045
- *
1046
- * // Check individual permission
1047
- * if (this.permissionValidator.hasPermission('user.view')) {
1048
- * // Show UI element
1049
- * }
1050
- *
1051
- * // Access current permissions reactively
1052
- * const permissions = this.permissionValidator.permissions();
1053
- * ```
1054
- *
1055
- * @packageDocumentation
803
+ * Permission state management service.
804
+ * Provides signal-based storage and permission checking with wildcard support.
1056
805
  */
1057
806
  declare class PermissionValidatorService {
1058
- /**
1059
- * Private writable signal for permissions
1060
- */
1061
807
  private readonly _permissions;
1062
- /**
1063
- * Readonly permission signal for external consumers
1064
- */
1065
808
  readonly permissions: _angular_core.Signal<string[]>;
1066
- /**
1067
- * Private writable signal for loaded state
1068
- */
1069
809
  private readonly _isLoaded;
1070
- /**
1071
- * Set permissions (replaces existing permissions)
1072
- * @param permissions - Array of permission codes
1073
- */
810
+ readonly isLoaded: _angular_core.Signal<boolean>;
811
+ /** Set permissions (replaces existing) */
1074
812
  setPermissions(permissions: string[]): void;
1075
- /**
1076
- * Clear all permissions
1077
- */
813
+ /** Clear all permissions */
1078
814
  clearPermissions(): void;
1079
- /**
1080
- * Check if user has a specific permission
1081
- * @param permissionCode - Required permission code
1082
- * @returns True if user has permission
1083
- */
1084
- hasPermission(permissionCode: string): boolean;
1085
- /**
1086
- * Check if permissions are loaded
1087
- * @returns True if permissions have been loaded
1088
- */
815
+ /** Check if user has permission (supports wildcards: '*', 'module.*') */
816
+ hasPermission(code: string): boolean;
817
+ /** @deprecated Use `isLoaded()` signal instead */
1089
818
  isPermissionsLoaded(): boolean;
1090
819
  static ɵfac: _angular_core.ɵɵFactoryDeclaration<PermissionValidatorService, never>;
1091
820
  static ɵprov: _angular_core.ɵɵInjectableDeclaration<PermissionValidatorService>;
@@ -1286,7 +1015,6 @@ interface IApiService<DtoT, InterfaceT> {
1286
1015
  */
1287
1016
  declare abstract class ApiResourceService<DtoT, InterfaceT> implements IApiService<DtoT, InterfaceT> {
1288
1017
  protected readonly baseUrl: string;
1289
- protected readonly loaderService: ApiLoaderService;
1290
1018
  protected readonly injector: Injector;
1291
1019
  protected readonly http: HttpClient;
1292
1020
  protected readonly moduleApiName: string;
@@ -1602,6 +1330,45 @@ declare class LazySelectComponent extends BaseFormControl<string | null> {
1602
1330
  static ɵcmp: _angular_core.ɵɵComponentDeclaration<LazySelectComponent, "lib-lazy-select", never, { "placeHolder": { "alias": "placeHolder"; "required": false; "isSignal": true; }; "optionLabel": { "alias": "optionLabel"; "required": true; "isSignal": true; }; "optionValue": { "alias": "optionValue"; "required": true; "isSignal": true; }; "isEditMode": { "alias": "isEditMode"; "required": true; "isSignal": true; }; "isLoading": { "alias": "isLoading"; "required": true; "isSignal": true; }; "total": { "alias": "total"; "required": true; "isSignal": true; }; "pagination": { "alias": "pagination"; "required": true; "isSignal": true; }; "selectDataList": { "alias": "selectDataList"; "required": true; "isSignal": true; }; "value": { "alias": "value"; "required": false; "isSignal": true; }; }, { "value": "valueChange"; "onSearch": "onSearch"; "onPagination": "onPagination"; }, never, never, true, never>;
1603
1331
  }
1604
1332
 
1333
+ /**
1334
+ * Base class for user selection components.
1335
+ * Provides shared user loading, pagination, and search functionality.
1336
+ *
1337
+ * Subclasses must implement:
1338
+ * - `setupValueEffect()` to track value changes and emit selection events
1339
+ */
1340
+ declare abstract class BaseUserSelectComponent {
1341
+ protected readonly destroyRef: DestroyRef;
1342
+ protected readonly injector: Injector;
1343
+ protected readonly userProvider: IUserProvider;
1344
+ protected abortController: AbortController | null;
1345
+ readonly loadUsers: _angular_core.InputSignal<LoadUsersFn | undefined>;
1346
+ readonly placeHolder: _angular_core.InputSignal<string>;
1347
+ readonly isEditMode: _angular_core.InputSignal<boolean>;
1348
+ readonly filterActive: _angular_core.InputSignal<boolean>;
1349
+ readonly additionalFilters: _angular_core.InputSignal<Record<string, unknown>>;
1350
+ readonly pageSize: _angular_core.InputSignal<number>;
1351
+ readonly onError: _angular_core.OutputEmitterRef<Error>;
1352
+ readonly isLoading: _angular_core.WritableSignal<boolean>;
1353
+ readonly users: _angular_core.WritableSignal<IUserBasicInfo[]>;
1354
+ readonly total: _angular_core.WritableSignal<number | undefined>;
1355
+ readonly pagination: _angular_core.WritableSignal<IPagination>;
1356
+ readonly searchTerm: _angular_core.WritableSignal<string>;
1357
+ readonly dropdownUsers: _angular_core.Signal<IDropDown[]>;
1358
+ constructor();
1359
+ /** Setup effect to track value changes and emit selection events */
1360
+ protected abstract setupValueEffect(): void;
1361
+ handleSearch(search: string): void;
1362
+ handlePagination(pagination: IPagination): void;
1363
+ /** Reload users (useful when filters change externally) */
1364
+ reload(): void;
1365
+ protected fetchUsers(append?: boolean): Promise<void>;
1366
+ /** Load users from USER_PROVIDER with active filter */
1367
+ private loadUsersFromProvider;
1368
+ static ɵfac: _angular_core.ɵɵFactoryDeclaration<BaseUserSelectComponent, never>;
1369
+ static ɵdir: _angular_core.ɵɵDirectiveDeclaration<BaseUserSelectComponent, never, never, { "loadUsers": { "alias": "loadUsers"; "required": false; "isSignal": true; }; "placeHolder": { "alias": "placeHolder"; "required": false; "isSignal": true; }; "isEditMode": { "alias": "isEditMode"; "required": true; "isSignal": true; }; "filterActive": { "alias": "filterActive"; "required": false; "isSignal": true; }; "additionalFilters": { "alias": "additionalFilters"; "required": false; "isSignal": true; }; "pageSize": { "alias": "pageSize"; "required": false; "isSignal": true; }; }, { "onError": "onError"; }, never, never, true, never>;
1370
+ }
1371
+
1605
1372
  /**
1606
1373
  * User Select Component - Single user selection with lazy loading.
1607
1374
  *
@@ -1629,35 +1396,12 @@ declare class LazySelectComponent extends BaseFormControl<string | null> {
1629
1396
  * />
1630
1397
  * ```
1631
1398
  */
1632
- declare class UserSelectComponent {
1633
- private readonly destroyRef;
1634
- private readonly userProvider;
1635
- private abortController;
1636
- readonly loadUsers: _angular_core.InputSignal<LoadUsersFn | undefined>;
1637
- readonly placeHolder: _angular_core.InputSignal<string>;
1638
- readonly isEditMode: _angular_core.InputSignal<boolean>;
1639
- readonly filterActive: _angular_core.InputSignal<boolean>;
1640
- readonly additionalFilters: _angular_core.InputSignal<Record<string, unknown>>;
1641
- readonly pageSize: _angular_core.InputSignal<number>;
1399
+ declare class UserSelectComponent extends BaseUserSelectComponent {
1642
1400
  readonly value: _angular_core.ModelSignal<string | null>;
1643
1401
  readonly userSelected: _angular_core.OutputEmitterRef<IUserBasicInfo | null>;
1644
- readonly onError: _angular_core.OutputEmitterRef<Error>;
1645
- readonly isLoading: _angular_core.WritableSignal<boolean>;
1646
- readonly users: _angular_core.WritableSignal<IUserBasicInfo[]>;
1647
- readonly total: _angular_core.WritableSignal<number | undefined>;
1648
- readonly pagination: _angular_core.WritableSignal<IPagination>;
1649
- readonly searchTerm: _angular_core.WritableSignal<string>;
1650
- readonly dropdownUsers: _angular_core.Signal<IDropDown[]>;
1651
- constructor();
1652
- handleSearch(search: string): void;
1653
- handlePagination(pagination: IPagination): void;
1654
- private fetchUsers;
1655
- /** Load users from USER_PROVIDER with active filter */
1656
- private loadUsersFromProvider;
1657
- /** Reload users (useful when filters change externally) */
1658
- reload(): void;
1402
+ protected setupValueEffect(): void;
1659
1403
  static ɵfac: _angular_core.ɵɵFactoryDeclaration<UserSelectComponent, never>;
1660
- static ɵcmp: _angular_core.ɵɵComponentDeclaration<UserSelectComponent, "lib-user-select", never, { "loadUsers": { "alias": "loadUsers"; "required": false; "isSignal": true; }; "placeHolder": { "alias": "placeHolder"; "required": false; "isSignal": true; }; "isEditMode": { "alias": "isEditMode"; "required": true; "isSignal": true; }; "filterActive": { "alias": "filterActive"; "required": false; "isSignal": true; }; "additionalFilters": { "alias": "additionalFilters"; "required": false; "isSignal": true; }; "pageSize": { "alias": "pageSize"; "required": false; "isSignal": true; }; "value": { "alias": "value"; "required": false; "isSignal": true; }; }, { "value": "valueChange"; "userSelected": "userSelected"; "onError": "onError"; }, never, never, true, never>;
1404
+ static ɵcmp: _angular_core.ɵɵComponentDeclaration<UserSelectComponent, "lib-user-select", never, { "value": { "alias": "value"; "required": false; "isSignal": true; }; }, { "value": "valueChange"; "userSelected": "userSelected"; }, never, never, true, never>;
1661
1405
  }
1662
1406
 
1663
1407
  /**
@@ -1688,35 +1432,12 @@ declare class UserSelectComponent {
1688
1432
  * />
1689
1433
  * ```
1690
1434
  */
1691
- declare class UserMultiSelectComponent {
1692
- private readonly destroyRef;
1693
- private readonly userProvider;
1694
- private abortController;
1695
- readonly loadUsers: _angular_core.InputSignal<LoadUsersFn | undefined>;
1696
- readonly placeHolder: _angular_core.InputSignal<string>;
1697
- readonly isEditMode: _angular_core.InputSignal<boolean>;
1698
- readonly filterActive: _angular_core.InputSignal<boolean>;
1699
- readonly additionalFilters: _angular_core.InputSignal<Record<string, unknown>>;
1700
- readonly pageSize: _angular_core.InputSignal<number>;
1435
+ declare class UserMultiSelectComponent extends BaseUserSelectComponent {
1701
1436
  readonly value: _angular_core.ModelSignal<string[] | null>;
1702
1437
  readonly usersSelected: _angular_core.OutputEmitterRef<IUserBasicInfo[]>;
1703
- readonly onError: _angular_core.OutputEmitterRef<Error>;
1704
- readonly isLoading: _angular_core.WritableSignal<boolean>;
1705
- readonly users: _angular_core.WritableSignal<IUserBasicInfo[]>;
1706
- readonly total: _angular_core.WritableSignal<number | undefined>;
1707
- readonly pagination: _angular_core.WritableSignal<IPagination>;
1708
- readonly searchTerm: _angular_core.WritableSignal<string>;
1709
- readonly dropdownUsers: _angular_core.Signal<IDropDown[]>;
1710
- constructor();
1711
- handleSearch(search: string): void;
1712
- handlePagination(pagination: IPagination): void;
1713
- private fetchUsers;
1714
- /** Load users from USER_PROVIDER with active filter */
1715
- private loadUsersFromProvider;
1716
- /** Reload users (useful when filters change externally) */
1717
- reload(): void;
1438
+ protected setupValueEffect(): void;
1718
1439
  static ɵfac: _angular_core.ɵɵFactoryDeclaration<UserMultiSelectComponent, never>;
1719
- static ɵcmp: _angular_core.ɵɵComponentDeclaration<UserMultiSelectComponent, "lib-user-multi-select", never, { "loadUsers": { "alias": "loadUsers"; "required": false; "isSignal": true; }; "placeHolder": { "alias": "placeHolder"; "required": false; "isSignal": true; }; "isEditMode": { "alias": "isEditMode"; "required": true; "isSignal": true; }; "filterActive": { "alias": "filterActive"; "required": false; "isSignal": true; }; "additionalFilters": { "alias": "additionalFilters"; "required": false; "isSignal": true; }; "pageSize": { "alias": "pageSize"; "required": false; "isSignal": true; }; "value": { "alias": "value"; "required": false; "isSignal": true; }; }, { "value": "valueChange"; "usersSelected": "usersSelected"; "onError": "onError"; }, never, never, true, never>;
1440
+ static ɵcmp: _angular_core.ɵɵComponentDeclaration<UserMultiSelectComponent, "lib-user-multi-select", never, { "value": { "alias": "value"; "required": false; "isSignal": true; }; }, { "value": "valueChange"; "usersSelected": "usersSelected"; }, never, never, true, never>;
1720
1441
  }
1721
1442
 
1722
1443
  /**
@@ -1921,58 +1642,29 @@ declare const PROFILE_UPLOAD_PROVIDER: InjectionToken<IProfileUploadProvider>;
1921
1642
  declare const USER_LIST_PROVIDER: InjectionToken<IUserListProvider<IUserListItem>>;
1922
1643
 
1923
1644
  /**
1924
- * Permission Guard
1925
- *
1926
- * Route-level guard for permission-based access control.
1927
- * Validates permissions before allowing navigation.
1928
- *
1929
- * Features:
1930
- * - Single permission check
1931
- * - Complex ILogicNode logic trees
1932
- * - Configurable redirect URL
1933
- * - Debug logging for denied access
1645
+ * Permission Guard - Single permission or ILogicNode check.
1934
1646
  *
1935
1647
  * @example
1936
1648
  * ```typescript
1937
- * // Simple permission check
1938
1649
  * { path: 'users', canActivate: [permissionGuard('user.view')] }
1939
- *
1940
- * // Complex logic
1941
- * { path: 'admin', canActivate: [permissionGuard({
1942
- * id: 'root',
1943
- * type: 'group',
1944
- * operator: 'AND',
1945
- * children: [
1946
- * { id: '1', type: 'action', actionId: 'admin.view' },
1947
- * { id: '2', type: 'action', actionId: 'admin.manage' }
1948
- * ]
1949
- * })] }
1950
- *
1951
- * // With custom redirect
1952
- * { path: 'users', canActivate: [permissionGuard('user.view', '/access-denied')] }
1650
+ * { path: 'admin', canActivate: [permissionGuard(logicNode, '/access-denied')] }
1953
1651
  * ```
1954
1652
  */
1955
1653
  declare function permissionGuard(permission: string | ILogicNode, redirectTo?: string): CanActivateFn;
1956
1654
  /**
1957
- * Any Permission Guard (OR logic)
1958
- *
1959
- * Allows access if user has ANY of the specified permissions.
1655
+ * Any Permission Guard (OR logic) - Access if user has ANY permission.
1960
1656
  *
1961
1657
  * @example
1962
1658
  * ```typescript
1963
- * // Allow if user has view OR create permission
1964
1659
  * { path: 'users', canActivate: [anyPermissionGuard(['user.view', 'user.create'])] }
1965
1660
  * ```
1966
1661
  */
1967
1662
  declare function anyPermissionGuard(permissions: string[], redirectTo?: string): CanActivateFn;
1968
1663
  /**
1969
- * All Permissions Guard (AND logic)
1970
- *
1971
- * Allows access only if user has ALL of the specified permissions.
1664
+ * All Permissions Guard (AND logic) - Access only if user has ALL permissions.
1972
1665
  *
1973
1666
  * @example
1974
1667
  * ```typescript
1975
- * // Allow only if user has BOTH view AND create permissions
1976
1668
  * { path: 'admin', canActivate: [allPermissionsGuard(['admin.view', 'admin.manage'])] }
1977
1669
  * ```
1978
1670
  */
@@ -2293,5 +1985,38 @@ declare function hasAnyPermission(permissionCodes: string[], permissions: string
2293
1985
  /** Check if user has ALL of the specified permissions (AND logic) */
2294
1986
  declare function hasAllPermissions(permissionCodes: string[], permissions: string[]): boolean;
2295
1987
 
2296
- export { ACTION_PERMISSIONS, AUTH_STATE_PROVIDER, AngularModule, ApiResourceService, ApiResourceService as ApiService, BRANCH_PERMISSIONS, BaseFormControl, BaseFormPage, BaseListPage, COMPANY_ACTION_PERMISSIONS, COMPANY_API_PROVIDER, COMPANY_PERMISSIONS, ContactTypeEnum, CookieService, EMAIL_CONFIG_PERMISSIONS, EMAIL_TEMPLATE_PERMISSIONS, EditModeElementChangerDirective, FILE_PERMISSIONS, FILE_TYPE_FILTERS, FOLDER_PERMISSIONS, FORM_PERMISSIONS, FileSelectorDialogComponent, FileUploaderComponent, FileUrlService, HasPermissionDirective, IconComponent, IconTypeEnum, IsEmptyImageDirective, LazyMultiSelectComponent, LazySelectComponent, PERMISSIONS, PROFILE_PERMISSION_PROVIDER, PROFILE_UPLOAD_PROVIDER, PermissionValidatorService, PlatformService, PreventDefaultDirective, PrimeModule, ROLE_ACTION_PERMISSIONS, ROLE_PERMISSIONS, STORAGE_CONFIG_PERMISSIONS, USER_ACTION_PERMISSIONS, USER_LIST_PROVIDER, USER_PERMISSIONS, USER_PERMISSION_PROVIDER, USER_PROVIDER, USER_ROLE_PERMISSIONS, UserMultiSelectComponent, UserSelectComponent, allPermissionsGuard, anyPermissionGuard, evaluateLogicNode, evaluatePermission, formatFileSize, getAcceptString, getFileIconClass, hasAllPermissions, hasAnyPermission, hasPermission, isFileTypeAllowed, permissionGuard, provideValueAccessor };
2297
- export type { ApiResponse, DeleteType, FilesResponseDto, GetFileUrlsFn, GetFilesRequestDto, IActionNode, IActivatable, IApiService, IAuthStateProvider, IBaseEntity, IBulkMeta, IBulkResponse, ICompanyApiProvider, ICompanyBasicInfo, IDeleteData, IDropDown, IErrorResponse, IFileBasicInfo, IFileData, IFileSelectFilter, IFileUploadOptions, IFilter, IFilterData, IGroupNode, IListResponse, ILoggedUserInfo, ILogicNode, ILoginResponse, ILoginUserData, IMessageResponse, IMetadata, IOrderable, IPagination, IPaginationMeta, IProfileActionInfo, IProfilePermissionProvider, IProfileRoleInfo, IProfileUploadOptions, IProfileUploadProvider, IProfileUploadResult, IRefreshTokenResponse, IRequestMeta, ISingleResponse, ISoftDeletable, ISort, ITimestampable, IUploadedFile, IUserBasicInfo, IUserBranchPayload, IUserCompanyPayload, IUserListAction, IUserListColumn, IUserListFilter, IUserListItem, IUserListProvider, IUserPermissionProvider, IUserProvider, IUserSelectFilter, IValidationError, LoadFilesFn, LoadUsersFn, PermissionCode, UploadFileFn };
1988
+ /**
1989
+ * Configuration for scroll pagination behavior
1990
+ */
1991
+ interface ScrollPaginationConfig {
1992
+ /** Distance from bottom to trigger pagination (default: 50px) */
1993
+ threshold?: number;
1994
+ /** Current pagination state */
1995
+ pagination: IPagination;
1996
+ /** Total items available */
1997
+ total: number | undefined;
1998
+ /** Whether currently loading */
1999
+ isLoading: boolean;
2000
+ }
2001
+ /**
2002
+ * Check if scroll has reached near bottom and calculate next page if available.
2003
+ * Returns next pagination if should load more, null otherwise.
2004
+ *
2005
+ * @example
2006
+ * ```typescript
2007
+ * onScroll(event: Event): void {
2008
+ * const nextPagination = checkScrollPagination(event, {
2009
+ * pagination: this.pagination(),
2010
+ * total: this.total(),
2011
+ * isLoading: this.isLoading(),
2012
+ * });
2013
+ * if (nextPagination) {
2014
+ * this.onPagination.emit(nextPagination);
2015
+ * }
2016
+ * }
2017
+ * ```
2018
+ */
2019
+ declare function checkScrollPagination(event: Event, config: ScrollPaginationConfig): IPagination | null;
2020
+
2021
+ export { ACTION_PERMISSIONS, AUTH_STATE_PROVIDER, AngularModule, ApiResourceService, ApiResourceService as ApiService, BRANCH_PERMISSIONS, BaseFormControl, BaseFormPage, BaseListPage, BaseUserSelectComponent, COMPANY_ACTION_PERMISSIONS, COMPANY_API_PROVIDER, COMPANY_PERMISSIONS, ContactTypeEnum, CookieService, EMAIL_CONFIG_PERMISSIONS, EMAIL_TEMPLATE_PERMISSIONS, EditModeElementChangerDirective, FILE_PERMISSIONS, FILE_TYPE_FILTERS, FOLDER_PERMISSIONS, FORM_PERMISSIONS, FileSelectorDialogComponent, FileUploaderComponent, FileUrlService, HasPermissionDirective, IconComponent, IconTypeEnum, IsEmptyImageDirective, LazyMultiSelectComponent, LazySelectComponent, PERMISSIONS, PROFILE_PERMISSION_PROVIDER, PROFILE_UPLOAD_PROVIDER, PermissionValidatorService, PlatformService, PreventDefaultDirective, PrimeModule, ROLE_ACTION_PERMISSIONS, ROLE_PERMISSIONS, STORAGE_CONFIG_PERMISSIONS, USER_ACTION_PERMISSIONS, USER_LIST_PROVIDER, USER_PERMISSIONS, USER_PERMISSION_PROVIDER, USER_PROVIDER, USER_ROLE_PERMISSIONS, UserMultiSelectComponent, UserSelectComponent, allPermissionsGuard, anyPermissionGuard, checkScrollPagination, evaluateLogicNode, evaluatePermission, formatFileSize, getAcceptString, getFileIconClass, hasAllPermissions, hasAnyPermission, hasPermission, isFileTypeAllowed, permissionGuard, provideValueAccessor };
2022
+ export type { ApiResponse, DeleteType, FilesResponseDto, GetFileUrlsFn, IActionNode, IActivatable, IApiService, IAuthStateProvider, IBaseEntity, IBulkMeta, IBulkResponse, ICompanyApiProvider, ICompanyBasicInfo, IDeleteData, IDropDown, IErrorResponse, IFileBasicInfo, IFileData, IFileSelectFilter, IFileUploadOptions, IFilter, IFilterData, IGroupNode, IListResponse, ILoggedUserInfo, ILogicNode, ILoginResponse, ILoginUserData, IMessageResponse, IMetadata, IOrderable, IPagination, IPaginationMeta, IProfileActionInfo, IProfilePermissionProvider, IProfileRoleInfo, IProfileUploadOptions, IProfileUploadProvider, IProfileUploadResult, IRefreshTokenResponse, IRequestMeta, ISingleResponse, ISoftDeletable, ISort, ITimestampable, IUploadedFile, IUserBasicInfo, IUserBranchPayload, IUserBranchPermission, IUserCompanyPayload, IUserListAction, IUserListColumn, IUserListFilter, IUserListItem, IUserListProvider, IUserPermissionProvider, IUserProvider, IUserSelectFilter, IValidationError, LoadFilesFn, LoadUsersFn, PermissionCode, ScrollPaginationConfig, UploadFileFn };