@snabcentr/client-ui 0.7.0 → 0.8.2

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.

Potentially problematic release.


This version of @snabcentr/client-ui might be problematic. Click here for more details.

@@ -1,7 +1,7 @@
1
1
  import * as i0 from '@angular/core';
2
- import { Component, ChangeDetectionStrategy, EventEmitter, Output, Input, NgModule, Directive, HostBinding, ContentChild, Injectable, ElementRef, Inject, ContentChildren, ViewChild, HostListener, ChangeDetectorRef, Optional, Self, inject, InjectionToken, forwardRef } from '@angular/core';
2
+ import { EventEmitter, Component, ChangeDetectionStrategy, Inject, Input, Output, NgModule, Directive, HostBinding, ContentChild, Injectable, ElementRef, ContentChildren, ViewChild, HostListener, ChangeDetectorRef, Optional, Self, inject, InjectionToken, forwardRef } from '@angular/core';
3
3
  import * as i12 from 'rxjs';
4
- import { Subject, filter, map, switchMap, catchError, of, startWith, share, tap, finalize, timer, scan, takeWhile, endWith, distinctUntilChanged, shareReplay, interval, takeUntil, skip, debounceTime, merge } from 'rxjs';
4
+ import { Subject, filter, map, switchMap, tap, catchError, of, finalize, startWith, share, timer, scan, takeWhile, endWith, distinctUntilChanged, shareReplay, interval, takeUntil, skip, debounceTime, merge } from 'rxjs';
5
5
  import * as i1 from '@snabcentr/client-core';
6
6
  import { SC_URLS, SC_PATH_IMAGE_NOT_FOUND, ScCatalogService, ScCartService, ScIconTypesEnum, ScUserService } from '@snabcentr/client-core';
7
7
  import * as i2 from '@angular/common';
@@ -9,9 +9,9 @@ import { CommonModule, formatDate } from '@angular/common';
9
9
  import * as i4 from '@taiga-ui/core';
10
10
  import { TuiTextfieldControllerModule, TuiLinkModule, TuiButtonModule, TuiLabelModule, TuiModeModule, TuiErrorModule, TuiLoaderModule, tuiFadeIn, tuiFormatNumber, TuiSvgModule, TuiHintModule, TuiFormatNumberPipeModule, TuiNotificationModule, TuiFormatPhonePipeModule } from '@taiga-ui/core';
11
11
  import * as i2$1 from '@angular/forms';
12
- import { FormGroup, FormControl, Validators, FormsModule, ReactiveFormsModule, NgControl } from '@angular/forms';
12
+ import { FormGroupDirective, FormGroup, FormControl, Validators, FormsModule, ReactiveFormsModule, NgControl } from '@angular/forms';
13
13
  import * as i6 from '@taiga-ui/cdk';
14
- import { tuiIsFalsy, TuiLetModule, tuiCreateToken, AbstractTuiNullableControl, TUI_IS_MOBILE, tuiIsPresent, TuiDestroyService, tuiPure } from '@taiga-ui/cdk';
14
+ import { tuiControlValue, tuiIsFalsy, TuiLetModule, tuiCreateToken, AbstractTuiNullableControl, TUI_IS_MOBILE, tuiIsPresent, TuiDestroyService, tuiPure } from '@taiga-ui/cdk';
15
15
  import * as i3 from '@taiga-ui/kit';
16
16
  import { TuiInputPasswordModule, TuiInputModule, TuiFieldErrorPipeModule, TuiInputPhoneModule, TuiAccordionModule, TuiElasticContainerModule, TuiCarouselModule, TUI_NUMBER_VALUE_TRANSFORMER, TuiInputNumberComponent, TuiIslandModule, TuiInputNumberModule, TuiTreeService, TuiTreeItemContentComponent, TUI_TREE_START, TUI_TREE_CONTENT, TUI_TREE_LOADING, TUI_TREE_LOADER, TuiTreeModule, TuiCheckboxLabeledModule } from '@taiga-ui/kit';
17
17
  import * as i7 from '@maskito/angular';
@@ -59,67 +59,34 @@ const phoneApproveCodeMask = {
59
59
  };
60
60
 
61
61
  /**
62
- * Компонент аутентификации по номеру телефона и коду подтверждения.
62
+ * Компонент формы проверки телефона и получения кода подтверждения.
63
63
  */
64
- class ScSignInFormByPhoneComponent {
64
+ class ScPhoneApproveFormComponent {
65
65
  /**
66
- * Инициализирует экземпляр класса {@link ScSignInFormByPhoneComponent}.
66
+ * Инициализирует экземпляр класса {@link ScPhoneApproveFormComponent}.
67
67
  *
68
- * @param authService Сервис аутентификации.
69
68
  * @param verificationService Сервис верификации.
69
+ * @param formGroupDirective Директива c `FormGroup` из DOM.
70
70
  */
71
- constructor(authService, verificationService) {
72
- this.authService = authService;
71
+ constructor(verificationService, formGroupDirective) {
73
72
  this.verificationService = verificationService;
73
+ this.formGroupDirective = formGroupDirective;
74
74
  /**
75
- * Этап процесса аутентификации.
75
+ * Признак, следует ли телефону быть в системе. От этого признака зависит в каких случаях выдавать ошибку при проверки занятости телефона.
76
76
  */
77
- this.haveCode = false;
78
- /**
79
- * Группа полей ввода для формы «Вход на сайт».
80
- */
81
- this.formByPhone = new FormGroup({
82
- phone: new FormControl(null, [Validators.required, Validators.minLength(12)]),
83
- phoneApproveCode: new FormControl(null, [Validators.required, Validators.minLength(6)]),
84
- });
77
+ this.shouldBeBusy = true;
85
78
  /**
86
- * {@link Subject} События отправки формы.
79
+ * Признак, следует ли проверять подтверждён ли телефона в системе. При `true` будет вызывать ошибку при наличие телефона в системе без подтверждения.
87
80
  */
88
- this.onSubmit = new Subject();
81
+ this.shouldBeConfirmed = false;
89
82
  /**
90
- * {@link Observable} Запроса данных аутентификации.
83
+ * Наличие кода подтверждения у пользователя.
91
84
  */
92
- this.phoneRequest$ = this.onSubmit.pipe(filter(() => this.formByPhone.valid), map(() => this.formByPhone.value), switchMap((value) => this.authService.getSignIn$(value).pipe(catchError((error) => {
93
- var _a;
94
- const errorResponse = error.error;
95
- for (const key in errorResponse.errors) {
96
- (_a = this.formByPhone.get(key)) === null || _a === void 0 ? void 0 : _a.setErrors({ serverResponse: errorResponse.errors[`${key}`] });
97
- }
98
- if (!errorResponse.errors && errorResponse.message) {
99
- this.formByPhone.setErrors({ serverResponse: [errorResponse.message] });
100
- }
101
- return of({});
102
- }), startWith(null))), share());
85
+ this.haveCode = false;
103
86
  /**
104
- * {@link Observable} Запроса данных получения информации о том свободен ли номер телефона.
87
+ * Событие для обратной привязки наличия кода подтверждения
105
88
  */
106
- this.isPhoneNotBusy$ = this.phoneControl.valueChanges.pipe(tap(() => this.reloadTimer$.next(0)), switchMap((value) => {
107
- if (this.phoneControl.valid && !!value) {
108
- return this.verificationService.getPhoneCheck$(value).pipe(map((result) => result.isBusy), tap((isBusy) => {
109
- if (!isBusy) {
110
- this.phoneControl.setErrors({ serverResponse: ['Пользователя с таким номером телефона не существует'] });
111
- this.phoneControl.markAsTouched();
112
- }
113
- }), catchError((error) => {
114
- var _a, _b;
115
- const errorResponse = error.error;
116
- this.phoneControl.setErrors({ serverResponse: (_b = (_a = errorResponse === null || errorResponse === void 0 ? void 0 : errorResponse.errors) === null || _a === void 0 ? void 0 : _a[`phone`]) !== null && _b !== void 0 ? _b : [errorResponse.message] });
117
- return of(false);
118
- }), startWith(null));
119
- }
120
- this.setHaveCode(false);
121
- return of(false);
122
- }), share());
89
+ this.haveCodeChange = new EventEmitter();
123
90
  /**
124
91
  * {@link Subject} События отправки кода подтверждения.
125
92
  */
@@ -146,10 +113,6 @@ class ScSignInFormByPhoneComponent {
146
113
  * Маска поля ввода кода для подтверждения.
147
114
  */
148
115
  this.approveCodeMask = phoneApproveCodeMask;
149
- /**
150
- * {@link Observable} Изменения состояния загрузки данных аутентификации по номеру телефона.
151
- */
152
- this.loadingPhoneAuth$ = this.phoneRequest$.pipe(map(tuiIsFalsy));
153
116
  /**
154
117
  * {@link Subject} События запуска/остановки таймера.
155
118
  */
@@ -165,11 +128,52 @@ class ScSignInFormByPhoneComponent {
165
128
  return `${Math.round(minutes).toString().padStart(2, '0')}:${Math.round(seconds).toString().padStart(2, '0')}`;
166
129
  }), endWith(null), startWith(null), distinctUntilChanged())));
167
130
  }
