@snabcentr/client-ui 3.47.8 → 3.48.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.
- package/catalog/catalog-filters/index.d.ts +3 -0
- package/catalog/catalog-filters/sc-catalog-filters.component.d.ts +99 -0
- package/catalog/catalog-filters/tokens/sc-catalog-products-filters.d.ts +7 -0
- package/catalog/catalog-filters/tokens/sc-catalog-show-products-recursively.d.ts +5 -0
- package/catalog/index.d.ts +1 -0
- package/esm2022/catalog/catalog-filters/index.mjs +4 -0
- package/esm2022/catalog/catalog-filters/sc-catalog-filters.component.mjs +202 -0
- package/esm2022/catalog/catalog-filters/tokens/sc-catalog-products-filters.mjs +10 -0
- package/esm2022/catalog/catalog-filters/tokens/sc-catalog-show-products-recursively.mjs +6 -0
- package/esm2022/catalog/index.mjs +2 -1
- package/esm2022/methods/index.mjs +2 -0
- package/esm2022/methods/sc-get-current-route.mjs +14 -0
- package/esm2022/pages/frequently-asked-questions-with-groups/sc-frequently-asked-questions-with-groups.component.mjs +3 -2
- package/esm2022/providers/index.mjs +2 -1
- package/esm2022/providers/sc-category.providers.mjs +43 -0
- package/esm2022/public-api.mjs +2 -1
- package/fesm2022/snabcentr-client-ui.mjs +397 -151
- package/fesm2022/snabcentr-client-ui.mjs.map +1 -1
- package/methods/index.d.ts +1 -0
- package/methods/sc-get-current-route.d.ts +8 -0
- package/package.json +19 -19
- package/providers/index.d.ts +1 -0
- package/providers/sc-category.providers.d.ts +11 -0
- package/public-api.d.ts +1 -0
- package/styles/tailwind/tailwind.scss +5 -1
|
@@ -1,17 +1,17 @@
|
|
|
1
1
|
import * as i0 from '@angular/core';
|
|
2
|
-
import { inject, Injectable, EventEmitter, signal, ChangeDetectorRef, Directive, Input, Output, InjectionToken, Pipe, ElementRef, HostListener, Renderer2, ContentChildren, NgModule,
|
|
2
|
+
import { inject, Injectable, EventEmitter, signal, ChangeDetectorRef, Directive, Input, Output, computed, output, effect, Component, ChangeDetectionStrategy, input, InjectionToken, Pipe, ElementRef, HostListener, Renderer2, ContentChildren, NgModule, Inject, HostBinding, model, SkipSelf, DestroyRef, ContentChild, ViewChild, Optional, viewChild, forwardRef } from '@angular/core';
|
|
3
3
|
import * as i1 from '@snabcentr/client-core';
|
|
4
|
-
import { ScContactsService, ScUserService, ScAuthService, SEARCH_TERM, ScUnitsHelper, ScImageHelper, SC_PATH_IMAGE_NOT_FOUND, ScImage, ScLocationsService, ScPhoneService, ScUserMetrikaService, ScUserMetrikaGoalsEnum, IS_RUNNING_ON_TERMINAL, ScVCardService, ScVerificationService, ScISuggestionType, SC_MIN_LENGTH_SEARCH_TERM, ScConvertersService, ScOpfList, ScReferencesService, ScContragentService, ScMediaImageTransformerPipe, ScMimeTypes,
|
|
4
|
+
import { ScContactsService, ScUserService, ScAuthService, SEARCH_TERM, ScUnitsHelper, ScImageHelper, SC_PATH_IMAGE_NOT_FOUND, ScImage, IS_SERVER, RESPONSE, ScCatalogService, ScLocationsService, ScPhoneService, ScUserMetrikaService, ScUserMetrikaGoalsEnum, IS_RUNNING_ON_TERMINAL, ScVCardService, ScVerificationService, ScISuggestionType, SC_MIN_LENGTH_SEARCH_TERM, ScConvertersService, ScOpfList, ScReferencesService, ScContragentService, ScMediaImageTransformerPipe, ScMimeTypes, SC_URLS, ScWarehouseService, SEARCH_TERM_PROVIDERS, ScPaginationService, SC_NEXT_PAGE_PAGINATION_CLICK, SC_PRODUCT_PAGINATION_OPTIONS, ScCatalogFilterService, ScIdOrSlugPipe, ScCartService, ScUploadedFile, ScConfiguratorService, ScIconTypesEnum, ScDocumentInfoTypesEnum, ScFrequentlyAskedQuestionsService, SC_COMPANY_INFO, ScFeedbackService, ScJsonLdModule } from '@snabcentr/client-core';
|
|
5
5
|
import * as i6$1 from 'rxjs';
|
|
6
|
-
import { EMPTY, BehaviorSubject, switchMap, of, shareReplay,
|
|
6
|
+
import { EMPTY, BehaviorSubject, switchMap, of, shareReplay, noop, filter, map, startWith, catchError, Subject, tap, finalize, share, timer, scan, takeWhile, endWith, distinctUntilChanged, debounceTime, throwError, combineLatest, Observable, pairwise, first, merge, skip } from 'rxjs';
|
|
7
7
|
import * as i6 from '@taiga-ui/cdk';
|
|
8
|
-
import { tuiCreateToken, tuiCreateTokenFromFactory, TUI_IS_MOBILE, TuiDay, TuiTime, TuiValueTransformer, tuiControlValue,
|
|
9
|
-
import {
|
|
8
|
+
import { tuiCreateToken, tuiCreateTokenFromFactory, TUI_IS_MOBILE, tuiIsPresent, TuiDay, TuiTime, TuiValueTransformer, tuiControlValue, tuiMarkControlAsTouchedAndValidate, tuiIsFalsy, TuiLet, TuiAutoFocus, TuiRepeatTimes, TuiHovered, TuiDayRange, TuiMonth, tuiPure, TUI_WINDOW_SIZE, TuiValidationError, TUI_TRUE_HANDLER } from '@taiga-ui/cdk';
|
|
9
|
+
import { HttpErrorResponse, HttpClient } from '@angular/common/http';
|
|
10
10
|
import { takeUntilDestroyed, toSignal, outputFromObservable, toObservable } from '@angular/core/rxjs-interop';
|
|
11
11
|
import * as i1$1 from '@angular/forms';
|
|
12
12
|
import { FormControl, FormGroupDirective, NgControl, FormGroup, Validators, FormArray, FormsModule, ReactiveFormsModule } from '@angular/forms';
|
|
13
13
|
import * as i1$2 from '@taiga-ui/core';
|
|
14
|
-
import { TuiButton,
|
|
14
|
+
import { TuiButton, TuiAppearance, TuiWithAppearance, TuiIcons, TuiWithIcons, TuiDialog, TuiDialogService, TuiLink, TuiFallbackSrcPipe, TuiInitialsPipe, TuiIcon, TUI_DATA_LIST_HOST, tuiDropdownOptionsProvider, TuiLabel, TuiError, TuiLoader, TuiDataList, TuiNotification, TuiTextfield, TuiTitle, TuiHint, TUI_MONTHS, TuiFormatNumberPipe, TuiNumberFormat, tuiNumberFormatProvider, tuiItemsHandlersProvider, TUI_BUTTON_OPTIONS, TUI_BUTTON_DEFAULT_OPTIONS, TuiScrollbar, TuiSurface, tuiFadeIn } from '@taiga-ui/core';
|
|
15
15
|
import { isValidPhoneNumber } from 'libphonenumber-js/max';
|
|
16
16
|
import * as i4 from '@taiga-ui/legacy/components/primitive-textfield';
|
|
17
17
|
import * as i3 from '@taiga-ui/legacy';
|
|
@@ -22,9 +22,11 @@ import * as i5 from '@taiga-ui/core/components/label';
|
|
|
22
22
|
import * as i8 from '@maskito/angular';
|
|
23
23
|
import { MaskitoDirective } from '@maskito/angular';
|
|
24
24
|
import * as i2$1 from '@taiga-ui/kit';
|
|
25
|
-
import { TUI_DATE_VALUE_TRANSFORMER, TuiPreview, TuiAvatar, TuiAccordionItem, TuiElasticContainer, TuiAccordion, TuiFieldErrorPipe, TuiFilterByInputPipe, TuiStringifyContentPipe, TuiDataListWrapper, TuiButtonLoading, TuiSortCountriesPipe, TuiStepper, TuiCarousel, TuiPush, TuiCheckbox, TuiBadge, TuiTooltip, TuiHighlight, TuiLineClamp, TuiPreviewDialogService, TuiFiles, TuiChip, TuiInputNumber, tuiInputNumberOptionsProvider, TuiDataListWrapperComponent, TuiChevron, TuiSelect, TuiInputSlider, TuiTreeService, TuiTreeItemContent, TUI_TREE_START, TUI_TREE_CONTENT, TUI_TREE_LOADING, TUI_TREE_LOADER, TuiTree, tuiItemsHandlersProvider as tuiItemsHandlersProvider$1, TuiPagination, TuiAccordionDirective, TuiAccordionItemContent, tuiFilesAccepted } from '@taiga-ui/kit';
|
|
25
|
+
import { TUI_DATE_VALUE_TRANSFORMER, TuiPreview, TuiAvatar, TuiAccordionItem, TuiElasticContainer, TuiAccordion, TuiFieldErrorPipe, TuiFilterByInputPipe, TuiStringifyContentPipe, TuiDataListWrapper, TuiButtonLoading, TuiSortCountriesPipe, TuiStepper, TuiCarousel, TuiPush, TuiCheckbox, TuiBadge, TuiTooltip, TuiHighlight, TuiLineClamp, TuiInputRange, TuiPreviewDialogService, TuiFiles, TuiChip, TuiInputNumber, tuiInputNumberOptionsProvider, TuiDataListWrapperComponent, TuiChevron, TuiSelect, TuiInputSlider, TuiTreeService, TuiTreeItemContent, TUI_TREE_START, TUI_TREE_CONTENT, TUI_TREE_LOADING, TUI_TREE_LOADER, TuiTree, tuiItemsHandlersProvider as tuiItemsHandlersProvider$1, TuiPagination, TuiAccordionDirective, TuiAccordionItemContent, tuiFilesAccepted } from '@taiga-ui/kit';
|
|
26
26
|
import * as i2$2 from '@angular/common';
|
|
27
27
|
import { DOCUMENT, CommonModule, NgIf, AsyncPipe, NgFor, NgClass } from '@angular/common';
|
|
28
|
+
import * as i2$4 from '@angular/router';
|
|
29
|
+
import { ActivatedRoute, RouterLink, Router, NavigationStart, NavigationEnd, RouterModule } from '@angular/router';
|
|
28
30
|
import * as i2$3 from '@taiga-ui/polymorpheus';
|
|
29
31
|
import { POLYMORPHEUS_CONTEXT, PolymorpheusComponent, PolymorpheusTemplate, PolymorpheusOutlet, injectContext } from '@taiga-ui/polymorpheus';
|
|
30
32
|
import * as i2 from 'angularx-qrcode';
|
|
@@ -35,8 +37,6 @@ import * as i3$1 from '@taiga-ui/core/components/data-list';
|
|
|
35
37
|
import * as i1$4 from '@taiga-ui/cdk/directives/item';
|
|
36
38
|
import * as i3$2 from '@ng-web-apis/intersection-observer';
|
|
37
39
|
import { IntersectionObserverService, WaIntersectionObserver } from '@ng-web-apis/intersection-observer';
|
|
38
|
-
import * as i2$4 from '@angular/router';
|
|
39
|
-
import { RouterModule, ActivatedRoute, RouterLink, Router, NavigationStart } from '@angular/router';
|
|
40
40
|
import { TuiCurrencyPipe, TuiAmountPipe } from '@taiga-ui/addon-commerce';
|
|
41
41
|
import { WA_WINDOW } from '@ng-web-apis/common';
|
|
42
42
|
import * as i1$5 from '@taiga-ui/layout';
|
|
@@ -44,12 +44,12 @@ import { TuiCardLarge, TuiBlockStatus, TuiHeader } from '@taiga-ui/layout';
|
|
|
44
44
|
import { __decorate } from 'tslib';
|
|
45
45
|
import * as i5$1 from '@taiga-ui/addon-charts';
|
|
46
46
|
import { TuiLineDaysChart, TuiLineDaysChartHint, TuiAxes } from '@taiga-ui/addon-charts';
|
|
47
|
+
import * as i2$5 from '@taiga-ui/experimental/components/expand';
|
|
47
48
|
import { TuiAppearance as TuiAppearance$1, TuiWithAppearance as TuiWithAppearance$1 } from '@taiga-ui/core/directives/appearance';
|
|
48
49
|
import { TuiIcons as TuiIcons$1, TuiWithIcons as TuiWithIcons$1 } from '@taiga-ui/core/directives/icons';
|
|
49
50
|
import * as i5$2 from '@taiga-ui/kit/components/slider';
|
|
50
51
|
import * as i9 from 'angular8-yandex-maps';
|
|
51
52
|
import { AngularYandexMapsModule } from 'angular8-yandex-maps';
|
|
52
|
-
import * as i2$5 from '@taiga-ui/experimental/components/expand';
|
|
53
53
|
import * as i3$3 from '@taiga-ui/kit/components/data-list-wrapper';
|
|
54
54
|
import { TuiGroup } from '@taiga-ui/core/directives/group';
|
|
55
55
|
import * as i4$1 from 'ng-recaptcha-2';
|
|
@@ -408,6 +408,194 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImpo
|
|
|
408
408
|
type: Output
|
|
409
409
|
}] } });
|
|
410
410
|
|
|
411
|
+
/**
|
|
412
|
+
* Токен обработчика смены ошибки.
|
|
413
|
+
*/
|
|
414
|
+
// eslint-disable-next-line unicorn/consistent-function-scoping
|
|
415
|
+
const SC_ERROR_CHANGE_HANDLER = tuiCreateTokenFromFactory(() => () => noop);
|
|
416
|
+
|
|
417
|
+
/**
|
|
418
|
+
* Компонент представления данных об ошибке.
|
|
419
|
+
*/
|
|
420
|
+
class ScErrorBlockStatusComponent {
|
|
421
|
+
/**
|
|
422
|
+
* Инициализирует экземпляр класса {@link ErrorPageComponent}.
|
|
423
|
+
*/
|
|
424
|
+
constructor() {
|
|
425
|
+
/**
|
|
426
|
+
* Компонент управляющий кодом ошибки отображаемой на странице.
|
|
427
|
+
*/
|
|
428
|
+
this.errorHandlerComponent = inject(ScErrorHandlerComponent, { skipSelf: true });
|
|
429
|
+
/**
|
|
430
|
+
* Сигнал кода ошибки.
|
|
431
|
+
*/
|
|
432
|
+
this.code = this.errorHandlerComponent.getErrorCode();
|
|
433
|
+
/**
|
|
434
|
+
* Данные об ошибке.
|
|
435
|
+
*/
|
|
436
|
+
// eslint-disable-next-line unicorn/consistent-function-scoping
|
|
437
|
+
this.error = computed(() => this.getErrorMessage(this.code()));
|
|
438
|
+
/**
|
|
439
|
+
* Создает сигнал изменения строкового представления об ошибке.
|
|
440
|
+
*/
|
|
441
|
+
this.pageErrorChange = output();
|
|
442
|
+
/**
|
|
443
|
+
* Признак, что текущий скрипт исполняется на сервере.
|
|
444
|
+
*/
|
|
445
|
+
this.isServer = inject(IS_SERVER);
|
|
446
|
+
/**
|
|
447
|
+
* Данные об ответе на запрос.
|
|
448
|
+
*/
|
|
449
|
+
this.response = inject(RESPONSE, { optional: true });
|
|
450
|
+
// Если компонент отображён маршрутизацией из-за перехода по неизвестному маршруту, то устанавливаем код 404.
|
|
451
|
+
if (inject(ActivatedRoute).snapshot.data['routes_key'] === 'error') {
|
|
452
|
+
this.errorHandlerComponent.setErrorCode(404);
|
|
453
|
+
}
|
|
454
|
+
effect(() => {
|
|
455
|
+
if (this.code() !== null) {
|
|
456
|
+
this.pageErrorChange.emit(this.error());
|
|
457
|
+
if (this.isServer) {
|
|
458
|
+
this.response?.status(this.code() ?? 0);
|
|
459
|
+
}
|
|
460
|
+
}
|
|
461
|
+
});
|
|
462
|
+
}
|
|
463
|
+
/**
|
|
464
|
+
* Возвращает описание ошибки.
|
|
465
|
+
*
|
|
466
|
+
* @param code Код ошибки.
|
|
467
|
+
*/
|
|
468
|
+
// eslint-disable-next-line class-methods-use-this
|
|
469
|
+
getErrorMessage(code) {
|
|
470
|
+
switch (code) {
|
|
471
|
+
case 403:
|
|
472
|
+
return {
|
|
473
|
+
message: 'К сожалению, у вас нет доступа к этому ресурсу',
|
|
474
|
+
description: 'Воспользуйтесь навигацией в шапке или подвале сайта, чтобы перейти в интересующий вас раздел',
|
|
475
|
+
code,
|
|
476
|
+
};
|
|
477
|
+
case 404:
|
|
478
|
+
return {
|
|
479
|
+
message: 'К сожалению, такой страницы нет',
|
|
480
|
+
description: 'Воспользуйтесь навигацией в шапке или подвале сайта, чтобы перейти в интересующий вас раздел',
|
|
481
|
+
code,
|
|
482
|
+
};
|
|
483
|
+
default:
|
|
484
|
+
return {
|
|
485
|
+
message: 'Неизвестная ошибка',
|
|
486
|
+
description: 'Пожалуйста обновите страницу или обратитесь к менеджеру',
|
|
487
|
+
code: 0,
|
|
488
|
+
};
|
|
489
|
+
}
|
|
490
|
+
}
|
|
491
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: ScErrorBlockStatusComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
492
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.14", type: ScErrorBlockStatusComponent, isStandalone: true, selector: "sc-error-block-status", outputs: { pageErrorChange: "pageErrorChange" }, ngImport: i0, template: "<div class=\"flex flex-col items-center gap-8\">\n <div class=\"border-20 border-solid border-tui-primary text-center sm:border-32\">\n <div class=\"text-8xl leading-1.15 text-black sm:text-44\">\n {{ error().code }}\n </div>\n <div class=\"text-6xl leading-1.15 text-tui-primary sm:text-8xl\">ERROR</div>\n </div>\n <div class=\"flex flex-col gap-2 text-center\">\n <div class=\"text-h5 sm:text-h4\">{{ error().message }}</div>\n <div class=\"text-body-m-bold sm:text-h6\">{{ error().description }}</div>\n </div>\n <button\n tuiButton\n appearance=\"primary\"\n routerLink=\"/\"\n >\n \u0412\u0435\u0440\u043D\u0443\u0442\u044C\u0441\u044F \u043D\u0430 \u0433\u043B\u0430\u0432\u043D\u0443\u044E\n </button>\n</div>\n", dependencies: [{ kind: "directive", type: TuiButton, selector: "a[tuiButton],button[tuiButton],a[tuiIconButton],button[tuiIconButton]", inputs: ["size"] }, { kind: "directive", type: RouterLink, selector: "[routerLink]", inputs: ["target", "queryParams", "fragment", "queryParamsHandling", "state", "info", "relativeTo", "preserveFragment", "skipLocationChange", "replaceUrl", "routerLink"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
|
|
493
|
+
}
|
|
494
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: ScErrorBlockStatusComponent, decorators: [{
|
|
495
|
+
type: Component,
|
|
496
|
+
args: [{ standalone: true, selector: 'sc-error-block-status', imports: [TuiAppearance, TuiWithAppearance, TuiIcons, TuiWithIcons, TuiButton, RouterLink], changeDetection: ChangeDetectionStrategy.OnPush, template: "<div class=\"flex flex-col items-center gap-8\">\n <div class=\"border-20 border-solid border-tui-primary text-center sm:border-32\">\n <div class=\"text-8xl leading-1.15 text-black sm:text-44\">\n {{ error().code }}\n </div>\n <div class=\"text-6xl leading-1.15 text-tui-primary sm:text-8xl\">ERROR</div>\n </div>\n <div class=\"flex flex-col gap-2 text-center\">\n <div class=\"text-h5 sm:text-h4\">{{ error().message }}</div>\n <div class=\"text-body-m-bold sm:text-h6\">{{ error().description }}</div>\n </div>\n <button\n tuiButton\n appearance=\"primary\"\n routerLink=\"/\"\n >\n \u0412\u0435\u0440\u043D\u0443\u0442\u044C\u0441\u044F \u043D\u0430 \u0433\u043B\u0430\u0432\u043D\u0443\u044E\n </button>\n</div>\n" }]
|
|
497
|
+
}], ctorParameters: () => [] });
|
|
498
|
+
|
|
499
|
+
/**
|
|
500
|
+
* Компонент для управления кодом ошибки отображаемой на странице.
|
|
501
|
+
*/
|
|
502
|
+
class ScErrorHandlerComponent {
|
|
503
|
+
/**
|
|
504
|
+
* Инициирует экземпляр класса {@link ErrorHandlerComponent}.
|
|
505
|
+
*/
|
|
506
|
+
constructor() {
|
|
507
|
+
/**
|
|
508
|
+
* Сигнал для хранения кода ошибки.
|
|
509
|
+
*/
|
|
510
|
+
this.code = signal(null);
|
|
511
|
+
/**
|
|
512
|
+
* Сигнал дефолтного передаваемого из вне значения ошибки.
|
|
513
|
+
*/
|
|
514
|
+
// eslint-disable-next-line @angular-eslint/no-input-rename
|
|
515
|
+
this.defaultCode = input(null, { alias: 'code' });
|
|
516
|
+
/**
|
|
517
|
+
* Сервис маршрутизации.
|
|
518
|
+
*/
|
|
519
|
+
this.router = inject(Router);
|
|
520
|
+
/**
|
|
521
|
+
* Обработчик изменения ошибки.
|
|
522
|
+
*/
|
|
523
|
+
this.errorChangeHandler = inject(SC_ERROR_CHANGE_HANDLER);
|
|
524
|
+
this.router.events.pipe(filter((event) => event instanceof NavigationStart)).subscribe(() => {
|
|
525
|
+
// Сбрасываем ошибку при переходе на новый маршрут.
|
|
526
|
+
this.code.set(this.defaultCode());
|
|
527
|
+
});
|
|
528
|
+
}
|
|
529
|
+
/**
|
|
530
|
+
* Возвращает текущий сигнал с кодом ошибки.
|
|
531
|
+
*/
|
|
532
|
+
getErrorCode() {
|
|
533
|
+
return this.code;
|
|
534
|
+
}
|
|
535
|
+
/**
|
|
536
|
+
* Устанавливает новый код ошибки.
|
|
537
|
+
*
|
|
538
|
+
* @param code Новый код ошибки.
|
|
539
|
+
*/
|
|
540
|
+
setErrorCode(code) {
|
|
541
|
+
this.code.set(code);
|
|
542
|
+
}
|
|
543
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: ScErrorHandlerComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
544
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.2.14", type: ScErrorHandlerComponent, isStandalone: true, selector: "sc-error-handler", inputs: { defaultCode: { classPropertyName: "defaultCode", publicName: "code", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0, template: "@if (code() === null) {\n <ng-content />\n} @else {\n <sc-error-block-status (pageErrorChange)=\"errorChangeHandler($event)\"></sc-error-block-status>\n}\n", dependencies: [{ kind: "component", type: ScErrorBlockStatusComponent, selector: "sc-error-block-status", outputs: ["pageErrorChange"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
|
|
545
|
+
}
|
|
546
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: ScErrorHandlerComponent, decorators: [{
|
|
547
|
+
type: Component,
|
|
548
|
+
args: [{ standalone: true, selector: 'sc-error-handler', imports: [ScErrorBlockStatusComponent], changeDetection: ChangeDetectionStrategy.OnPush, template: "@if (code() === null) {\n <ng-content />\n} @else {\n <sc-error-block-status (pageErrorChange)=\"errorChangeHandler($event)\"></sc-error-block-status>\n}\n" }]
|
|
549
|
+
}], ctorParameters: () => [] });
|
|
550
|
+
|
|
551
|
+
/**
|
|
552
|
+
* Возвращает текущий маршрут.
|
|
553
|
+
* Функция проходит по дереву маршрутов начиная с переданного route и возвращает самый вложенный активный маршрут.
|
|
554
|
+
*
|
|
555
|
+
* @param route Данные маршрута, от которого ищем текущий маршрут в приложении.
|
|
556
|
+
*/
|
|
557
|
+
const scGetCurrentRoute = (route) => {
|
|
558
|
+
let currentRoute = route;
|
|
559
|
+
while (currentRoute.firstChild) {
|
|
560
|
+
currentRoute = currentRoute.firstChild;
|
|
561
|
+
}
|
|
562
|
+
return currentRoute;
|
|
563
|
+
};
|
|
564
|
+
|
|
565
|
+
/**
|
|
566
|
+
* Токен потока данных о категории.
|
|
567
|
+
*/
|
|
568
|
+
const SC_CATEGORY_INFO = new InjectionToken('A stream with current category information');
|
|
569
|
+
/**
|
|
570
|
+
* Фабрика создания потока данных о категории.
|
|
571
|
+
*
|
|
572
|
+
* @param router Сервис маршрутизации.
|
|
573
|
+
* @param route Маршрут.
|
|
574
|
+
* @param catalogService Сервис для работы с каталогом.
|
|
575
|
+
* @param catalogService.paramMap Параметры.
|
|
576
|
+
* @param errorHandlerComponent Компонент для управления кодом ошибки отображаемой на странице.
|
|
577
|
+
*/
|
|
578
|
+
function categoryFactory(router, route, catalogService, errorHandlerComponent) {
|
|
579
|
+
return router.events
|
|
580
|
+
.pipe(filter((event) => event instanceof NavigationEnd), map(() => scGetCurrentRoute(route).snapshot.paramMap), startWith(scGetCurrentRoute(route).snapshot.paramMap))
|
|
581
|
+
.pipe(map((parameters) => parameters.get('categoryIdOrSlug')), filter(tuiIsPresent), switchMap((categoryId) => catalogService.getCategoryCached$(categoryId).pipe(catchError((error) => {
|
|
582
|
+
if (error instanceof HttpErrorResponse) {
|
|
583
|
+
errorHandlerComponent.setErrorCode(error.status);
|
|
584
|
+
}
|
|
585
|
+
return EMPTY;
|
|
586
|
+
}), shareReplay())), takeUntilDestroyed());
|
|
587
|
+
}
|
|
588
|
+
/**
|
|
589
|
+
* Провайдеры потока данных о категории.
|
|
590
|
+
*/
|
|
591
|
+
const SC_CATEGORY_PROVIDERS = [
|
|
592
|
+
{
|
|
593
|
+
provide: SC_CATEGORY_INFO,
|
|
594
|
+
deps: [Router, ActivatedRoute, ScCatalogService, ScErrorHandlerComponent],
|
|
595
|
+
useFactory: categoryFactory,
|
|
596
|
+
},
|
|
597
|
+
];
|
|
598
|
+
|
|
411
599
|
/**
|
|
412
600
|
* Токен признака, что разрешено выбирать записи ликвидированных организаций.
|
|
413
601
|
*/
|
|
@@ -5119,6 +5307,203 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImpo
|
|
|
5119
5307
|
}]
|
|
5120
5308
|
}] });
|
|
5121
5309
|
|
|
5310
|
+
/**
|
|
5311
|
+
* Токен для инъекции {@link Subject} для хранения фильтров продуктов.
|
|
5312
|
+
*/
|
|
5313
|
+
const SC_CATALOG_PRODUCTS_FILTERS = new InjectionToken('SC_CATALOG_PRODUCTS_FILTERS$', {
|
|
5314
|
+
providedIn: 'root',
|
|
5315
|
+
factory: () => new Subject(),
|
|
5316
|
+
});
|
|
5317
|
+
|
|
5318
|
+
/**
|
|
5319
|
+
* Токен для инъекции признака необходимости отображать фильтры для вложенных категорий.
|
|
5320
|
+
*/
|
|
5321
|
+
const SC_CATALOG_SHOW_PRODUCTS_RECURSIVELY = new InjectionToken('SC_CATALOG_SHOW_PRODUCTS_RECURSIVELY');
|
|
5322
|
+
|
|
5323
|
+
/* eslint-disable class-methods-use-this */
|
|
5324
|
+
/**
|
|
5325
|
+
* Компонент вывода фильтров каталога.
|
|
5326
|
+
*/
|
|
5327
|
+
class ScCatalogFiltersComponent {
|
|
5328
|
+
/**
|
|
5329
|
+
* Инициализирует экземпляр класса {@link ScCatalogFiltersComponent}.
|
|
5330
|
+
*/
|
|
5331
|
+
constructor() {
|
|
5332
|
+
/**
|
|
5333
|
+
* Состояние открытия accordion.
|
|
5334
|
+
*/
|
|
5335
|
+
this.isOpenAccordion = input(false);
|
|
5336
|
+
/**
|
|
5337
|
+
* Сервис для работы с фильтрами каталога.
|
|
5338
|
+
*/
|
|
5339
|
+
this.catalogFilterService = inject(ScCatalogFilterService);
|
|
5340
|
+
/**
|
|
5341
|
+
* Пайп, возвращающий идентификатор или символьное обозначение (slug) исходя из настроек окружения.
|
|
5342
|
+
*/
|
|
5343
|
+
this.idOrSlugPipe = inject(ScIdOrSlugPipe);
|
|
5344
|
+
/**
|
|
5345
|
+
* Subject для хранения фильтров продуктов.
|
|
5346
|
+
*/
|
|
5347
|
+
this.catalogProductsFilters$ = inject(SC_CATALOG_PRODUCTS_FILTERS);
|
|
5348
|
+
/**
|
|
5349
|
+
* Признак необходимости отображать фильтры для вложенных категорий.
|
|
5350
|
+
*/
|
|
5351
|
+
this.isRecursively = inject(SC_CATALOG_SHOW_PRODUCTS_RECURSIVELY);
|
|
5352
|
+
/**
|
|
5353
|
+
* {@link Observable} фильтров категории.
|
|
5354
|
+
*/
|
|
5355
|
+
this.filters = toSignal(inject(SC_CATEGORY_INFO).pipe(filter(tuiIsPresent), switchMap((category) => this.catalogFilterService.getFilters$(this.idOrSlugPipe.transform(category), this.isRecursively)), map((filters) => filters.filter((item) => item.type !== 'range' || item.min !== item.max)), tap((filters) => {
|
|
5356
|
+
// Обновляем состав контролов формы на основе полученных фильтров.
|
|
5357
|
+
this.updateFormControls(filters);
|
|
5358
|
+
}), share()), { initialValue: [] });
|
|
5359
|
+
/**
|
|
5360
|
+
* FormGroup для фильтров.
|
|
5361
|
+
*/
|
|
5362
|
+
this.form = new FormGroup({});
|
|
5363
|
+
this.form.valueChanges.pipe(debounceTime(0), takeUntilDestroyed()).subscribe((filters) => {
|
|
5364
|
+
this.catalogProductsFilters$.next(this.buildPropertyFilters(filters));
|
|
5365
|
+
});
|
|
5366
|
+
}
|
|
5367
|
+
/**
|
|
5368
|
+
* Обновляет состав контролов формы на основе переданных фильтров.
|
|
5369
|
+
*
|
|
5370
|
+
* @param filters Массив фильтров для создания контролов.
|
|
5371
|
+
*/
|
|
5372
|
+
updateFormControls(filters) {
|
|
5373
|
+
Object.keys(this.form.controls).forEach((key) => {
|
|
5374
|
+
this.form.removeControl(key, { emitEvent: false });
|
|
5375
|
+
});
|
|
5376
|
+
filters.forEach((item) => {
|
|
5377
|
+
switch (item.type) {
|
|
5378
|
+
case 'checkbox':
|
|
5379
|
+
this.form.addControl(item.id, this.createCheckboxFormControl(item), { emitEvent: false });
|
|
5380
|
+
break;
|
|
5381
|
+
case 'range':
|
|
5382
|
+
this.form.addControl(item.id, this.createRangeFormControl(item), { emitEvent: false });
|
|
5383
|
+
break;
|
|
5384
|
+
case 'toggle':
|
|
5385
|
+
this.form.addControl(item.id, this.createToggleFormControl(item), { emitEvent: false });
|
|
5386
|
+
break;
|
|
5387
|
+
default:
|
|
5388
|
+
break;
|
|
5389
|
+
}
|
|
5390
|
+
});
|
|
5391
|
+
this.form.updateValueAndValidity();
|
|
5392
|
+
}
|
|
5393
|
+
/**
|
|
5394
|
+
* Преобразует значения формы в объект фильтров свойств.
|
|
5395
|
+
*
|
|
5396
|
+
* @param value Значения формы.
|
|
5397
|
+
* @returns Объект фильтров свойств.
|
|
5398
|
+
*/
|
|
5399
|
+
buildPropertyFilters(value) {
|
|
5400
|
+
const result = {};
|
|
5401
|
+
this.filters().forEach((filterItem) => {
|
|
5402
|
+
const controlValue = value[filterItem.id];
|
|
5403
|
+
if (isNil(controlValue)) {
|
|
5404
|
+
return;
|
|
5405
|
+
}
|
|
5406
|
+
switch (filterItem.type) {
|
|
5407
|
+
case 'checkbox':
|
|
5408
|
+
this.processCheckboxFilter(result, filterItem.id, controlValue);
|
|
5409
|
+
break;
|
|
5410
|
+
case 'range':
|
|
5411
|
+
this.processRangeFilter(result, filterItem.id, controlValue);
|
|
5412
|
+
break;
|
|
5413
|
+
case 'toggle':
|
|
5414
|
+
this.processToggleFilter(result, filterItem.id, controlValue);
|
|
5415
|
+
break;
|
|
5416
|
+
default:
|
|
5417
|
+
break;
|
|
5418
|
+
}
|
|
5419
|
+
});
|
|
5420
|
+
return result;
|
|
5421
|
+
}
|
|
5422
|
+
/**
|
|
5423
|
+
* Создает FormGroup для checkbox.
|
|
5424
|
+
*
|
|
5425
|
+
* @param checkboxFilter Фильтр типа checkbox.
|
|
5426
|
+
*/
|
|
5427
|
+
createCheckboxFormControl(checkboxFilter) {
|
|
5428
|
+
const controls = {};
|
|
5429
|
+
checkboxFilter.values.forEach((value) => {
|
|
5430
|
+
controls[value.id] = new FormControl(false, { nonNullable: true });
|
|
5431
|
+
});
|
|
5432
|
+
return new FormGroup(controls);
|
|
5433
|
+
}
|
|
5434
|
+
/**
|
|
5435
|
+
* Создает FormControl для range.
|
|
5436
|
+
*
|
|
5437
|
+
* @param rangeFilter Фильтр типа range.
|
|
5438
|
+
*/
|
|
5439
|
+
createRangeFormControl(rangeFilter) {
|
|
5440
|
+
// TODO: Добавить updateOn: 'blur' после исправления бага в taiga-ui.
|
|
5441
|
+
return new FormControl([Number(rangeFilter.selectedMin ?? rangeFilter.min), Number(rangeFilter.selectedMax ?? rangeFilter.max)], { nonNullable: true });
|
|
5442
|
+
}
|
|
5443
|
+
/**
|
|
5444
|
+
* Создает FormControl для toggle.
|
|
5445
|
+
*
|
|
5446
|
+
* @param toggleFilter Фильтр типа toggle.
|
|
5447
|
+
*/
|
|
5448
|
+
createToggleFormControl(toggleFilter) {
|
|
5449
|
+
return new FormControl(toggleFilter.selectedValue ?? false, { nonNullable: true });
|
|
5450
|
+
}
|
|
5451
|
+
/**
|
|
5452
|
+
* Обрабатывает checkbox фильтр.
|
|
5453
|
+
*
|
|
5454
|
+
* @param result Объект результата для заполнения.
|
|
5455
|
+
* @param filterId Идентификатор фильтра.
|
|
5456
|
+
* @param controlValue Значение контрола формы.
|
|
5457
|
+
*/
|
|
5458
|
+
processCheckboxFilter(result, filterId, controlValue) {
|
|
5459
|
+
// Для checkbox: FormGroup с FormControl<boolean> -> string[] (массив ID выбранных значений)
|
|
5460
|
+
const selectedIds = Object.entries(controlValue)
|
|
5461
|
+
.filter(([, isSelected]) => isSelected)
|
|
5462
|
+
.map(([id]) => id);
|
|
5463
|
+
if (selectedIds.length > 0) {
|
|
5464
|
+
// eslint-disable-next-line security/detect-object-injection, no-param-reassign
|
|
5465
|
+
result[filterId] = selectedIds;
|
|
5466
|
+
}
|
|
5467
|
+
}
|
|
5468
|
+
/**
|
|
5469
|
+
* Обрабатывает range фильтр.
|
|
5470
|
+
*
|
|
5471
|
+
* @param result Объект результата для заполнения.
|
|
5472
|
+
* @param filterId Идентификатор фильтра.
|
|
5473
|
+
* @param controlValue Значение контрола формы.
|
|
5474
|
+
* @param controlValue.0 Начальное значение диапазона.
|
|
5475
|
+
* @param controlValue.1 Конечное значение диапазона.
|
|
5476
|
+
*/
|
|
5477
|
+
processRangeFilter(result, filterId, [from, to]) {
|
|
5478
|
+
// Для range: FormControl<[number, number]> -> { from?: string; to?: string; }
|
|
5479
|
+
// eslint-disable-next-line security/detect-object-injection, no-param-reassign
|
|
5480
|
+
result[filterId] = {
|
|
5481
|
+
from: String(from),
|
|
5482
|
+
to: String(to),
|
|
5483
|
+
};
|
|
5484
|
+
}
|
|
5485
|
+
/**
|
|
5486
|
+
* Обрабатывает toggle фильтр.
|
|
5487
|
+
*
|
|
5488
|
+
* @param result Объект результата для заполнения.
|
|
5489
|
+
* @param filterId Идентификатор фильтра.
|
|
5490
|
+
* @param controlValue Значение контрола формы.
|
|
5491
|
+
*/
|
|
5492
|
+
processToggleFilter(result, filterId, controlValue) {
|
|
5493
|
+
// Для toggle: FormControl<boolean> -> boolean
|
|
5494
|
+
if (controlValue) {
|
|
5495
|
+
// eslint-disable-next-line security/detect-object-injection, no-param-reassign
|
|
5496
|
+
result[filterId] = controlValue;
|
|
5497
|
+
}
|
|
5498
|
+
}
|
|
5499
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: ScCatalogFiltersComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
5500
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.2.14", type: ScCatalogFiltersComponent, isStandalone: true, selector: "sc-catalog-filters", inputs: { isOpenAccordion: { classPropertyName: "isOpenAccordion", publicName: "isOpenAccordion", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0, template: "@if (filters().length) {\n <div class=\"bg-tui-base-01 shadow-sc mb-4 flex flex-col items-center gap-3 rounded-xl\">\n <tui-accordion class=\"accordion\">\n <button\n [tuiAccordion]=\"isOpenAccordion()\"\n appearance=\"primary\"\n >\n \u0424\u0438\u043B\u044C\u0442\u0440\u044B\n </button>\n <tui-expand>\n <form\n [formGroup]=\"form\"\n class=\"flex flex-col gap-4 pb-1\"\n >\n @for (filter of filters(); track filter.id) {\n <div class=\"flex flex-col gap-2\">\n <label class=\"text-body-s font-medium\">{{ filter.label }}</label>\n\n @if (filter.type === 'checkbox') {\n <div\n [formGroupName]=\"filter.id\"\n class=\"flex flex-col gap-2\"\n >\n @for (value of filter.values; track value.id) {\n <label class=\"flex items-center gap-2\">\n <input\n [formControlName]=\"value.id\"\n tuiCheckbox\n type=\"checkbox\"\n />\n <span class=\"text-body-s\">{{ value.label }}</span>\n </label>\n }\n </div>\n }\n\n @if (filter.type === 'range') {\n <tui-input-range\n [formControlName]=\"filter.id\"\n [min]=\"+filter.min\"\n [max]=\"+filter.max\"\n />\n }\n\n @if (filter.type === 'toggle') {\n <label class=\"flex items-center gap-2\">\n <input\n [formControlName]=\"filter.id\"\n tuiCheckbox\n type=\"checkbox\"\n />\n <span class=\"text-body-s\">\u0414\u0430</span>\n </label>\n }\n </div>\n }\n </form>\n </tui-expand>\n </tui-accordion>\n </div>\n}\n", styles: [".accordion [tuiAccordion]{border:none;mask:none}.accordion tui-expand{box-shadow:none}\n"], dependencies: [{ kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1$1.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i1$1.CheckboxControlValueAccessor, selector: "input[type=checkbox][formControlName],input[type=checkbox][formControl],input[type=checkbox][ngModel]" }, { kind: "directive", type: i1$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$1.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "component", type: TuiCheckbox, selector: "input[type=\"checkbox\"][tuiCheckbox]", inputs: ["size"] }, { kind: "component", type: i2$1.TuiInputRangeComponent, selector: "tui-input-range", inputs: ["min", "max", "step", "segments", "keySteps", "prefix", "postfix", "quantum", "content"] }, { kind: "component", type: i1$3.TuiAccordionComponent, selector: "tui-accordion", inputs: ["closeOthers", "size"] }, { kind: "directive", type: i1$3.TuiAccordionDirective, selector: "button[tuiAccordion]", inputs: ["tuiAccordion"], outputs: ["tuiAccordionChange"] }, { kind: "component", type: i2$5.TuiExpand, selector: "tui-expand", inputs: ["expanded"] }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1$1.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i1$1.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { kind: "directive", type: i1$1.FormGroupName, selector: "[formGroupName]", inputs: ["formGroupName"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
|
|
5501
|
+
}
|
|
5502
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: ScCatalogFiltersComponent, decorators: [{
|
|
5503
|
+
type: Component,
|
|
5504
|
+
args: [{ standalone: true, selector: 'sc-catalog-filters', changeDetection: ChangeDetectionStrategy.OnPush, imports: [FormsModule, TuiTextfield, TuiCheckbox, TuiInputRange, TuiAccordion$1, ReactiveFormsModule], template: "@if (filters().length) {\n <div class=\"bg-tui-base-01 shadow-sc mb-4 flex flex-col items-center gap-3 rounded-xl\">\n <tui-accordion class=\"accordion\">\n <button\n [tuiAccordion]=\"isOpenAccordion()\"\n appearance=\"primary\"\n >\n \u0424\u0438\u043B\u044C\u0442\u0440\u044B\n </button>\n <tui-expand>\n <form\n [formGroup]=\"form\"\n class=\"flex flex-col gap-4 pb-1\"\n >\n @for (filter of filters(); track filter.id) {\n <div class=\"flex flex-col gap-2\">\n <label class=\"text-body-s font-medium\">{{ filter.label }}</label>\n\n @if (filter.type === 'checkbox') {\n <div\n [formGroupName]=\"filter.id\"\n class=\"flex flex-col gap-2\"\n >\n @for (value of filter.values; track value.id) {\n <label class=\"flex items-center gap-2\">\n <input\n [formControlName]=\"value.id\"\n tuiCheckbox\n type=\"checkbox\"\n />\n <span class=\"text-body-s\">{{ value.label }}</span>\n </label>\n }\n </div>\n }\n\n @if (filter.type === 'range') {\n <tui-input-range\n [formControlName]=\"filter.id\"\n [min]=\"+filter.min\"\n [max]=\"+filter.max\"\n />\n }\n\n @if (filter.type === 'toggle') {\n <label class=\"flex items-center gap-2\">\n <input\n [formControlName]=\"filter.id\"\n tuiCheckbox\n type=\"checkbox\"\n />\n <span class=\"text-body-s\">\u0414\u0430</span>\n </label>\n }\n </div>\n }\n </form>\n </tui-expand>\n </tui-accordion>\n </div>\n}\n", styles: [".accordion [tuiAccordion]{border:none;mask:none}.accordion tui-expand{box-shadow:none}\n"] }]
|
|
5505
|
+
}], ctorParameters: () => [] });
|
|
5506
|
+
|
|
5122
5507
|
/* eslint-disable no-underscore-dangle */
|
|
5123
5508
|
/**
|
|
5124
5509
|
* Компонент карточки элемента корзины.
|
|
@@ -6347,146 +6732,6 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImpo
|
|
|
6347
6732
|
args: [{ standalone: true, selector: 'sc-resource-preview', imports: [TuiNotification, TuiButton], changeDetection: ChangeDetectionStrategy.OnPush, template: "@if (src && isVideoResource()) {\n <video\n #video\n controls\n (canplay)=\"onCanPlay(video)\"\n class=\"size-full bg-black\"\n >\n <source\n [src]=\"src\"\n [type]=\"type\"\n />\n </video>\n} @else {\n <tui-notification\n appearance=\"warning\"\n size=\"l\"\n >\n <div\n tuiTitle\n [style.padding-inline-end.rem]=\"2\"\n class=\"flex flex-col\"\n >\n {{ !src || !type ? '\u0418\u0437\u0432\u0438\u043D\u0438\u0442\u0435, \u0440\u0435\u0441\u0443\u0440\u0441 \u043D\u0435 \u043D\u0430\u0439\u0434\u0435\u043D.' : '\u0418\u0437\u0432\u0438\u043D\u0438\u0442\u0435, \u0434\u0430\u043D\u043D\u044B\u0439 \u0444\u043E\u0440\u043C\u0430\u0442 \u0440\u0435\u0441\u0443\u0440\u0441\u0430 \u043D\u0435 \u043F\u043E\u0434\u0434\u0435\u0440\u0436\u0438\u0432\u0430\u0435\u0442\u0441\u044F.' }}\n <button\n tuiButton\n type=\"button\"\n size=\"m\"\n appearance=\"primary\"\n (click)=\"context?.$implicit?.complete()\"\n class=\"mt-4 self-center\"\n >\n \u0417\u0430\u043A\u0440\u044B\u0442\u044C\n </button>\n </div>\n </tui-notification>\n}\n", styles: [":host{display:flex;height:100lvh;width:100%;justify-content:center;align-items:center}\n"] }]
|
|
6348
6733
|
}] });
|
|
6349
6734
|
|
|
6350
|
-
/**
|
|
6351
|
-
* Токен обработчика смены ошибки.
|
|
6352
|
-
*/
|
|
6353
|
-
// eslint-disable-next-line unicorn/consistent-function-scoping
|
|
6354
|
-
const SC_ERROR_CHANGE_HANDLER = tuiCreateTokenFromFactory(() => () => noop);
|
|
6355
|
-
|
|
6356
|
-
/**
|
|
6357
|
-
* Компонент представления данных об ошибке.
|
|
6358
|
-
*/
|
|
6359
|
-
class ScErrorBlockStatusComponent {
|
|
6360
|
-
/**
|
|
6361
|
-
* Инициализирует экземпляр класса {@link ErrorPageComponent}.
|
|
6362
|
-
*/
|
|
6363
|
-
constructor() {
|
|
6364
|
-
/**
|
|
6365
|
-
* Компонент управляющий кодом ошибки отображаемой на странице.
|
|
6366
|
-
*/
|
|
6367
|
-
this.errorHandlerComponent = inject(ScErrorHandlerComponent, { skipSelf: true });
|
|
6368
|
-
/**
|
|
6369
|
-
* Сигнал кода ошибки.
|
|
6370
|
-
*/
|
|
6371
|
-
this.code = this.errorHandlerComponent.getErrorCode();
|
|
6372
|
-
/**
|
|
6373
|
-
* Данные об ошибке.
|
|
6374
|
-
*/
|
|
6375
|
-
// eslint-disable-next-line unicorn/consistent-function-scoping
|
|
6376
|
-
this.error = computed(() => this.getErrorMessage(this.code()));
|
|
6377
|
-
/**
|
|
6378
|
-
* Создает сигнал изменения строкового представления об ошибке.
|
|
6379
|
-
*/
|
|
6380
|
-
this.pageErrorChange = output();
|
|
6381
|
-
/**
|
|
6382
|
-
* Признак, что текущий скрипт исполняется на сервере.
|
|
6383
|
-
*/
|
|
6384
|
-
this.isServer = inject(IS_SERVER);
|
|
6385
|
-
/**
|
|
6386
|
-
* Данные об ответе на запрос.
|
|
6387
|
-
*/
|
|
6388
|
-
this.response = inject(RESPONSE, { optional: true });
|
|
6389
|
-
// Если компонент отображён маршрутизацией из-за перехода по неизвестному маршруту, то устанавливаем код 404.
|
|
6390
|
-
if (inject(ActivatedRoute).snapshot.data['routes_key'] === 'error') {
|
|
6391
|
-
this.errorHandlerComponent.setErrorCode(404);
|
|
6392
|
-
}
|
|
6393
|
-
effect(() => {
|
|
6394
|
-
if (this.code() !== null) {
|
|
6395
|
-
this.pageErrorChange.emit(this.error());
|
|
6396
|
-
if (this.isServer) {
|
|
6397
|
-
this.response?.status(this.code() ?? 0);
|
|
6398
|
-
}
|
|
6399
|
-
}
|
|
6400
|
-
});
|
|
6401
|
-
}
|
|
6402
|
-
/**
|
|
6403
|
-
* Возвращает описание ошибки.
|
|
6404
|
-
*
|
|
6405
|
-
* @param code Код ошибки.
|
|
6406
|
-
*/
|
|
6407
|
-
// eslint-disable-next-line class-methods-use-this
|
|
6408
|
-
getErrorMessage(code) {
|
|
6409
|
-
switch (code) {
|
|
6410
|
-
case 403:
|
|
6411
|
-
return {
|
|
6412
|
-
message: 'К сожалению, у вас нет доступа к этому ресурсу',
|
|
6413
|
-
description: 'Воспользуйтесь навигацией в шапке или подвале сайта, чтобы перейти в интересующий вас раздел',
|
|
6414
|
-
code,
|
|
6415
|
-
};
|
|
6416
|
-
case 404:
|
|
6417
|
-
return {
|
|
6418
|
-
message: 'К сожалению, такой страницы нет',
|
|
6419
|
-
description: 'Воспользуйтесь навигацией в шапке или подвале сайта, чтобы перейти в интересующий вас раздел',
|
|
6420
|
-
code,
|
|
6421
|
-
};
|
|
6422
|
-
default:
|
|
6423
|
-
return {
|
|
6424
|
-
message: 'Неизвестная ошибка',
|
|
6425
|
-
description: 'Пожалуйста обновите страницу или обратитесь к менеджеру',
|
|
6426
|
-
code: 0,
|
|
6427
|
-
};
|
|
6428
|
-
}
|
|
6429
|
-
}
|
|
6430
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: ScErrorBlockStatusComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
6431
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.14", type: ScErrorBlockStatusComponent, isStandalone: true, selector: "sc-error-block-status", outputs: { pageErrorChange: "pageErrorChange" }, ngImport: i0, template: "<div class=\"flex flex-col items-center gap-8\">\n <div class=\"border-20 border-solid border-tui-primary text-center sm:border-32\">\n <div class=\"text-8xl leading-1.15 text-black sm:text-44\">\n {{ error().code }}\n </div>\n <div class=\"text-6xl leading-1.15 text-tui-primary sm:text-8xl\">ERROR</div>\n </div>\n <div class=\"flex flex-col gap-2 text-center\">\n <div class=\"text-h5 sm:text-h4\">{{ error().message }}</div>\n <div class=\"text-body-m-bold sm:text-h6\">{{ error().description }}</div>\n </div>\n <button\n tuiButton\n appearance=\"primary\"\n routerLink=\"/\"\n >\n \u0412\u0435\u0440\u043D\u0443\u0442\u044C\u0441\u044F \u043D\u0430 \u0433\u043B\u0430\u0432\u043D\u0443\u044E\n </button>\n</div>\n", dependencies: [{ kind: "directive", type: TuiButton, selector: "a[tuiButton],button[tuiButton],a[tuiIconButton],button[tuiIconButton]", inputs: ["size"] }, { kind: "directive", type: RouterLink, selector: "[routerLink]", inputs: ["target", "queryParams", "fragment", "queryParamsHandling", "state", "info", "relativeTo", "preserveFragment", "skipLocationChange", "replaceUrl", "routerLink"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
|
|
6432
|
-
}
|
|
6433
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: ScErrorBlockStatusComponent, decorators: [{
|
|
6434
|
-
type: Component,
|
|
6435
|
-
args: [{ standalone: true, selector: 'sc-error-block-status', imports: [TuiAppearance, TuiWithAppearance, TuiIcons, TuiWithIcons, TuiButton, RouterLink], changeDetection: ChangeDetectionStrategy.OnPush, template: "<div class=\"flex flex-col items-center gap-8\">\n <div class=\"border-20 border-solid border-tui-primary text-center sm:border-32\">\n <div class=\"text-8xl leading-1.15 text-black sm:text-44\">\n {{ error().code }}\n </div>\n <div class=\"text-6xl leading-1.15 text-tui-primary sm:text-8xl\">ERROR</div>\n </div>\n <div class=\"flex flex-col gap-2 text-center\">\n <div class=\"text-h5 sm:text-h4\">{{ error().message }}</div>\n <div class=\"text-body-m-bold sm:text-h6\">{{ error().description }}</div>\n </div>\n <button\n tuiButton\n appearance=\"primary\"\n routerLink=\"/\"\n >\n \u0412\u0435\u0440\u043D\u0443\u0442\u044C\u0441\u044F \u043D\u0430 \u0433\u043B\u0430\u0432\u043D\u0443\u044E\n </button>\n</div>\n" }]
|
|
6436
|
-
}], ctorParameters: () => [] });
|
|
6437
|
-
|
|
6438
|
-
/**
|
|
6439
|
-
* Компонент для управления кодом ошибки отображаемой на странице.
|
|
6440
|
-
*/
|
|
6441
|
-
class ScErrorHandlerComponent {
|
|
6442
|
-
/**
|
|
6443
|
-
* Инициирует экземпляр класса {@link ErrorHandlerComponent}.
|
|
6444
|
-
*/
|
|
6445
|
-
constructor() {
|
|
6446
|
-
/**
|
|
6447
|
-
* Сигнал для хранения кода ошибки.
|
|
6448
|
-
*/
|
|
6449
|
-
this.code = signal(null);
|
|
6450
|
-
/**
|
|
6451
|
-
* Сигнал дефолтного передаваемого из вне значения ошибки.
|
|
6452
|
-
*/
|
|
6453
|
-
// eslint-disable-next-line @angular-eslint/no-input-rename
|
|
6454
|
-
this.defaultCode = input(null, { alias: 'code' });
|
|
6455
|
-
/**
|
|
6456
|
-
* Сервис маршрутизации.
|
|
6457
|
-
*/
|
|
6458
|
-
this.router = inject(Router);
|
|
6459
|
-
/**
|
|
6460
|
-
* Обработчик изменения ошибки.
|
|
6461
|
-
*/
|
|
6462
|
-
this.errorChangeHandler = inject(SC_ERROR_CHANGE_HANDLER);
|
|
6463
|
-
this.router.events.pipe(filter((event) => event instanceof NavigationStart)).subscribe(() => {
|
|
6464
|
-
// Сбрасываем ошибку при переходе на новый маршрут.
|
|
6465
|
-
this.code.set(this.defaultCode());
|
|
6466
|
-
});
|
|
6467
|
-
}
|
|
6468
|
-
/**
|
|
6469
|
-
* Возвращает текущий сигнал с кодом ошибки.
|
|
6470
|
-
*/
|
|
6471
|
-
getErrorCode() {
|
|
6472
|
-
return this.code;
|
|
6473
|
-
}
|
|
6474
|
-
/**
|
|
6475
|
-
* Устанавливает новый код ошибки.
|
|
6476
|
-
*
|
|
6477
|
-
* @param code Новый код ошибки.
|
|
6478
|
-
*/
|
|
6479
|
-
setErrorCode(code) {
|
|
6480
|
-
this.code.set(code);
|
|
6481
|
-
}
|
|
6482
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: ScErrorHandlerComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
6483
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.2.14", type: ScErrorHandlerComponent, isStandalone: true, selector: "sc-error-handler", inputs: { defaultCode: { classPropertyName: "defaultCode", publicName: "code", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0, template: "@if (code() === null) {\n <ng-content />\n} @else {\n <sc-error-block-status (pageErrorChange)=\"errorChangeHandler($event)\"></sc-error-block-status>\n}\n", dependencies: [{ kind: "component", type: ScErrorBlockStatusComponent, selector: "sc-error-block-status", outputs: ["pageErrorChange"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
|
|
6484
|
-
}
|
|
6485
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: ScErrorHandlerComponent, decorators: [{
|
|
6486
|
-
type: Component,
|
|
6487
|
-
args: [{ standalone: true, selector: 'sc-error-handler', imports: [ScErrorBlockStatusComponent], changeDetection: ChangeDetectionStrategy.OnPush, template: "@if (code() === null) {\n <ng-content />\n} @else {\n <sc-error-block-status (pageErrorChange)=\"errorChangeHandler($event)\"></sc-error-block-status>\n}\n" }]
|
|
6488
|
-
}], ctorParameters: () => [] });
|
|
6489
|
-
|
|
6490
6735
|
/* eslint-disable class-methods-use-this */
|
|
6491
6736
|
/**
|
|
6492
6737
|
* Сервис работающий с значками элементов дерева.
|
|
@@ -7281,6 +7526,7 @@ class ScFrequentlyAskedQuestionsWithGroupsComponent {
|
|
|
7281
7526
|
page: this.page$,
|
|
7282
7527
|
perPage: this.perPage$,
|
|
7283
7528
|
group: this.groupId$,
|
|
7529
|
+
paginate: of(true),
|
|
7284
7530
|
}).pipe(
|
|
7285
7531
|
// Нулевой debounceTime для случая, когда меняются направление и поле сортировки одновременно.
|
|
7286
7532
|
debounceTime(0), switchMap((value) => this.frequentlyAskedQuestionsService
|
|
@@ -8675,5 +8921,5 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImpo
|
|
|
8675
8921
|
* Generated bundle index. Do not edit.
|
|
8676
8922
|
*/
|
|
8677
8923
|
|
|
8678
|
-
export { AbstractScPriceCard, AuthMethod, CURRENT_COUNTRY_ID, CostWithDiscountComponent, FilesAndDocumentsComponent, FilesAndDocumentsModule, FinishDateTimeTransformerDirective, IS_DEFAULT_COUNTRY, MAX_FILES_IN_FORM_INPUT, SC_ALLOW_SELECT_TERMINATED, SC_BANNER_DURATION, SC_DATE_FORMATTER, SC_DEBOUNCE_TIME_DEFAULT, SC_ERROR_CHANGE_HANDLER, SC_HELP_NOTIFICATION_CLOSE, SC_HELP_NOTIFICATION_LIMIT, SC_MANAGER_QR_HANDLER, SC_NOTIFY_WHEN_IN_STOCK_REQUIRED_FIELDS, SC_PAGE_SIZE_OPTIONS$1 as SC_PAGE_SIZE_OPTIONS, SC_SHOW_HELP_NOTIFICATION_IN_PHONE_INPUT, SC_USER_CITY_INFO, SC_USER_INFO, SC_USER_PROVIDERS, SC_VERIFICATION_CODE_TIMEOUT, ScAccordionComponent, ScAccordionContentDirective, ScAccordionModule, ScAddContactDialogComponent, ScAddContragentBankAccountsDialogComponent, ScAddContragentDialogComponent, ScAddDeliveryAddressDialogComponent, ScAddOrEditingCartItemDialogComponent, ScAddOrEditingCartItemFormComponent, ScAddressesSelectionFieldComponent, ScAuthModule, ScBannerComponent, ScBannerModule, ScBrandsListComponent, ScBrandsListModule, ScCartAddProductsFromCsvDialogComponent, ScCartItemComponent, ScCatalogModule, ScCategoryCardComponent, ScContactsAccordionComponent, ScContactsModule, ScContragentsAccordionComponent, ScContragentsAccordionItemComponent, ScContragentsModule, ScDeliveryAddressAccordionComponent, ScDeliveryAddressAccordionItemComponent, ScDeliveryAddressModule, ScDownloadPriceListComponent, ScEmailLinkDirective, ScErrorBlockStatusComponent, ScErrorHandlerComponent, ScFavoriteButtonComponent, ScFeedbackFormComponent, ScFocusFirstInvalidFieldDirective, ScFormFieldsModule, ScFormatDatePipe, ScFrequentlyAskedQuestionsComponent, ScFrequentlyAskedQuestionsGroupSelectorComponent, ScFrequentlyAskedQuestionsWithGroupsComponent, ScGratitudeComponent, ScHelpNotificationService, ScHoverImageCarouselComponent, ScInputQuantityComponent, ScJsonLdCategoryComponent, ScLinks, ScManagerCardComponent, ScManagerCardPushComponent, ScNewContactFormComponent, ScNewContragentBankAccountsFormComponent, ScNewContragentFormComponent, ScNewsCardComponent, ScNewsCardSkeletonComponent, ScNewsModule, ScNextInputFocusDirective, ScNextInputFocusModule, ScNoindexDirective, ScNoindexWrapperComponent, ScNotifyWhenInStockDialogComponent, ScOrderItemMobileComponent, ScOrderModule, ScPaymentStatusComponent, ScPersonalDataProcessingPolicyComponent, ScPhoneFormatPipe, ScPreviewSampleComponent, ScPreviewSampleModule, ScPreviewSamplesMosquitoComponent, ScPriceCardComponent, ScPriceCardInlineComponent, ScPriceHistoryComponent, ScPriceListPaginationComponent, ScPriceWarehouseStockComponent, ScPrivacyPolicyComponent, ScProductInAllWarehousesPipe, ScProfileAccordionsContentComponent, ScProfileModule, ScPublicOfferComponent, ScQRCodeDialogComponent, ScQRCodeModule, ScResetUserPasswordComponent, ScResourcePreviewComponent, ScSandwichComponent, ScSandwichSkeletonComponent, ScSelectOnFocusinDirective, ScShareButtonComponent, ScShareButtonModule, ScSignInFormByEmailComponent, ScSignInFormByPhoneComponent, ScSignInFormComponent, ScSignUpFormComponent, ScSimpleSignUpFormComponent, ScSuggestionFieldComponent, ScTelLinkDirective, ScTerminalLinkDirective, ScUpdateUserInfoDialogComponent, ScUserManagersComponent, ScUserModule, ScUserPhoneApproveDialogComponent, ScVerificationModule, ScVerificationPhoneCheckFormComponent, TreeDirective, TreeIconService, TreeLoaderService, TreeTopDirective, phoneValidator, scAtLeastOneRequiredValidator, scBicValidator, scClientUiIconsName, scCorrespondentAccountValidator, scPasswordConfirmMatchingValidator, stepValidator, tuiDateValueTransformerDefaultProvider };
|
|
8924
|
+
export { AbstractScPriceCard, AuthMethod, CURRENT_COUNTRY_ID, CostWithDiscountComponent, FilesAndDocumentsComponent, FilesAndDocumentsModule, FinishDateTimeTransformerDirective, IS_DEFAULT_COUNTRY, MAX_FILES_IN_FORM_INPUT, SC_ALLOW_SELECT_TERMINATED, SC_BANNER_DURATION, SC_CATALOG_PRODUCTS_FILTERS, SC_CATALOG_SHOW_PRODUCTS_RECURSIVELY, SC_CATEGORY_INFO, SC_CATEGORY_PROVIDERS, SC_DATE_FORMATTER, SC_DEBOUNCE_TIME_DEFAULT, SC_ERROR_CHANGE_HANDLER, SC_HELP_NOTIFICATION_CLOSE, SC_HELP_NOTIFICATION_LIMIT, SC_MANAGER_QR_HANDLER, SC_NOTIFY_WHEN_IN_STOCK_REQUIRED_FIELDS, SC_PAGE_SIZE_OPTIONS$1 as SC_PAGE_SIZE_OPTIONS, SC_SHOW_HELP_NOTIFICATION_IN_PHONE_INPUT, SC_USER_CITY_INFO, SC_USER_INFO, SC_USER_PROVIDERS, SC_VERIFICATION_CODE_TIMEOUT, ScAccordionComponent, ScAccordionContentDirective, ScAccordionModule, ScAddContactDialogComponent, ScAddContragentBankAccountsDialogComponent, ScAddContragentDialogComponent, ScAddDeliveryAddressDialogComponent, ScAddOrEditingCartItemDialogComponent, ScAddOrEditingCartItemFormComponent, ScAddressesSelectionFieldComponent, ScAuthModule, ScBannerComponent, ScBannerModule, ScBrandsListComponent, ScBrandsListModule, ScCartAddProductsFromCsvDialogComponent, ScCartItemComponent, ScCatalogFiltersComponent, ScCatalogModule, ScCategoryCardComponent, ScContactsAccordionComponent, ScContactsModule, ScContragentsAccordionComponent, ScContragentsAccordionItemComponent, ScContragentsModule, ScDeliveryAddressAccordionComponent, ScDeliveryAddressAccordionItemComponent, ScDeliveryAddressModule, ScDownloadPriceListComponent, ScEmailLinkDirective, ScErrorBlockStatusComponent, ScErrorHandlerComponent, ScFavoriteButtonComponent, ScFeedbackFormComponent, ScFocusFirstInvalidFieldDirective, ScFormFieldsModule, ScFormatDatePipe, ScFrequentlyAskedQuestionsComponent, ScFrequentlyAskedQuestionsGroupSelectorComponent, ScFrequentlyAskedQuestionsWithGroupsComponent, ScGratitudeComponent, ScHelpNotificationService, ScHoverImageCarouselComponent, ScInputQuantityComponent, ScJsonLdCategoryComponent, ScLinks, ScManagerCardComponent, ScManagerCardPushComponent, ScNewContactFormComponent, ScNewContragentBankAccountsFormComponent, ScNewContragentFormComponent, ScNewsCardComponent, ScNewsCardSkeletonComponent, ScNewsModule, ScNextInputFocusDirective, ScNextInputFocusModule, ScNoindexDirective, ScNoindexWrapperComponent, ScNotifyWhenInStockDialogComponent, ScOrderItemMobileComponent, ScOrderModule, ScPaymentStatusComponent, ScPersonalDataProcessingPolicyComponent, ScPhoneFormatPipe, ScPreviewSampleComponent, ScPreviewSampleModule, ScPreviewSamplesMosquitoComponent, ScPriceCardComponent, ScPriceCardInlineComponent, ScPriceHistoryComponent, ScPriceListPaginationComponent, ScPriceWarehouseStockComponent, ScPrivacyPolicyComponent, ScProductInAllWarehousesPipe, ScProfileAccordionsContentComponent, ScProfileModule, ScPublicOfferComponent, ScQRCodeDialogComponent, ScQRCodeModule, ScResetUserPasswordComponent, ScResourcePreviewComponent, ScSandwichComponent, ScSandwichSkeletonComponent, ScSelectOnFocusinDirective, ScShareButtonComponent, ScShareButtonModule, ScSignInFormByEmailComponent, ScSignInFormByPhoneComponent, ScSignInFormComponent, ScSignUpFormComponent, ScSimpleSignUpFormComponent, ScSuggestionFieldComponent, ScTelLinkDirective, ScTerminalLinkDirective, ScUpdateUserInfoDialogComponent, ScUserManagersComponent, ScUserModule, ScUserPhoneApproveDialogComponent, ScVerificationModule, ScVerificationPhoneCheckFormComponent, TreeDirective, TreeIconService, TreeLoaderService, TreeTopDirective, phoneValidator, scAtLeastOneRequiredValidator, scBicValidator, scClientUiIconsName, scCorrespondentAccountValidator, scGetCurrentRoute, scPasswordConfirmMatchingValidator, stepValidator, tuiDateValueTransformerDefaultProvider };
|
|
8679
8925
|
//# sourceMappingURL=snabcentr-client-ui.mjs.map
|