@kuzntsv/uikit 1.0.40 → 1.0.43

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.
package/package.json CHANGED
@@ -1,9 +1,10 @@
1
1
  {
2
2
  "name": "@kuzntsv/uikit",
3
- "version": "1.0.40",
3
+ "version": "1.0.43",
4
4
  "peerDependencies": {
5
5
  "@angular/common": "^22.2.2",
6
- "@angular/core": "^22.2.2"
6
+ "@angular/core": "^22.2.2",
7
+ "zod": "^4.6.7"
7
8
  },
8
9
  "dependencies": {
9
10
  "tslib": "^2.8.1"
@@ -1,17 +1,19 @@
1
1
  import * as i0 from "@angular/core";
2
- import { AfterViewInit, ElementRef, EnvironmentProviders, InjectionToken, OnDestroy, OnInit, PipeTransform } from "@angular/core";
2
+ import { AfterViewInit, ElementRef, EnvironmentProviders, InjectionToken, OnDestroy, OnInit, PipeTransform, WritableSignal } from "@angular/core";
3
3
  import { NotificationService, RoleService } from "@kuzntsv/uikit";
4
+ import { HttpClient, HttpContext, HttpParams, HttpResourceRef } from "@angular/common/http";
4
5
  import { Observable, Subject, Subscription } from "rxjs";
5
6
  import { SelectionModel } from "@angular/cdk/collections";
6
7
  import { MatMenuTrigger } from "@angular/material/menu";
7
8
  import { MatPaginator } from "@angular/material/paginator";
8
9
  import { MatSort } from "@angular/material/sort";
9
10
  import { MatTableDataSource } from "@angular/material/table";
11
+ import z, { z as z$1 } from "zod";
10
12
  import { FormControl, FormGroup } from "@angular/forms";
11
13
  import { MatDialog, MatDialogRef } from "@angular/material/dialog";
12
14
  import { SafeUrl } from "@angular/platform-browser";
13
15
  import { CanActivateFn, Router } from "@angular/router";
14
- import { HttpClient, HttpContext, HttpParams } from "@angular/common/http";
16
+ import { FieldTree } from "@angular/forms/signals";
15
17
  import { MatAutocompleteSelectedEvent } from "@angular/material/autocomplete";
16
18
  import { NativeDateAdapter } from "@angular/material/core";
17
19
  interface Authenticate {
@@ -48,9 +50,13 @@ export type ObjectKeys<T extends string | number | symbol = string, K = any> = {
48
50
  export type fnType<T> = ((data: T, extraData?: any) => void) | undefined;
49
51
  export type fnCbType<T> = ((callback: () => void, data: T, extraData?: any) => void) | undefined;
50
52
  export type SortDirection = 'asc' | 'desc' | '';
53
+ /** @deprecated */
51
54
  export type fnGetDataType<T> = () => Observable<T[]>;
55
+ /** @deprecated */
52
56
  export type fnGetCountType<T> = () => Observable<number>;
53
- export type fnMapEntityType<T> = () => ((item: T) => T);
57
+ export type fnGetDataResType<T> = () => HttpResourceRef<T[]>;
58
+ export type fnGetCountResType<T> = () => HttpResourceRef<number>;
59
+ export type fnMapEntityType<T> = () => (item: T) => T;
54
60
  export interface ISortState {
55
61
  sortActive: string;
56
62
  sortDirection: SortDirection;
@@ -531,12 +537,20 @@ export declare class BaseToolbarComponent {
531
537
  "clickedClearBtn": "clickedClearBtn";
532
538
  }, never, never, true, never>;
533
539
  }
540
+ export declare const BaseSchema: z$1.ZodObject<{
541
+ id: z$1.ZodNumber;
542
+ }, z$1.core.$strip>;
543
+ export type BaseSchemaClass = z$1.infer<typeof BaseSchema>;
544
+ /** @deprecated */
534
545
  export interface BaseClass {
535
546
  id: number;
536
547
  }
548
+ /** Объект передаваемый в диалог формы редактирования, оперирует доменной моделью. */
537
549
  export interface IEditDialogData<T, K = any> {
538
550
  action: Action;
551
+ /** Здесь всегда доменная модель */
539
552
  entity: T;
553
+ /** Дополнительные данные, например, фото. */
540
554
  extraData?: K;
541
555
  }
542
556
  export declare enum Action {
@@ -841,6 +855,260 @@ export declare abstract class BaseServiceClass<T extends BaseClass> {
841
855
  static ɵfac: i0.ɵɵFactoryDeclaration<BaseServiceClass<any>, never>;
842
856
  static ɵprov: i0.ɵɵInjectableDeclaration<any>;
843
857
  }
858
+ export declare abstract class BaseSignalEditClass<TDomain extends Record<string, any>, TForm extends Record<string, any> = TDomain> implements OnDestroy {
859
+ /** Заголовок. */
860
+ abstract title: string;
861
+ /** Данные диалога. */
862
+ protected abstract dialogData: WritableSignal<IEditDialogData<TDomain>>;
863
+ protected formAction: import("@angular/core").Signal<Action>;
864
+ protected formActionIsAdd: import("@angular/core").Signal<boolean>;
865
+ protected formActionIsEdit: import("@angular/core").Signal<boolean>;
866
+ protected domainModel: import("@angular/core").Signal<TDomain>;
867
+ protected formModel: WritableSignal<TForm>;
868
+ /** Форма. */
869
+ protected abstract form: FieldTree<TForm>;
870
+ /** Ссылка на диалог. */
871
+ protected abstract dialogRef?: MatDialogRef<any, IEditDialogData<TDomain> | null>;
872
+ /** Сервис индикатор загрузки. */
873
+ protected loaderService: LoaderService;
874
+ /** Сервис уведомлений. */
875
+ protected notificationService: NotificationService;
876
+ /** Объект для отписки (вызывается метод unsubscribe при уничтожении компонента).
877
+ * @deprecated
878
+ */
879
+ protected subscription: Subscription;
880
+ /**
881
+ * Маппинг: Домен -> Форма.
882
+ * Реализация по умолчанию делает поверхностную копию. Наследник может её переопределить.
883
+ */
884
+ protected domainModelToFormModel(domainModel: TDomain): TForm;
885
+ /**
886
+ * Маппинг: Форма -> Домен.
887
+ * Реализация по умолчанию объединяет старый домен и новые поля формы.
888
+ */
889
+ protected formModelToDomainModel(formModel: TForm, originalDomain?: TDomain): TDomain;
890
+ ngOnDestroy(): void;
891
+ onNoClick(event: MouseEvent): void;
892
+ onSubmit(): void;
893
+ static ɵfac: i0.ɵɵFactoryDeclaration<BaseSignalEditClass<any, any>, never>;
894
+ static ɵdir: i0.ɵɵDirectiveDeclaration<BaseSignalEditClass<any, any>, never, never, {}, {}, never, never, true, never>;
895
+ }
896
+ type FilterValue = string | number | boolean | readonly string[] | readonly number[] | null | undefined;
897
+ type SafeFilterState = Readonly<Record<string, FilterValue>>;
898
+ type CleanFilterValue = Exclude<FilterValue, null | undefined>;
899
+ type CleanFilterState = Readonly<Record<string, CleanFilterValue>>;
900
+ declare function cleanFilterParams(filters: SafeFilterState): CleanFilterState;
901
+ export declare class BaseSignalFilterClass implements OnDestroy {
902
+ /** Сервис индикатор загрузки. */
903
+ protected loaderService: LoaderService;
904
+ /** Сервис уведомлений. */
905
+ protected notificationService: NotificationService;
906
+ /** Время на успокоение значения фильтра. */
907
+ defaultDebounceTime: number;
908
+ /**
909
+ * writable-сигнал, Принимаем текущее реактивное состояние фильтров с родительской страницы.
910
+ * Родитель передает значение через [(filters)]="pageFilters()".
911
+ * При любом изменении полей ввода обновляйте сигнал целиком через метод update.
912
+ *
913
+ * @example
914
+ * updateCategory(newCategory: string) {
915
+ * this.filters.update(prev => ({ ...prev, category: newCategory }));
916
+ * }
917
+ */
918
+ initialValues: import("@angular/core").InputSignal<Readonly<Record<string, FilterValue>>>;
919
+ /** Входной сигнал для сброса состояния формы. */
920
+ clearFilter: import("@angular/core").InputSignal<any>;
921
+ filterChange: import("@angular/core").OutputEmitterRef<Readonly<Record<string, FilterValue>>>;
922
+ filter: import("@angular/core").WritableSignal<Readonly<Record<string, FilterValue>>>;
923
+ /**
924
+ * Объект для отписки от внутренних подписок (например, valueChanges у FormControl).
925
+ * Метод unsubscribe вызывается при уничтожении компонента.
926
+ */
927
+ subscription: Subscription;
928
+ ngOnDestroy(): void;
929
+ static ɵfac: i0.ɵɵFactoryDeclaration<BaseSignalFilterClass, never>;
930
+ static ɵdir: i0.ɵɵDirectiveDeclaration<BaseSignalFilterClass, never, never, {
931
+ "initialValues": {
932
+ "alias": "initialValues";
933
+ "required": false;
934
+ "isSignal": true;
935
+ };
936
+ "clearFilter": {
937
+ "alias": "clearFilter";
938
+ "required": false;
939
+ "isSignal": true;
940
+ };
941
+ }, {
942
+ "filterChange": "filterChange";
943
+ }, never, never, true, never>;
944
+ }
945
+ export declare class BaseSignalPageClass<T> implements OnDestroy {
946
+ protected dialog: MatDialog;
947
+ entityService: any;
948
+ entityType: any;
949
+ entityEditComponent: any;
950
+ extraData?: any;
951
+ defaultPageIndex: number;
952
+ defaultPageSize: number;
953
+ dialogEditWidth: string;
954
+ dialogRemoveWidth: string;
955
+ routeAddress: string;
956
+ /** Сообщение при удалении записи(й). */
957
+ removalMessage: string;
958
+ /** Заголовок страницы. */
959
+ pageTitle: string;
960
+ /**
961
+ * Создание записи: вызывается перед открытием диалога.
962
+ */
963
+ beforeOpenDialogOnNewEvent: fnType<T>;
964
+ /**
965
+ * Редактирование записи: вызывается перед открытием диалога.
966
+ */
967
+ beforeOpenDialogOnEditEvent: fnType<T>;
968
+ /**
969
+ * Создание записи: вызывается перед сохранением объекта.
970
+ */
971
+ beforeSaveOnNewEvent: fnType<T>;
972
+ /**
973
+ * Редактирование записи: вызывается перед сохранением объекта.
974
+ */
975
+ beforeSaveOnEditEvent: fnType<T>;
976
+ /**
977
+ * Создание записи: вызывается после сохранения объекта.
978
+ */
979
+ afterSaveOnNewEvent: fnCbType<T>;
980
+ /**
981
+ * Редактирование записи: вызывается после сохранения объекта.
982
+ */
983
+ afterSaveOnEditEvent: fnCbType<T>;
984
+ editorRoles: string[];
985
+ executeRoles: string[];
986
+ /** Список ролей, для которых скрыть элемент. */
987
+ hideRoles: string[];
988
+ /** Загрузка данных. */
989
+ /** Загрузка количества записей. */
990
+ /** Очистка фильтра. (для очистки присвоить пустой объект '{}'). */
991
+ clearFilters: import("@angular/core").WritableSignal<any>;
992
+ /** Разрешен выбор нескольких строк. */
993
+ allowMultiSelect: boolean;
994
+ /** Выбранные строки в таблице. */
995
+ selected: T[];
996
+ protected fnGetData: import("@angular/core").WritableSignal<fnGetDataResType<T> | null>;
997
+ protected fnGetCount: import("@angular/core").WritableSignal<fnGetCountResType<T> | null>;
998
+ protected fnMapEntity: import("@angular/core").WritableSignal<fnMapEntityType<T> | undefined>;
999
+ protected dataResource: import("@angular/core").Signal<import("@angular/common/http").HttpResourceRef<T[]> | null>;
1000
+ protected countResource: import("@angular/core").Signal<import("@angular/common/http").HttpResourceRef<number> | null>;
1001
+ /** Данные для табличного компонента. */
1002
+ data: import("@angular/core").Signal<T[]>;
1003
+ /** Количество записей по фильтру. */
1004
+ length: import("@angular/core").Signal<number>;
1005
+ /** Глобальный индикатор загрузки (для спиннера на странице) */
1006
+ isLoading: import("@angular/core").Signal<boolean>;
1007
+ /** Доступность кнопки "Изменить". */
1008
+ editBtnDisabled: boolean;
1009
+ /** Доступность кнопки "Удалить". */
1010
+ removeBtnDisabled: boolean;
1011
+ /** Разрешено ли отправлять событие rowDoubleClicked при двойном щелчке мышью. */
1012
+ dblClickedEventEnable: boolean;
1013
+ opt: IContextMenuOptions<T>[];
1014
+ protected router: Router;
1015
+ /** Сервис для работы с LocalStorage. */
1016
+ protected localStorageService: LocalStorageService;
1017
+ /** Сервис индикатор загрузки. */
1018
+ protected loaderService: LoaderService;
1019
+ /** Сервис уведомлений. */
1020
+ protected notificationService: import("@kuzntsv/uikit").INotificationService;
1021
+ /** Объект для отписки (вызывается метод unsubscribe при уничтожении компонента). */
1022
+ subscription: Subscription;
1023
+ private getInitialFilters;
1024
+ private getInitialFilters2;
1025
+ filters: import("@angular/core").WritableSignal<Readonly<Record<string, FilterValue>>>;
1026
+ filters2: import("@angular/core").WritableSignal<Record<string, any>>;
1027
+ /** Состояние сортировки, пагинации. */
1028
+ tableState: import("@angular/core").WritableSignal<ITableState>;
1029
+ constructor();
1030
+ ngOnDestroy(): void;
1031
+ subscribeToLoadData(fnGetData: fnGetDataResType<T>, fnGetCount: fnGetCountResType<T>, fnMapEntity?: fnMapEntityType<T>): void;
1032
+ setFilter(key: string, value: any): void;
1033
+ onPageChange(pageState: IPageState): void;
1034
+ onSortChange(sortState: ISortState): void;
1035
+ entityFactory(type: new () => T): T;
1036
+ /** Событие изменение выбранных записей. */
1037
+ onSelectionChange(selected: T[]): void;
1038
+ /** Обновление доступности кнопки "Изменить" - вызывается при изменении выбранных записей. */
1039
+ editBtnDisabledUpdate(selected: T[]): void;
1040
+ /** Обновление доступности кнопки "Удалить" - вызывается при изменении выбранных записей. */
1041
+ removeBtnDisabledUpdate(selected: T[]): void;
1042
+ /** Событие двойной клик. */
1043
+ onRowDoubleClicked(): void;
1044
+ /** Событие создание. */
1045
+ newEvent(): void;
1046
+ /** Событие редактирование. */
1047
+ editEvent(): void;
1048
+ /** Событие удаление. */
1049
+ removeEvent(): void;
1050
+ /** Событие обновления данных. */
1051
+ refreshEvent(): void;
1052
+ /** Событие очистки фильтра. */
1053
+ clearEvent(): void;
1054
+ /** Изменение сообщения об удалении. */
1055
+ onRemovalMessageChange(message: string): void;
1056
+ /** Изменение заголовка страницы. */
1057
+ onPageTitleChange(title: string): void;
1058
+ openDialog(entityComponent: any, data: IEditDialogData<T>, dialog: any): any;
1059
+ openDialogRemoveConfirm(removalMessage: string): MatDialogRef<DialogComponent> | undefined;
1060
+ protected onMiddleButton(baseUrl: string, queryParamName?: string, queryParamValue?: string): ($event: MouseEvent, item: T | undefined, contextMenu: MatMenuTrigger) => void;
1061
+ protected onActionMiddleButton(baseUrl: string, queryParamName?: string, queryParamValue?: string): ($event: MouseEvent, item: T | undefined) => void;
1062
+ protected dateToString(date: string | number | Date): string | null;
1063
+ static ɵfac: i0.ɵɵFactoryDeclaration<BaseSignalPageClass<any>, never>;
1064
+ static ɵdir: i0.ɵɵDirectiveDeclaration<BaseSignalPageClass<any>, never, never, {}, {}, never, never, true, never>;
1065
+ }
1066
+ export declare abstract class BaseSignalServiceClass<T extends BaseSchemaClass> {
1067
+ abstract baseRoute: string;
1068
+ abstract entityType: any;
1069
+ protected abstract readonly schema: z.ZodType<T>;
1070
+ protected countRoute: string;
1071
+ protected pageIndexParam: string;
1072
+ protected pageSizeParam: string;
1073
+ protected sortColumnParam: string;
1074
+ protected directionParam: string;
1075
+ protected apiContextName: string;
1076
+ protected http: HttpClient;
1077
+ protected readonly _refreshTrigger: import("@angular/core").WritableSignal<number>;
1078
+ refresh(): void;
1079
+ getObjects(): HttpResourceRef<T[] | undefined>;
1080
+ getObject(id: number | (() => number)): HttpResourceRef<T | undefined>;
1081
+ getCount(): HttpResourceRef<number | undefined>;
1082
+ getObjectsByPaging(pageIndex: () => number, pageSize: () => number, sortColumn: () => string, direction: () => string): HttpResourceRef<T[] | undefined>;
1083
+ /**
1084
+ * МЕТОД СОЗДАНИЯ (POST)
1085
+ * Принимает данные БЕЗ id. Тип формируется автоматически через Zod.
1086
+ */
1087
+ newObject(entity: Omit<T, 'id'>): any;
1088
+ /**
1089
+ * Метод для СОЗДАНИЯ объекта (POST)
1090
+ * Тип аргумента генерируется автоматически: это ваш тип T, но БЕЗ поля id.
1091
+ */
1092
+ create(dto: Omit<T, 'id'>): HttpResourceRef<T | undefined>;
1093
+ editObject(entity: T): any;
1094
+ /**
1095
+ * Метод для ОБНОВЛЕНИЯ объекта (PUT / PATCH)
1096
+ * Принимает id и частичный объект (все свойства T становятся необязательными, кроме id)
1097
+ */
1098
+ update(id: number, dto: Partial<Omit<T, 'id'>>): HttpResourceRef<T | undefined>;
1099
+ /**
1100
+ * Метод DELETE (Переписанный под новую архитектуру)
1101
+ * Возвращает Observable. При подписке делает DELETE запрос,
1102
+ * а оператор 'tap' автоматически обновляет список getObjects() при успехе.
1103
+ */
1104
+ deleteObject(entity: T): any;
1105
+ protected getParams(pageIndex: number, pageSize: number, sortColumn: string, direction: string): HttpParams;
1106
+ protected getHttpContext(): {
1107
+ context?: HttpContext;
1108
+ };
1109
+ static ɵfac: i0.ɵɵFactoryDeclaration<BaseSignalServiceClass<any>, never>;
1110
+ static ɵprov: i0.ɵɵInjectableDeclaration<any>;
1111
+ }
844
1112
  export declare class DisableIfRoleDirective {
845
1113
  readonly forbiddenRoles: import("@angular/core").InputSignal<string[]>;
846
1114
  private readonly el;