131
+ /**
132
+ * Группа полей ввода для формы «Вход на сайт».
133
+ */
134
+ get form() {
135
+ var _a;
136
+ return (_a = this.formGroupDirective) === null || _a === void 0 ? void 0 : _a.form;
137
+ }
168
138
  /**
169
139
  * Поле ввода 'Номер телефона'.
170
140
  */
171
141
  get phoneControl() {
172
- return this.formByPhone.get('phone');
142
+ var _a;
143
+ return (_a = this.form) === null || _a === void 0 ? void 0 : _a.controls.phone;
144
+ }
145
+ /** @inheritDoc */
146
+ ngOnInit() {
147
+ this.phoneCheck$ = tuiControlValue(this.phoneControl).pipe(tap(() => this.reloadTimer$.next(0)), switchMap((value) => {
148
+ if (this.phoneControl.valid && !!value) {
149
+ return this.verificationService.getPhoneCheck$(value).pipe(map((result) => {
150
+ if (this.shouldBeBusy !== result.isBusy) {
151
+ this.phoneControl.setErrors({
152
+ serverResponse: [
153
+ this.shouldBeBusy ? 'Пользователя с таким номером телефона не существует' : 'Пользователь с таким номером телефона уже существует',
154
+ ],
155
+ });
156
+ this.phoneControl.markAsTouched();
157
+ return false;
158
+ }
159
+ if (this.shouldBeConfirmed && result.isConfirmed === false) {
160
+ this.phoneControl.setErrors({
161
+ serverResponse: ['Номер телефона не подтверждён. Обратитесь к вашему персональному менеджеру или войдите с использованием e-mail и пароля.'],
162
+ });
163
+ this.phoneControl.markAsTouched();
164
+ return false;
165
+ }
166
+ return true;
167
+ }), catchError((error) => {
168
+ var _a, _b;
169
+ const errorResponse = error.error;
170
+ this.phoneControl.setErrors({ serverResponse: (_b = (_a = errorResponse === null || errorResponse === void 0 ? void 0 : errorResponse.errors) === null || _a === void 0 ? void 0 : _a[`phone`]) !== null && _b !== void 0 ? _b : [errorResponse.message] });
171
+ return of(false);
172
+ }), startWith(null));
173
+ }
174
+ this.setHaveCode(false);
175
+ return of(false);
176
+ }), share());
173
177
  }
174
178
  /**
175
179
  * Устанавливает состояние наличия кода подтверждения у пользователя.
@@ -178,14 +182,82 @@ class ScSignInFormByPhoneComponent {
178
182
  */
179
183
  setHaveCode(haveCode) {
180
184
  this.haveCode = haveCode;
185
+ this.haveCodeChange.emit(haveCode);
186
+ }
187
+ }
188
+ ScPhoneApproveFormComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: ScPhoneApproveFormComponent, deps: [{ token: i1.ScVerificationService }, { token: FormGroupDirective }], target: i0.ɵɵFactoryTarget.Component });
189
+ ScPhoneApproveFormComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.3.0", type: ScPhoneApproveFormComponent, selector: "sc-phone-approve-form", inputs: { shouldBeBusy: "shouldBeBusy", shouldBeConfirmed: "shouldBeConfirmed", haveCode: "haveCode" }, outputs: { haveCodeChange: "haveCodeChange" }, ngImport: i0, template: "<form [formGroup]=\"form\" *tuiLet=\"(loadingApproveCode$ | async) as loadingApproveCode\" class=\"flex flex-col gap-3\">\n <label tuiLabel=\"\u041D\u043E\u043C\u0435\u0440 \u0442\u0435\u043B\u0435\u0444\u043E\u043D\u0430\">\n <tui-input-phone formControlName=\"phone\" [tuiTextfieldCustomContent]=\"checkingPhone\">\n \u041D\u043E\u043C\u0435\u0440 \u0442\u0435\u043B\u0435\u0444\u043E\u043D\u0430\n <input tuiTextfield autocomplete=\"phone\" />\n </tui-input-phone>\n <tui-error formControlName=\"phone\" [error]=\"[] | tuiFieldError | async\"></tui-error>\n </label>\n\n <label *ngIf=\"loadingApproveCode === false && haveCode\" tuiLabel=\"\u041A\u043E\u0434 \u0438\u0437 \u0421\u041C\u0421\">\n <tui-input formControlName=\"phoneApproveCode\">\n \u041A\u043E\u0434 \u0438\u0437 \u0421\u041C\u0421\n <input tuiTextfield [maskito]=\"approveCodeMask\" autocomplete=\"new-password\" />\n </tui-input>\n <tui-error formControlName=\"phoneApproveCode\" [error]=\"[] | tuiFieldError | async\"></tui-error>\n </label>\n\n <div *tuiLet=\"!!loadingApproveCode as loadingApproveCode\" class=\"flex gap-4 justify-center\">\n <button\n *ngIf=\"!haveCode\"\n tuiButton\n size=\"s\"\n (click)=\"onSendCode.next()\"\n [disabled]=\"loadingApproveCode || !!!(phoneCheck$ | async) || phoneControl.invalid\"\n [showLoader]=\"loadingApproveCode\"\n icon=\"scIconLogIn\"\n >\n \u041F\u043E\u043B\u0443\u0447\u0438\u0442\u044C \u043A\u043E\u0434\n </button>\n <button *ngIf=\"!loadingApproveCode && !haveCode\" tuiLink [pseudo]=\"true\" [disabled]=\"!!!(phoneCheck$ | async) || phoneControl.invalid\" (click)=\"setHaveCode(true)\">\n \u0423 \u043C\u0435\u043D\u044F \u0435\u0441\u0442\u044C \u043A\u043E\u0434\n </button>\n\n <ng-container *tuiLet=\"timer$ | async as timer\">\n <tui-loader *ngIf=\"haveCode\" [showLoader]=\"loadingApproveCode\">\n <button tuiLink [pseudo]=\"true\" [disabled]=\"loadingApproveCode || timer\" (click)=\"onSendCode.next()\">\n \u041F\u043E\u0432\u0442\u043E\u0440\u043D\u043E \u043E\u0442\u043F\u0440\u0430\u0432\u0438\u0442\u044C \u043A\u043E\u0434\n <ng-container *ngIf=\"timer\" class=\"!text-tui-base-08\">(\u0447\u0435\u0440\u0435\u0437 {{ timer }})</ng-container>\n </button>\n </tui-loader>\n </ng-container>\n </div>\n</form>\n\n<ng-template #checkingPhone>\n <tui-loader *ngIf=\"!!!(phoneCheck$ | async) && phoneControl.valid\" class=\"w-4 h-4\"> </tui-loader>\n</ng-template>\n", dependencies: [{ kind: "directive", type: i2.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i2$1.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i2$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i2$1.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i2$1.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i2$1.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { kind: "component", type: i4.TuiTextfieldComponent, selector: "input[tuiTextfield], textarea[tuiTextfield]" }, { kind: "component", type: i3.TuiInputComponent, selector: "tui-input" }, { kind: "directive", type: i3.TuiInputDirective, selector: "tui-input" }, { kind: "directive", type: i4.TuiTextfieldCustomContentDirective, selector: "[tuiTextfieldCustomContent]", inputs: ["tuiTextfieldCustomContent"] }, { kind: "component", type: i4.TuiLinkComponent, selector: "a[tuiLink], button[tuiLink]", inputs: ["pseudo", "icon", "iconAlign", "iconRotated", "mode"], exportAs: ["tuiLink"] }, { kind: "component", type: i4.TuiButtonComponent, selector: "button[tuiButton], button[tuiIconButton], a[tuiButton], a[tuiIconButton]", inputs: ["appearance", "disabled", "icon", "iconRight", "shape", "showLoader", "size"] }, { kind: "component", type: i4.TuiLabelComponent, selector: "label[tuiLabel]", inputs: ["tuiLabel", "context"] }, { kind: "component", type: i4.TuiErrorComponent, selector: "tui-error", inputs: ["error"] }, { kind: "directive", type: i6.TuiLetDirective, selector: "[tuiLet]", inputs: ["tuiLet"] }, { kind: "component", type: i4.TuiLoaderComponent, selector: "tui-loader", inputs: ["size", "inheritColor", "overlay", "textContent", "showLoader"] }, { kind: "component", type: i3.TuiInputPhoneComponent, selector: "tui-input-phone", inputs: ["countryCode", "phoneMaskAfterCountryCode", "allowText", "search"], outputs: ["searchChange"] }, { kind: "directive", type: i3.TuiInputPhoneDirective, selector: "tui-input-phone" }, { kind: "directive", type: i7.MaskitoDirective, selector: "[maskito]", inputs: ["maskito", "maskitoElement"] }, { kind: "directive", type: i7.MaskitoCva, selector: "input[maskito], textarea[maskito]", inputs: ["maskito"] }, { kind: "pipe", type: i2.AsyncPipe, name: "async" }, { kind: "pipe", type: i3.TuiFieldErrorPipe, name: "tuiFieldError" }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
190
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: ScPhoneApproveFormComponent, decorators: [{
191
+ type: Component,
192
+ args: [{ selector: 'sc-phone-approve-form', changeDetection: ChangeDetectionStrategy.OnPush, template: "<form [formGroup]=\"form\" *tuiLet=\"(loadingApproveCode$ | async) as loadingApproveCode\" class=\"flex flex-col gap-3\">\n <label tuiLabel=\"\u041D\u043E\u043C\u0435\u0440 \u0442\u0435\u043B\u0435\u0444\u043E\u043D\u0430\">\n <tui-input-phone formControlName=\"phone\" [tuiTextfieldCustomContent]=\"checkingPhone\">\n \u041D\u043E\u043C\u0435\u0440 \u0442\u0435\u043B\u0435\u0444\u043E\u043D\u0430\n <input tuiTextfield autocomplete=\"phone\" />\n </tui-input-phone>\n <tui-error formControlName=\"phone\" [error]=\"[] | tuiFieldError | async\"></tui-error>\n </label>\n\n <label *ngIf=\"loadingApproveCode === false && haveCode\" tuiLabel=\"\u041A\u043E\u0434 \u0438\u0437 \u0421\u041C\u0421\">\n <tui-input formControlName=\"phoneApproveCode\">\n \u041A\u043E\u0434 \u0438\u0437 \u0421\u041C\u0421\n <input tuiTextfield [maskito]=\"approveCodeMask\" autocomplete=\"new-password\" />\n </tui-input>\n <tui-error formControlName=\"phoneApproveCode\" [error]=\"[] | tuiFieldError | async\"></tui-error>\n </label>\n\n <div *tuiLet=\"!!loadingApproveCode as loadingApproveCode\" class=\"flex gap-4 justify-center\">\n <button\n *ngIf=\"!haveCode\"\n tuiButton\n size=\"s\"\n (click)=\"onSendCode.next()\"\n [disabled]=\"loadingApproveCode || !!!(phoneCheck$ | async) || phoneControl.invalid\"\n [showLoader]=\"loadingApproveCode\"\n icon=\"scIconLogIn\"\n >\n \u041F\u043E\u043B\u0443\u0447\u0438\u0442\u044C \u043A\u043E\u0434\n </button>\n <button *ngIf=\"!loadingApproveCode && !haveCode\" tuiLink [pseudo]=\"true\" [disabled]=\"!!!(phoneCheck$ | async) || phoneControl.invalid\" (click)=\"setHaveCode(true)\">\n \u0423 \u043C\u0435\u043D\u044F \u0435\u0441\u0442\u044C \u043A\u043E\u0434\n </button>\n\n <ng-container *tuiLet=\"timer$ | async as timer\">\n <tui-loader *ngIf=\"haveCode\" [showLoader]=\"loadingApproveCode\">\n <button tuiLink [pseudo]=\"true\" [disabled]=\"loadingApproveCode || timer\" (click)=\"onSendCode.next()\">\n \u041F\u043E\u0432\u0442\u043E\u0440\u043D\u043E \u043E\u0442\u043F\u0440\u0430\u0432\u0438\u0442\u044C \u043A\u043E\u0434\n <ng-container *ngIf=\"timer\" class=\"!text-tui-base-08\">(\u0447\u0435\u0440\u0435\u0437 {{ timer }})</ng-container>\n </button>\n </tui-loader>\n </ng-container>\n </div>\n</form>\n\n<ng-template #checkingPhone>\n <tui-loader *ngIf=\"!!!(phoneCheck$ | async) && phoneControl.valid\" class=\"w-4 h-4\"> </tui-loader>\n</ng-template>\n" }]
193
+ }], ctorParameters: function () {
194
+ return [{ type: i1.ScVerificationService }, { type: i2$1.FormGroupDirective, decorators: [{
195
+ type: Inject,
196
+ args: [FormGroupDirective]
197
+ }] }];
198
+ }, propDecorators: { shouldBeBusy: [{
199
+ type: Input
200
+ }], shouldBeConfirmed: [{
201
+ type: Input
202
+ }], haveCode: [{
203
+ type: Input
204
+ }], haveCodeChange: [{
205
+ type: Output
206
+ }] } });
207
+
208
+ /**
209
+ * Компонент аутентификации по номеру телефона и коду подтверждения.
210
+ */
211
+ class ScSignInFormByPhoneComponent {
212
+ /**
213
+ * Инициализирует экземпляр класса {@link ScSignInFormByPhoneComponent}.
214
+ *
215
+ * @param authService Сервис аутентификации.
216
+ * @param verificationService Сервис верификации.
217
+ */
218
+ constructor(authService) {
219
+ this.authService = authService;
220
+ /**
221
+ * Наличие кода подтверждения у пользователя.
222
+ */
223
+ this.haveCode = false;
224
+ /**
225
+ * Группа полей ввода для формы «Вход на сайт».
226
+ */
227
+ this.formByPhone = new FormGroup({
228
+ phone: new FormControl(null, [Validators.required, Validators.minLength(12)]),
229
+ phoneApproveCode: new FormControl(null, [Validators.required, Validators.minLength(6)]),
230
+ });
231
+ /**
232
+ * {@link Subject} События отправки формы.
233
+ */
234
+ this.onSubmit = new Subject();
235
+ /**
236
+ * {@link Observable} Запроса данных аутентификации.
237
+ */
238
+ this.phoneRequest$ = this.onSubmit.pipe(filter(() => this.formByPhone.valid), map(() => this.formByPhone.value), switchMap((value) => this.authService.getSignIn$(value).pipe(catchError((error) => {
239
+ var _a;
240
+ const errorResponse = error.error;
241
+ for (const key in errorResponse.errors) {
242
+ (_a = this.formByPhone.get(key)) === null || _a === void 0 ? void 0 : _a.setErrors({ serverResponse: errorResponse.errors[`${key}`] });
243
+ }
244
+ if (!errorResponse.errors && errorResponse.message) {
245
+ this.formByPhone.setErrors({ serverResponse: [errorResponse.message] });
246
+ }
247
+ return of({});
248
+ }), startWith(null))), share());
249
+ /**
250
+ * {@link Observable} Изменения состояния загрузки данных аутентификации по номеру телефона.
251
+ */
252
+ this.loadingPhoneAuth$ = this.phoneRequest$.pipe(map(tuiIsFalsy));
181
253
  }
182
254
  }
183
- ScSignInFormByPhoneComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: ScSignInFormByPhoneComponent, deps: [{ token: i1.ScAuthService }, { token: i1.ScVerificationService }], target: i0.ɵɵFactoryTarget.Component });
184
- ScSignInFormByPhoneComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.3.0", type: ScSignInFormByPhoneComponent, selector: "sc-sign-in-form-by-phone", ngImport: i0, template: "<form [formGroup]=\"formByPhone\" *tuiLet=\"(loadingApproveCode$ | async) as loadingApproveCode\" (ngSubmit)=\"onSubmit.next()\">\n <div class=\"flex flex-col gap-4 mb-8\">\n <label tuiLabel=\"\u041D\u043E\u043C\u0435\u0440 \u0442\u0435\u043B\u0435\u0444\u043E\u043D\u0430\">\n <tui-input-phone formControlName=\"phone\" [tuiTextfieldCustomContent]=\"checkingPhone\">\n \u041D\u043E\u043C\u0435\u0440 \u0442\u0435\u043B\u0435\u0444\u043E\u043D\u0430\n <input tuiTextfield autocomplete=\"phone\" />\n </tui-input-phone>\n <tui-error formControlName=\"phone\" [error]=\"[] | tuiFieldError | async\"></tui-error>\n </label>\n <tui-error [error]=\"[] | tuiFieldError | async\"></tui-error>\n\n <label *ngIf=\"loadingApproveCode === false && haveCode\" tuiLabel=\"\u041A\u043E\u0434 \u0438\u0437 \u0421\u041C\u0421\">\n <tui-input formControlName=\"phoneApproveCode\">\n \u041A\u043E\u0434 \u0438\u0437 \u0421\u041C\u0421\n <input tuiTextfield [maskito]=\"approveCodeMask\" autocomplete=\"new-password\" />\n </tui-input>\n <tui-error formControlName=\"phoneApproveCode\" [error]=\"[] | tuiFieldError | async\"></tui-error>\n </label>\n </div>\n\n <div *tuiLet=\"!!loadingApproveCode as loadingApproveCode\" class=\"flex flex-col gap-4 items-center mb-4\">\n <button\n *ngIf=\"!haveCode\"\n tuiButton\n size=\"s\"\n (click)=\"onSendCode.next()\"\n [disabled]=\"loadingApproveCode || !!!(isPhoneNotBusy$ | async) || phoneControl.invalid\"\n [showLoader]=\"loadingApproveCode\"\n icon=\"scIconLogIn\"\n >\n \u041F\u043E\u043B\u0443\u0447\u0438\u0442\u044C \u043A\u043E\u0434\n </button>\n <button *ngIf=\"!loadingApproveCode && !haveCode\" tuiLink [pseudo]=\"true\" [disabled]=\"!!!(isPhoneNotBusy$ | async) || phoneControl.invalid\" (click)=\"setHaveCode(true)\">\n \u0423 \u043C\u0435\u043D\u044F \u0435\u0441\u0442\u044C \u043A\u043E\u0434\n </button>\n\n <ng-container *tuiLet=\"timer$ | async as timer\">\n <tui-loader *ngIf=\"haveCode\" [showLoader]=\"loadingApproveCode\">\n <button tuiLink [pseudo]=\"true\" [disabled]=\"loadingApproveCode || timer\" (click)=\"onSendCode.next()\">\n \u041F\u043E\u0432\u0442\u043E\u0440\u043D\u043E \u043E\u0442\u043F\u0440\u0430\u0432\u0438\u0442\u044C \u043A\u043E\u0434\n <ng-container *ngIf=\"timer\" class=\"!text-tui-base-08\">(\u0447\u0435\u0440\u0435\u0437 {{ timer }})</ng-container>\n </button>\n </tui-loader>\n </ng-container>\n <button\n *ngIf=\"haveCode\"\n tuiButton\n size=\"s\"\n type=\"submit\"\n [showLoader]=\"!!(loadingPhoneAuth$ | async)\"\n [disabled]=\"formByPhone.invalid || !!(loadingPhoneAuth$ | async)\"\n icon=\"scIconLogIn\"\n >\n \u0412\u043E\u0439\u0442\u0438\n </button>\n </div>\n</form>\n\n<ng-template #checkingPhone>\n <tui-loader *ngIf=\"!!!(isPhoneNotBusy$ | async) && phoneControl.valid\" class=\"w-4 h-4\"> </tui-loader>\n</ng-template>\n", dependencies: [{ kind: "directive", type: i2.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i2$1.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i2$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i2$1.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i2$1.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i2$1.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { kind: "component", type: i4.TuiTextfieldComponent, selector: "input[tuiTextfield], textarea[tuiTextfield]" }, { kind: "component", type: i3.TuiInputComponent, selector: "tui-input" }, { kind: "directive", type: i3.TuiInputDirective, selector: "tui-input" }, { kind: "directive", type: i4.TuiTextfieldCustomContentDirective, selector: "[tuiTextfieldCustomContent]", inputs: ["tuiTextfieldCustomContent"] }, { kind: "component", type: i4.TuiLinkComponent, selector: "a[tuiLink], button[tuiLink]", inputs: ["pseudo", "icon", "iconAlign", "iconRotated", "mode"], exportAs: ["tuiLink"] }, { kind: "component", type: i4.TuiButtonComponent, selector: "button[tuiButton], button[tuiIconButton], a[tuiButton], a[tuiIconButton]", inputs: ["appearance", "disabled", "icon", "iconRight", "shape", "showLoader", "size"] }, { kind: "component", type: i4.TuiLabelComponent, selector: "label[tuiLabel]", inputs: ["tuiLabel", "context"] }, { kind: "component", type: i4.TuiErrorComponent, selector: "tui-error", inputs: ["error"] }, { kind: "directive", type: i6.TuiLetDirective, selector: "[tuiLet]", inputs: ["tuiLet"] }, { kind: "component", type: i4.TuiLoaderComponent, selector: "tui-loader", inputs: ["size", "inheritColor", "overlay", "textContent", "showLoader"] }, { kind: "component", type: i3.TuiInputPhoneComponent, selector: "tui-input-phone", inputs: ["countryCode", "phoneMaskAfterCountryCode", "allowText", "search"], outputs: ["searchChange"] }, { kind: "directive", type: i3.TuiInputPhoneDirective, selector: "tui-input-phone" }, { kind: "directive", type: i7.MaskitoDirective, selector: "[maskito]", inputs: ["maskito", "maskitoElement"] }, { kind: "directive", type: i7.MaskitoCva, selector: "input[maskito], textarea[maskito]", inputs: ["maskito"] }, { kind: "pipe", type: i2.AsyncPipe, name: "async" }, { kind: "pipe", type: i3.TuiFieldErrorPipe, name: "tuiFieldError" }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
255
+ ScSignInFormByPhoneComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: ScSignInFormByPhoneComponent, deps: [{ token: i1.ScAuthService }], target: i0.ɵɵFactoryTarget.Component });
256
+ ScSignInFormByPhoneComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.3.0", type: ScSignInFormByPhoneComponent, selector: "sc-sign-in-form-by-phone", ngImport: i0, template: "<form [formGroup]=\"formByPhone\" (ngSubmit)=\"onSubmit.next()\" class=\"flex flex-col gap-4 items-center mb-4\">\n <sc-phone-approve-form [(haveCode)]=\"haveCode\" class=\"w-full\"></sc-phone-approve-form>\n <button\n *ngIf=\"haveCode\"\n tuiButton\n size=\"s\"\n type=\"submit\"\n [showLoader]=\"!!(loadingPhoneAuth$ | async)\"\n [disabled]=\"formByPhone.invalid || !!(loadingPhoneAuth$ | async)\"\n icon=\"scIconLogIn\"\n >\n \u0412\u043E\u0439\u0442\u0438\n </button>\n</form>\n", dependencies: [{ kind: "directive", type: i2.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i2$1.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i2$1.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i2$1.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "component", type: i4.TuiButtonComponent, selector: "button[tuiButton], button[tuiIconButton], a[tuiButton], a[tuiIconButton]", inputs: ["appearance", "disabled", "icon", "iconRight", "shape", "showLoader", "size"] }, { kind: "component", type: ScPhoneApproveFormComponent, selector: "sc-phone-approve-form", inputs: ["shouldBeBusy", "shouldBeConfirmed", "haveCode"], outputs: ["haveCodeChange"] }, { kind: "pipe", type: i2.AsyncPipe, name: "async" }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
185
257
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: ScSignInFormByPhoneComponent, decorators: [{
186
258
  type: Component,
187
- args: [{ selector: 'sc-sign-in-form-by-phone', changeDetection: ChangeDetectionStrategy.OnPush, template: "<form [formGroup]=\"formByPhone\" *tuiLet=\"(loadingApproveCode$ | async) as loadingApproveCode\" (ngSubmit)=\"onSubmit.next()\">\n <div class=\"flex flex-col gap-4 mb-8\">\n <label tuiLabel=\"\u041D\u043E\u043C\u0435\u0440 \u0442\u0435\u043B\u0435\u0444\u043E\u043D\u0430\">\n <tui-input-phone formControlName=\"phone\" [tuiTextfieldCustomContent]=\"checkingPhone\">\n \u041D\u043E\u043C\u0435\u0440 \u0442\u0435\u043B\u0435\u0444\u043E\u043D\u0430\n <input tuiTextfield autocomplete=\"phone\" />\n </tui-input-phone>\n <tui-error formControlName=\"phone\" [error]=\"[] | tuiFieldError | async\"></tui-error>\n </label>\n <tui-error [error]=\"[] | tuiFieldError | async\"></tui-error>\n\n <label *ngIf=\"loadingApproveCode === false && haveCode\" tuiLabel=\"\u041A\u043E\u0434 \u0438\u0437 \u0421\u041C\u0421\">\n <tui-input formControlName=\"phoneApproveCode\">\n \u041A\u043E\u0434 \u0438\u0437 \u0421\u041C\u0421\n <input tuiTextfield [maskito]=\"approveCodeMask\" autocomplete=\"new-password\" />\n </tui-input>\n <tui-error formControlName=\"phoneApproveCode\" [error]=\"[] | tuiFieldError | async\"></tui-error>\n </label>\n </div>\n\n <div *tuiLet=\"!!loadingApproveCode as loadingApproveCode\" class=\"flex flex-col gap-4 items-center mb-4\">\n <button\n *ngIf=\"!haveCode\"\n tuiButton\n size=\"s\"\n (click)=\"onSendCode.next()\"\n [disabled]=\"loadingApproveCode || !!!(isPhoneNotBusy$ | async) || phoneControl.invalid\"\n [showLoader]=\"loadingApproveCode\"\n icon=\"scIconLogIn\"\n >\n \u041F\u043E\u043B\u0443\u0447\u0438\u0442\u044C \u043A\u043E\u0434\n </button>\n <button *ngIf=\"!loadingApproveCode && !haveCode\" tuiLink [pseudo]=\"true\" [disabled]=\"!!!(isPhoneNotBusy$ | async) || phoneControl.invalid\" (click)=\"setHaveCode(true)\">\n \u0423 \u043C\u0435\u043D\u044F \u0435\u0441\u0442\u044C \u043A\u043E\u0434\n </button>\n\n <ng-container *tuiLet=\"timer$ | async as timer\">\n <tui-loader *ngIf=\"haveCode\" [showLoader]=\"loadingApproveCode\">\n <button tuiLink [pseudo]=\"true\" [disabled]=\"loadingApproveCode || timer\" (click)=\"onSendCode.next()\">\n \u041F\u043E\u0432\u0442\u043E\u0440\u043D\u043E \u043E\u0442\u043F\u0440\u0430\u0432\u0438\u0442\u044C \u043A\u043E\u0434\n <ng-container *ngIf=\"timer\" class=\"!text-tui-base-08\">(\u0447\u0435\u0440\u0435\u0437 {{ timer }})</ng-container>\n </button>\n </tui-loader>\n </ng-container>\n <button\n *ngIf=\"haveCode\"\n tuiButton\n size=\"s\"\n type=\"submit\"\n [showLoader]=\"!!(loadingPhoneAuth$ | async)\"\n [disabled]=\"formByPhone.invalid || !!(loadingPhoneAuth$ | async)\"\n icon=\"scIconLogIn\"\n >\n \u0412\u043E\u0439\u0442\u0438\n </button>\n </div>\n</form>\n\n<ng-template #checkingPhone>\n <tui-loader *ngIf=\"!!!(isPhoneNotBusy$ | async) && phoneControl.valid\" class=\"w-4 h-4\"> </tui-loader>\n</ng-template>\n" }]
188
- }], ctorParameters: function () { return [{ type: i1.ScAuthService }, { type: i1.ScVerificationService }]; } });
259
+ args: [{ selector: 'sc-sign-in-form-by-phone', changeDetection: ChangeDetectionStrategy.OnPush, template: "<form [formGroup]=\"formByPhone\" (ngSubmit)=\"onSubmit.next()\" class=\"flex flex-col gap-4 items-center mb-4\">\n <sc-phone-approve-form [(haveCode)]=\"haveCode\" class=\"w-full\"></sc-phone-approve-form>\n <button\n *ngIf=\"haveCode\"\n tuiButton\n size=\"s\"\n type=\"submit\"\n [showLoader]=\"!!(loadingPhoneAuth$ | async)\"\n [disabled]=\"formByPhone.invalid || !!(loadingPhoneAuth$ | async)\"\n icon=\"scIconLogIn\"\n >\n \u0412\u043E\u0439\u0442\u0438\n </button>\n</form>\n" }]
260
+ }], ctorParameters: function () { return [{ type: i1.ScAuthService }]; } });
189
261
 
190
262
  /**
191
263
  * Компонент аутентификации по адресу электронной почты и паролю.
@@ -304,6 +376,70 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImpor
304
376
  type: Output
305
377
  }] } });
306
378
 
379
+ /**
380
+ * Модуль отправки кодов подтверждения (номера телефона, адреса эл. почты и т.д.).
381
+ */
382
+ class ScVerificationModule {
383
+ }
384
+ ScVerificationModule.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: ScVerificationModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule });
385
+ ScVerificationModule.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "14.3.0", ngImport: i0, type: ScVerificationModule, declarations: [ScPhoneApproveFormComponent], imports: [CommonModule,
386
+ FormsModule,
387
+ ReactiveFormsModule,
388
+ TuiInputPasswordModule,
389
+ TuiInputModule,
390
+ TuiTextfieldControllerModule,
391
+ TuiLinkModule,
392
+ TuiButtonModule,
393
+ TuiLabelModule,
394
+ TuiModeModule,
395
+ TuiFieldErrorPipeModule,
396
+ TuiErrorModule,
397
+ TuiLetModule,
398
+ TuiLoaderModule,
399
+ TuiInputPhoneModule,
400
+ MaskitoModule], exports: [ScPhoneApproveFormComponent] });
401
+ ScVerificationModule.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: ScVerificationModule, imports: [CommonModule,
402
+ FormsModule,
403
+ ReactiveFormsModule,
404
+ TuiInputPasswordModule,
405
+ TuiInputModule,
406
+ TuiTextfieldControllerModule,
407
+ TuiLinkModule,
408
+ TuiButtonModule,
409
+ TuiLabelModule,
410
+ TuiModeModule,
411
+ TuiFieldErrorPipeModule,
412
+ TuiErrorModule,
413
+ TuiLetModule,
414
+ TuiLoaderModule,
415
+ TuiInputPhoneModule,
416
+ MaskitoModule] });
417
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: ScVerificationModule, decorators: [{
418
+ type: NgModule,
419
+ args: [{
420
+ imports: [
421
+ CommonModule,
422
+ FormsModule,
423
+ ReactiveFormsModule,
424
+ TuiInputPasswordModule,
425
+ TuiInputModule,
426
+ TuiTextfieldControllerModule,
427
+ TuiLinkModule,
428
+ TuiButtonModule,
429
+ TuiLabelModule,
430
+ TuiModeModule,
431
+ TuiFieldErrorPipeModule,
432
+ TuiErrorModule,
433
+ TuiLetModule,
434
+ TuiLoaderModule,
435
+ TuiInputPhoneModule,
436
+ MaskitoModule,
437
+ ],
438
+ exports: [ScPhoneApproveFormComponent],
439
+ declarations: [ScPhoneApproveFormComponent],
440
+ }]
441
+ }] });
442
+
307
443
  /**
308
444
  * Модуль аутентификации.
309
445
  */
@@ -325,7 +461,8 @@ ScAuthModule.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "
325
461
  TuiLetModule,
326
462
  TuiLoaderModule,
327
463
  TuiInputPhoneModule,
328
- MaskitoModule], exports: [ScSignInFormComponent, ScSignInFormByPhoneComponent, ScSignInFormByEmailComponent] });
464
+ MaskitoModule,
465
+ ScVerificationModule], exports: [ScSignInFormComponent, ScSignInFormByPhoneComponent, ScSignInFormByEmailComponent] });
329
466
  ScAuthModule.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: ScAuthModule, imports: [CommonModule,
330
467
  FormsModule,
331
468
  ReactiveFormsModule,
@@ -341,7 +478,8 @@ ScAuthModule.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "
341
478
  TuiLetModule,
342
479
  TuiLoaderModule,
343
480
  TuiInputPhoneModule,
344
- MaskitoModule] });
481
+ MaskitoModule,
482
+ ScVerificationModule] });
345
483
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: ScAuthModule, decorators: [{
346
484
  type: NgModule,
347
485
  args: [{
@@ -363,6 +501,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImpor
363
501
  TuiLoaderModule,
364
502
  TuiInputPhoneModule,
365
503
  MaskitoModule,
504
+ ScVerificationModule,
366
505
  ],
367
506
  exports: [ScSignInFormComponent, ScSignInFormByPhoneComponent, ScSignInFormByEmailComponent],
368
507
  }]
@@ -1095,6 +1234,47 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImpor
1095
1234
  type: Output
1096
1235
  }] } });
1097
1236
 
1237
+ /**
1238
+ * Компонент списка категорий.
1239
+ */
1240
+ class ScCategoriesListComponent {
1241
+ /**
1242
+ * Инициализирует экземпляр класса {@link ScCategoriesListComponent}.
1243
+ *
1244
+ * @param urls объект информации о базовом списке ссылок приложения.
1245
+ */
1246
+ constructor(urls) {
1247
+ this.urls = urls;
1248
+ /**
1249
+ * Событие нажатия на категорию.
1250
+ */
1251
+ this.clickCategoryEvent = new EventEmitter();
1252
+ }
1253
+ /**
1254
+ * Возвращает путь до изображения на сервере.
1255
+ *
1256
+ * @param imgPath путь, где хранится изображение.
1257
+ */
1258
+ getCategoryImage(imgPath) {
1259
+ return this.urls.imgServerUrl + '/' + imgPath;
1260
+ }
1261
+ }
1262
+ ScCategoriesListComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: ScCategoriesListComponent, deps: [{ token: SC_URLS }], target: i0.ɵɵFactoryTarget.Component });
1263
+ ScCategoriesListComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.3.0", type: ScCategoriesListComponent, selector: "sc-categories-list", inputs: { categories: "categories" }, outputs: { clickCategoryEvent: "clickCategoryEvent" }, ngImport: i0, template: "<div class=\"flex flex-col\">\n <ng-container *ngIf=\"categories; else categoriesSkeleton\">\n <button *ngFor=\"let item of $any(categories)\" class=\"flex flex-row h-11 w-full border-b justify-between items-center py-7\" (click)=\"clickCategoryEvent.emit(item)\">\n <p class=\"truncate mr-0 text-left font-bold max-w-[85%]\">{{ item.name }}</p>\n <tui-svg *ngIf=\"item.isFavorite\" src=\"scIconFavoriteFill\" class=\"text-tui-primary !text-xs mr-auto\"></tui-svg>\n <img *ngIf=\"item.properties?.image\" [src]=\"getCategoryImage(item.properties?.image)\" [alt]=\"item.name\" class=\"w-6 h-6 ml-auto\" />\n <i *ngIf=\"item.properties?.['icon'] && !item.properties?.image\" class=\"{{ item.properties?.['icon'] }} w-6 h-6 ml-auto\"></i>\n </button>\n </ng-container>\n</div>\n\n<ng-template #categoriesSkeleton>\n <button\n *ngFor=\"let _ of [].constructor(10); let index = index\"\n tuiButton\n size=\"m\"\n appearance=\"secondary\"\n tuiMode=\"onLight\"\n style.width=\"{{ ((index % 3) + 3) * 20 }}%\"\n class=\"!flex-shrink tui-skeleton my-4\"\n ></button>\n</ng-template>\n", dependencies: [{ kind: "directive", type: i2.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i2.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "component", type: i4.TuiButtonComponent, selector: "button[tuiButton], button[tuiIconButton], a[tuiButton], a[tuiIconButton]", inputs: ["appearance", "disabled", "icon", "iconRight", "shape", "showLoader", "size"] }, { kind: "component", type: i4.TuiSvgComponent, selector: "tui-svg", inputs: ["src"] }, { kind: "directive", type: i4.TuiModeDirective, selector: "[tuiMode]", inputs: ["tuiMode"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
1264
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: ScCategoriesListComponent, decorators: [{
1265
+ type: Component,
1266
+ args: [{ selector: 'sc-categories-list', changeDetection: ChangeDetectionStrategy.OnPush, template: "<div class=\"flex flex-col\">\n <ng-container *ngIf=\"categories; else categoriesSkeleton\">\n <button *ngFor=\"let item of $any(categories)\" class=\"flex flex-row h-11 w-full border-b justify-between items-center py-7\" (click)=\"clickCategoryEvent.emit(item)\">\n <p class=\"truncate mr-0 text-left font-bold max-w-[85%]\">{{ item.name }}</p>\n <tui-svg *ngIf=\"item.isFavorite\" src=\"scIconFavoriteFill\" class=\"text-tui-primary !text-xs mr-auto\"></tui-svg>\n <img *ngIf=\"item.properties?.image\" [src]=\"getCategoryImage(item.properties?.image)\" [alt]=\"item.name\" class=\"w-6 h-6 ml-auto\" />\n <i *ngIf=\"item.properties?.['icon'] && !item.properties?.image\" class=\"{{ item.properties?.['icon'] }} w-6 h-6 ml-auto\"></i>\n </button>\n </ng-container>\n</div>\n\n<ng-template #categoriesSkeleton>\n <button\n *ngFor=\"let _ of [].constructor(10); let index = index\"\n tuiButton\n size=\"m\"\n appearance=\"secondary\"\n tuiMode=\"onLight\"\n style.width=\"{{ ((index % 3) + 3) * 20 }}%\"\n class=\"!flex-shrink tui-skeleton my-4\"\n ></button>\n</ng-template>\n" }]
1267
+ }], ctorParameters: function () {
1268
+ return [{ type: undefined, decorators: [{
1269
+ type: Inject,
1270
+ args: [SC_URLS]
1271
+ }] }];
1272
+ }, propDecorators: { categories: [{
1273
+ type: Input
1274
+ }], clickCategoryEvent: [{
1275
+ type: Output
1276
+ }] } });
1277
+
1098
1278
  /**
1099
1279
  * Компонент кнопки избранных товаров и категорий.
1100
1280
  */
@@ -1836,7 +2016,8 @@ ScCatalogModule.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version
1836
2016
  ScInputQuantityComponent,
1837
2017
  ScPriceCardComponent,
1838
2018
  ScPriceWarehouseStockComponent,
1839
- ScPriceHistoryComponent], imports: [CommonModule,
2019
+ ScPriceHistoryComponent,
2020
+ ScCategoriesListComponent], imports: [CommonModule,
1840
2021
  RouterModule,
1841
2022
  TuiButtonModule,
1842
2023
  TuiSvgModule,
@@ -1857,7 +2038,8 @@ ScCatalogModule.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version
1857
2038
  ScInputQuantityComponent,
1858
2039
  ScPriceCardComponent,
1859
2040
  ScPriceWarehouseStockComponent,
1860
- ScPriceHistoryComponent] });
2041
+ ScPriceHistoryComponent,
2042
+ ScCategoriesListComponent] });
1861
2043
  ScCatalogModule.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: ScCatalogModule, imports: [CommonModule,
1862
2044
  RouterModule,
1863
2045
  TuiButtonModule,
@@ -1887,6 +2069,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImpor
1887
2069
  ScPriceCardComponent,
1888
2070
  ScPriceWarehouseStockComponent,
1889
2071
  ScPriceHistoryComponent,
2072
+ ScCategoriesListComponent,
1890
2073
  ],
1891
2074
  exports: [
1892
2075
  ScPriceListPaginationComponent,
@@ -1896,6 +2079,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImpor
1896
2079
  ScPriceCardComponent,
1897
2080
  ScPriceWarehouseStockComponent,
1898
2081
  ScPriceHistoryComponent,
2082
+ ScCategoriesListComponent,
1899
2083
  ],
1900
2084
  imports: [
1901
2085
  CommonModule,
@@ -3081,5 +3265,5 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImpor
3081
3265
  * Generated bundle index. Do not edit.
3082
3266
  */
3083
3267
 
3084
- export { AuthMethod, FilesAndDocumentsComponent, FilesAndDocumentsModule, SC_LINEAR_VALUES, SC_LINEAR_VALUES_TOKEN, SC_LOADING_PAGINATION_CHANGE_INFO, SC_NEXT_PAGE_PAGINATION_CHANGE_INFO, SC_NEXT_PAGE_PAGINATION_CLICK, SC_PRODUCT_PAGINATION_CHANGE_INFO, SC_PRODUCT_PAGINATION_CHANGE_PROVIDERS, SC_PRODUCT_PAGINATION_DEFAULT_OPTIONS, SC_PRODUCT_PAGINATION_OPTIONS, SC_PRODUCT_PAGINATION_PARAMS, SC_USER_INFO, SC_USER_PROVIDERS, ScAccordionComponent, ScAccordionContentDirective, ScAccordionModule, ScAuthModule, ScBannerComponent, ScBannerModule, ScCartItemMobileComponent, ScCartModule, ScCatalogModule, ScCategoryCardComponent, ScContactsAccordionComponent, ScContactsModule, ScContragentsAccordionComponent, ScContragentsAccordionItemComponent, ScContragentsModule, ScDeliveryAddressAccordionComponent, ScDeliveryAddressAccordionItemComponent, ScDeliveryAddressModule, ScFavoriteBtnComponent, ScInputQuantityComponent, ScNewsCardComponent, ScNewsCardSkeletonComponent, ScNewsModule, ScOrderItemMobileComponent, ScOrderModule, ScPriceCardComponent, ScPriceHistoryComponent, ScPriceListPaginationComponent, ScPriceWarehouseStockComponent, ScProfileAccordionsContentComponent, ScProfileModule, ScResetUserPasswordComponent, ScShareButtonComponent, ScShareButtonModule, ScSignInFormByEmailComponent, ScSignInFormByPhoneComponent, ScSignInFormComponent, ScUserModule, TreeDirective, TreeIconService, TreeLoaderService, TreeTopDirective, nextPageClickEvent, paginationParams$, phoneApproveCodeMask, scClientUiIconsName, scPasswordConfirmMatchingValidator, scUserFactory, stepValidator };
3268
+ export { AuthMethod, FilesAndDocumentsComponent, FilesAndDocumentsModule, SC_LINEAR_VALUES, SC_LINEAR_VALUES_TOKEN, SC_LOADING_PAGINATION_CHANGE_INFO, SC_NEXT_PAGE_PAGINATION_CHANGE_INFO, SC_NEXT_PAGE_PAGINATION_CLICK, SC_PRODUCT_PAGINATION_CHANGE_INFO, SC_PRODUCT_PAGINATION_CHANGE_PROVIDERS, SC_PRODUCT_PAGINATION_DEFAULT_OPTIONS, SC_PRODUCT_PAGINATION_OPTIONS, SC_PRODUCT_PAGINATION_PARAMS, SC_USER_INFO, SC_USER_PROVIDERS, ScAccordionComponent, ScAccordionContentDirective, ScAccordionModule, ScAuthModule, ScBannerComponent, ScBannerModule, ScCartItemMobileComponent, ScCartModule, ScCatalogModule, ScCategoriesListComponent, ScCategoryCardComponent, ScContactsAccordionComponent, ScContactsModule, ScContragentsAccordionComponent, ScContragentsAccordionItemComponent, ScContragentsModule, ScDeliveryAddressAccordionComponent, ScDeliveryAddressAccordionItemComponent, ScDeliveryAddressModule, ScFavoriteBtnComponent, ScInputQuantityComponent, ScNewsCardComponent, ScNewsCardSkeletonComponent, ScNewsModule, ScOrderItemMobileComponent, ScOrderModule, ScPhoneApproveFormComponent, ScPriceCardComponent, ScPriceHistoryComponent, ScPriceListPaginationComponent, ScPriceWarehouseStockComponent, ScProfileAccordionsContentComponent, ScProfileModule, ScResetUserPasswordComponent, ScShareButtonComponent, ScShareButtonModule, ScSignInFormByEmailComponent, ScSignInFormByPhoneComponent, ScSignInFormComponent, ScUserModule, ScVerificationModule, TreeDirective, TreeIconService, TreeLoaderService, TreeTopDirective, nextPageClickEvent, paginationParams$, phoneApproveCodeMask, scClientUiIconsName, scPasswordConfirmMatchingValidator, scUserFactory, stepValidator };
3085
3269
  //# sourceMappingURL=snabcentr-client-ui.mjs.map