@snabcentr/client-ui 4.14.4 → 4.14.6-profstroy
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/banner/sc-banner.component.d.ts +32 -3
- package/cart/sc-cart-add-products-from-csv-dialog/sc-cart-add-products-from-csv-dialog.component.d.ts +3 -3
- package/catalog/input-quantity/sc-input-quantity.component.d.ts +17 -1
- package/esm2022/banner/sc-banner.component.mjs +52 -7
- package/esm2022/cart/sc-cart-add-products-from-csv-dialog/sc-cart-add-products-from-csv-dialog.component.mjs +5 -16
- package/esm2022/catalog/input-quantity/sc-input-quantity.component.mjs +29 -6
- package/esm2022/helpers/sc-file-helper.mjs +29 -0
- package/esm2022/order/draft/helpers/sc-draft-list-helper.mjs +42 -0
- package/esm2022/order/draft/models/sc-i-draft-list-item.mjs +2 -0
- package/esm2022/order/draft/profstroy/actualization-panel/sc-profstroy-actualization-panel.component.mjs +68 -0
- package/esm2022/order/draft/profstroy/badge/sc-profstroy-badge.component.mjs +21 -0
- package/esm2022/order/draft/profstroy/badges/sc-profstroy-draft-badges.component.mjs +31 -0
- package/esm2022/order/draft/profstroy/create-dialog/sc-profstroy-draft-create-dialog.component.mjs +132 -0
- package/esm2022/order/draft/profstroy/enums/sc-profstroy-draft-state.mjs +32 -0
- package/esm2022/order/draft/profstroy/helpers/sc-profstroy-draft-helper.mjs +72 -0
- package/esm2022/order/draft/profstroy/index.mjs +8 -0
- package/esm2022/order/draft/profstroy/models/sc-i-profstroy-draft-state-view.mjs +2 -0
- package/esm2022/order/draft/sc-draft.component.mjs +173 -10
- package/esm2022/order/index.mjs +5 -1
- package/esm2022/order/models/sc-i-order-items-group.mjs +2 -0
- package/esm2022/order/order-direction-items/sc-order-direction-items.component.mjs +7 -3
- package/esm2022/order/order-item/sc-order-item.component.mjs +14 -5
- package/esm2022/order/order-items-list/sc-order-items-list.component.mjs +60 -7
- package/esm2022/order/order-items-list-by-directions/sc-order-items-list-by-directions.component.mjs +7 -3
- package/esm2022/order/order-items-list-by-stock/sc-order-items-list-by-stock.component.mjs +1 -1
- package/esm2022/pipes/sc-format-date.mjs +1 -1
- package/esm2022/providers/sc-date-formatter.mjs +1 -1
- package/fesm2022/snabcentr-client-ui.mjs +718 -44
- package/fesm2022/snabcentr-client-ui.mjs.map +1 -1
- package/helpers/sc-file-helper.d.ts +13 -0
- package/order/draft/helpers/sc-draft-list-helper.d.ts +22 -0
- package/order/draft/models/sc-i-draft-list-item.d.ts +14 -0
- package/order/draft/profstroy/actualization-panel/sc-profstroy-actualization-panel.component.d.ts +54 -0
- package/order/draft/profstroy/badge/sc-profstroy-badge.component.d.ts +12 -0
- package/order/draft/profstroy/badges/sc-profstroy-draft-badges.component.d.ts +21 -0
- package/order/draft/profstroy/create-dialog/sc-profstroy-draft-create-dialog.component.d.ts +58 -0
- package/order/draft/profstroy/enums/sc-profstroy-draft-state.d.ts +29 -0
- package/order/draft/profstroy/helpers/sc-profstroy-draft-helper.d.ts +26 -0
- package/order/draft/profstroy/index.d.ts +7 -0
- package/order/draft/profstroy/models/sc-i-profstroy-draft-state-view.d.ts +17 -0
- package/order/draft/sc-draft.component.d.ts +88 -1
- package/order/index.d.ts +4 -0
- package/order/models/sc-i-order-items-group.d.ts +22 -0
- package/order/order-direction-items/sc-order-direction-items.component.d.ts +5 -1
- package/order/order-item/sc-order-item.component.d.ts +9 -1
- package/order/order-items-list/sc-order-items-list.component.d.ts +23 -1
- package/order/order-items-list-by-directions/sc-order-items-list-by-directions.component.d.ts +5 -1
- package/package.json +2 -2
- package/pipes/sc-format-date.d.ts +1 -1
- package/providers/sc-date-formatter.d.ts +1 -1
- package/release_notes.tmp +2 -4
- package/styles/tailwind/tailwind.scss +16 -0
|
@@ -1,16 +1,16 @@
|
|
|
1
1
|
import * as i0 from '@angular/core';
|
|
2
|
-
import { InjectionToken, inject, Injectable, NgZone, signal, EventEmitter, ChangeDetectorRef, Directive, Input, Output, Pipe, ElementRef, HostListener, Renderer2, ContentChildren, NgModule, input, computed, Component, ChangeDetectionStrategy, Inject, HostBinding, model, output, SkipSelf, DestroyRef, effect, ContentChild, ViewChild, viewChild, Optional, contentChild, TemplateRef, forwardRef, ViewEncapsulation, Injector, viewChildren, afterNextRender } from '@angular/core';
|
|
2
|
+
import { InjectionToken, inject, Injectable, NgZone, signal, EventEmitter, ChangeDetectorRef, Directive, Input, Output, Pipe, ElementRef, HostListener, Renderer2, ContentChildren, NgModule, input, computed, Component, ChangeDetectionStrategy, Inject, HostBinding, model, output, SkipSelf, DestroyRef, effect, ContentChild, ViewChild, viewChild, Optional, contentChild, TemplateRef, forwardRef, untracked, ViewEncapsulation, Injector, viewChildren, afterNextRender } from '@angular/core';
|
|
3
3
|
import * as i1 from '@snabcentr/client-core';
|
|
4
|
-
import { ScContactsService, ScUserService, ScLocationsService, ScAuthService, SEARCH_TERM, ScUnitsHelper, ScImageHelper, SC_PATH_IMAGE_NOT_FOUND, ScImage, ScPhoneService, ScUserMetrikaService, ScUserMetrikaGoalsEnum, IS_RUNNING_ON_TERMINAL, ScVCardService, ScVerificationService, ScISuggestionType, SC_MIN_LENGTH_SEARCH_TERM, ScConvertersService, ScOpfList, ScReferencesService, ScContragentService, ScBannerService, ScMediaImageTransformerPipe,
|
|
4
|
+
import { ScContactsService, ScUserService, ScLocationsService, ScAuthService, SEARCH_TERM, ScUnitsHelper, ScImageHelper, SC_PATH_IMAGE_NOT_FOUND, ScImage, ScPhoneService, ScUserMetrikaService, ScUserMetrikaGoalsEnum, IS_RUNNING_ON_TERMINAL, ScVCardService, ScVerificationService, ScISuggestionType, SC_MIN_LENGTH_SEARCH_TERM, ScConvertersService, ScOpfList, ScReferencesService, ScContragentService, ScBannerService, ScMediaImageTransformerPipe, ScUploadedFile, ScCartService, loadingPlaceholder, SC_ORDER_LOADER, ScMimeTypes, ScCatalogService, SC_URLS, ScWarehouseService, SEARCH_TERM_PROVIDERS, ScPaginationService, SC_NEXT_PAGE_PAGINATION_CLICK, SC_PRODUCT_PAGINATION_OPTIONS, ScCatalogFilterService, ScIdOrSlugPipe, SC_CATEGORY_INFO, ScConfiguratorService, IS_SERVER, RESPONSE, ScIconTypesEnum, ScDocumentInfoTypesEnum, ScDeliveryAddressService, ScOrdersService, ScUIService, SC_USER_INFO as SC_USER_INFO$1, ScPaymentType, ScDeliveryType, TERMINAL_PROVIDERS, ScOrderDraft, ScOrderDraftActualizationStatus, ScOrderDraftsService, SC_UPDATE_INTERVAL, ScRouteKeys, ScProfstroyOrderItem, ScSeoService, scOrderIsLoaded, SC_PAGE_QUERY_PARAM, ScFrequentlyAskedQuestionsService, SchemaOrgFactory, scGetPageQueryParamChanges, ScNewsService, SC_COMPANY_INFO, ScFeedbackService } from '@snabcentr/client-core';
|
|
5
5
|
import * as i5$1 from 'rxjs';
|
|
6
|
-
import { EMPTY, BehaviorSubject, switchMap, of, shareReplay, map, Subject, filter, tap, catchError, finalize, startWith, share, timer, scan, takeWhile, endWith, distinctUntilChanged, debounceTime, throwError, combineLatest, Observable, pairwise, Subscription, merge, skip, from, concatMap, noop, first, retry, fromEvent, animationFrames,
|
|
6
|
+
import { EMPTY, BehaviorSubject, switchMap, of, shareReplay, map, Subject, filter, tap, catchError, finalize, startWith, share, timer, scan, takeWhile, endWith, distinctUntilChanged, debounceTime, throwError, combineLatest, Observable, pairwise, Subscription, merge, skip, from, concatMap, noop, first, retry, take, fromEvent, animationFrames, takeUntil } from 'rxjs';
|
|
7
7
|
import { WA_WINDOW } from '@ng-web-apis/common';
|
|
8
8
|
import { takeUntilDestroyed, toSignal, outputFromObservable, toObservable } from '@angular/core/rxjs-interop';
|
|
9
9
|
import * as i4$1 from '@taiga-ui/cdk';
|
|
10
|
-
import { TuiDay, TuiTime, TuiValueTransformer, TUI_IS_MOBILE, tuiControlValue, tuiIsPresent, tuiMarkControlAsTouchedAndValidate, tuiIsFalsy, TuiAutoFocus, TuiRepeatTimes, TuiHovered, TuiDayRange, TuiMonth, tuiPure, tuiProvide, TuiValidationError, TUI_WINDOW_SIZE, tuiClamp, TUI_TRUE_HANDLER } from '@taiga-ui/cdk';
|
|
10
|
+
import { TuiDay, TuiTime, TuiValueTransformer, TUI_IS_MOBILE, tuiControlValue, tuiIsPresent, tuiMarkControlAsTouchedAndValidate, tuiIsFalsy, TuiAutoFocus, TuiRepeatTimes, TuiSwipeService, TUI_SWIPE_OPTIONS, TuiHovered, TuiDayRange, TuiMonth, tuiPure, tuiProvide, TuiValidationError, TUI_WINDOW_SIZE, tuiClamp, TUI_TRUE_HANDLER } from '@taiga-ui/cdk';
|
|
11
11
|
import * as i2$1 from '@taiga-ui/kit';
|
|
12
12
|
import { TUI_DATE_VALUE_TRANSFORMER, TuiPreview, TuiAvatar, TuiAccordionItem, TuiElasticContainer, TuiAccordion, TuiFieldErrorPipe, TuiFilterByInputPipe, TuiStringifyContentPipe, TuiDataListWrapper, TuiButtonLoading, TuiSortCountriesPipe, TuiStepper, TuiCarousel, TuiPush, TuiCheckbox, TuiFiles, TuiChip, TuiInputNumber, TuiBadge, TuiTooltip, TuiHighlight, TuiLineClamp, TuiFade, TuiRange, tuiInputNumberOptionsProvider, TuiDataListWrapperComponent, TuiChevron, TuiSelect, TuiInputSlider, TuiTreeService, TuiTreeItemContent, TUI_TREE_START, TUI_TREE_CONTENT, TUI_TREE_LOADING, TUI_TREE_LOADER, TuiTree, TuiPreviewDialogService, tuiFilesAccepted, TuiInputFiles, TuiInputFilesDirective, TuiFilesComponent, TuiFile, TuiFileRejectedPipe, TUI_CONFIRM, tuiItemsHandlersProvider as tuiItemsHandlersProvider$1, TUI_PAGINATION_TEXTS, TuiAccordionDirective, TuiAccordionItemContent } from '@taiga-ui/kit';
|
|
13
|
-
import { HttpClient, HttpErrorResponse } from '@angular/common/http';
|
|
13
|
+
import { HttpClient, HttpErrorResponse, HttpStatusCode } from '@angular/common/http';
|
|
14
14
|
import * as i1$1 from '@angular/forms';
|
|
15
15
|
import { FormControl, FormGroupDirective, NgControl, FormGroup, Validators, FormArray, FormsModule, ReactiveFormsModule } from '@angular/forms';
|
|
16
16
|
import * as i1$2 from '@taiga-ui/core';
|
|
@@ -4024,7 +4024,11 @@ class ScBannerComponent {
|
|
|
4024
4024
|
/**
|
|
4025
4025
|
* Идентификатор текущего баннера.
|
|
4026
4026
|
*/
|
|
4027
|
-
this.currentBannerId = 0;
|
|
4027
|
+
this.currentBannerId = signal(0);
|
|
4028
|
+
/**
|
|
4029
|
+
* Идентификатор баннера на момент начала касания.
|
|
4030
|
+
*/
|
|
4031
|
+
this.touchStartBannerId = 0;
|
|
4028
4032
|
/**
|
|
4029
4033
|
* Сервис для работы с данными о баннерах.
|
|
4030
4034
|
*/
|
|
@@ -4033,6 +4037,14 @@ class ScBannerComponent {
|
|
|
4033
4037
|
* Сервис для сбора метрик о действиях пользователей.
|
|
4034
4038
|
*/
|
|
4035
4039
|
this.userMetrikaService = inject(ScUserMetrikaService);
|
|
4040
|
+
/**
|
|
4041
|
+
* Поток событий свайпа по баннеру.
|
|
4042
|
+
*/
|
|
4043
|
+
this.swipes$ = inject(TuiSwipeService);
|
|
4044
|
+
/**
|
|
4045
|
+
* Ссылка для автоматического управления уничтожением зависимостей.
|
|
4046
|
+
*/
|
|
4047
|
+
this.destroyRef = inject(DestroyRef);
|
|
4036
4048
|
/**
|
|
4037
4049
|
* Список баннеров.
|
|
4038
4050
|
*/
|
|
@@ -4052,6 +4064,15 @@ class ScBannerComponent {
|
|
|
4052
4064
|
*/
|
|
4053
4065
|
this.totalItems = computed(() => this.banners().length + this.bannersListRef.length);
|
|
4054
4066
|
}
|
|
4067
|
+
/**
|
|
4068
|
+
* @inheritDoc
|
|
4069
|
+
*/
|
|
4070
|
+
ngAfterViewInit() {
|
|
4071
|
+
// Подписка идёт после карусели, чтобы свайп обрабатывался последним: иначе её собственная обработка жеста добавит ещё один слайд.
|
|
4072
|
+
this.swipes$.pipe(takeUntilDestroyed(this.destroyRef)).subscribe((swipe) => {
|
|
4073
|
+
this.onSwipe(swipe);
|
|
4074
|
+
});
|
|
4075
|
+
}
|
|
4055
4076
|
/**
|
|
4056
4077
|
* trackBy для *ngFor баннеров: сохраняет узлы при обновлении списка,
|
|
4057
4078
|
* чтобы карусель не видела 0 слайдов между тиками и не вызывала tuiClamp(…, -1).
|
|
@@ -4064,6 +4085,12 @@ class ScBannerComponent {
|
|
|
4064
4085
|
// eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
|
|
4065
4086
|
return banner.id ?? _index;
|
|
4066
4087
|
}
|
|
4088
|
+
/**
|
|
4089
|
+
* Обработчик начала касания баннера.
|
|
4090
|
+
*/
|
|
4091
|
+
onTouchStart() {
|
|
4092
|
+
this.touchStartBannerId = this.currentBannerId();
|
|
4093
|
+
}
|
|
4067
4094
|
/**
|
|
4068
4095
|
* Обработчик нажатия на баннер.
|
|
4069
4096
|
*
|
|
@@ -4080,15 +4107,32 @@ class ScBannerComponent {
|
|
|
4080
4107
|
this.clickBannerEvent.emit(banner);
|
|
4081
4108
|
}
|
|
4082
4109
|
}
|
|
4110
|
+
/**
|
|
4111
|
+
* Обработчик свайпа по баннеру.
|
|
4112
|
+
*
|
|
4113
|
+
* Баннер отсчитывается от показанного в начале касания: часть жестов карусель обрабатывает сама
|
|
4114
|
+
* (короткий свайп, перетаскивание слайда пальцем), и жест не должен пролистать два баннера.
|
|
4115
|
+
*
|
|
4116
|
+
* @param swipe Событие свайпа.
|
|
4117
|
+
*/
|
|
4118
|
+
onSwipe(swipe) {
|
|
4119
|
+
if (swipe.direction === 'left') {
|
|
4120
|
+
this.currentBannerId.set(Math.min(this.touchStartBannerId + 1, this.totalItems() - 1));
|
|
4121
|
+
}
|
|
4122
|
+
else if (swipe.direction === 'right') {
|
|
4123
|
+
this.currentBannerId.set(Math.max(this.touchStartBannerId - 1, 0));
|
|
4124
|
+
}
|
|
4125
|
+
}
|
|
4083
4126
|
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: ScBannerComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
4084
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.2.14", type: ScBannerComponent, selector: "sc-banner", inputs: { navigateButton: { classPropertyName: "navigateButton", publicName: "navigateButton", isSignal: false, isRequired: false, transformFunction: null }, duration: { classPropertyName: "duration", publicName: "duration", isSignal: false, isRequired: false, transformFunction: null }, bannerLocation: { classPropertyName: "bannerLocation", publicName: "bannerLocation", isSignal: true, isRequired: false, transformFunction: null }, resizable: { classPropertyName: "resizable", publicName: "resizable", isSignal: false, isRequired: false, transformFunction: null } }, outputs: { loadBannersEvent: "loadBannersEvent", clickBannerEvent: "clickBannerEvent" }, host: { attributes: { "ngSkipHydration": "true" }, properties: { "class.!hidden": "totalItems() === 0", "style.aspect-ratio": "this.aspectRatio" } }, providers: [IntersectionObserverService], queries: [{ propertyName: "bannersListRef", predicate: ["banner"] }], ngImport: i0, template: "@let effectiveDuration = totalItems() > 1 ? duration : 0;\n\n<tui-carousel\n [duration]=\"effectiveDuration\"\n #carousel\n [attr.resizable]=\"resizable\"\n class=\"size-full overflow-hidden rounded-xl bg-white\"\n [(index)]=\"currentBannerId\"\n>\n @for (banner of banners(); track trackByBannerId($index, banner)) {\n @switch (banner.mediaType) {\n @case ('image') {\n <a\n *tuiItem\n (click)=\"onClick(banner)\"\n target=\"_blank\"\n [title]=\"banner.title\"\n [style.aspect-ratio]=\"aspectRatio\"\n [attr.href]=\"banner.url ? banner.url : null\"\n class=\"size-full\"\n >\n <picture>\n @if (banner.mediaFileWebp) {\n <source\n type=\"image/webp\"\n [srcset]=\"banner.mediaFileWebp | scMediaImageTransformer\"\n />\n }\n <img\n [src]=\"banner.mediaFile | scMediaImageTransformer: true\"\n [alt]=\"banner.title\"\n class=\"size-full object-cover\"\n />\n </picture>\n </a>\n }\n }\n }\n @for (item of bannersListRef; track $index) {\n <div\n *tuiItem\n [style.aspect-ratio]=\"aspectRatio\"\n class=\"size-full overflow-hidden\"\n >\n <ng-container [ngTemplateOutlet]=\"item\"></ng-container>\n </div>\n }\n</tui-carousel>\n\n@if (navigateButton &&
|
|
4127
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.2.14", type: ScBannerComponent, selector: "sc-banner", inputs: { navigateButton: { classPropertyName: "navigateButton", publicName: "navigateButton", isSignal: false, isRequired: false, transformFunction: null }, duration: { classPropertyName: "duration", publicName: "duration", isSignal: false, isRequired: false, transformFunction: null }, bannerLocation: { classPropertyName: "bannerLocation", publicName: "bannerLocation", isSignal: true, isRequired: false, transformFunction: null }, resizable: { classPropertyName: "resizable", publicName: "resizable", isSignal: false, isRequired: false, transformFunction: null } }, outputs: { loadBannersEvent: "loadBannersEvent", clickBannerEvent: "clickBannerEvent" }, host: { attributes: { "ngSkipHydration": "true" }, listeners: { "touchstart": "onTouchStart()" }, properties: { "class.!hidden": "totalItems() === 0", "style.aspect-ratio": "this.aspectRatio" } }, providers: [IntersectionObserverService, TuiSwipeService, { provide: TUI_SWIPE_OPTIONS, useValue: { timeout: Number.POSITIVE_INFINITY, threshold: 30 } }], queries: [{ propertyName: "bannersListRef", predicate: ["banner"] }], ngImport: i0, template: "@let effectiveDuration = totalItems() > 1 ? duration : 0;\n\n<tui-carousel\n [duration]=\"effectiveDuration\"\n #carousel\n [attr.resizable]=\"resizable\"\n class=\"size-full overflow-hidden rounded-xl bg-white\"\n [(index)]=\"currentBannerId\"\n>\n @for (banner of banners(); track trackByBannerId($index, banner)) {\n @switch (banner.mediaType) {\n @case ('image') {\n <a\n *tuiItem\n (click)=\"onClick(banner)\"\n target=\"_blank\"\n [title]=\"banner.title\"\n [style.aspect-ratio]=\"aspectRatio\"\n [attr.href]=\"banner.url ? banner.url : null\"\n class=\"size-full\"\n >\n <picture>\n @if (banner.mediaFileWebp) {\n <source\n type=\"image/webp\"\n [srcset]=\"banner.mediaFileWebp | scMediaImageTransformer\"\n />\n }\n <img\n [src]=\"banner.mediaFile | scMediaImageTransformer: true\"\n [alt]=\"banner.title\"\n class=\"size-full object-cover\"\n />\n </picture>\n </a>\n }\n }\n }\n @for (item of bannersListRef; track $index) {\n <div\n *tuiItem\n [style.aspect-ratio]=\"aspectRatio\"\n class=\"size-full overflow-hidden\"\n >\n <ng-container [ngTemplateOutlet]=\"item\"></ng-container>\n </div>\n }\n</tui-carousel>\n\n@if (navigateButton && totalItems() > 1) {\n <div\n tuiTheme=\"light\"\n class=\"flex items-center\"\n >\n <button\n tuiIconButton\n iconStart=\"@tui.chevron-left\"\n size=\"m\"\n [style.border-radius.%]=\"100\"\n appearance=\"flat\"\n (click)=\"carousel.prev()\"\n class=\"!absolute left-2\"\n ></button>\n <button\n tuiIconButton\n iconStart=\"@tui.chevron-right\"\n size=\"m\"\n [style.border-radius.%]=\"100\"\n appearance=\"flat\"\n (click)=\"carousel.next()\"\n class=\"!absolute right-2\"\n ></button>\n </div>\n}\n", styles: [":host{--tui-carousel-padding: 0;display:flex;position:relative}::ng-deep tui-carousel[resizable=true] .t-scroller,::ng-deep tui-carousel[resizable=true] .t-items{width:100%;height:100%}\n"], dependencies: [{ kind: "directive", type: i2$2.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "directive", type: i1$2.TuiButton, selector: "a[tuiButton],button[tuiButton],a[tuiIconButton],button[tuiIconButton]", inputs: ["size"] }, { kind: "directive", type: i1$4.TuiItem, selector: "[tuiItem]" }, { kind: "component", type: i2$1.TuiCarouselComponent, selector: "tui-carousel", inputs: ["draggable", "itemsCount", "index"], outputs: ["indexChange", "shift"] }, { kind: "pipe", type: i1.ScMediaImageTransformerPipe, name: "scMediaImageTransformer" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
|
|
4085
4128
|
}
|
|
4086
4129
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: ScBannerComponent, decorators: [{
|
|
4087
4130
|
type: Component,
|
|
4088
|
-
args: [{ selector: 'sc-banner', providers: [IntersectionObserverService], host: {
|
|
4131
|
+
args: [{ selector: 'sc-banner', providers: [IntersectionObserverService, TuiSwipeService, { provide: TUI_SWIPE_OPTIONS, useValue: { timeout: Number.POSITIVE_INFINITY, threshold: 30 } }], host: {
|
|
4089
4132
|
ngSkipHydration: 'true',
|
|
4090
4133
|
'[class.!hidden]': 'totalItems() === 0',
|
|
4091
|
-
|
|
4134
|
+
'(touchstart)': 'onTouchStart()',
|
|
4135
|
+
}, changeDetection: ChangeDetectionStrategy.OnPush, template: "@let effectiveDuration = totalItems() > 1 ? duration : 0;\n\n<tui-carousel\n [duration]=\"effectiveDuration\"\n #carousel\n [attr.resizable]=\"resizable\"\n class=\"size-full overflow-hidden rounded-xl bg-white\"\n [(index)]=\"currentBannerId\"\n>\n @for (banner of banners(); track trackByBannerId($index, banner)) {\n @switch (banner.mediaType) {\n @case ('image') {\n <a\n *tuiItem\n (click)=\"onClick(banner)\"\n target=\"_blank\"\n [title]=\"banner.title\"\n [style.aspect-ratio]=\"aspectRatio\"\n [attr.href]=\"banner.url ? banner.url : null\"\n class=\"size-full\"\n >\n <picture>\n @if (banner.mediaFileWebp) {\n <source\n type=\"image/webp\"\n [srcset]=\"banner.mediaFileWebp | scMediaImageTransformer\"\n />\n }\n <img\n [src]=\"banner.mediaFile | scMediaImageTransformer: true\"\n [alt]=\"banner.title\"\n class=\"size-full object-cover\"\n />\n </picture>\n </a>\n }\n }\n }\n @for (item of bannersListRef; track $index) {\n <div\n *tuiItem\n [style.aspect-ratio]=\"aspectRatio\"\n class=\"size-full overflow-hidden\"\n >\n <ng-container [ngTemplateOutlet]=\"item\"></ng-container>\n </div>\n }\n</tui-carousel>\n\n@if (navigateButton && totalItems() > 1) {\n <div\n tuiTheme=\"light\"\n class=\"flex items-center\"\n >\n <button\n tuiIconButton\n iconStart=\"@tui.chevron-left\"\n size=\"m\"\n [style.border-radius.%]=\"100\"\n appearance=\"flat\"\n (click)=\"carousel.prev()\"\n class=\"!absolute left-2\"\n ></button>\n <button\n tuiIconButton\n iconStart=\"@tui.chevron-right\"\n size=\"m\"\n [style.border-radius.%]=\"100\"\n appearance=\"flat\"\n (click)=\"carousel.next()\"\n class=\"!absolute right-2\"\n ></button>\n </div>\n}\n", styles: [":host{--tui-carousel-padding: 0;display:flex;position:relative}::ng-deep tui-carousel[resizable=true] .t-scroller,::ng-deep tui-carousel[resizable=true] .t-items{width:100%;height:100%}\n"] }]
|
|
4092
4136
|
}], propDecorators: { navigateButton: [{
|
|
4093
4137
|
type: Input
|
|
4094
4138
|
}], duration: [{
|
|
@@ -4124,6 +4168,33 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImpo
|
|
|
4124
4168
|
}]
|
|
4125
4169
|
}] });
|
|
4126
4170
|
|
|
4171
|
+
/**
|
|
4172
|
+
* Класс-помощник для работы с файлами, выбранными пользователем.
|
|
4173
|
+
*/
|
|
4174
|
+
class ScFileHelper {
|
|
4175
|
+
/**
|
|
4176
|
+
* Читает файл и возвращает его для отправки в API: название и содержимое в виде data-URI. При отписке чтение прерывается.
|
|
4177
|
+
*
|
|
4178
|
+
* @param file Выбранный файл.
|
|
4179
|
+
*/
|
|
4180
|
+
static readAsUploadedFile$(file) {
|
|
4181
|
+
return new Observable((observer) => {
|
|
4182
|
+
const reader = new FileReader();
|
|
4183
|
+
reader.addEventListener('load', () => {
|
|
4184
|
+
observer.next(new ScUploadedFile(file.name, reader.result));
|
|
4185
|
+
observer.complete();
|
|
4186
|
+
});
|
|
4187
|
+
reader.addEventListener('error', () => {
|
|
4188
|
+
observer.error(reader.error);
|
|
4189
|
+
});
|
|
4190
|
+
reader.readAsDataURL(file);
|
|
4191
|
+
return () => {
|
|
4192
|
+
reader.abort();
|
|
4193
|
+
};
|
|
4194
|
+
});
|
|
4195
|
+
}
|
|
4196
|
+
}
|
|
4197
|
+
|
|
4127
4198
|
/**
|
|
4128
4199
|
* Компонент диалога для добавления товаров в корзину из CSV файла.
|
|
4129
4200
|
*/
|
|
@@ -4166,19 +4237,7 @@ class ScCartAddProductsFromCsvDialogComponent {
|
|
|
4166
4237
|
/**
|
|
4167
4238
|
* {@link Observable} запроса на добавление товаров из CSV файла.
|
|
4168
4239
|
*/
|
|
4169
|
-
this.submitRequest$ = this.onSubmit$.pipe(map(() => this.control.value), filter(tuiIsPresent), switchMap((file) =>
|
|
4170
|
-
const reader = new FileReader();
|
|
4171
|
-
reader.addEventListener('load', () => {
|
|
4172
|
-
observer.next(new ScUploadedFile(file.name, reader.result));
|
|
4173
|
-
});
|
|
4174
|
-
reader.addEventListener('error', (e) => {
|
|
4175
|
-
observer.error(e);
|
|
4176
|
-
});
|
|
4177
|
-
reader.readAsDataURL(file);
|
|
4178
|
-
return () => {
|
|
4179
|
-
reader.abort();
|
|
4180
|
-
};
|
|
4181
|
-
})), switchMap((file) => this.cartService.addProductsFromCsv$(file).pipe(tap(() => {
|
|
4240
|
+
this.submitRequest$ = this.onSubmit$.pipe(map(() => this.control.value), filter(tuiIsPresent), switchMap((file) => ScFileHelper.readAsUploadedFile$(file)), switchMap((file) => this.cartService.addProductsFromCsv$(file).pipe(tap(() => {
|
|
4182
4241
|
this.context.$implicit.complete();
|
|
4183
4242
|
}), startWith(null))));
|
|
4184
4243
|
/**
|
|
@@ -4799,6 +4858,13 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImpo
|
|
|
4799
4858
|
class ScInputQuantityComponent extends AbstractTuiNullableControl {
|
|
4800
4859
|
constructor() {
|
|
4801
4860
|
super(...arguments);
|
|
4861
|
+
/**
|
|
4862
|
+
* Компонент поля ввода.
|
|
4863
|
+
*/
|
|
4864
|
+
/**
|
|
4865
|
+
* Минимальное количество знаков после запятой.
|
|
4866
|
+
*/
|
|
4867
|
+
this.minPrecision = 2;
|
|
4802
4868
|
/**
|
|
4803
4869
|
* Шаг увеличения количества. Отвечает за проверку кратности ввода.
|
|
4804
4870
|
*/
|
|
@@ -4845,6 +4911,21 @@ class ScInputQuantityComponent extends AbstractTuiNullableControl {
|
|
|
4845
4911
|
/**
|
|
4846
4912
|
* Элемент формы ввода количества.
|
|
4847
4913
|
*/
|
|
4914
|
+
/**
|
|
4915
|
+
* Количество знаков после запятой: по шагу, но не меньше двух.
|
|
4916
|
+
*/
|
|
4917
|
+
get precision() {
|
|
4918
|
+
return Math.max(this.minPrecision, (this.step.toString().split('.')[1] ?? '').length);
|
|
4919
|
+
}
|
|
4920
|
+
/**
|
|
4921
|
+
* Настройки формата числа поля. Точность задаётся только для шага с тремя и более знаками после запятой, иначе действует общая настройка.
|
|
4922
|
+
*/
|
|
4923
|
+
get numberFormat() {
|
|
4924
|
+
if (this.numberFormatCache?.step !== this.step) {
|
|
4925
|
+
this.numberFormatCache = { step: this.step, format: this.precision > this.minPrecision ? { precision: this.precision, decimalMode: 'not-zero' } : {} };
|
|
4926
|
+
}
|
|
4927
|
+
return this.numberFormatCache.format;
|
|
4928
|
+
}
|
|
4848
4929
|
get formControl() {
|
|
4849
4930
|
return this.control;
|
|
4850
4931
|
}
|
|
@@ -4881,7 +4962,7 @@ class ScInputQuantityComponent extends AbstractTuiNullableControl {
|
|
|
4881
4962
|
}
|
|
4882
4963
|
const remainder = (((this.numberInput.value ?? 0) * 1000) % (this.step * 1000)) / 1000; // Умножаем и делим на 1000 чтобы решить ошибку IEEE‑754 при получении остатка от деления.
|
|
4883
4964
|
const step = this.step - remainder;
|
|
4884
|
-
this.numberInput.value = Math.max(Number(((this.numberInput.value ?? 0) + step).toFixed(
|
|
4965
|
+
this.numberInput.value = Math.max(Number(((this.numberInput.value ?? 0) + step).toFixed(this.precision)), this.ignoreStepValidators ? 1 : Math.max(step, 0)); // Используем toFixed чтобы решить ошибку IEEE‑754 при сложении.
|
|
4885
4966
|
this.numberInput['nativeValue'] = this.numberInput['formattedValue'];
|
|
4886
4967
|
// eslint-disable-next-line no-underscore-dangle, @typescript-eslint/no-explicit-any, @typescript-eslint/no-unsafe-member-access
|
|
4887
4968
|
if (checkUpdateOn && this.formControl?._updateOn === 'blur') {
|
|
@@ -4899,7 +4980,7 @@ class ScInputQuantityComponent extends AbstractTuiNullableControl {
|
|
|
4899
4980
|
}
|
|
4900
4981
|
const remainder = (((this.numberInput.value ?? 0) * 1000) % (this.step * 1000)) / 1000; // Умножаем и делим на 1000 чтобы решить ошибку IEEE‑754 при получении остатка от деления.
|
|
4901
4982
|
const step = -remainder || -this.step;
|
|
4902
|
-
this.numberInput.value = Math.max(Number(((this.numberInput.value ?? 0) + step).toFixed(
|
|
4983
|
+
this.numberInput.value = Math.max(Number(((this.numberInput.value ?? 0) + step).toFixed(this.precision)), this.ignoreStepValidators ? 1 : Math.max(step, 0)); // Используем toFixed чтобы решить ошибку IEEE‑754 при сложении.
|
|
4903
4984
|
this.numberInput['nativeValue'] = this.numberInput['formattedValue'];
|
|
4904
4985
|
// eslint-disable-next-line no-underscore-dangle, @typescript-eslint/no-explicit-any, @typescript-eslint/no-unsafe-member-access
|
|
4905
4986
|
if (checkUpdateOn && this.formControl?._updateOn === 'blur') {
|
|
@@ -4914,7 +4995,7 @@ class ScInputQuantityComponent extends AbstractTuiNullableControl {
|
|
|
4914
4995
|
this.clickClearEvent.emit();
|
|
4915
4996
|
}
|
|
4916
4997
|
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: ScInputQuantityComponent, deps: null, target: i0.ɵɵFactoryTarget.Component }); }
|
|
4917
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.14", type: ScInputQuantityComponent, isStandalone: true, selector: "sc-input-quantity", inputs: { step: "step", showLoader: "showLoader", showCross: "showCross", ignoreStepValidators: "ignoreStepValidators", appearance: "appearance", isDisabled: "isDisabled", size: "size" }, outputs: { clickClearEvent: "clickClearEvent" }, host: { listeners: { "keydown.arrowDown": "onArrow(-step)", "keydown.arrowUp": "onArrow(step)" }, properties: { "attr.data-appearance": "this.appearance", "attr.data-disabled": "this.isDisabled", "attr.data-size": "this.size" } }, viewQueries: [{ propertyName: "numberInput", first: true, predicate: TuiInputNumberComponent, descendants: true }], usesInheritance: true, ngImport: i0, template: "<tui-loader\n *ngIf=\"formControl\"\n class=\"w-full\"\n [overlay]=\"true\"\n [showLoader]=\"showLoader\"\n [size]=\"size\"\n>\n <div class=\"flex items-center gap-1 text-center\">\n <div class=\"field-with-button flex grow rounded-xl\">\n <button\n tuiIconButton\n [appearance]=\"appearance\"\n [size]=\"size\"\n [disabled]=\"!numberInput['canDecrement']\"\n (click.prevent)=\"decrement(true)\"\n >\n <tui-icon icon=\"@tui.minus\"></tui-icon>\n </button>\n <tui-input-number\n #numberInput\n [formControl]=\"formControl\"\n [tuiHint]=\"([] | tuiFieldError | async)?.message\"\n [tuiTextfieldLabelOutside]=\"true\"\n [min]=\"ignoreStepValidators ? 1 : step\"\n [tuiTextfieldSize]=\"size\"\n [required]=\"true\"\n [style.text-align]=\"'center'\"\n [style.font-weight]=\"700\"\n (focusin)=\"$any($event.target).select()\"\n oncontextmenu=\"return false;\"\n (keydown.arrowDown)=\"(0)\"\n (keydown.arrowUp)=\"(0)\"\n class=\"grow\"\n >\n </tui-input-number>\n <button\n tuiIconButton\n [appearance]=\"appearance\"\n [size]=\"size\"\n [disabled]=\"!numberInput['canIncrement']\"\n (click.prevent)=\"incident(true)\"\n >\n <tui-icon icon=\"@tui.plus\"></tui-icon>\n </button>\n </div>\n <button\n *ngIf=\"showCross\"\n tuiIconButton\n appearance=\"secondary\"\n [size]=\"size\"\n [disabled]=\"!numberInput['canIncrement']\"\n (click.prevent)=\"clear()\"\n >\n <tui-icon icon=\"@tui.x\"></tui-icon>\n </button>\n </div>\n</tui-loader>\n", styles: [":host [data-size=l]{--tui-height-l: var(--tui-height-m);--tui-font-text-m: bold .875rem/1.25rem var(--tui-font-text);--tui-padding-l: 0}:host [data-size=m]{--tui-height-m: var(--tui-height-s);--tui-font-text-s: bold .75rem/1rem var(--tui-font-text);--tui-padding-m: 0}:host [data-size=m] tui-svg{font-size:12px!important}:host [data-size=s]{--tui-height-s: var(--tui-height-xs);--tui-font-text-s: bold .75rem/1rem var(--tui-font-text);--tui-padding-s: 0}:host [data-size=s] tui-svg{font-size:12px!important}:host[data-disabled=true]{pointer-events:none;opacity:var(--tui-disabled-opacity)}:host[data-appearance=secondary] .field-with-button{background-color:var(--tui-background-base);box-shadow:inset 0 0 0 .0625rem var(--tui-background-neutral-1-hover)}:host[data-appearance=primary] .field-with-button{background-color:var(--tui-status-warning-pale)}:host .field-with-button:has(._invalid){background-color:var(--tui-status-negative-pale)}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i2$2.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "pipe", type: i2$2.AsyncPipe, name: "async" }, { kind: "ngmodule", type: RouterModule }, { kind: "directive", type: TuiButton, selector: "a[tuiButton],button[tuiButton],a[tuiIconButton],button[tuiIconButton]", inputs: ["size"] }, { kind: "component", type: TuiIcon, selector: "tui-icon", inputs: ["icon", "background"] }, { kind: "ngmodule", type: TuiInputNumberModule }, { kind: "component", type: i3.TuiInputNumberComponent, selector: "tui-input-number", inputs: ["min", "max", "step"] }, { kind: "directive", type: i3.TuiInputNumberDirective, selector: "tui-input-number" }, { kind: "ngmodule", type: TuiTextfieldControllerModule }, { kind: "directive", type: i3.TuiTextfieldLabelOutsideDirective, selector: "[tuiTextfieldLabelOutside]", inputs: ["tuiTextfieldLabelOutside"] }, { kind: "directive", type: i3.TuiTextfieldSizeDirective, selector: "[tuiTextfieldSize]", inputs: ["tuiTextfieldSize"] }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$1.RequiredValidator, selector: ":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]", inputs: ["required"] }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1$1.FormControlDirective, selector: "[formControl]", inputs: ["formControl", "disabled", "ngModel"], outputs: ["ngModelChange"], exportAs: ["ngForm"] }, { kind: "directive", type: i1$2.TuiHintDirective, selector: "[tuiHint]:not(ng-container):not(ng-template)", inputs: ["tuiHintContext", "tuiHintAppearance", "tuiHint"], outputs: ["tuiHintVisible"] }, { kind: "pipe", type: TuiFieldErrorPipe, name: "tuiFieldError" }, { kind: "component", type: TuiLoader, selector: "tui-loader", inputs: ["size", "inheritColor", "overlay", "textContent", "showLoader"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
|
|
4998
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.14", type: ScInputQuantityComponent, isStandalone: true, selector: "sc-input-quantity", inputs: { step: "step", showLoader: "showLoader", showCross: "showCross", ignoreStepValidators: "ignoreStepValidators", appearance: "appearance", isDisabled: "isDisabled", size: "size" }, outputs: { clickClearEvent: "clickClearEvent" }, host: { listeners: { "keydown.arrowDown": "onArrow(-step)", "keydown.arrowUp": "onArrow(step)" }, properties: { "attr.data-appearance": "this.appearance", "attr.data-disabled": "this.isDisabled", "attr.data-size": "this.size" } }, viewQueries: [{ propertyName: "numberInput", first: true, predicate: TuiInputNumberComponent, descendants: true }], usesInheritance: true, ngImport: i0, template: "<tui-loader\n *ngIf=\"formControl\"\n class=\"w-full\"\n [overlay]=\"true\"\n [showLoader]=\"showLoader\"\n [size]=\"size\"\n>\n <div class=\"flex items-center gap-1 text-center\">\n <div class=\"field-with-button flex grow rounded-xl\">\n <button\n tuiIconButton\n [appearance]=\"appearance\"\n [size]=\"size\"\n [disabled]=\"!numberInput['canDecrement']\"\n (click.prevent)=\"decrement(true)\"\n >\n <tui-icon icon=\"@tui.minus\"></tui-icon>\n </button>\n <tui-input-number\n #numberInput\n [formControl]=\"formControl\"\n [tuiHint]=\"([] | tuiFieldError | async)?.message\"\n [tuiTextfieldLabelOutside]=\"true\"\n [min]=\"ignoreStepValidators ? 1 : step\"\n [tuiNumberFormat]=\"numberFormat\"\n [tuiTextfieldSize]=\"size\"\n [required]=\"true\"\n [style.text-align]=\"'center'\"\n [style.font-weight]=\"700\"\n (focusin)=\"$any($event.target).select()\"\n oncontextmenu=\"return false;\"\n (keydown.arrowDown)=\"(0)\"\n (keydown.arrowUp)=\"(0)\"\n class=\"grow\"\n >\n </tui-input-number>\n <button\n tuiIconButton\n [appearance]=\"appearance\"\n [size]=\"size\"\n [disabled]=\"!numberInput['canIncrement']\"\n (click.prevent)=\"incident(true)\"\n >\n <tui-icon icon=\"@tui.plus\"></tui-icon>\n </button>\n </div>\n <button\n *ngIf=\"showCross\"\n tuiIconButton\n appearance=\"secondary\"\n [size]=\"size\"\n [disabled]=\"!numberInput['canIncrement']\"\n (click.prevent)=\"clear()\"\n >\n <tui-icon icon=\"@tui.x\"></tui-icon>\n </button>\n </div>\n</tui-loader>\n", styles: [":host [data-size=l]{--tui-height-l: var(--tui-height-m);--tui-font-text-m: bold .875rem/1.25rem var(--tui-font-text);--tui-padding-l: 0}:host [data-size=m]{--tui-height-m: var(--tui-height-s);--tui-font-text-s: bold .75rem/1rem var(--tui-font-text);--tui-padding-m: 0}:host [data-size=m] tui-svg{font-size:12px!important}:host [data-size=s]{--tui-height-s: var(--tui-height-xs);--tui-font-text-s: bold .75rem/1rem var(--tui-font-text);--tui-padding-s: 0}:host [data-size=s] tui-svg{font-size:12px!important}:host[data-disabled=true]{pointer-events:none;opacity:var(--tui-disabled-opacity)}:host[data-appearance=secondary] .field-with-button{background-color:var(--tui-background-base);box-shadow:inset 0 0 0 .0625rem var(--tui-background-neutral-1-hover)}:host[data-appearance=primary] .field-with-button{background-color:var(--tui-status-warning-pale)}:host .field-with-button:has(._invalid){background-color:var(--tui-status-negative-pale)}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i2$2.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "pipe", type: i2$2.AsyncPipe, name: "async" }, { kind: "ngmodule", type: RouterModule }, { kind: "directive", type: TuiButton, selector: "a[tuiButton],button[tuiButton],a[tuiIconButton],button[tuiIconButton]", inputs: ["size"] }, { kind: "component", type: TuiIcon, selector: "tui-icon", inputs: ["icon", "background"] }, { kind: "ngmodule", type: TuiInputNumberModule }, { kind: "component", type: i3.TuiInputNumberComponent, selector: "tui-input-number", inputs: ["min", "max", "step"] }, { kind: "directive", type: i3.TuiInputNumberDirective, selector: "tui-input-number" }, { kind: "ngmodule", type: TuiTextfieldControllerModule }, { kind: "directive", type: i3.TuiTextfieldLabelOutsideDirective, selector: "[tuiTextfieldLabelOutside]", inputs: ["tuiTextfieldLabelOutside"] }, { kind: "directive", type: i3.TuiTextfieldSizeDirective, selector: "[tuiTextfieldSize]", inputs: ["tuiTextfieldSize"] }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$1.RequiredValidator, selector: ":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]", inputs: ["required"] }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1$1.FormControlDirective, selector: "[formControl]", inputs: ["formControl", "disabled", "ngModel"], outputs: ["ngModelChange"], exportAs: ["ngForm"] }, { kind: "directive", type: i1$2.TuiHintDirective, selector: "[tuiHint]:not(ng-container):not(ng-template)", inputs: ["tuiHintContext", "tuiHintAppearance", "tuiHint"], outputs: ["tuiHintVisible"] }, { kind: "pipe", type: TuiFieldErrorPipe, name: "tuiFieldError" }, { kind: "component", type: TuiLoader, selector: "tui-loader", inputs: ["size", "inheritColor", "overlay", "textContent", "showLoader"] }, { kind: "directive", type: TuiNumberFormat, selector: "[tuiNumberFormat]", inputs: ["tuiNumberFormat"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
|
|
4918
4999
|
}
|
|
4919
5000
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: ScInputQuantityComponent, decorators: [{
|
|
4920
5001
|
type: Component,
|
|
@@ -4931,7 +5012,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImpo
|
|
|
4931
5012
|
...TuiHint,
|
|
4932
5013
|
TuiFieldErrorPipe,
|
|
4933
5014
|
TuiLoader,
|
|
4934
|
-
|
|
5015
|
+
TuiNumberFormat,
|
|
5016
|
+
], changeDetection: ChangeDetectionStrategy.OnPush, template: "<tui-loader\n *ngIf=\"formControl\"\n class=\"w-full\"\n [overlay]=\"true\"\n [showLoader]=\"showLoader\"\n [size]=\"size\"\n>\n <div class=\"flex items-center gap-1 text-center\">\n <div class=\"field-with-button flex grow rounded-xl\">\n <button\n tuiIconButton\n [appearance]=\"appearance\"\n [size]=\"size\"\n [disabled]=\"!numberInput['canDecrement']\"\n (click.prevent)=\"decrement(true)\"\n >\n <tui-icon icon=\"@tui.minus\"></tui-icon>\n </button>\n <tui-input-number\n #numberInput\n [formControl]=\"formControl\"\n [tuiHint]=\"([] | tuiFieldError | async)?.message\"\n [tuiTextfieldLabelOutside]=\"true\"\n [min]=\"ignoreStepValidators ? 1 : step\"\n [tuiNumberFormat]=\"numberFormat\"\n [tuiTextfieldSize]=\"size\"\n [required]=\"true\"\n [style.text-align]=\"'center'\"\n [style.font-weight]=\"700\"\n (focusin)=\"$any($event.target).select()\"\n oncontextmenu=\"return false;\"\n (keydown.arrowDown)=\"(0)\"\n (keydown.arrowUp)=\"(0)\"\n class=\"grow\"\n >\n </tui-input-number>\n <button\n tuiIconButton\n [appearance]=\"appearance\"\n [size]=\"size\"\n [disabled]=\"!numberInput['canIncrement']\"\n (click.prevent)=\"incident(true)\"\n >\n <tui-icon icon=\"@tui.plus\"></tui-icon>\n </button>\n </div>\n <button\n *ngIf=\"showCross\"\n tuiIconButton\n appearance=\"secondary\"\n [size]=\"size\"\n [disabled]=\"!numberInput['canIncrement']\"\n (click.prevent)=\"clear()\"\n >\n <tui-icon icon=\"@tui.x\"></tui-icon>\n </button>\n </div>\n</tui-loader>\n", styles: [":host [data-size=l]{--tui-height-l: var(--tui-height-m);--tui-font-text-m: bold .875rem/1.25rem var(--tui-font-text);--tui-padding-l: 0}:host [data-size=m]{--tui-height-m: var(--tui-height-s);--tui-font-text-s: bold .75rem/1rem var(--tui-font-text);--tui-padding-m: 0}:host [data-size=m] tui-svg{font-size:12px!important}:host [data-size=s]{--tui-height-s: var(--tui-height-xs);--tui-font-text-s: bold .75rem/1rem var(--tui-font-text);--tui-padding-s: 0}:host [data-size=s] tui-svg{font-size:12px!important}:host[data-disabled=true]{pointer-events:none;opacity:var(--tui-disabled-opacity)}:host[data-appearance=secondary] .field-with-button{background-color:var(--tui-background-base);box-shadow:inset 0 0 0 .0625rem var(--tui-background-neutral-1-hover)}:host[data-appearance=primary] .field-with-button{background-color:var(--tui-status-warning-pale)}:host .field-with-button:has(._invalid){background-color:var(--tui-status-negative-pale)}\n"] }]
|
|
4935
5017
|
}], propDecorators: { numberInput: [{
|
|
4936
5018
|
type: ViewChild,
|
|
4937
5019
|
args: [TuiInputNumberComponent]
|
|
@@ -8296,6 +8378,14 @@ class ScOrderItemComponent extends AbstractScPriceCard {
|
|
|
8296
8378
|
* Признак, что необходимо отобразить элементы редактирования.
|
|
8297
8379
|
*/
|
|
8298
8380
|
this.isShowEditControls = input(true);
|
|
8381
|
+
/**
|
|
8382
|
+
* Признак, что цена за единицу берётся из позиции, а не из текущей цены товара (например, цена, зафиксированная в заявке).
|
|
8383
|
+
*/
|
|
8384
|
+
this.useLinePrice = input(false);
|
|
8385
|
+
/**
|
|
8386
|
+
* Признак, что позиции, которые не попадут в заказ, помечаются причиной и остаются доступными для изменения количества.
|
|
8387
|
+
*/
|
|
8388
|
+
this.markUnavailable = input(false);
|
|
8299
8389
|
}
|
|
8300
8390
|
/**
|
|
8301
8391
|
* Отображает спецификацию.
|
|
@@ -8316,13 +8406,13 @@ class ScOrderItemComponent extends AbstractScPriceCard {
|
|
|
8316
8406
|
}
|
|
8317
8407
|
}
|
|
8318
8408
|
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: ScOrderItemComponent, deps: null, target: i0.ɵɵFactoryTarget.Component }); }
|
|
8319
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.2.14", type: ScOrderItemComponent, isStandalone: true, selector: "sc-order-item", inputs: { isShowEditControls: { classPropertyName: "isShowEditControls", publicName: "isShowEditControls", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { clickSettings: "clickSettings" }, providers: [
|
|
8409
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.2.14", type: ScOrderItemComponent, isStandalone: true, selector: "sc-order-item", inputs: { isShowEditControls: { classPropertyName: "isShowEditControls", publicName: "isShowEditControls", isSignal: true, isRequired: false, transformFunction: null }, useLinePrice: { classPropertyName: "useLinePrice", publicName: "useLinePrice", isSignal: true, isRequired: false, transformFunction: null }, markUnavailable: { classPropertyName: "markUnavailable", publicName: "markUnavailable", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { clickSettings: "clickSettings" }, providers: [
|
|
8320
8410
|
SEARCH_TERM_PROVIDERS,
|
|
8321
8411
|
tuiTextfieldOptionsProvider({
|
|
8322
8412
|
appearance: signal('textfield'),
|
|
8323
8413
|
}),
|
|
8324
8414
|
tuiHintOptionsProvider({ direction: 'top', showDelay: 100, hideDelay: 100 }),
|
|
8325
|
-
], usesInheritance: true, ngImport: i0, template: "@if (product && orderItem) {\n <div class=\"@container relative flex w-full gap-4 rounded-xl p-1 text-body-s hover:bg-tui-background-neutral-1\">\n <sc-noindex-wrapper>\n @let isDisabled = product.isHidden || product.isNull;\n <sc-hover-image-carousel\n (click)=\"isDisabled ? null : clickCardEvent.emit()\"\n [images]=\"!isMobile ? getCardImagePreviewList(product) : [getCardImagePreview()]\"\n [isShowActions]=\"false\"\n class=\"aspect-square w-24 shrink-0 cursor-pointer self-start\"\n />\n <div class=\"flex w-full flex-col gap-y-1 gap-x-4 @5xl:flex-row @5xl:items-center @5xl:gap-5\">\n <div class=\"flex min-w-0 flex-1 flex-col gap-1\">\n <div\n [tuiHighlight]=\"(search$ | async) ?? ''\"\n class=\"text-tui-text-02\"\n >\n \u0410\u0440\u0442\u0438\u043A\u0443\u043B: {{ product.code }}\n </div>\n <div class=\"flex flex-col gap-1\">\n <a\n tuiLink\n [attr.href]=\"href ?? null\"\n [tuiHighlight]=\"(search$ | async) ?? ''\"\n (click)=\"$event.preventDefault(); clickCardEvent.emit()\"\n [class.disabled]=\"isDisabled\"\n class=\"!text-body-m-bold\"\n >\n {{ product.name }}\n </a>\n @if (product.supplierSku) {\n <span class=\"text-tui-text-02\"> \u0410\u0440\u0442\u0438\u043A\u0443\u043B \u043F\u0440\u043E\u0438\u0437\u0432\u043E\u0434\u0438\u0442\u0435\u043B\u044F: {{ product.supplierSku }} </span>\n }\n @if (product.pack) {\n <div class=\"flex items-center gap-1 text-tui-text-02\">\n \u041D\u043E\u0440\u043C\u0430 \u0443\u043F\u0430\u043A\u043E\u0432\u043A\u0438: {{ product.pack }}\n @if (product.ignoreMinCountCheck) {\n <tui-icon\n icon=\"@tui.package\"\n [tuiHint]=\"minCountHint\"\n [tuiHintShowDelay]=\"100\"\n tuiHintDirection=\"top\"\n class=\"text-body-xl text-tui-text-01 opacity-90\"\n />\n <ng-template #minCountHint>\n \u0414\u043E\u0441\u0442\u0443\u043F\u0435\u043D \u0437\u0430\u043A\u0430\u0437 <br />\n \u043F\u0440\u043E\u0438\u0437\u0432\u043E\u043B\u044C\u043D\u043E\u0433\u043E <br />\n \u043A\u043E\u043B\u0438\u0447\u0435\u0441\u0442\u0432\u0430\n </ng-template>\n }\n </div>\n }\n\n <sc-cost-with-discount\n scPrint=\"cost\"\n [product]=\"product\"\n />\n </div>\n @if (orderItem.specificationImgUrl) {\n <a\n tuiLink\n (click)=\"showSpecification(specificationPreview)\"\n [class.disabled]=\"isDisabled\"\n >\n \u0421\u043F\u0435\u0446\u0438\u0444\u0438\u043A\u0430\u0446\u0438\u044F\n </a>\n }\n <ng-template\n #specificationPreview\n let-preview\n >\n <tui-preview\n [rotatable]=\"false\"\n [zoomable]=\"false\"\n >\n <img\n *polymorpheusOutlet=\"orderItem.specificationImgUrl as src\"\n alt=\"preview\"\n [src]=\"orderItem.specificationImgUrl\"\n />\n <button\n iconStart=\"@tui.x\"\n title=\"Close\"\n tuiIconButton\n tuiPreviewAction\n type=\"button\"\n (click)=\"preview.complete()\"\n ></button>\n </tui-preview>\n </ng-template>\n </div>\n <div class=\"grid grid-cols-1 @lg:grid-cols-3 gap-2 @2xl:gap-4 @2xl:grid-rows-1\">\n <div class=\"grid grid-cols-1 items-center @lg:gap-2 @2xl:grid-cols-2 @lg:col-span-2\">\n <!-- \u041A\u043E\u043B\u0438\u0447\u0435\u0441\u0442\u0432\u043E \u0442\u043E\u0432\u0430\u0440\u0430. -->\n @if (isShowEditControls() && showQuantityControl) {\n <!-- \u041F\u043E\u043B\u0435 \u0432\u0432\u043E\u0434\u0430 \u043A\u043E\u043B\u0438\u0447\u0435\u0441\u0442\u0432\u0430 \u0442\u043E\u0432\u0430\u0440\u0430. -->\n <sc-input-quantity\n #inputQuantity\n [tuiAutoFocus]=\"autoFocuseQuantityInput()\"\n [formControl]=\"quantityControl\"\n size=\"m\"\n [showCross]=\"false\"\n [isDisabled]=\"isDisabled\"\n [step]=\"ScUnitsHelper.getProductMultiplicity(product)\"\n [ignoreStepValidators]=\"product.ignoreMinCountCheck\"\n [showLoader]=\"showLoader()\"\n (clickClearEvent)=\"clickClearEvent.emit(orderItem)\"\n (keydown.enter)=\"inputQuantity.nativeFocusableElement?.blur()\"\n class=\"w-32 shrink-0\"\n />\n } @else {\n <button\n [appearance]=\"isShowEditControls() ? 'action-grayscale' : ''\"\n tuiTheme=\"light\"\n tuiHint=\"\u0414\u043B\u044F \u0438\u0437\u043C\u0435\u043D\u0435\u043D\u0438\u044F \u043A\u043E\u043B\u0438\u0447\u0435\u0441\u0442\u0432\u0430 \u0432\u043E\u0441\u043F\u043E\u043B\u044C\u0437\u0443\u0439\u0442\u0435\u0441\u044C \u043A\u043E\u043D\u0444\u0438\u0433\u0443\u0440\u0430\u0442\u043E\u0440\u043E\u043C\"\n (tuiHintVisible)=\"configuratorHintVisible($event)\"\n tuiLink\n [style.text-decoration-line]=\"isShowEditControls() ? 'underline' : 'none'\"\n [class.pointer-events-none]=\"!isShowEditControls()\"\n >\n <div class=\"!text-body-m text-start\">\n \u041A\u043E\u043B\u0438\u0447\u0435\u0441\u0442\u0432\u043E:\n <strong> {{ orderItem.quantity }} \u0448\u0442.</strong>\n </div>\n </button>\n }\n\n @let showAdditionalInfo = orderItem.configurator || orderItem.height || orderItem.length || orderItem.width || orderItem.marker;\n @if (showAdditionalInfo) {\n <div class=\"flex items-center gap-2 @lg:gap-3 max-w-min\">\n <!-- \u041A\u043D\u043E\u043F\u043A\u0430 \u0440\u0435\u0434\u0430\u043A\u0442\u0438\u0440\u043E\u0432\u0430\u043D\u0438\u044F \u0442\u043E\u0432\u0430\u0440\u0430. -->\n @if (isShowEditControls()) {\n <button\n tuiIconButton\n iconStart=\"@tui.settings\"\n [disabled]=\"isDisabled\"\n [loading]=\"showLoader()\"\n (click)=\"clickSettings.emit()\"\n size=\"s\"\n [appearance]=\"isConfiguratorHintVisible() ? 'primary' : 'secondary'\"\n class=\"shrink-0\"\n ></button>\n }\n\n <!-- \u0414\u043E\u043F\u043E\u043B\u043D\u0438\u0442\u0435\u043B\u044C\u043D\u0430\u044F \u0438\u043D\u0444\u043E\u0440\u043C\u0430\u0446\u0438\u044F \u043E \u0442\u043E\u0432\u0430\u0440\u0435. -->\n <div\n class=\"flex flex-col gap-x-1 text-tui-base-07\"\n [class.text-body-m]=\"!isShowEditControls()\"\n >\n @if (orderItem.marker) {\n <p>\u041C\u0430\u0440\u043A\u0438\u0440\u043E\u0432\u043A\u0430: {{ orderItem.marker }}</p>\n }\n @if (orderItem.width) {\n <button\n [appearance]=\"isShowEditControls() ? 'action-grayscale' : ''\"\n tuiTheme=\"light\"\n tuiHint=\"\u0414\u043B\u044F \u0438\u0437\u043C\u0435\u043D\u0435\u043D\u0438\u044F \u0448\u0438\u0440\u0438\u043D\u044B \u0432\u043E\u0441\u043F\u043E\u043B\u044C\u0437\u0443\u0439\u0442\u0435\u0441\u044C \u043A\u043E\u043D\u0444\u0438\u0433\u0443\u0440\u0430\u0442\u043E\u0440\u043E\u043C\"\n (tuiHintVisible)=\"configuratorHintVisible($event)\"\n tuiLink\n [style.text-decoration-line]=\"isShowEditControls() ? 'underline' : 'none'\"\n [class.pointer-events-none]=\"!isShowEditControls()\"\n class=\"text-body-s self-start whitespace-nowrap\"\n >\n \u0428\u0438\u0440\u0438\u043D\u0430: <span class=\"text-body-s-bold\">{{ orderItem.width }} \u043C.</span>\n </button>\n }\n @if (orderItem.height) {\n <button\n [appearance]=\"isShowEditControls() ? 'action-grayscale' : ''\"\n tuiTheme=\"light\"\n tuiHint=\"\u0414\u043B\u044F \u0438\u0437\u043C\u0435\u043D\u0435\u043D\u0438\u044F \u0432\u044B\u0441\u043E\u0442\u044B \u0432\u043E\u0441\u043F\u043E\u043B\u044C\u0437\u0443\u0439\u0442\u0435\u0441\u044C \u043A\u043E\u043D\u0444\u0438\u0433\u0443\u0440\u0430\u0442\u043E\u0440\u043E\u043C\"\n (tuiHintVisible)=\"configuratorHintVisible($event)\"\n tuiLink\n [style.text-decoration-line]=\"isShowEditControls() ? 'underline' : 'none'\"\n [class.pointer-events-none]=\"!isShowEditControls()\"\n class=\"text-body-s self-start whitespace-nowrap\"\n >\n \u0412\u044B\u0441\u043E\u0442\u0430: <span class=\"text-body-s-bold\">{{ orderItem.height }} \u043C.</span>\n </button>\n } @else if (orderItem.length) {\n <button\n [appearance]=\"isShowEditControls() ? 'action-grayscale' : ''\"\n tuiTheme=\"light\"\n tuiHint=\"\u0414\u043B\u044F \u0438\u0437\u043C\u0435\u043D\u0435\u043D\u0438\u044F \u0434\u043B\u0438\u043D\u044B \u0432\u043E\u0441\u043F\u043E\u043B\u044C\u0437\u0443\u0439\u0442\u0435\u0441\u044C \u043A\u043E\u043D\u0444\u0438\u0433\u0443\u0440\u0430\u0442\u043E\u0440\u043E\u043C\"\n (tuiHintVisible)=\"configuratorHintVisible($event)\"\n tuiLink\n [style.text-decoration-line]=\"isShowEditControls() ? 'underline' : 'none'\"\n [class.pointer-events-none]=\"!isShowEditControls()\"\n class=\"text-body-s self-start whitespace-nowrap\"\n >\n \u0414\u043B\u0438\u043D\u0430: <span class=\"text-body-s-bold\">{{ orderItem.length }} \u043C.</span>\n </button>\n }\n </div>\n </div>\n }\n </div>\n\n <!-- \u0421\u0443\u043C\u043C\u0430 \u0442\u043E\u0432\u0430\u0440\u0430 \u0438 \u0441\u043A\u043B\u0430\u0434\u0441\u043A\u043E\u0435 \u043D\u0430\u043B\u0438\u0447\u0438\u0435. -->\n <div\n scPrint=\"cost\"\n class=\"flex min-w-[11rem] flex-col @lg:justify-end @2xl:!justify-center text-body-m\"\n >\n <p class=\"whitespace-nowrap\">\n \u0421\u0443\u043C\u043C\u0430:\n <strong> {{ orderItem.costRub | tuiFormatNumber: { precision: 2, decimalSeparator: '.', rounding: 'ceil' } | async }} {{ 'RUB' | tuiCurrency }}</strong>\n </p>\n <sc-price-warehouse-stock\n scPrint=\"defaultNoPrint\"\n [product]=\"product\"\n />\n </div>\n </div>\n </div>\n </sc-noindex-wrapper>\n </div>\n} @else {\n <div class=\"tui-skeleton flex h-[8.25rem] w-full overflow-hidden rounded-xl\"></div>\n}\n", dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "pipe", type: i2$2.AsyncPipe, name: "async" }, { kind: "ngmodule", type: RouterModule }, { kind: "directive", type: TuiButton, selector: "a[tuiButton],button[tuiButton],a[tuiIconButton],button[tuiIconButton]", inputs: ["size"] }, { kind: "component", type: TuiIcon, selector: "tui-icon", inputs: ["icon", "background"] }, { kind: "ngmodule", type: TuiTextfieldControllerModule }, { kind: "directive", type: i2$3.PolymorpheusOutlet, selector: "[polymorpheusOutlet]", inputs: ["polymorpheusOutlet", "polymorpheusOutletContext"] }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1$1.FormControlDirective, selector: "[formControl]", inputs: ["formControl", "disabled", "ngModel"], outputs: ["ngModelChange"], exportAs: ["ngForm"] }, { kind: "directive", type: i1$2.TuiHintDirective, selector: "[tuiHint]:not(ng-container):not(ng-template)", inputs: ["tuiHintContext", "tuiHintAppearance", "tuiHint"], outputs: ["tuiHintVisible"] }, { kind: "directive", type: TuiLink, selector: "a[tuiLink], button[tuiLink]", inputs: ["pseudo"] }, { kind: "directive", type: TuiHighlight, selector: "[tuiHighlight]", inputs: ["tuiHighlight", "tuiHighlightColor"] }, { kind: "directive", type: TuiAutoFocus, selector: "[tuiAutoFocus]", inputs: ["tuiAutoFocus"] }, { kind: "component", type: ScHoverImageCarouselComponent, selector: "sc-hover-image-carousel", inputs: ["images", "isShowActions", "productName"] }, { kind: "component", type: CostWithDiscountComponent, selector: "sc-cost-with-discount", inputs: ["product", "size"] }, { kind: "component", type: ScPriceWarehouseStockComponent, selector: "sc-price-warehouse-stock", inputs: ["classList", "product", "withStockHint", "fromMain"] }, { kind: "component", type: ScInputQuantityComponent, selector: "sc-input-quantity", inputs: ["step", "showLoader", "showCross", "ignoreStepValidators", "appearance", "isDisabled", "size"], outputs: ["clickClearEvent"] }, { kind: "pipe", type: TuiCurrencyPipe, name: "tuiCurrency" }, { kind: "pipe", type: TuiFormatNumberPipe, name: "tuiFormatNumber" }, { kind: "component", type: i2$1.TuiPreviewComponent, selector: "tui-preview", inputs: ["zoomable", "rotatable", "initialScale"] }, { kind: "directive", type: i2$1.TuiPreviewAction, selector: "[tuiPreviewAction]" }, { kind: "component", type: ScNoindexWrapperComponent, selector: "sc-noindex-wrapper" }, { kind: "component", type: TuiButtonLoading, selector: "[tuiButton][loading],[tuiIconButton][loading]", inputs: ["size", "loading"] }, { kind: "directive", type: ScPrintDirective, selector: "[scPrint]", inputs: ["scPrint"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
|
|
8415
|
+
], usesInheritance: true, ngImport: i0, template: "@if (product && orderItem) {\n <div class=\"@container relative flex w-full gap-4 rounded-xl p-1 text-body-s hover:bg-tui-background-neutral-1\">\n <sc-noindex-wrapper>\n @let isDisabled = product.isHidden || product.isNull;\n @let unavailableReason = markUnavailable() ? orderItem.getUnavailableReason() : '';\n <sc-hover-image-carousel\n (click)=\"isDisabled ? null : clickCardEvent.emit()\"\n [images]=\"!isMobile ? getCardImagePreviewList(product) : [getCardImagePreview()]\"\n [isShowActions]=\"false\"\n class=\"aspect-square w-24 shrink-0 cursor-pointer self-start\"\n />\n <div class=\"flex w-full flex-col gap-y-1 gap-x-4 @5xl:flex-row @5xl:items-center @5xl:gap-5\">\n <div class=\"flex min-w-0 flex-1 flex-col gap-1\">\n @if (product.code) {\n <div\n [tuiHighlight]=\"(search$ | async) ?? ''\"\n class=\"text-tui-text-02\"\n >\n \u0410\u0440\u0442\u0438\u043A\u0443\u043B: {{ product.code }}\n </div>\n }\n <div class=\"flex flex-col gap-1\">\n <a\n tuiLink\n [attr.href]=\"href ?? null\"\n [tuiHighlight]=\"(search$ | async) ?? ''\"\n (click)=\"$event.preventDefault(); clickCardEvent.emit()\"\n [class.disabled]=\"isDisabled\"\n [class.!line-through]=\"!!unavailableReason\"\n class=\"!text-body-m-bold\"\n >\n {{ product.name }}\n </a>\n @if (unavailableReason) {\n <tui-badge\n appearance=\"warning\"\n size=\"m\"\n class=\"self-start\"\n >\n {{ unavailableReason }}\n </tui-badge>\n }\n @if (product.supplierSku) {\n <span class=\"text-tui-text-02\"> \u0410\u0440\u0442\u0438\u043A\u0443\u043B \u043F\u0440\u043E\u0438\u0437\u0432\u043E\u0434\u0438\u0442\u0435\u043B\u044F: {{ product.supplierSku }} </span>\n }\n @if (product.pack) {\n <div class=\"flex items-center gap-1 text-tui-text-02\">\n \u041D\u043E\u0440\u043C\u0430 \u0443\u043F\u0430\u043A\u043E\u0432\u043A\u0438: {{ product.pack }}\n @if (product.ignoreMinCountCheck) {\n <tui-icon\n icon=\"@tui.package\"\n [tuiHint]=\"minCountHint\"\n [tuiHintShowDelay]=\"100\"\n tuiHintDirection=\"top\"\n class=\"text-body-xl text-tui-text-01 opacity-90\"\n />\n <ng-template #minCountHint>\n \u0414\u043E\u0441\u0442\u0443\u043F\u0435\u043D \u0437\u0430\u043A\u0430\u0437 <br />\n \u043F\u0440\u043E\u0438\u0437\u0432\u043E\u043B\u044C\u043D\u043E\u0433\u043E <br />\n \u043A\u043E\u043B\u0438\u0447\u0435\u0441\u0442\u0432\u0430\n </ng-template>\n }\n </div>\n }\n\n @if (useLinePrice()) {\n @if (!unavailableReason) {\n <span\n scPrint=\"cost\"\n class=\"text-body-m\"\n >\n {{ orderItem.costOneRub > 0 ? orderItem.getCostInRubDescPerItem() : orderItem.getCostMessage() }}\n </span>\n }\n } @else {\n <sc-cost-with-discount\n scPrint=\"cost\"\n [product]=\"product\"\n />\n }\n </div>\n @if (orderItem.specificationImgUrl) {\n <a\n tuiLink\n (click)=\"showSpecification(specificationPreview)\"\n [class.disabled]=\"isDisabled\"\n >\n \u0421\u043F\u0435\u0446\u0438\u0444\u0438\u043A\u0430\u0446\u0438\u044F\n </a>\n }\n <ng-template\n #specificationPreview\n let-preview\n >\n <tui-preview\n [rotatable]=\"false\"\n [zoomable]=\"false\"\n >\n <img\n *polymorpheusOutlet=\"orderItem.specificationImgUrl as src\"\n alt=\"preview\"\n [src]=\"orderItem.specificationImgUrl\"\n />\n <button\n iconStart=\"@tui.x\"\n title=\"Close\"\n tuiIconButton\n tuiPreviewAction\n type=\"button\"\n (click)=\"preview.complete()\"\n ></button>\n </tui-preview>\n </ng-template>\n </div>\n <div class=\"grid grid-cols-1 @lg:grid-cols-3 gap-2 @2xl:gap-4 @2xl:grid-rows-1\">\n <div class=\"grid grid-cols-1 items-center @lg:gap-2 @2xl:grid-cols-2 @lg:col-span-2\">\n <!-- \u041A\u043E\u043B\u0438\u0447\u0435\u0441\u0442\u0432\u043E \u0442\u043E\u0432\u0430\u0440\u0430. -->\n @if (isShowEditControls() && showQuantityControl) {\n <!-- \u041F\u043E\u043B\u0435 \u0432\u0432\u043E\u0434\u0430 \u043A\u043E\u043B\u0438\u0447\u0435\u0441\u0442\u0432\u0430 \u0442\u043E\u0432\u0430\u0440\u0430. -->\n <sc-input-quantity\n #inputQuantity\n [tuiAutoFocus]=\"autoFocuseQuantityInput()\"\n [formControl]=\"quantityControl\"\n size=\"m\"\n [showCross]=\"false\"\n [isDisabled]=\"isDisabled && !markUnavailable()\"\n [step]=\"orderItem.quantityStep\"\n [ignoreStepValidators]=\"product.ignoreMinCountCheck\"\n [showLoader]=\"showLoader()\"\n (clickClearEvent)=\"clickClearEvent.emit(orderItem)\"\n (keydown.enter)=\"inputQuantity.nativeFocusableElement?.blur()\"\n class=\"w-32 shrink-0\"\n />\n } @else {\n <button\n [appearance]=\"isShowEditControls() ? 'action-grayscale' : ''\"\n tuiTheme=\"light\"\n tuiHint=\"\u0414\u043B\u044F \u0438\u0437\u043C\u0435\u043D\u0435\u043D\u0438\u044F \u043A\u043E\u043B\u0438\u0447\u0435\u0441\u0442\u0432\u0430 \u0432\u043E\u0441\u043F\u043E\u043B\u044C\u0437\u0443\u0439\u0442\u0435\u0441\u044C \u043A\u043E\u043D\u0444\u0438\u0433\u0443\u0440\u0430\u0442\u043E\u0440\u043E\u043C\"\n (tuiHintVisible)=\"configuratorHintVisible($event)\"\n tuiLink\n [style.text-decoration-line]=\"isShowEditControls() ? 'underline' : 'none'\"\n [class.pointer-events-none]=\"!isShowEditControls()\"\n >\n <div class=\"!text-body-m text-start\">\n \u041A\u043E\u043B\u0438\u0447\u0435\u0441\u0442\u0432\u043E:\n <strong> {{ orderItem.quantity }} \u0448\u0442.</strong>\n </div>\n </button>\n }\n\n @let showAdditionalInfo = orderItem.configurator || orderItem.height || orderItem.length || orderItem.width || orderItem.marker;\n @if (showAdditionalInfo) {\n <div class=\"flex items-center gap-2 @lg:gap-3 max-w-min\">\n <!-- \u041A\u043D\u043E\u043F\u043A\u0430 \u0440\u0435\u0434\u0430\u043A\u0442\u0438\u0440\u043E\u0432\u0430\u043D\u0438\u044F \u0442\u043E\u0432\u0430\u0440\u0430. -->\n @if (isShowEditControls()) {\n <button\n tuiIconButton\n iconStart=\"@tui.settings\"\n [disabled]=\"isDisabled\"\n [loading]=\"showLoader()\"\n (click)=\"clickSettings.emit()\"\n size=\"s\"\n [appearance]=\"isConfiguratorHintVisible() ? 'primary' : 'secondary'\"\n class=\"shrink-0\"\n ></button>\n }\n\n <!-- \u0414\u043E\u043F\u043E\u043B\u043D\u0438\u0442\u0435\u043B\u044C\u043D\u0430\u044F \u0438\u043D\u0444\u043E\u0440\u043C\u0430\u0446\u0438\u044F \u043E \u0442\u043E\u0432\u0430\u0440\u0435. -->\n <div\n class=\"flex flex-col gap-x-1 text-tui-base-07\"\n [class.text-body-m]=\"!isShowEditControls()\"\n >\n @if (orderItem.marker) {\n <p>\u041C\u0430\u0440\u043A\u0438\u0440\u043E\u0432\u043A\u0430: {{ orderItem.marker }}</p>\n }\n @if (orderItem.width) {\n <button\n [appearance]=\"isShowEditControls() ? 'action-grayscale' : ''\"\n tuiTheme=\"light\"\n tuiHint=\"\u0414\u043B\u044F \u0438\u0437\u043C\u0435\u043D\u0435\u043D\u0438\u044F \u0448\u0438\u0440\u0438\u043D\u044B \u0432\u043E\u0441\u043F\u043E\u043B\u044C\u0437\u0443\u0439\u0442\u0435\u0441\u044C \u043A\u043E\u043D\u0444\u0438\u0433\u0443\u0440\u0430\u0442\u043E\u0440\u043E\u043C\"\n (tuiHintVisible)=\"configuratorHintVisible($event)\"\n tuiLink\n [style.text-decoration-line]=\"isShowEditControls() ? 'underline' : 'none'\"\n [class.pointer-events-none]=\"!isShowEditControls()\"\n class=\"text-body-s self-start whitespace-nowrap\"\n >\n \u0428\u0438\u0440\u0438\u043D\u0430: <span class=\"text-body-s-bold\">{{ orderItem.width }} \u043C.</span>\n </button>\n }\n @if (orderItem.height) {\n <button\n [appearance]=\"isShowEditControls() ? 'action-grayscale' : ''\"\n tuiTheme=\"light\"\n tuiHint=\"\u0414\u043B\u044F \u0438\u0437\u043C\u0435\u043D\u0435\u043D\u0438\u044F \u0432\u044B\u0441\u043E\u0442\u044B \u0432\u043E\u0441\u043F\u043E\u043B\u044C\u0437\u0443\u0439\u0442\u0435\u0441\u044C \u043A\u043E\u043D\u0444\u0438\u0433\u0443\u0440\u0430\u0442\u043E\u0440\u043E\u043C\"\n (tuiHintVisible)=\"configuratorHintVisible($event)\"\n tuiLink\n [style.text-decoration-line]=\"isShowEditControls() ? 'underline' : 'none'\"\n [class.pointer-events-none]=\"!isShowEditControls()\"\n class=\"text-body-s self-start whitespace-nowrap\"\n >\n \u0412\u044B\u0441\u043E\u0442\u0430: <span class=\"text-body-s-bold\">{{ orderItem.height }} \u043C.</span>\n </button>\n } @else if (orderItem.length) {\n <button\n [appearance]=\"isShowEditControls() ? 'action-grayscale' : ''\"\n tuiTheme=\"light\"\n tuiHint=\"\u0414\u043B\u044F \u0438\u0437\u043C\u0435\u043D\u0435\u043D\u0438\u044F \u0434\u043B\u0438\u043D\u044B \u0432\u043E\u0441\u043F\u043E\u043B\u044C\u0437\u0443\u0439\u0442\u0435\u0441\u044C \u043A\u043E\u043D\u0444\u0438\u0433\u0443\u0440\u0430\u0442\u043E\u0440\u043E\u043C\"\n (tuiHintVisible)=\"configuratorHintVisible($event)\"\n tuiLink\n [style.text-decoration-line]=\"isShowEditControls() ? 'underline' : 'none'\"\n [class.pointer-events-none]=\"!isShowEditControls()\"\n class=\"text-body-s self-start whitespace-nowrap\"\n >\n \u0414\u043B\u0438\u043D\u0430: <span class=\"text-body-s-bold\">{{ orderItem.length }} \u043C.</span>\n </button>\n }\n </div>\n </div>\n }\n </div>\n\n <!-- \u0421\u0443\u043C\u043C\u0430 \u0442\u043E\u0432\u0430\u0440\u0430 \u0438 \u0441\u043A\u043B\u0430\u0434\u0441\u043A\u043E\u0435 \u043D\u0430\u043B\u0438\u0447\u0438\u0435. -->\n <div\n scPrint=\"cost\"\n class=\"flex min-w-[11rem] flex-col @lg:justify-end @2xl:!justify-center text-body-m\"\n >\n <p class=\"whitespace-nowrap\">\n \u0421\u0443\u043C\u043C\u0430:\n <strong> {{ orderItem.costRub | tuiFormatNumber: { precision: 2, decimalSeparator: '.', rounding: 'ceil' } | async }} {{ 'RUB' | tuiCurrency }}</strong>\n </p>\n @if (!(markUnavailable() && product.isNull)) {\n <sc-price-warehouse-stock\n scPrint=\"defaultNoPrint\"\n [product]=\"product\"\n />\n }\n </div>\n </div>\n </div>\n </sc-noindex-wrapper>\n </div>\n} @else {\n <div class=\"tui-skeleton flex h-[8.25rem] w-full overflow-hidden rounded-xl\"></div>\n}\n", dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "pipe", type: i2$2.AsyncPipe, name: "async" }, { kind: "ngmodule", type: RouterModule }, { kind: "directive", type: TuiButton, selector: "a[tuiButton],button[tuiButton],a[tuiIconButton],button[tuiIconButton]", inputs: ["size"] }, { kind: "component", type: TuiIcon, selector: "tui-icon", inputs: ["icon", "background"] }, { kind: "ngmodule", type: TuiTextfieldControllerModule }, { kind: "directive", type: i2$3.PolymorpheusOutlet, selector: "[polymorpheusOutlet]", inputs: ["polymorpheusOutlet", "polymorpheusOutletContext"] }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1$1.FormControlDirective, selector: "[formControl]", inputs: ["formControl", "disabled", "ngModel"], outputs: ["ngModelChange"], exportAs: ["ngForm"] }, { kind: "directive", type: i1$2.TuiHintDirective, selector: "[tuiHint]:not(ng-container):not(ng-template)", inputs: ["tuiHintContext", "tuiHintAppearance", "tuiHint"], outputs: ["tuiHintVisible"] }, { kind: "directive", type: TuiLink, selector: "a[tuiLink], button[tuiLink]", inputs: ["pseudo"] }, { kind: "directive", type: TuiHighlight, selector: "[tuiHighlight]", inputs: ["tuiHighlight", "tuiHighlightColor"] }, { kind: "directive", type: TuiAutoFocus, selector: "[tuiAutoFocus]", inputs: ["tuiAutoFocus"] }, { kind: "component", type: ScHoverImageCarouselComponent, selector: "sc-hover-image-carousel", inputs: ["images", "isShowActions", "productName"] }, { kind: "component", type: CostWithDiscountComponent, selector: "sc-cost-with-discount", inputs: ["product", "size"] }, { kind: "component", type: ScPriceWarehouseStockComponent, selector: "sc-price-warehouse-stock", inputs: ["classList", "product", "withStockHint", "fromMain"] }, { kind: "component", type: ScInputQuantityComponent, selector: "sc-input-quantity", inputs: ["step", "showLoader", "showCross", "ignoreStepValidators", "appearance", "isDisabled", "size"], outputs: ["clickClearEvent"] }, { kind: "pipe", type: TuiCurrencyPipe, name: "tuiCurrency" }, { kind: "pipe", type: TuiFormatNumberPipe, name: "tuiFormatNumber" }, { kind: "component", type: i2$1.TuiPreviewComponent, selector: "tui-preview", inputs: ["zoomable", "rotatable", "initialScale"] }, { kind: "directive", type: i2$1.TuiPreviewAction, selector: "[tuiPreviewAction]" }, { kind: "directive", type: TuiBadge, selector: "tui-badge,[tuiBadge]", inputs: ["size"] }, { kind: "component", type: ScNoindexWrapperComponent, selector: "sc-noindex-wrapper" }, { kind: "component", type: TuiButtonLoading, selector: "[tuiButton][loading],[tuiIconButton][loading]", inputs: ["size", "loading"] }, { kind: "directive", type: ScPrintDirective, selector: "[scPrint]", inputs: ["scPrint"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
|
|
8326
8416
|
}
|
|
8327
8417
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: ScOrderItemComponent, decorators: [{
|
|
8328
8418
|
type: Component,
|
|
@@ -8349,6 +8439,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImpo
|
|
|
8349
8439
|
TuiCurrencyPipe,
|
|
8350
8440
|
TuiFormatNumberPipe,
|
|
8351
8441
|
TuiPreview,
|
|
8442
|
+
TuiBadge,
|
|
8352
8443
|
ScNoindexWrapperComponent,
|
|
8353
8444
|
TuiAppearance,
|
|
8354
8445
|
TuiButtonLoading,
|
|
@@ -8359,7 +8450,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImpo
|
|
|
8359
8450
|
appearance: signal('textfield'),
|
|
8360
8451
|
}),
|
|
8361
8452
|
tuiHintOptionsProvider({ direction: 'top', showDelay: 100, hideDelay: 100 }),
|
|
8362
|
-
], changeDetection: ChangeDetectionStrategy.OnPush, template: "@if (product && orderItem) {\n <div class=\"@container relative flex w-full gap-4 rounded-xl p-1 text-body-s hover:bg-tui-background-neutral-1\">\n <sc-noindex-wrapper>\n @let isDisabled = product.isHidden || product.isNull;\n <sc-hover-image-carousel\n (click)=\"isDisabled ? null : clickCardEvent.emit()\"\n [images]=\"!isMobile ? getCardImagePreviewList(product) : [getCardImagePreview()]\"\n [isShowActions]=\"false\"\n class=\"aspect-square w-24 shrink-0 cursor-pointer self-start\"\n />\n <div class=\"flex w-full flex-col gap-y-1 gap-x-4 @5xl:flex-row @5xl:items-center @5xl:gap-5\">\n <div class=\"flex min-w-0 flex-1 flex-col gap-1\">\n <div\n [tuiHighlight]=\"(search$ | async) ?? ''\"\n class=\"text-tui-text-02\"\n >\n \u0410\u0440\u0442\u0438\u043A\u0443\u043B: {{ product.code }}\n </div>\n <div class=\"flex flex-col gap-1\">\n <a\n tuiLink\n [attr.href]=\"href ?? null\"\n [tuiHighlight]=\"(search$ | async) ?? ''\"\n (click)=\"$event.preventDefault(); clickCardEvent.emit()\"\n [class.disabled]=\"isDisabled\"\n class=\"!text-body-m-bold\"\n >\n {{ product.name }}\n </a>\n @if (product.supplierSku) {\n <span class=\"text-tui-text-02\"> \u0410\u0440\u0442\u0438\u043A\u0443\u043B \u043F\u0440\u043E\u0438\u0437\u0432\u043E\u0434\u0438\u0442\u0435\u043B\u044F: {{ product.supplierSku }} </span>\n }\n @if (product.pack) {\n <div class=\"flex items-center gap-1 text-tui-text-02\">\n \u041D\u043E\u0440\u043C\u0430 \u0443\u043F\u0430\u043A\u043E\u0432\u043A\u0438: {{ product.pack }}\n @if (product.ignoreMinCountCheck) {\n <tui-icon\n icon=\"@tui.package\"\n [tuiHint]=\"minCountHint\"\n [tuiHintShowDelay]=\"100\"\n tuiHintDirection=\"top\"\n class=\"text-body-xl text-tui-text-01 opacity-90\"\n />\n <ng-template #minCountHint>\n \u0414\u043E\u0441\u0442\u0443\u043F\u0435\u043D \u0437\u0430\u043A\u0430\u0437 <br />\n \u043F\u0440\u043E\u0438\u0437\u0432\u043E\u043B\u044C\u043D\u043E\u0433\u043E <br />\n \u043A\u043E\u043B\u0438\u0447\u0435\u0441\u0442\u0432\u0430\n </ng-template>\n }\n </div>\n }\n\n <sc-cost-with-discount\n scPrint=\"cost\"\n [product]=\"product\"\n />\n </div>\n @if (orderItem.specificationImgUrl) {\n <a\n tuiLink\n (click)=\"showSpecification(specificationPreview)\"\n [class.disabled]=\"isDisabled\"\n >\n \u0421\u043F\u0435\u0446\u0438\u0444\u0438\u043A\u0430\u0446\u0438\u044F\n </a>\n }\n <ng-template\n #specificationPreview\n let-preview\n >\n <tui-preview\n [rotatable]=\"false\"\n [zoomable]=\"false\"\n >\n <img\n *polymorpheusOutlet=\"orderItem.specificationImgUrl as src\"\n alt=\"preview\"\n [src]=\"orderItem.specificationImgUrl\"\n />\n <button\n iconStart=\"@tui.x\"\n title=\"Close\"\n tuiIconButton\n tuiPreviewAction\n type=\"button\"\n (click)=\"preview.complete()\"\n ></button>\n </tui-preview>\n </ng-template>\n </div>\n <div class=\"grid grid-cols-1 @lg:grid-cols-3 gap-2 @2xl:gap-4 @2xl:grid-rows-1\">\n <div class=\"grid grid-cols-1 items-center @lg:gap-2 @2xl:grid-cols-2 @lg:col-span-2\">\n <!-- \u041A\u043E\u043B\u0438\u0447\u0435\u0441\u0442\u0432\u043E \u0442\u043E\u0432\u0430\u0440\u0430. -->\n @if (isShowEditControls() && showQuantityControl) {\n <!-- \u041F\u043E\u043B\u0435 \u0432\u0432\u043E\u0434\u0430 \u043A\u043E\u043B\u0438\u0447\u0435\u0441\u0442\u0432\u0430 \u0442\u043E\u0432\u0430\u0440\u0430. -->\n <sc-input-quantity\n #inputQuantity\n [tuiAutoFocus]=\"autoFocuseQuantityInput()\"\n [formControl]=\"quantityControl\"\n size=\"m\"\n [showCross]=\"false\"\n [isDisabled]=\"isDisabled\"\n [step]=\"ScUnitsHelper.getProductMultiplicity(product)\"\n [ignoreStepValidators]=\"product.ignoreMinCountCheck\"\n [showLoader]=\"showLoader()\"\n (clickClearEvent)=\"clickClearEvent.emit(orderItem)\"\n (keydown.enter)=\"inputQuantity.nativeFocusableElement?.blur()\"\n class=\"w-32 shrink-0\"\n />\n } @else {\n <button\n [appearance]=\"isShowEditControls() ? 'action-grayscale' : ''\"\n tuiTheme=\"light\"\n tuiHint=\"\u0414\u043B\u044F \u0438\u0437\u043C\u0435\u043D\u0435\u043D\u0438\u044F \u043A\u043E\u043B\u0438\u0447\u0435\u0441\u0442\u0432\u0430 \u0432\u043E\u0441\u043F\u043E\u043B\u044C\u0437\u0443\u0439\u0442\u0435\u0441\u044C \u043A\u043E\u043D\u0444\u0438\u0433\u0443\u0440\u0430\u0442\u043E\u0440\u043E\u043C\"\n (tuiHintVisible)=\"configuratorHintVisible($event)\"\n tuiLink\n [style.text-decoration-line]=\"isShowEditControls() ? 'underline' : 'none'\"\n [class.pointer-events-none]=\"!isShowEditControls()\"\n >\n <div class=\"!text-body-m text-start\">\n \u041A\u043E\u043B\u0438\u0447\u0435\u0441\u0442\u0432\u043E:\n <strong> {{ orderItem.quantity }} \u0448\u0442.</strong>\n </div>\n </button>\n }\n\n @let showAdditionalInfo = orderItem.configurator || orderItem.height || orderItem.length || orderItem.width || orderItem.marker;\n @if (showAdditionalInfo) {\n <div class=\"flex items-center gap-2 @lg:gap-3 max-w-min\">\n <!-- \u041A\u043D\u043E\u043F\u043A\u0430 \u0440\u0435\u0434\u0430\u043A\u0442\u0438\u0440\u043E\u0432\u0430\u043D\u0438\u044F \u0442\u043E\u0432\u0430\u0440\u0430. -->\n @if (isShowEditControls()) {\n <button\n tuiIconButton\n iconStart=\"@tui.settings\"\n [disabled]=\"isDisabled\"\n [loading]=\"showLoader()\"\n (click)=\"clickSettings.emit()\"\n size=\"s\"\n [appearance]=\"isConfiguratorHintVisible() ? 'primary' : 'secondary'\"\n class=\"shrink-0\"\n ></button>\n }\n\n <!-- \u0414\u043E\u043F\u043E\u043B\u043D\u0438\u0442\u0435\u043B\u044C\u043D\u0430\u044F \u0438\u043D\u0444\u043E\u0440\u043C\u0430\u0446\u0438\u044F \u043E \u0442\u043E\u0432\u0430\u0440\u0435. -->\n <div\n class=\"flex flex-col gap-x-1 text-tui-base-07\"\n [class.text-body-m]=\"!isShowEditControls()\"\n >\n @if (orderItem.marker) {\n <p>\u041C\u0430\u0440\u043A\u0438\u0440\u043E\u0432\u043A\u0430: {{ orderItem.marker }}</p>\n }\n @if (orderItem.width) {\n <button\n [appearance]=\"isShowEditControls() ? 'action-grayscale' : ''\"\n tuiTheme=\"light\"\n tuiHint=\"\u0414\u043B\u044F \u0438\u0437\u043C\u0435\u043D\u0435\u043D\u0438\u044F \u0448\u0438\u0440\u0438\u043D\u044B \u0432\u043E\u0441\u043F\u043E\u043B\u044C\u0437\u0443\u0439\u0442\u0435\u0441\u044C \u043A\u043E\u043D\u0444\u0438\u0433\u0443\u0440\u0430\u0442\u043E\u0440\u043E\u043C\"\n (tuiHintVisible)=\"configuratorHintVisible($event)\"\n tuiLink\n [style.text-decoration-line]=\"isShowEditControls() ? 'underline' : 'none'\"\n [class.pointer-events-none]=\"!isShowEditControls()\"\n class=\"text-body-s self-start whitespace-nowrap\"\n >\n \u0428\u0438\u0440\u0438\u043D\u0430: <span class=\"text-body-s-bold\">{{ orderItem.width }} \u043C.</span>\n </button>\n }\n @if (orderItem.height) {\n <button\n [appearance]=\"isShowEditControls() ? 'action-grayscale' : ''\"\n tuiTheme=\"light\"\n tuiHint=\"\u0414\u043B\u044F \u0438\u0437\u043C\u0435\u043D\u0435\u043D\u0438\u044F \u0432\u044B\u0441\u043E\u0442\u044B \u0432\u043E\u0441\u043F\u043E\u043B\u044C\u0437\u0443\u0439\u0442\u0435\u0441\u044C \u043A\u043E\u043D\u0444\u0438\u0433\u0443\u0440\u0430\u0442\u043E\u0440\u043E\u043C\"\n (tuiHintVisible)=\"configuratorHintVisible($event)\"\n tuiLink\n [style.text-decoration-line]=\"isShowEditControls() ? 'underline' : 'none'\"\n [class.pointer-events-none]=\"!isShowEditControls()\"\n class=\"text-body-s self-start whitespace-nowrap\"\n >\n \u0412\u044B\u0441\u043E\u0442\u0430: <span class=\"text-body-s-bold\">{{ orderItem.height }} \u043C.</span>\n </button>\n } @else if (orderItem.length) {\n <button\n [appearance]=\"isShowEditControls() ? 'action-grayscale' : ''\"\n tuiTheme=\"light\"\n tuiHint=\"\u0414\u043B\u044F \u0438\u0437\u043C\u0435\u043D\u0435\u043D\u0438\u044F \u0434\u043B\u0438\u043D\u044B \u0432\u043E\u0441\u043F\u043E\u043B\u044C\u0437\u0443\u0439\u0442\u0435\u0441\u044C \u043A\u043E\u043D\u0444\u0438\u0433\u0443\u0440\u0430\u0442\u043E\u0440\u043E\u043C\"\n (tuiHintVisible)=\"configuratorHintVisible($event)\"\n tuiLink\n [style.text-decoration-line]=\"isShowEditControls() ? 'underline' : 'none'\"\n [class.pointer-events-none]=\"!isShowEditControls()\"\n class=\"text-body-s self-start whitespace-nowrap\"\n >\n \u0414\u043B\u0438\u043D\u0430: <span class=\"text-body-s-bold\">{{ orderItem.length }} \u043C.</span>\n </button>\n }\n </div>\n </div>\n }\n </div>\n\n <!-- \u0421\u0443\u043C\u043C\u0430 \u0442\u043E\u0432\u0430\u0440\u0430 \u0438 \u0441\u043A\u043B\u0430\u0434\u0441\u043A\u043E\u0435 \u043D\u0430\u043B\u0438\u0447\u0438\u0435. -->\n <div\n scPrint=\"cost\"\n class=\"flex min-w-[11rem] flex-col @lg:justify-end @2xl:!justify-center text-body-m\"\n >\n <p class=\"whitespace-nowrap\">\n \u0421\u0443\u043C\u043C\u0430:\n <strong> {{ orderItem.costRub | tuiFormatNumber: { precision: 2, decimalSeparator: '.', rounding: 'ceil' } | async }} {{ 'RUB' | tuiCurrency }}</strong>\n </p>\n <sc-price-warehouse-stock\n scPrint=\"defaultNoPrint\"\n [product]=\"product\"\n />\n </div>\n </div>\n </div>\n </sc-noindex-wrapper>\n </div>\n} @else {\n <div class=\"tui-skeleton flex h-[8.25rem] w-full overflow-hidden rounded-xl\"></div>\n}\n" }]
|
|
8453
|
+
], changeDetection: ChangeDetectionStrategy.OnPush, template: "@if (product && orderItem) {\n <div class=\"@container relative flex w-full gap-4 rounded-xl p-1 text-body-s hover:bg-tui-background-neutral-1\">\n <sc-noindex-wrapper>\n @let isDisabled = product.isHidden || product.isNull;\n @let unavailableReason = markUnavailable() ? orderItem.getUnavailableReason() : '';\n <sc-hover-image-carousel\n (click)=\"isDisabled ? null : clickCardEvent.emit()\"\n [images]=\"!isMobile ? getCardImagePreviewList(product) : [getCardImagePreview()]\"\n [isShowActions]=\"false\"\n class=\"aspect-square w-24 shrink-0 cursor-pointer self-start\"\n />\n <div class=\"flex w-full flex-col gap-y-1 gap-x-4 @5xl:flex-row @5xl:items-center @5xl:gap-5\">\n <div class=\"flex min-w-0 flex-1 flex-col gap-1\">\n @if (product.code) {\n <div\n [tuiHighlight]=\"(search$ | async) ?? ''\"\n class=\"text-tui-text-02\"\n >\n \u0410\u0440\u0442\u0438\u043A\u0443\u043B: {{ product.code }}\n </div>\n }\n <div class=\"flex flex-col gap-1\">\n <a\n tuiLink\n [attr.href]=\"href ?? null\"\n [tuiHighlight]=\"(search$ | async) ?? ''\"\n (click)=\"$event.preventDefault(); clickCardEvent.emit()\"\n [class.disabled]=\"isDisabled\"\n [class.!line-through]=\"!!unavailableReason\"\n class=\"!text-body-m-bold\"\n >\n {{ product.name }}\n </a>\n @if (unavailableReason) {\n <tui-badge\n appearance=\"warning\"\n size=\"m\"\n class=\"self-start\"\n >\n {{ unavailableReason }}\n </tui-badge>\n }\n @if (product.supplierSku) {\n <span class=\"text-tui-text-02\"> \u0410\u0440\u0442\u0438\u043A\u0443\u043B \u043F\u0440\u043E\u0438\u0437\u0432\u043E\u0434\u0438\u0442\u0435\u043B\u044F: {{ product.supplierSku }} </span>\n }\n @if (product.pack) {\n <div class=\"flex items-center gap-1 text-tui-text-02\">\n \u041D\u043E\u0440\u043C\u0430 \u0443\u043F\u0430\u043A\u043E\u0432\u043A\u0438: {{ product.pack }}\n @if (product.ignoreMinCountCheck) {\n <tui-icon\n icon=\"@tui.package\"\n [tuiHint]=\"minCountHint\"\n [tuiHintShowDelay]=\"100\"\n tuiHintDirection=\"top\"\n class=\"text-body-xl text-tui-text-01 opacity-90\"\n />\n <ng-template #minCountHint>\n \u0414\u043E\u0441\u0442\u0443\u043F\u0435\u043D \u0437\u0430\u043A\u0430\u0437 <br />\n \u043F\u0440\u043E\u0438\u0437\u0432\u043E\u043B\u044C\u043D\u043E\u0433\u043E <br />\n \u043A\u043E\u043B\u0438\u0447\u0435\u0441\u0442\u0432\u0430\n </ng-template>\n }\n </div>\n }\n\n @if (useLinePrice()) {\n @if (!unavailableReason) {\n <span\n scPrint=\"cost\"\n class=\"text-body-m\"\n >\n {{ orderItem.costOneRub > 0 ? orderItem.getCostInRubDescPerItem() : orderItem.getCostMessage() }}\n </span>\n }\n } @else {\n <sc-cost-with-discount\n scPrint=\"cost\"\n [product]=\"product\"\n />\n }\n </div>\n @if (orderItem.specificationImgUrl) {\n <a\n tuiLink\n (click)=\"showSpecification(specificationPreview)\"\n [class.disabled]=\"isDisabled\"\n >\n \u0421\u043F\u0435\u0446\u0438\u0444\u0438\u043A\u0430\u0446\u0438\u044F\n </a>\n }\n <ng-template\n #specificationPreview\n let-preview\n >\n <tui-preview\n [rotatable]=\"false\"\n [zoomable]=\"false\"\n >\n <img\n *polymorpheusOutlet=\"orderItem.specificationImgUrl as src\"\n alt=\"preview\"\n [src]=\"orderItem.specificationImgUrl\"\n />\n <button\n iconStart=\"@tui.x\"\n title=\"Close\"\n tuiIconButton\n tuiPreviewAction\n type=\"button\"\n (click)=\"preview.complete()\"\n ></button>\n </tui-preview>\n </ng-template>\n </div>\n <div class=\"grid grid-cols-1 @lg:grid-cols-3 gap-2 @2xl:gap-4 @2xl:grid-rows-1\">\n <div class=\"grid grid-cols-1 items-center @lg:gap-2 @2xl:grid-cols-2 @lg:col-span-2\">\n <!-- \u041A\u043E\u043B\u0438\u0447\u0435\u0441\u0442\u0432\u043E \u0442\u043E\u0432\u0430\u0440\u0430. -->\n @if (isShowEditControls() && showQuantityControl) {\n <!-- \u041F\u043E\u043B\u0435 \u0432\u0432\u043E\u0434\u0430 \u043A\u043E\u043B\u0438\u0447\u0435\u0441\u0442\u0432\u0430 \u0442\u043E\u0432\u0430\u0440\u0430. -->\n <sc-input-quantity\n #inputQuantity\n [tuiAutoFocus]=\"autoFocuseQuantityInput()\"\n [formControl]=\"quantityControl\"\n size=\"m\"\n [showCross]=\"false\"\n [isDisabled]=\"isDisabled && !markUnavailable()\"\n [step]=\"orderItem.quantityStep\"\n [ignoreStepValidators]=\"product.ignoreMinCountCheck\"\n [showLoader]=\"showLoader()\"\n (clickClearEvent)=\"clickClearEvent.emit(orderItem)\"\n (keydown.enter)=\"inputQuantity.nativeFocusableElement?.blur()\"\n class=\"w-32 shrink-0\"\n />\n } @else {\n <button\n [appearance]=\"isShowEditControls() ? 'action-grayscale' : ''\"\n tuiTheme=\"light\"\n tuiHint=\"\u0414\u043B\u044F \u0438\u0437\u043C\u0435\u043D\u0435\u043D\u0438\u044F \u043A\u043E\u043B\u0438\u0447\u0435\u0441\u0442\u0432\u0430 \u0432\u043E\u0441\u043F\u043E\u043B\u044C\u0437\u0443\u0439\u0442\u0435\u0441\u044C \u043A\u043E\u043D\u0444\u0438\u0433\u0443\u0440\u0430\u0442\u043E\u0440\u043E\u043C\"\n (tuiHintVisible)=\"configuratorHintVisible($event)\"\n tuiLink\n [style.text-decoration-line]=\"isShowEditControls() ? 'underline' : 'none'\"\n [class.pointer-events-none]=\"!isShowEditControls()\"\n >\n <div class=\"!text-body-m text-start\">\n \u041A\u043E\u043B\u0438\u0447\u0435\u0441\u0442\u0432\u043E:\n <strong> {{ orderItem.quantity }} \u0448\u0442.</strong>\n </div>\n </button>\n }\n\n @let showAdditionalInfo = orderItem.configurator || orderItem.height || orderItem.length || orderItem.width || orderItem.marker;\n @if (showAdditionalInfo) {\n <div class=\"flex items-center gap-2 @lg:gap-3 max-w-min\">\n <!-- \u041A\u043D\u043E\u043F\u043A\u0430 \u0440\u0435\u0434\u0430\u043A\u0442\u0438\u0440\u043E\u0432\u0430\u043D\u0438\u044F \u0442\u043E\u0432\u0430\u0440\u0430. -->\n @if (isShowEditControls()) {\n <button\n tuiIconButton\n iconStart=\"@tui.settings\"\n [disabled]=\"isDisabled\"\n [loading]=\"showLoader()\"\n (click)=\"clickSettings.emit()\"\n size=\"s\"\n [appearance]=\"isConfiguratorHintVisible() ? 'primary' : 'secondary'\"\n class=\"shrink-0\"\n ></button>\n }\n\n <!-- \u0414\u043E\u043F\u043E\u043B\u043D\u0438\u0442\u0435\u043B\u044C\u043D\u0430\u044F \u0438\u043D\u0444\u043E\u0440\u043C\u0430\u0446\u0438\u044F \u043E \u0442\u043E\u0432\u0430\u0440\u0435. -->\n <div\n class=\"flex flex-col gap-x-1 text-tui-base-07\"\n [class.text-body-m]=\"!isShowEditControls()\"\n >\n @if (orderItem.marker) {\n <p>\u041C\u0430\u0440\u043A\u0438\u0440\u043E\u0432\u043A\u0430: {{ orderItem.marker }}</p>\n }\n @if (orderItem.width) {\n <button\n [appearance]=\"isShowEditControls() ? 'action-grayscale' : ''\"\n tuiTheme=\"light\"\n tuiHint=\"\u0414\u043B\u044F \u0438\u0437\u043C\u0435\u043D\u0435\u043D\u0438\u044F \u0448\u0438\u0440\u0438\u043D\u044B \u0432\u043E\u0441\u043F\u043E\u043B\u044C\u0437\u0443\u0439\u0442\u0435\u0441\u044C \u043A\u043E\u043D\u0444\u0438\u0433\u0443\u0440\u0430\u0442\u043E\u0440\u043E\u043C\"\n (tuiHintVisible)=\"configuratorHintVisible($event)\"\n tuiLink\n [style.text-decoration-line]=\"isShowEditControls() ? 'underline' : 'none'\"\n [class.pointer-events-none]=\"!isShowEditControls()\"\n class=\"text-body-s self-start whitespace-nowrap\"\n >\n \u0428\u0438\u0440\u0438\u043D\u0430: <span class=\"text-body-s-bold\">{{ orderItem.width }} \u043C.</span>\n </button>\n }\n @if (orderItem.height) {\n <button\n [appearance]=\"isShowEditControls() ? 'action-grayscale' : ''\"\n tuiTheme=\"light\"\n tuiHint=\"\u0414\u043B\u044F \u0438\u0437\u043C\u0435\u043D\u0435\u043D\u0438\u044F \u0432\u044B\u0441\u043E\u0442\u044B \u0432\u043E\u0441\u043F\u043E\u043B\u044C\u0437\u0443\u0439\u0442\u0435\u0441\u044C \u043A\u043E\u043D\u0444\u0438\u0433\u0443\u0440\u0430\u0442\u043E\u0440\u043E\u043C\"\n (tuiHintVisible)=\"configuratorHintVisible($event)\"\n tuiLink\n [style.text-decoration-line]=\"isShowEditControls() ? 'underline' : 'none'\"\n [class.pointer-events-none]=\"!isShowEditControls()\"\n class=\"text-body-s self-start whitespace-nowrap\"\n >\n \u0412\u044B\u0441\u043E\u0442\u0430: <span class=\"text-body-s-bold\">{{ orderItem.height }} \u043C.</span>\n </button>\n } @else if (orderItem.length) {\n <button\n [appearance]=\"isShowEditControls() ? 'action-grayscale' : ''\"\n tuiTheme=\"light\"\n tuiHint=\"\u0414\u043B\u044F \u0438\u0437\u043C\u0435\u043D\u0435\u043D\u0438\u044F \u0434\u043B\u0438\u043D\u044B \u0432\u043E\u0441\u043F\u043E\u043B\u044C\u0437\u0443\u0439\u0442\u0435\u0441\u044C \u043A\u043E\u043D\u0444\u0438\u0433\u0443\u0440\u0430\u0442\u043E\u0440\u043E\u043C\"\n (tuiHintVisible)=\"configuratorHintVisible($event)\"\n tuiLink\n [style.text-decoration-line]=\"isShowEditControls() ? 'underline' : 'none'\"\n [class.pointer-events-none]=\"!isShowEditControls()\"\n class=\"text-body-s self-start whitespace-nowrap\"\n >\n \u0414\u043B\u0438\u043D\u0430: <span class=\"text-body-s-bold\">{{ orderItem.length }} \u043C.</span>\n </button>\n }\n </div>\n </div>\n }\n </div>\n\n <!-- \u0421\u0443\u043C\u043C\u0430 \u0442\u043E\u0432\u0430\u0440\u0430 \u0438 \u0441\u043A\u043B\u0430\u0434\u0441\u043A\u043E\u0435 \u043D\u0430\u043B\u0438\u0447\u0438\u0435. -->\n <div\n scPrint=\"cost\"\n class=\"flex min-w-[11rem] flex-col @lg:justify-end @2xl:!justify-center text-body-m\"\n >\n <p class=\"whitespace-nowrap\">\n \u0421\u0443\u043C\u043C\u0430:\n <strong> {{ orderItem.costRub | tuiFormatNumber: { precision: 2, decimalSeparator: '.', rounding: 'ceil' } | async }} {{ 'RUB' | tuiCurrency }}</strong>\n </p>\n @if (!(markUnavailable() && product.isNull)) {\n <sc-price-warehouse-stock\n scPrint=\"defaultNoPrint\"\n [product]=\"product\"\n />\n }\n </div>\n </div>\n </div>\n </sc-noindex-wrapper>\n </div>\n} @else {\n <div class=\"tui-skeleton flex h-[8.25rem] w-full overflow-hidden rounded-xl\"></div>\n}\n" }]
|
|
8363
8454
|
}] });
|
|
8364
8455
|
|
|
8365
8456
|
/* eslint-disable no-param-reassign */
|
|
@@ -8368,6 +8459,10 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImpo
|
|
|
8368
8459
|
* Позиции разбиты.
|
|
8369
8460
|
*/
|
|
8370
8461
|
class ScOrderItemsListComponent {
|
|
8462
|
+
/**
|
|
8463
|
+
* Инициализирует экземпляр класса {@link ScOrderItemsListComponent}.
|
|
8464
|
+
* Входы выбора и пометки недоступных позиций могут прийти после списка позиций, поэтому при их изменении выбор синхронизируется заново.
|
|
8465
|
+
*/
|
|
8371
8466
|
constructor() {
|
|
8372
8467
|
/**
|
|
8373
8468
|
* Внутренний сигнал списка элементов корзины (товаров).
|
|
@@ -8381,6 +8476,38 @@ class ScOrderItemsListComponent {
|
|
|
8381
8476
|
* Включить редактирование позиций.
|
|
8382
8477
|
*/
|
|
8383
8478
|
this.editable = input(false);
|
|
8479
|
+
/**
|
|
8480
|
+
* Функция, возвращающая название группы позиции. Если не задана, позиции выводятся одним списком без заголовков.
|
|
8481
|
+
*/
|
|
8482
|
+
this.groupBy = input(null);
|
|
8483
|
+
/**
|
|
8484
|
+
* Признак, что позиции, которые не попадут в заказ, помечаются причиной, не выбираются и остаются доступными для изменения.
|
|
8485
|
+
*/
|
|
8486
|
+
this.markUnavailable = input(false);
|
|
8487
|
+
/**
|
|
8488
|
+
* Признак, что цена за единицу берётся из позиции, а не из текущей цены товара.
|
|
8489
|
+
*/
|
|
8490
|
+
this.useLinePrice = input(false);
|
|
8491
|
+
/**
|
|
8492
|
+
* Позиции, разбитые на группы в порядке первого появления группы.
|
|
8493
|
+
*/
|
|
8494
|
+
this.groups = computed(() => {
|
|
8495
|
+
const items = this.itemsSignal();
|
|
8496
|
+
const groupBy = this.groupBy();
|
|
8497
|
+
if (!groupBy) {
|
|
8498
|
+
return [{ name: '', items, orderableCount: items.filter((item) => item.isOrderable).length, sum: items.reduce((sum, item) => sum + item.costRub, 0) }];
|
|
8499
|
+
}
|
|
8500
|
+
const groups = new Map();
|
|
8501
|
+
items.forEach((item) => {
|
|
8502
|
+
const name = groupBy(item);
|
|
8503
|
+
const group = groups.get(name) ?? { name, items: [], orderableCount: 0, sum: 0 };
|
|
8504
|
+
group.items.push(item);
|
|
8505
|
+
group.orderableCount += item.isOrderable ? 1 : 0;
|
|
8506
|
+
group.sum += item.costRub;
|
|
8507
|
+
groups.set(name, group);
|
|
8508
|
+
});
|
|
8509
|
+
return [...groups.values()];
|
|
8510
|
+
});
|
|
8384
8511
|
/**
|
|
8385
8512
|
* Внутренняя группа формы для выбора позиций.
|
|
8386
8513
|
*/
|
|
@@ -8435,6 +8562,13 @@ class ScOrderItemsListComponent {
|
|
|
8435
8562
|
* Предоставляется родителем через токен {@link SC_DIALOG_SERVICE_TOKEN}.
|
|
8436
8563
|
*/
|
|
8437
8564
|
this.scDialogService = inject(SC_DIALOG_SERVICE_TOKEN);
|
|
8565
|
+
effect(() => {
|
|
8566
|
+
this.markUnavailable();
|
|
8567
|
+
this.selectable();
|
|
8568
|
+
untracked(() => {
|
|
8569
|
+
this.syncSelectionControls();
|
|
8570
|
+
});
|
|
8571
|
+
});
|
|
8438
8572
|
}
|
|
8439
8573
|
/**
|
|
8440
8574
|
* Список элементов корзины (товаров). При установке синхронно обновляет контролы выбора в форме.
|
|
@@ -8458,8 +8592,18 @@ class ScOrderItemsListComponent {
|
|
|
8458
8592
|
}
|
|
8459
8593
|
});
|
|
8460
8594
|
currentItems.forEach((item) => {
|
|
8461
|
-
|
|
8462
|
-
|
|
8595
|
+
const control = this.selectionFormGroup.get(item.id);
|
|
8596
|
+
const isSelectable = !this.markUnavailable() || item.isOrderable;
|
|
8597
|
+
if (!control) {
|
|
8598
|
+
this.selectionFormGroup.addControl(item.id, new FormControl({ value: isSelectable, disabled: !isSelectable }, { nonNullable: true }));
|
|
8599
|
+
}
|
|
8600
|
+
else if (!isSelectable && control.enabled) {
|
|
8601
|
+
control.setValue(false);
|
|
8602
|
+
control.disable();
|
|
8603
|
+
}
|
|
8604
|
+
else if (isSelectable && control.disabled) {
|
|
8605
|
+
control.enable();
|
|
8606
|
+
control.setValue(true);
|
|
8463
8607
|
}
|
|
8464
8608
|
});
|
|
8465
8609
|
}
|
|
@@ -8545,12 +8689,12 @@ class ScOrderItemsListComponent {
|
|
|
8545
8689
|
this.scDialogService.openPriceHistoryChartDialog(product);
|
|
8546
8690
|
}
|
|
8547
8691
|
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: ScOrderItemsListComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
8548
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.2.14", type: ScOrderItemsListComponent, isStandalone: true, selector: "sc-order-items-list", inputs: { selectable: { classPropertyName: "selectable", publicName: "selectable", isSignal: true, isRequired: false, transformFunction: null }, editable: { classPropertyName: "editable", publicName: "editable", isSignal: true, isRequired: false, transformFunction: null }, items: { classPropertyName: "items", publicName: "items", isSignal: false, isRequired: true, transformFunction: null } }, outputs: { selectedItemsIdsChange: "selectedItemsIdsChange" }, ngImport: i0, template: "<div\n [formGroup]=\"selectionFormGroup\"\n class=\"flex flex-col gap-5\"\n>\n <!-- \u0413\u0440\u0443\u043F\u043F\u044B \u0442\u043E\u0432\u0430\u0440\u043E\u0432 \u043F\u043E \u043D\u0430\u043F\u0440\u0430\u0432\u043B\u0435\u043D\u0438\u044F\u043C \u043F\u0440\u043E\u0434\u0430\u0436. -->\n\n @for (
|
|
8692
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.2.14", type: ScOrderItemsListComponent, isStandalone: true, selector: "sc-order-items-list", inputs: { selectable: { classPropertyName: "selectable", publicName: "selectable", isSignal: true, isRequired: false, transformFunction: null }, editable: { classPropertyName: "editable", publicName: "editable", isSignal: true, isRequired: false, transformFunction: null }, groupBy: { classPropertyName: "groupBy", publicName: "groupBy", isSignal: true, isRequired: false, transformFunction: null }, markUnavailable: { classPropertyName: "markUnavailable", publicName: "markUnavailable", isSignal: true, isRequired: false, transformFunction: null }, useLinePrice: { classPropertyName: "useLinePrice", publicName: "useLinePrice", isSignal: true, isRequired: false, transformFunction: null }, items: { classPropertyName: "items", publicName: "items", isSignal: false, isRequired: true, transformFunction: null } }, outputs: { selectedItemsIdsChange: "selectedItemsIdsChange" }, ngImport: i0, template: "<div\n [formGroup]=\"selectionFormGroup\"\n class=\"flex flex-col gap-5\"\n>\n <!-- \u0413\u0440\u0443\u043F\u043F\u044B \u0442\u043E\u0432\u0430\u0440\u043E\u0432 \u043F\u043E \u043D\u0430\u043F\u0440\u0430\u0432\u043B\u0435\u043D\u0438\u044F\u043C \u043F\u0440\u043E\u0434\u0430\u0436. -->\n\n @for (group of groups(); track group.name) {\n <!-- \u0417\u0430\u0433\u043E\u043B\u043E\u0432\u043E\u043A \u0433\u0440\u0443\u043F\u043F\u044B \u043F\u043E\u0437\u0438\u0446\u0438\u0439. -->\n @if (group.name) {\n <div class=\"flex flex-wrap items-end justify-between gap-x-4 gap-y-1 border-b border-tui-base-03 pb-2\">\n <div class=\"flex flex-col\">\n <span class=\"text-body-l-bold\">{{ group.name }}</span>\n <span class=\"text-body-s text-tui-text-02\">\u043F\u043E\u0437\u0438\u0446\u0438\u0439: {{ group.items.length }}, \u0432 \u0437\u0430\u043A\u0430\u0437: {{ group.orderableCount }}</span>\n </div>\n <span class=\"text-body-m-bold\">\n {{ group.sum | tuiFormatNumber: { precision: 2, decimalSeparator: '.', rounding: 'ceil' } | async }} {{ 'RUB' | tuiCurrency }}\n </span>\n </div>\n }\n\n @for (item of group.items; track item.id) {\n @if ($index !== 0) {\n <hr class=\"mt-auto h-px w-full bg-tui-clear\" />\n }\n\n <div class=\"flex items-center gap-4 relative\">\n @let isActive = !selectable() || selectionFormGroup.get(item.id)?.value || (markUnavailable() && !item.isOrderable);\n\n <!-- \u0427\u0435\u043A\u0431\u043E\u043A\u0441 \u0432\u044B\u0431\u043E\u0440\u0430 \u0442\u043E\u0432\u0430\u0440\u0430. -->\n @if (selectable()) {\n <input\n tuiCheckbox\n [disabled]=\"itemComponent.showLoader()\"\n type=\"checkbox\"\n size=\"m\"\n [formControlName]=\"item.id\"\n />\n }\n\n <!-- \u041A\u0430\u0440\u0442\u043E\u0447\u043A\u0430 \u0442\u043E\u0432\u0430\u0440\u0430. -->\n <sc-order-item\n #itemComponent\n [product]=\"item.product\"\n [orderItem]=\"item\"\n [showQuantityControl]=\"canEdit() && !item.configurator\"\n [isShowEditControls]=\"canEdit()\"\n [useLinePrice]=\"useLinePrice()\"\n [markUnavailable]=\"markUnavailable()\"\n class=\"w-full duration-200\"\n [class.opacity-60]=\"(selectable() && !selectionFormGroup.get(item.id)?.value) || (markUnavailable() && !item.isOrderable)\"\n (clickCardEvent)=\"openProductInfoDialog(item.product, item, orderOptions?.orderId())\"\n (quantityValueChanges)=\"patchItem($event, itemComponent)\"\n (clickPriceHistoryEvent)=\"openPriceHistoryChartDialog(item.product)\"\n (clickSettings)=\"openSettingsDialog(item)\"\n [class.pointer-events-none]=\"!isActive\"\n />\n\n <!-- \u041A\u043D\u043E\u043F\u043A\u0430 \u0443\u0434\u0430\u043B\u0435\u043D\u0438\u044F \u0442\u043E\u0432\u0430\u0440\u0430. -->\n @if (canEdit()) {\n <button\n tuiIconButton\n iconStart=\"@tui.trash\"\n (click)=\"deleteItem(item, itemComponent)\"\n [loading]=\"itemComponent.showLoader()\"\n size=\"s\"\n appearance=\"secondary\"\n class=\"!absolute left-1 top-1 lg:!relative lg:left-0 lg:top-0 lg:!self-center\"\n ></button>\n }\n </div>\n }\n }\n\n <!-- \u0424\u0443\u0442\u0435\u0440 \u0433\u0440\u0443\u043F\u043F\u044B \u0442\u043E\u0432\u0430\u0440\u043E\u0432. -->\n <div\n scPrint=\"cost\"\n class=\"flex flex-col items-end gap-2.5\"\n >\n @let totalSum = sumSelectedItems();\n <!-- \u0418\u0442\u043E\u0433\u043E\u0432\u0430\u044F \u0441\u0443\u043C\u043C\u0430. -->\n <div class=\"text-base font-bold\">\u0418\u0442\u043E\u0433\u043E: {{ totalSum | tuiFormatNumber: { precision: 2, decimalSeparator: '.', rounding: 'ceil' } | async }} {{ 'RUB' | tuiCurrency }}</div>\n </div>\n</div>\n", dependencies: [{ kind: "component", type: ScOrderItemComponent, selector: "sc-order-item", inputs: ["isShowEditControls", "useLinePrice", "markUnavailable"], outputs: ["clickSettings"] }, { kind: "directive", type: ScPrintDirective, selector: "[scPrint]", inputs: ["scPrint"] }, { kind: "ngmodule", type: ReactiveFormsModule }, { 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: "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: "component", type: TuiCheckbox, selector: "input[type=\"checkbox\"][tuiCheckbox]", inputs: ["size"] }, { kind: "directive", type: TuiButton, selector: "a[tuiButton],button[tuiButton],a[tuiIconButton],button[tuiIconButton]", inputs: ["size"] }, { kind: "component", type: TuiButtonLoading, selector: "[tuiButton][loading],[tuiIconButton][loading]", inputs: ["size", "loading"] }, { kind: "pipe", type: TuiCurrencyPipe, name: "tuiCurrency" }, { kind: "pipe", type: AsyncPipe, name: "async" }, { kind: "pipe", type: TuiFormatNumberPipe, name: "tuiFormatNumber" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
|
|
8549
8693
|
}
|
|
8550
8694
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: ScOrderItemsListComponent, decorators: [{
|
|
8551
8695
|
type: Component,
|
|
8552
|
-
args: [{ standalone: true, selector: 'sc-order-items-list', imports: [ScOrderItemComponent, ScPrintDirective, ReactiveFormsModule, TuiCheckbox, TuiButton, TuiButtonLoading, TuiCurrencyPipe, AsyncPipe, TuiFormatNumberPipe], changeDetection: ChangeDetectionStrategy.OnPush, template: "<div\n [formGroup]=\"selectionFormGroup\"\n class=\"flex flex-col gap-5\"\n>\n <!-- \u0413\u0440\u0443\u043F\u043F\u044B \u0442\u043E\u0432\u0430\u0440\u043E\u0432 \u043F\u043E \u043D\u0430\u043F\u0440\u0430\u0432\u043B\u0435\u043D\u0438\u044F\u043C \u043F\u0440\u043E\u0434\u0430\u0436. -->\n\n @for (
|
|
8553
|
-
}], propDecorators: { items: [{
|
|
8696
|
+
args: [{ standalone: true, selector: 'sc-order-items-list', imports: [ScOrderItemComponent, ScPrintDirective, ReactiveFormsModule, TuiCheckbox, TuiButton, TuiButtonLoading, TuiCurrencyPipe, AsyncPipe, TuiFormatNumberPipe], changeDetection: ChangeDetectionStrategy.OnPush, template: "<div\n [formGroup]=\"selectionFormGroup\"\n class=\"flex flex-col gap-5\"\n>\n <!-- \u0413\u0440\u0443\u043F\u043F\u044B \u0442\u043E\u0432\u0430\u0440\u043E\u0432 \u043F\u043E \u043D\u0430\u043F\u0440\u0430\u0432\u043B\u0435\u043D\u0438\u044F\u043C \u043F\u0440\u043E\u0434\u0430\u0436. -->\n\n @for (group of groups(); track group.name) {\n <!-- \u0417\u0430\u0433\u043E\u043B\u043E\u0432\u043E\u043A \u0433\u0440\u0443\u043F\u043F\u044B \u043F\u043E\u0437\u0438\u0446\u0438\u0439. -->\n @if (group.name) {\n <div class=\"flex flex-wrap items-end justify-between gap-x-4 gap-y-1 border-b border-tui-base-03 pb-2\">\n <div class=\"flex flex-col\">\n <span class=\"text-body-l-bold\">{{ group.name }}</span>\n <span class=\"text-body-s text-tui-text-02\">\u043F\u043E\u0437\u0438\u0446\u0438\u0439: {{ group.items.length }}, \u0432 \u0437\u0430\u043A\u0430\u0437: {{ group.orderableCount }}</span>\n </div>\n <span class=\"text-body-m-bold\">\n {{ group.sum | tuiFormatNumber: { precision: 2, decimalSeparator: '.', rounding: 'ceil' } | async }} {{ 'RUB' | tuiCurrency }}\n </span>\n </div>\n }\n\n @for (item of group.items; track item.id) {\n @if ($index !== 0) {\n <hr class=\"mt-auto h-px w-full bg-tui-clear\" />\n }\n\n <div class=\"flex items-center gap-4 relative\">\n @let isActive = !selectable() || selectionFormGroup.get(item.id)?.value || (markUnavailable() && !item.isOrderable);\n\n <!-- \u0427\u0435\u043A\u0431\u043E\u043A\u0441 \u0432\u044B\u0431\u043E\u0440\u0430 \u0442\u043E\u0432\u0430\u0440\u0430. -->\n @if (selectable()) {\n <input\n tuiCheckbox\n [disabled]=\"itemComponent.showLoader()\"\n type=\"checkbox\"\n size=\"m\"\n [formControlName]=\"item.id\"\n />\n }\n\n <!-- \u041A\u0430\u0440\u0442\u043E\u0447\u043A\u0430 \u0442\u043E\u0432\u0430\u0440\u0430. -->\n <sc-order-item\n #itemComponent\n [product]=\"item.product\"\n [orderItem]=\"item\"\n [showQuantityControl]=\"canEdit() && !item.configurator\"\n [isShowEditControls]=\"canEdit()\"\n [useLinePrice]=\"useLinePrice()\"\n [markUnavailable]=\"markUnavailable()\"\n class=\"w-full duration-200\"\n [class.opacity-60]=\"(selectable() && !selectionFormGroup.get(item.id)?.value) || (markUnavailable() && !item.isOrderable)\"\n (clickCardEvent)=\"openProductInfoDialog(item.product, item, orderOptions?.orderId())\"\n (quantityValueChanges)=\"patchItem($event, itemComponent)\"\n (clickPriceHistoryEvent)=\"openPriceHistoryChartDialog(item.product)\"\n (clickSettings)=\"openSettingsDialog(item)\"\n [class.pointer-events-none]=\"!isActive\"\n />\n\n <!-- \u041A\u043D\u043E\u043F\u043A\u0430 \u0443\u0434\u0430\u043B\u0435\u043D\u0438\u044F \u0442\u043E\u0432\u0430\u0440\u0430. -->\n @if (canEdit()) {\n <button\n tuiIconButton\n iconStart=\"@tui.trash\"\n (click)=\"deleteItem(item, itemComponent)\"\n [loading]=\"itemComponent.showLoader()\"\n size=\"s\"\n appearance=\"secondary\"\n class=\"!absolute left-1 top-1 lg:!relative lg:left-0 lg:top-0 lg:!self-center\"\n ></button>\n }\n </div>\n }\n }\n\n <!-- \u0424\u0443\u0442\u0435\u0440 \u0433\u0440\u0443\u043F\u043F\u044B \u0442\u043E\u0432\u0430\u0440\u043E\u0432. -->\n <div\n scPrint=\"cost\"\n class=\"flex flex-col items-end gap-2.5\"\n >\n @let totalSum = sumSelectedItems();\n <!-- \u0418\u0442\u043E\u0433\u043E\u0432\u0430\u044F \u0441\u0443\u043C\u043C\u0430. -->\n <div class=\"text-base font-bold\">\u0418\u0442\u043E\u0433\u043E: {{ totalSum | tuiFormatNumber: { precision: 2, decimalSeparator: '.', rounding: 'ceil' } | async }} {{ 'RUB' | tuiCurrency }}</div>\n </div>\n</div>\n" }]
|
|
8697
|
+
}], ctorParameters: () => [], propDecorators: { items: [{
|
|
8554
8698
|
type: Input,
|
|
8555
8699
|
args: [{ required: true }]
|
|
8556
8700
|
}] } });
|
|
@@ -8569,6 +8713,10 @@ class ScOrderItemsListByDirectionsComponent {
|
|
|
8569
8713
|
* Включить редактирование позиций.
|
|
8570
8714
|
*/
|
|
8571
8715
|
this.editable = input(false);
|
|
8716
|
+
/**
|
|
8717
|
+
* Признак, что цена за единицу берётся из позиции, а не из текущей цены товара.
|
|
8718
|
+
*/
|
|
8719
|
+
this.useLinePrice = input(false);
|
|
8572
8720
|
/**
|
|
8573
8721
|
* Включить отображение кнопки продолжения.
|
|
8574
8722
|
*/
|
|
@@ -8616,11 +8764,11 @@ class ScOrderItemsListByDirectionsComponent {
|
|
|
8616
8764
|
]);
|
|
8617
8765
|
}
|
|
8618
8766
|
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: ScOrderItemsListByDirectionsComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
8619
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.2.14", type: ScOrderItemsListByDirectionsComponent, isStandalone: true, selector: "sc-order-items-list-by-directions", inputs: { items: { classPropertyName: "items", publicName: "items", isSignal: true, isRequired: true, transformFunction: null }, selectable: { classPropertyName: "selectable", publicName: "selectable", isSignal: true, isRequired: false, transformFunction: null }, editable: { classPropertyName: "editable", publicName: "editable", isSignal: true, isRequired: false, transformFunction: null }, showContinueButton: { classPropertyName: "showContinueButton", publicName: "showContinueButton", isSignal: true, isRequired: false, transformFunction: null }, continueButtonText: { classPropertyName: "continueButtonText", publicName: "continueButtonText", isSignal: true, isRequired: false, transformFunction: null }, selectedItemsIds: { classPropertyName: "selectedItemsIds", publicName: "selectedItemsIds", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { continueClick: "continueClick", selectedItemsIds: "selectedItemsIdsChange" }, ngImport: i0, template: "<div class=\"flex flex-col gap-5\">\n <!-- \u0413\u0440\u0443\u043F\u043F\u044B \u0442\u043E\u0432\u0430\u0440\u043E\u0432 \u043F\u043E \u043D\u0430\u043F\u0440\u0430\u0432\u043B\u0435\u043D\u0438\u044F\u043C \u043F\u0440\u043E\u0434\u0430\u0436. -->\n @for (direction of itemsByDirections(); track direction.direction?.id; let groupIndex = $index) {\n <div class=\"flex flex-col gap-2.5\">\n @if (direction.direction && itemsByDirections().length > 1) {\n <div class=\"text-base font-bold\">\u041D\u0430\u043F\u0440\u0430\u0432\u043B\u0435\u043D\u0438\u0435 \u043F\u0440\u043E\u0434\u0430\u0436: {{ direction.direction.description }}</div>\n }\n\n <sc-order-items-list\n [items]=\"direction.items\"\n [selectable]=\"selectable()\"\n [editable]=\"editable()\"\n (selectedItemsIdsChange)=\"selectedItemsHandler($event, direction)\"\n />\n\n <!-- \u0424\u0443\u0442\u0435\u0440 \u0433\u0440\u0443\u043F\u043F\u044B \u0442\u043E\u0432\u0430\u0440\u043E\u0432. -->\n <div class=\"flex flex-col items-center sm:flex-row sm:items-start sm:flex-wrap-reverse grow gap-x-2.5 gap-y-4\">\n <ng-content select=\"[footerActions]\" />\n\n <!-- \u041A\u043D\u043E\u043F\u043A\u0430 \u043F\u0440\u043E\u0434\u043E\u043B\u0436\u0435\u043D\u0438\u044F. -->\n @if (showContinueButton()) {\n <button\n tuiButton\n type=\"button\"\n [disabled]=\"direction.getItemsByIds(selectedItemsIds()).length === 0\"\n [iconStart]=\"continueButtonText().iconStart\"\n class=\"sm:ml-auto\"\n (click)=\"continueClick.emit(direction)\"\n >\n {{ continueButtonText().title }}\n </button>\n }\n </div>\n </div>\n }\n\n @if (nullItems().length) {\n <div class=\"flex flex-col gap-2.5\">\n <div class=\"text-base font-bold\">\u0422\u043E\u0432\u0430\u0440\u044B \u0438 \u0443\u0441\u043B\u0443\u0433\u0438, \u043A\u043E\u0442\u043E\u0440\u044B\u0435 \u0431\u043E\u043B\u044C\u0448\u0435 \u043D\u0435 \u043F\u0440\u0435\u0434\u043E\u0441\u0442\u0430\u0432\u043B\u044F\u044E\u0442\u0441\u044F.</div>\n\n <sc-order-items-list\n [items]=\"nullItems()\"\n [selectable]=\"false\"\n [editable]=\"editable()\"\n />\n </div>\n }\n</div>\n", dependencies: [{ kind: "component", type: ScOrderItemsListComponent, selector: "sc-order-items-list", inputs: ["selectable", "editable", "items"], outputs: ["selectedItemsIdsChange"] }, { kind: "directive", type: TuiButton, selector: "a[tuiButton],button[tuiButton],a[tuiIconButton],button[tuiIconButton]", inputs: ["size"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
|
|
8767
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.2.14", type: ScOrderItemsListByDirectionsComponent, isStandalone: true, selector: "sc-order-items-list-by-directions", inputs: { items: { classPropertyName: "items", publicName: "items", isSignal: true, isRequired: true, transformFunction: null }, selectable: { classPropertyName: "selectable", publicName: "selectable", isSignal: true, isRequired: false, transformFunction: null }, editable: { classPropertyName: "editable", publicName: "editable", isSignal: true, isRequired: false, transformFunction: null }, useLinePrice: { classPropertyName: "useLinePrice", publicName: "useLinePrice", isSignal: true, isRequired: false, transformFunction: null }, showContinueButton: { classPropertyName: "showContinueButton", publicName: "showContinueButton", isSignal: true, isRequired: false, transformFunction: null }, continueButtonText: { classPropertyName: "continueButtonText", publicName: "continueButtonText", isSignal: true, isRequired: false, transformFunction: null }, selectedItemsIds: { classPropertyName: "selectedItemsIds", publicName: "selectedItemsIds", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { continueClick: "continueClick", selectedItemsIds: "selectedItemsIdsChange" }, ngImport: i0, template: "<div class=\"flex flex-col gap-5\">\n <!-- \u0413\u0440\u0443\u043F\u043F\u044B \u0442\u043E\u0432\u0430\u0440\u043E\u0432 \u043F\u043E \u043D\u0430\u043F\u0440\u0430\u0432\u043B\u0435\u043D\u0438\u044F\u043C \u043F\u0440\u043E\u0434\u0430\u0436. -->\n @for (direction of itemsByDirections(); track direction.direction?.id; let groupIndex = $index) {\n <div class=\"flex flex-col gap-2.5\">\n @if (direction.direction && itemsByDirections().length > 1) {\n <div class=\"text-base font-bold\">\u041D\u0430\u043F\u0440\u0430\u0432\u043B\u0435\u043D\u0438\u0435 \u043F\u0440\u043E\u0434\u0430\u0436: {{ direction.direction.description }}</div>\n }\n\n <sc-order-items-list\n [items]=\"direction.items\"\n [selectable]=\"selectable()\"\n [editable]=\"editable()\"\n [useLinePrice]=\"useLinePrice()\"\n (selectedItemsIdsChange)=\"selectedItemsHandler($event, direction)\"\n />\n\n <!-- \u0424\u0443\u0442\u0435\u0440 \u0433\u0440\u0443\u043F\u043F\u044B \u0442\u043E\u0432\u0430\u0440\u043E\u0432. -->\n <div class=\"flex flex-col items-center sm:flex-row sm:items-start sm:flex-wrap-reverse grow gap-x-2.5 gap-y-4\">\n <ng-content select=\"[footerActions]\" />\n\n <!-- \u041A\u043D\u043E\u043F\u043A\u0430 \u043F\u0440\u043E\u0434\u043E\u043B\u0436\u0435\u043D\u0438\u044F. -->\n @if (showContinueButton()) {\n <button\n tuiButton\n type=\"button\"\n [disabled]=\"direction.getItemsByIds(selectedItemsIds()).length === 0\"\n [iconStart]=\"continueButtonText().iconStart\"\n class=\"sm:ml-auto\"\n (click)=\"continueClick.emit(direction)\"\n >\n {{ continueButtonText().title }}\n </button>\n }\n </div>\n </div>\n }\n\n @if (nullItems().length) {\n <div class=\"flex flex-col gap-2.5\">\n <div class=\"text-base font-bold\">\u0422\u043E\u0432\u0430\u0440\u044B \u0438 \u0443\u0441\u043B\u0443\u0433\u0438, \u043A\u043E\u0442\u043E\u0440\u044B\u0435 \u0431\u043E\u043B\u044C\u0448\u0435 \u043D\u0435 \u043F\u0440\u0435\u0434\u043E\u0441\u0442\u0430\u0432\u043B\u044F\u044E\u0442\u0441\u044F.</div>\n\n <sc-order-items-list\n [items]=\"nullItems()\"\n [selectable]=\"false\"\n [editable]=\"editable()\"\n />\n </div>\n }\n</div>\n", dependencies: [{ kind: "component", type: ScOrderItemsListComponent, selector: "sc-order-items-list", inputs: ["selectable", "editable", "groupBy", "markUnavailable", "useLinePrice", "items"], outputs: ["selectedItemsIdsChange"] }, { kind: "directive", type: TuiButton, selector: "a[tuiButton],button[tuiButton],a[tuiIconButton],button[tuiIconButton]", inputs: ["size"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
|
|
8620
8768
|
}
|
|
8621
8769
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: ScOrderItemsListByDirectionsComponent, decorators: [{
|
|
8622
8770
|
type: Component,
|
|
8623
|
-
args: [{ standalone: true, selector: 'sc-order-items-list-by-directions', imports: [ScOrderItemsListComponent, TuiButton], changeDetection: ChangeDetectionStrategy.OnPush, template: "<div class=\"flex flex-col gap-5\">\n <!-- \u0413\u0440\u0443\u043F\u043F\u044B \u0442\u043E\u0432\u0430\u0440\u043E\u0432 \u043F\u043E \u043D\u0430\u043F\u0440\u0430\u0432\u043B\u0435\u043D\u0438\u044F\u043C \u043F\u0440\u043E\u0434\u0430\u0436. -->\n @for (direction of itemsByDirections(); track direction.direction?.id; let groupIndex = $index) {\n <div class=\"flex flex-col gap-2.5\">\n @if (direction.direction && itemsByDirections().length > 1) {\n <div class=\"text-base font-bold\">\u041D\u0430\u043F\u0440\u0430\u0432\u043B\u0435\u043D\u0438\u0435 \u043F\u0440\u043E\u0434\u0430\u0436: {{ direction.direction.description }}</div>\n }\n\n <sc-order-items-list\n [items]=\"direction.items\"\n [selectable]=\"selectable()\"\n [editable]=\"editable()\"\n (selectedItemsIdsChange)=\"selectedItemsHandler($event, direction)\"\n />\n\n <!-- \u0424\u0443\u0442\u0435\u0440 \u0433\u0440\u0443\u043F\u043F\u044B \u0442\u043E\u0432\u0430\u0440\u043E\u0432. -->\n <div class=\"flex flex-col items-center sm:flex-row sm:items-start sm:flex-wrap-reverse grow gap-x-2.5 gap-y-4\">\n <ng-content select=\"[footerActions]\" />\n\n <!-- \u041A\u043D\u043E\u043F\u043A\u0430 \u043F\u0440\u043E\u0434\u043E\u043B\u0436\u0435\u043D\u0438\u044F. -->\n @if (showContinueButton()) {\n <button\n tuiButton\n type=\"button\"\n [disabled]=\"direction.getItemsByIds(selectedItemsIds()).length === 0\"\n [iconStart]=\"continueButtonText().iconStart\"\n class=\"sm:ml-auto\"\n (click)=\"continueClick.emit(direction)\"\n >\n {{ continueButtonText().title }}\n </button>\n }\n </div>\n </div>\n }\n\n @if (nullItems().length) {\n <div class=\"flex flex-col gap-2.5\">\n <div class=\"text-base font-bold\">\u0422\u043E\u0432\u0430\u0440\u044B \u0438 \u0443\u0441\u043B\u0443\u0433\u0438, \u043A\u043E\u0442\u043E\u0440\u044B\u0435 \u0431\u043E\u043B\u044C\u0448\u0435 \u043D\u0435 \u043F\u0440\u0435\u0434\u043E\u0441\u0442\u0430\u0432\u043B\u044F\u044E\u0442\u0441\u044F.</div>\n\n <sc-order-items-list\n [items]=\"nullItems()\"\n [selectable]=\"false\"\n [editable]=\"editable()\"\n />\n </div>\n }\n</div>\n" }]
|
|
8771
|
+
args: [{ standalone: true, selector: 'sc-order-items-list-by-directions', imports: [ScOrderItemsListComponent, TuiButton], changeDetection: ChangeDetectionStrategy.OnPush, template: "<div class=\"flex flex-col gap-5\">\n <!-- \u0413\u0440\u0443\u043F\u043F\u044B \u0442\u043E\u0432\u0430\u0440\u043E\u0432 \u043F\u043E \u043D\u0430\u043F\u0440\u0430\u0432\u043B\u0435\u043D\u0438\u044F\u043C \u043F\u0440\u043E\u0434\u0430\u0436. -->\n @for (direction of itemsByDirections(); track direction.direction?.id; let groupIndex = $index) {\n <div class=\"flex flex-col gap-2.5\">\n @if (direction.direction && itemsByDirections().length > 1) {\n <div class=\"text-base font-bold\">\u041D\u0430\u043F\u0440\u0430\u0432\u043B\u0435\u043D\u0438\u0435 \u043F\u0440\u043E\u0434\u0430\u0436: {{ direction.direction.description }}</div>\n }\n\n <sc-order-items-list\n [items]=\"direction.items\"\n [selectable]=\"selectable()\"\n [editable]=\"editable()\"\n [useLinePrice]=\"useLinePrice()\"\n (selectedItemsIdsChange)=\"selectedItemsHandler($event, direction)\"\n />\n\n <!-- \u0424\u0443\u0442\u0435\u0440 \u0433\u0440\u0443\u043F\u043F\u044B \u0442\u043E\u0432\u0430\u0440\u043E\u0432. -->\n <div class=\"flex flex-col items-center sm:flex-row sm:items-start sm:flex-wrap-reverse grow gap-x-2.5 gap-y-4\">\n <ng-content select=\"[footerActions]\" />\n\n <!-- \u041A\u043D\u043E\u043F\u043A\u0430 \u043F\u0440\u043E\u0434\u043E\u043B\u0436\u0435\u043D\u0438\u044F. -->\n @if (showContinueButton()) {\n <button\n tuiButton\n type=\"button\"\n [disabled]=\"direction.getItemsByIds(selectedItemsIds()).length === 0\"\n [iconStart]=\"continueButtonText().iconStart\"\n class=\"sm:ml-auto\"\n (click)=\"continueClick.emit(direction)\"\n >\n {{ continueButtonText().title }}\n </button>\n }\n </div>\n </div>\n }\n\n @if (nullItems().length) {\n <div class=\"flex flex-col gap-2.5\">\n <div class=\"text-base font-bold\">\u0422\u043E\u0432\u0430\u0440\u044B \u0438 \u0443\u0441\u043B\u0443\u0433\u0438, \u043A\u043E\u0442\u043E\u0440\u044B\u0435 \u0431\u043E\u043B\u044C\u0448\u0435 \u043D\u0435 \u043F\u0440\u0435\u0434\u043E\u0441\u0442\u0430\u0432\u043B\u044F\u044E\u0442\u0441\u044F.</div>\n\n <sc-order-items-list\n [items]=\"nullItems()\"\n [selectable]=\"false\"\n [editable]=\"editable()\"\n />\n </div>\n }\n</div>\n" }]
|
|
8624
8772
|
}] });
|
|
8625
8773
|
|
|
8626
8774
|
/**
|
|
@@ -8640,6 +8788,10 @@ class ScOrderDirectionItemsComponent {
|
|
|
8640
8788
|
* Включить выбор позиций чекбоксами.
|
|
8641
8789
|
*/
|
|
8642
8790
|
this.selectable = input(true);
|
|
8791
|
+
/**
|
|
8792
|
+
* Признак, что цена за единицу берётся из позиции, а не из текущей цены товара.
|
|
8793
|
+
*/
|
|
8794
|
+
this.useLinePrice = input(false);
|
|
8643
8795
|
/**
|
|
8644
8796
|
* Время обработки и принятия заказов (из настроек окружения приложения).
|
|
8645
8797
|
*/
|
|
@@ -8650,11 +8802,11 @@ class ScOrderDirectionItemsComponent {
|
|
|
8650
8802
|
this.selectedItemsIdsChange = output();
|
|
8651
8803
|
}
|
|
8652
8804
|
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: ScOrderDirectionItemsComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
8653
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "18.2.14", type: ScOrderDirectionItemsComponent, isStandalone: true, selector: "sc-order-direction-items", inputs: { items: { classPropertyName: "items", publicName: "items", isSignal: true, isRequired: true, transformFunction: null }, editable: { classPropertyName: "editable", publicName: "editable", isSignal: true, isRequired: false, transformFunction: null }, selectable: { classPropertyName: "selectable", publicName: "selectable", isSignal: true, isRequired: false, transformFunction: null }, orderProcessingAcceptanceTime: { classPropertyName: "orderProcessingAcceptanceTime", publicName: "orderProcessingAcceptanceTime", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { selectedItemsIdsChange: "selectedItemsIdsChange" }, ngImport: i0, template: "<div class=\"flex flex-col gap-5\">\n <ul class=\"ml-4 list-disc text-tui-success-fill\">\n <li>\u0417\u0430\u044F\u0432\u043A\u0438 \u043F\u0440\u0438\u043D\u0438\u043C\u0430\u044E\u0442\u0441\u044F \u043D\u0435 \u043F\u043E\u0437\u0434\u043D\u0435\u0435 {{ orderProcessingAcceptanceTime() }} \u043F\u043B\u0430\u043D\u0438\u0440\u0443\u0435\u043C\u043E\u0433\u043E \u0434\u043D\u044F \u043F\u043E\u0441\u0442\u0430\u0432\u043A\u0438.</li>\n <li>\u0417\u0430\u043A\u0430\u0437\u044B \u0441 \u0434\u043E\u0441\u0442\u0430\u0432\u043A\u043E\u0439 \u043D\u0430 \u043F\u043E\u043D\u0435\u0434\u0435\u043B\u044C\u043D\u0438\u043A \u043F\u0440\u0438\u043D\u0438\u043C\u0430\u044E\u0442\u0441\u044F \u0434\u043E {{ orderProcessingAcceptanceTime() }} \u043F\u044F\u0442\u043D\u0438\u0446\u044B.</li>\n <li>\u0417\u0430\u043A\u0430\u0437\u044B, \u0441\u043E\u0437\u0434\u0430\u043D\u043D\u044B\u0435 \u043F\u043E\u0437\u0434\u043D\u0435\u0435 {{ orderProcessingAcceptanceTime() }} \u043F\u044F\u0442\u043D\u0438\u0446\u044B \u0438\u043B\u0438 \u0432 \u0441\u0443\u0431\u0431\u043E\u0442\u0443/\u0432\u043E\u0441\u043A\u0440\u0435\u0441\u0435\u043D\u044C\u0435 \u0431\u0443\u0434\u0443\u0442 \u043E\u0431\u0440\u0430\u0431\u043E\u0442\u0430\u043D\u044B \u0432 \u0431\u0443\u0434\u043D\u0438\u0435 \u0434\u043D\u0438.</li>\n <li>\n \u0423\u043F\u0440\u0430\u0432\u043B\u044F\u0442\u044C \u0441\u043F\u0438\u0441\u043A\u043E\u043C \u043A\u043E\u043D\u0442\u0440\u0430\u0433\u0435\u043D\u0442\u043E\u0432 \u0432\u044B \u043C\u043E\u0436\u0435\u0442\u0435 \u0432\n <a\n tuiLink\n routerLink=\"/profile\"\n >\n \u043B\u0438\u0447\u043D\u043E\u043C \u043A\u0430\u0431\u0438\u043D\u0435\u0442\u0435\n </a>\n .\n </li>\n </ul>\n\n <div class=\"sub-title\">\u0421\u043E\u0441\u0442\u0430\u0432 \u0437\u0430\u043A\u0430\u0437\u0430</div>\n\n <sc-order-items-list-by-directions\n [items]=\"items()\"\n [editable]=\"editable()\"\n [selectable]=\"selectable()\"\n [showContinueButton]=\"false\"\n (selectedItemsIdsChange)=\"selectedItemsIdsChange.emit($event)\"\n >\n <ng-content\n select=\"[footerActions]\"\n ngProjectAs=\"[footerActions]\"\n />\n </sc-order-items-list-by-directions>\n</div>\n", dependencies: [{ kind: "component", type: ScOrderItemsListByDirectionsComponent, selector: "sc-order-items-list-by-directions", inputs: ["items", "selectable", "editable", "showContinueButton", "continueButtonText", "selectedItemsIds"], outputs: ["continueClick", "selectedItemsIdsChange"] }, { kind: "directive", type: RouterLink, selector: "[routerLink]", inputs: ["target", "queryParams", "fragment", "queryParamsHandling", "state", "info", "relativeTo", "preserveFragment", "skipLocationChange", "replaceUrl", "routerLink"] }, { kind: "directive", type: TuiLink, selector: "a[tuiLink], button[tuiLink]", inputs: ["pseudo"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
|
|
8805
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "18.2.14", type: ScOrderDirectionItemsComponent, isStandalone: true, selector: "sc-order-direction-items", inputs: { items: { classPropertyName: "items", publicName: "items", isSignal: true, isRequired: true, transformFunction: null }, editable: { classPropertyName: "editable", publicName: "editable", isSignal: true, isRequired: false, transformFunction: null }, selectable: { classPropertyName: "selectable", publicName: "selectable", isSignal: true, isRequired: false, transformFunction: null }, useLinePrice: { classPropertyName: "useLinePrice", publicName: "useLinePrice", isSignal: true, isRequired: false, transformFunction: null }, orderProcessingAcceptanceTime: { classPropertyName: "orderProcessingAcceptanceTime", publicName: "orderProcessingAcceptanceTime", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { selectedItemsIdsChange: "selectedItemsIdsChange" }, ngImport: i0, template: "<div class=\"flex flex-col gap-5\">\n <ul class=\"ml-4 list-disc text-tui-success-fill\">\n <li>\u0417\u0430\u044F\u0432\u043A\u0438 \u043F\u0440\u0438\u043D\u0438\u043C\u0430\u044E\u0442\u0441\u044F \u043D\u0435 \u043F\u043E\u0437\u0434\u043D\u0435\u0435 {{ orderProcessingAcceptanceTime() }} \u043F\u043B\u0430\u043D\u0438\u0440\u0443\u0435\u043C\u043E\u0433\u043E \u0434\u043D\u044F \u043F\u043E\u0441\u0442\u0430\u0432\u043A\u0438.</li>\n <li>\u0417\u0430\u043A\u0430\u0437\u044B \u0441 \u0434\u043E\u0441\u0442\u0430\u0432\u043A\u043E\u0439 \u043D\u0430 \u043F\u043E\u043D\u0435\u0434\u0435\u043B\u044C\u043D\u0438\u043A \u043F\u0440\u0438\u043D\u0438\u043C\u0430\u044E\u0442\u0441\u044F \u0434\u043E {{ orderProcessingAcceptanceTime() }} \u043F\u044F\u0442\u043D\u0438\u0446\u044B.</li>\n <li>\u0417\u0430\u043A\u0430\u0437\u044B, \u0441\u043E\u0437\u0434\u0430\u043D\u043D\u044B\u0435 \u043F\u043E\u0437\u0434\u043D\u0435\u0435 {{ orderProcessingAcceptanceTime() }} \u043F\u044F\u0442\u043D\u0438\u0446\u044B \u0438\u043B\u0438 \u0432 \u0441\u0443\u0431\u0431\u043E\u0442\u0443/\u0432\u043E\u0441\u043A\u0440\u0435\u0441\u0435\u043D\u044C\u0435 \u0431\u0443\u0434\u0443\u0442 \u043E\u0431\u0440\u0430\u0431\u043E\u0442\u0430\u043D\u044B \u0432 \u0431\u0443\u0434\u043D\u0438\u0435 \u0434\u043D\u0438.</li>\n <li>\n \u0423\u043F\u0440\u0430\u0432\u043B\u044F\u0442\u044C \u0441\u043F\u0438\u0441\u043A\u043E\u043C \u043A\u043E\u043D\u0442\u0440\u0430\u0433\u0435\u043D\u0442\u043E\u0432 \u0432\u044B \u043C\u043E\u0436\u0435\u0442\u0435 \u0432\n <a\n tuiLink\n routerLink=\"/profile\"\n >\n \u043B\u0438\u0447\u043D\u043E\u043C \u043A\u0430\u0431\u0438\u043D\u0435\u0442\u0435\n </a>\n .\n </li>\n </ul>\n\n <div class=\"sub-title\">\u0421\u043E\u0441\u0442\u0430\u0432 \u0437\u0430\u043A\u0430\u0437\u0430</div>\n\n <sc-order-items-list-by-directions\n [items]=\"items()\"\n [editable]=\"editable()\"\n [selectable]=\"selectable()\"\n [useLinePrice]=\"useLinePrice()\"\n [showContinueButton]=\"false\"\n (selectedItemsIdsChange)=\"selectedItemsIdsChange.emit($event)\"\n >\n <ng-content\n select=\"[footerActions]\"\n ngProjectAs=\"[footerActions]\"\n />\n </sc-order-items-list-by-directions>\n</div>\n", dependencies: [{ kind: "component", type: ScOrderItemsListByDirectionsComponent, selector: "sc-order-items-list-by-directions", inputs: ["items", "selectable", "editable", "useLinePrice", "showContinueButton", "continueButtonText", "selectedItemsIds"], outputs: ["continueClick", "selectedItemsIdsChange"] }, { kind: "directive", type: RouterLink, selector: "[routerLink]", inputs: ["target", "queryParams", "fragment", "queryParamsHandling", "state", "info", "relativeTo", "preserveFragment", "skipLocationChange", "replaceUrl", "routerLink"] }, { kind: "directive", type: TuiLink, selector: "a[tuiLink], button[tuiLink]", inputs: ["pseudo"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
|
|
8654
8806
|
}
|
|
8655
8807
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: ScOrderDirectionItemsComponent, decorators: [{
|
|
8656
8808
|
type: Component,
|
|
8657
|
-
args: [{ standalone: true, selector: 'sc-order-direction-items', imports: [ScOrderItemsListByDirectionsComponent, RouterLink, TuiLink], changeDetection: ChangeDetectionStrategy.OnPush, template: "<div class=\"flex flex-col gap-5\">\n <ul class=\"ml-4 list-disc text-tui-success-fill\">\n <li>\u0417\u0430\u044F\u0432\u043A\u0438 \u043F\u0440\u0438\u043D\u0438\u043C\u0430\u044E\u0442\u0441\u044F \u043D\u0435 \u043F\u043E\u0437\u0434\u043D\u0435\u0435 {{ orderProcessingAcceptanceTime() }} \u043F\u043B\u0430\u043D\u0438\u0440\u0443\u0435\u043C\u043E\u0433\u043E \u0434\u043D\u044F \u043F\u043E\u0441\u0442\u0430\u0432\u043A\u0438.</li>\n <li>\u0417\u0430\u043A\u0430\u0437\u044B \u0441 \u0434\u043E\u0441\u0442\u0430\u0432\u043A\u043E\u0439 \u043D\u0430 \u043F\u043E\u043D\u0435\u0434\u0435\u043B\u044C\u043D\u0438\u043A \u043F\u0440\u0438\u043D\u0438\u043C\u0430\u044E\u0442\u0441\u044F \u0434\u043E {{ orderProcessingAcceptanceTime() }} \u043F\u044F\u0442\u043D\u0438\u0446\u044B.</li>\n <li>\u0417\u0430\u043A\u0430\u0437\u044B, \u0441\u043E\u0437\u0434\u0430\u043D\u043D\u044B\u0435 \u043F\u043E\u0437\u0434\u043D\u0435\u0435 {{ orderProcessingAcceptanceTime() }} \u043F\u044F\u0442\u043D\u0438\u0446\u044B \u0438\u043B\u0438 \u0432 \u0441\u0443\u0431\u0431\u043E\u0442\u0443/\u0432\u043E\u0441\u043A\u0440\u0435\u0441\u0435\u043D\u044C\u0435 \u0431\u0443\u0434\u0443\u0442 \u043E\u0431\u0440\u0430\u0431\u043E\u0442\u0430\u043D\u044B \u0432 \u0431\u0443\u0434\u043D\u0438\u0435 \u0434\u043D\u0438.</li>\n <li>\n \u0423\u043F\u0440\u0430\u0432\u043B\u044F\u0442\u044C \u0441\u043F\u0438\u0441\u043A\u043E\u043C \u043A\u043E\u043D\u0442\u0440\u0430\u0433\u0435\u043D\u0442\u043E\u0432 \u0432\u044B \u043C\u043E\u0436\u0435\u0442\u0435 \u0432\n <a\n tuiLink\n routerLink=\"/profile\"\n >\n \u043B\u0438\u0447\u043D\u043E\u043C \u043A\u0430\u0431\u0438\u043D\u0435\u0442\u0435\n </a>\n .\n </li>\n </ul>\n\n <div class=\"sub-title\">\u0421\u043E\u0441\u0442\u0430\u0432 \u0437\u0430\u043A\u0430\u0437\u0430</div>\n\n <sc-order-items-list-by-directions\n [items]=\"items()\"\n [editable]=\"editable()\"\n [selectable]=\"selectable()\"\n [showContinueButton]=\"false\"\n (selectedItemsIdsChange)=\"selectedItemsIdsChange.emit($event)\"\n >\n <ng-content\n select=\"[footerActions]\"\n ngProjectAs=\"[footerActions]\"\n />\n </sc-order-items-list-by-directions>\n</div>\n" }]
|
|
8809
|
+
args: [{ standalone: true, selector: 'sc-order-direction-items', imports: [ScOrderItemsListByDirectionsComponent, RouterLink, TuiLink], changeDetection: ChangeDetectionStrategy.OnPush, template: "<div class=\"flex flex-col gap-5\">\n <ul class=\"ml-4 list-disc text-tui-success-fill\">\n <li>\u0417\u0430\u044F\u0432\u043A\u0438 \u043F\u0440\u0438\u043D\u0438\u043C\u0430\u044E\u0442\u0441\u044F \u043D\u0435 \u043F\u043E\u0437\u0434\u043D\u0435\u0435 {{ orderProcessingAcceptanceTime() }} \u043F\u043B\u0430\u043D\u0438\u0440\u0443\u0435\u043C\u043E\u0433\u043E \u0434\u043D\u044F \u043F\u043E\u0441\u0442\u0430\u0432\u043A\u0438.</li>\n <li>\u0417\u0430\u043A\u0430\u0437\u044B \u0441 \u0434\u043E\u0441\u0442\u0430\u0432\u043A\u043E\u0439 \u043D\u0430 \u043F\u043E\u043D\u0435\u0434\u0435\u043B\u044C\u043D\u0438\u043A \u043F\u0440\u0438\u043D\u0438\u043C\u0430\u044E\u0442\u0441\u044F \u0434\u043E {{ orderProcessingAcceptanceTime() }} \u043F\u044F\u0442\u043D\u0438\u0446\u044B.</li>\n <li>\u0417\u0430\u043A\u0430\u0437\u044B, \u0441\u043E\u0437\u0434\u0430\u043D\u043D\u044B\u0435 \u043F\u043E\u0437\u0434\u043D\u0435\u0435 {{ orderProcessingAcceptanceTime() }} \u043F\u044F\u0442\u043D\u0438\u0446\u044B \u0438\u043B\u0438 \u0432 \u0441\u0443\u0431\u0431\u043E\u0442\u0443/\u0432\u043E\u0441\u043A\u0440\u0435\u0441\u0435\u043D\u044C\u0435 \u0431\u0443\u0434\u0443\u0442 \u043E\u0431\u0440\u0430\u0431\u043E\u0442\u0430\u043D\u044B \u0432 \u0431\u0443\u0434\u043D\u0438\u0435 \u0434\u043D\u0438.</li>\n <li>\n \u0423\u043F\u0440\u0430\u0432\u043B\u044F\u0442\u044C \u0441\u043F\u0438\u0441\u043A\u043E\u043C \u043A\u043E\u043D\u0442\u0440\u0430\u0433\u0435\u043D\u0442\u043E\u0432 \u0432\u044B \u043C\u043E\u0436\u0435\u0442\u0435 \u0432\n <a\n tuiLink\n routerLink=\"/profile\"\n >\n \u043B\u0438\u0447\u043D\u043E\u043C \u043A\u0430\u0431\u0438\u043D\u0435\u0442\u0435\n </a>\n .\n </li>\n </ul>\n\n <div class=\"sub-title\">\u0421\u043E\u0441\u0442\u0430\u0432 \u0437\u0430\u043A\u0430\u0437\u0430</div>\n\n <sc-order-items-list-by-directions\n [items]=\"items()\"\n [editable]=\"editable()\"\n [selectable]=\"selectable()\"\n [useLinePrice]=\"useLinePrice()\"\n [showContinueButton]=\"false\"\n (selectedItemsIdsChange)=\"selectedItemsIdsChange.emit($event)\"\n >\n <ng-content\n select=\"[footerActions]\"\n ngProjectAs=\"[footerActions]\"\n />\n </sc-order-items-list-by-directions>\n</div>\n" }]
|
|
8658
8810
|
}] });
|
|
8659
8811
|
|
|
8660
8812
|
/**
|
|
@@ -9269,17 +9421,383 @@ class ScOrderItemsListByStockComponent {
|
|
|
9269
9421
|
this.selectedItemsIds.update((previous) => [...previous.filter((id) => !items.some((item) => item.id === id) && this.items().some((item) => item.id === id)), ...itemsIds]);
|
|
9270
9422
|
}
|
|
9271
9423
|
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: ScOrderItemsListByStockComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
9272
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.2.14", type: ScOrderItemsListByStockComponent, isStandalone: true, selector: "sc-order-items-list-by-stock", inputs: { items: { classPropertyName: "items", publicName: "items", isSignal: true, isRequired: true, transformFunction: null }, warehouseId: { classPropertyName: "warehouseId", publicName: "warehouseId", isSignal: true, isRequired: true, transformFunction: null }, selectable: { classPropertyName: "selectable", publicName: "selectable", isSignal: true, isRequired: false, transformFunction: null }, editable: { classPropertyName: "editable", publicName: "editable", isSignal: true, isRequired: false, transformFunction: null }, sectionHeader: { classPropertyName: "sectionHeader", publicName: "sectionHeader", isSignal: true, isRequired: false, transformFunction: null }, selectedItemsIds: { classPropertyName: "selectedItemsIds", publicName: "selectedItemsIds", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { selectedItemsIds: "selectedItemsIdsChange" }, ngImport: i0, template: "<div class=\"flex flex-col gap-5\">\n @if (itemsInWarehouseStock().length > 0) {\n <sc-order-items-list\n [items]=\"itemsInWarehouseStock()\"\n [selectable]=\"selectable()\"\n [editable]=\"editable()\"\n (selectedItemsIdsChange)=\"selectedItemsHandler($event, itemsInWarehouseStock())\"\n />\n }\n\n @if (itemsOnOrder().length > 0) {\n <div class=\"flex flex-col gap-2.5\">\n @if (sectionHeader()) {\n <div class=\"text-base font-bold text-sc-dark-grey\">{{ sectionHeader() }}</div>\n }\n <sc-order-items-list\n [items]=\"itemsOnOrder()\"\n [selectable]=\"selectable()\"\n [editable]=\"editable()\"\n (selectedItemsIdsChange)=\"selectedItemsHandler($event, itemsOnOrder())\"\n />\n </div>\n }\n\n @if (itemsNotInWarehouseStock().length > 0) {\n <div class=\"flex flex-col gap-2.5\">\n @if (sectionHeader()) {\n <div class=\"text-base font-bold text-sc-dark-grey\">{{ sectionHeader() }}</div>\n }\n <sc-order-items-list\n [items]=\"itemsNotInWarehouseStock()\"\n [selectable]=\"selectable()\"\n [editable]=\"editable()\"\n (selectedItemsIdsChange)=\"selectedItemsHandler($event, itemsNotInWarehouseStock())\"\n />\n </div>\n }\n</div>\n", dependencies: [{ kind: "component", type: ScOrderItemsListComponent, selector: "sc-order-items-list", inputs: ["selectable", "editable", "items"], outputs: ["selectedItemsIdsChange"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
|
|
9424
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.2.14", type: ScOrderItemsListByStockComponent, isStandalone: true, selector: "sc-order-items-list-by-stock", inputs: { items: { classPropertyName: "items", publicName: "items", isSignal: true, isRequired: true, transformFunction: null }, warehouseId: { classPropertyName: "warehouseId", publicName: "warehouseId", isSignal: true, isRequired: true, transformFunction: null }, selectable: { classPropertyName: "selectable", publicName: "selectable", isSignal: true, isRequired: false, transformFunction: null }, editable: { classPropertyName: "editable", publicName: "editable", isSignal: true, isRequired: false, transformFunction: null }, sectionHeader: { classPropertyName: "sectionHeader", publicName: "sectionHeader", isSignal: true, isRequired: false, transformFunction: null }, selectedItemsIds: { classPropertyName: "selectedItemsIds", publicName: "selectedItemsIds", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { selectedItemsIds: "selectedItemsIdsChange" }, ngImport: i0, template: "<div class=\"flex flex-col gap-5\">\n @if (itemsInWarehouseStock().length > 0) {\n <sc-order-items-list\n [items]=\"itemsInWarehouseStock()\"\n [selectable]=\"selectable()\"\n [editable]=\"editable()\"\n (selectedItemsIdsChange)=\"selectedItemsHandler($event, itemsInWarehouseStock())\"\n />\n }\n\n @if (itemsOnOrder().length > 0) {\n <div class=\"flex flex-col gap-2.5\">\n @if (sectionHeader()) {\n <div class=\"text-base font-bold text-sc-dark-grey\">{{ sectionHeader() }}</div>\n }\n <sc-order-items-list\n [items]=\"itemsOnOrder()\"\n [selectable]=\"selectable()\"\n [editable]=\"editable()\"\n (selectedItemsIdsChange)=\"selectedItemsHandler($event, itemsOnOrder())\"\n />\n </div>\n }\n\n @if (itemsNotInWarehouseStock().length > 0) {\n <div class=\"flex flex-col gap-2.5\">\n @if (sectionHeader()) {\n <div class=\"text-base font-bold text-sc-dark-grey\">{{ sectionHeader() }}</div>\n }\n <sc-order-items-list\n [items]=\"itemsNotInWarehouseStock()\"\n [selectable]=\"selectable()\"\n [editable]=\"editable()\"\n (selectedItemsIdsChange)=\"selectedItemsHandler($event, itemsNotInWarehouseStock())\"\n />\n </div>\n }\n</div>\n", dependencies: [{ kind: "component", type: ScOrderItemsListComponent, selector: "sc-order-items-list", inputs: ["selectable", "editable", "groupBy", "markUnavailable", "useLinePrice", "items"], outputs: ["selectedItemsIdsChange"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
|
|
9273
9425
|
}
|
|
9274
9426
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: ScOrderItemsListByStockComponent, decorators: [{
|
|
9275
9427
|
type: Component,
|
|
9276
9428
|
args: [{ standalone: true, selector: 'sc-order-items-list-by-stock', imports: [ScOrderItemsListComponent], changeDetection: ChangeDetectionStrategy.OnPush, template: "<div class=\"flex flex-col gap-5\">\n @if (itemsInWarehouseStock().length > 0) {\n <sc-order-items-list\n [items]=\"itemsInWarehouseStock()\"\n [selectable]=\"selectable()\"\n [editable]=\"editable()\"\n (selectedItemsIdsChange)=\"selectedItemsHandler($event, itemsInWarehouseStock())\"\n />\n }\n\n @if (itemsOnOrder().length > 0) {\n <div class=\"flex flex-col gap-2.5\">\n @if (sectionHeader()) {\n <div class=\"text-base font-bold text-sc-dark-grey\">{{ sectionHeader() }}</div>\n }\n <sc-order-items-list\n [items]=\"itemsOnOrder()\"\n [selectable]=\"selectable()\"\n [editable]=\"editable()\"\n (selectedItemsIdsChange)=\"selectedItemsHandler($event, itemsOnOrder())\"\n />\n </div>\n }\n\n @if (itemsNotInWarehouseStock().length > 0) {\n <div class=\"flex flex-col gap-2.5\">\n @if (sectionHeader()) {\n <div class=\"text-base font-bold text-sc-dark-grey\">{{ sectionHeader() }}</div>\n }\n <sc-order-items-list\n [items]=\"itemsNotInWarehouseStock()\"\n [selectable]=\"selectable()\"\n [editable]=\"editable()\"\n (selectedItemsIdsChange)=\"selectedItemsHandler($event, itemsNotInWarehouseStock())\"\n />\n </div>\n }\n</div>\n" }]
|
|
9277
9429
|
}] });
|
|
9278
9430
|
|
|
9431
|
+
/**
|
|
9432
|
+
* Класс-помощник для работы со списком черновиков.
|
|
9433
|
+
*/
|
|
9434
|
+
class ScDraftListHelper {
|
|
9435
|
+
/**
|
|
9436
|
+
* Возвращает список черновиков страницы с обновлёнными краткими данными. Элементы списка обновляются на месте, чтобы сохранить раскрытые черновики и их полные данные.
|
|
9437
|
+
*
|
|
9438
|
+
* @param items Текущие элементы списка.
|
|
9439
|
+
* @param drafts Полученные краткие данные черновиков.
|
|
9440
|
+
* @param isFullPage Признак, что получена вся страница: тогда состав и порядок списка берутся из неё.
|
|
9441
|
+
*/
|
|
9442
|
+
static merge(items, drafts, isFullPage) {
|
|
9443
|
+
if (isFullPage) {
|
|
9444
|
+
return drafts.map((short) => {
|
|
9445
|
+
const item = items.find(({ order }) => order.id === short.id);
|
|
9446
|
+
return item ? ScDraftListHelper.update(item, short) : { order: short, isExpanded: false };
|
|
9447
|
+
});
|
|
9448
|
+
}
|
|
9449
|
+
return items.map((item) => {
|
|
9450
|
+
const short = drafts.find(({ id }) => id === item.order.id);
|
|
9451
|
+
return short ? ScDraftListHelper.update(item, short) : item;
|
|
9452
|
+
});
|
|
9453
|
+
}
|
|
9454
|
+
/**
|
|
9455
|
+
* Обновляет элемент списка краткими данными черновика. Полные данные черновика не заменяются, а дополняются.
|
|
9456
|
+
*
|
|
9457
|
+
* @param item Элемент списка.
|
|
9458
|
+
* @param short Краткие данные черновика.
|
|
9459
|
+
*/
|
|
9460
|
+
static update(item, short) {
|
|
9461
|
+
if (item.order instanceof ScOrderDraft) {
|
|
9462
|
+
item.order.updateDataFromShortOffer(short);
|
|
9463
|
+
}
|
|
9464
|
+
else {
|
|
9465
|
+
// eslint-disable-next-line no-param-reassign
|
|
9466
|
+
item.order = short;
|
|
9467
|
+
}
|
|
9468
|
+
return item;
|
|
9469
|
+
}
|
|
9470
|
+
}
|
|
9471
|
+
|
|
9472
|
+
/**
|
|
9473
|
+
* Перечисление состояний черновика Профстрой для отображения пользователю.
|
|
9474
|
+
*/
|
|
9475
|
+
// eslint-disable-next-line no-shadow
|
|
9476
|
+
var ScProfstroyDraftState;
|
|
9477
|
+
(function (ScProfstroyDraftState) {
|
|
9478
|
+
/**
|
|
9479
|
+
* Выполняется обработка.
|
|
9480
|
+
*/
|
|
9481
|
+
ScProfstroyDraftState["processing"] = "processing";
|
|
9482
|
+
/**
|
|
9483
|
+
* Актуализирован, срок действия не истёк.
|
|
9484
|
+
*/
|
|
9485
|
+
ScProfstroyDraftState["actual"] = "actual";
|
|
9486
|
+
/**
|
|
9487
|
+
* Актуализирован, но срок действия истёк.
|
|
9488
|
+
*/
|
|
9489
|
+
ScProfstroyDraftState["outdated"] = "outdated";
|
|
9490
|
+
/**
|
|
9491
|
+
* Обработка завершилась с ошибкой.
|
|
9492
|
+
*/
|
|
9493
|
+
ScProfstroyDraftState["error"] = "error";
|
|
9494
|
+
/**
|
|
9495
|
+
* Требуется актуализация после изменения состава.
|
|
9496
|
+
*/
|
|
9497
|
+
ScProfstroyDraftState["needsActualization"] = "needsActualization";
|
|
9498
|
+
/**
|
|
9499
|
+
* Состояние не известно.
|
|
9500
|
+
*/
|
|
9501
|
+
ScProfstroyDraftState["unknown"] = "unknown";
|
|
9502
|
+
})(ScProfstroyDraftState || (ScProfstroyDraftState = {}));
|
|
9503
|
+
|
|
9504
|
+
/**
|
|
9505
|
+
* Класс-помощник для отображения черновиков Профстрой.
|
|
9506
|
+
*/
|
|
9507
|
+
class ScProfstroyDraftHelper {
|
|
9508
|
+
/**
|
|
9509
|
+
* Данные об отображении состояний черновика.
|
|
9510
|
+
*/
|
|
9511
|
+
static { this.stateViews = {
|
|
9512
|
+
[ScProfstroyDraftState.processing]: {
|
|
9513
|
+
label: 'Выполняется обработка',
|
|
9514
|
+
appearance: 'info',
|
|
9515
|
+
description: 'Файл обрабатывается, позиции и цены уточняются. Изменение состава и оформление заказа станут доступны после завершения.',
|
|
9516
|
+
},
|
|
9517
|
+
[ScProfstroyDraftState.actual]: {
|
|
9518
|
+
label: 'Актуализирован',
|
|
9519
|
+
appearance: 'success',
|
|
9520
|
+
description: 'Цены и позиции актуальны, заказ можно оформлять.',
|
|
9521
|
+
},
|
|
9522
|
+
[ScProfstroyDraftState.outdated]: {
|
|
9523
|
+
label: 'Данные устарели',
|
|
9524
|
+
appearance: 'warning',
|
|
9525
|
+
description: 'С момента последней актуализации прошло много времени. Запустите её повторно, чтобы оформить заказ по актуальным ценам.',
|
|
9526
|
+
},
|
|
9527
|
+
[ScProfstroyDraftState.error]: {
|
|
9528
|
+
label: 'Ошибка обработки',
|
|
9529
|
+
appearance: 'error',
|
|
9530
|
+
description: 'Обработка завершилась с ошибкой. Запустите актуализацию повторно или соберите заявку из файла заново.',
|
|
9531
|
+
},
|
|
9532
|
+
[ScProfstroyDraftState.needsActualization]: {
|
|
9533
|
+
label: 'Требуется актуализация',
|
|
9534
|
+
appearance: 'warning',
|
|
9535
|
+
description: 'Состав заявки изменён после последней актуализации. Запустите актуализацию, чтобы обновить цены и оформить заказ.',
|
|
9536
|
+
},
|
|
9537
|
+
[ScProfstroyDraftState.unknown]: {
|
|
9538
|
+
label: 'Состояние неизвестно',
|
|
9539
|
+
appearance: 'neutral',
|
|
9540
|
+
description: '',
|
|
9541
|
+
},
|
|
9542
|
+
}; }
|
|
9543
|
+
/**
|
|
9544
|
+
* Возвращает состояние черновика на указанный момент.
|
|
9545
|
+
*
|
|
9546
|
+
* @param actualization Данные об актуализации.
|
|
9547
|
+
* @param now Момент проверки.
|
|
9548
|
+
*/
|
|
9549
|
+
static getState(actualization, now) {
|
|
9550
|
+
switch (actualization?.status) {
|
|
9551
|
+
case ScOrderDraftActualizationStatus.processing:
|
|
9552
|
+
return ScProfstroyDraftState.processing;
|
|
9553
|
+
case ScOrderDraftActualizationStatus.completed:
|
|
9554
|
+
return actualization.isOutdatedAt(now) ? ScProfstroyDraftState.outdated : ScProfstroyDraftState.actual;
|
|
9555
|
+
case ScOrderDraftActualizationStatus.error:
|
|
9556
|
+
return ScProfstroyDraftState.error;
|
|
9557
|
+
case ScOrderDraftActualizationStatus.needsActualization:
|
|
9558
|
+
return ScProfstroyDraftState.needsActualization;
|
|
9559
|
+
default:
|
|
9560
|
+
return ScProfstroyDraftState.unknown;
|
|
9561
|
+
}
|
|
9562
|
+
}
|
|
9563
|
+
/**
|
|
9564
|
+
* Возвращает данные об отображении состояния черновика на указанный момент.
|
|
9565
|
+
*
|
|
9566
|
+
* @param actualization Данные об актуализации.
|
|
9567
|
+
* @param now Момент проверки.
|
|
9568
|
+
*/
|
|
9569
|
+
static getStateView(actualization, now) {
|
|
9570
|
+
return ScProfstroyDraftHelper.stateViews[ScProfstroyDraftHelper.getState(actualization, now)];
|
|
9571
|
+
}
|
|
9572
|
+
}
|
|
9573
|
+
|
|
9574
|
+
/**
|
|
9575
|
+
* Компонент панели состояния актуализации черновика Профстрой с действиями актуализации и пересборки.
|
|
9576
|
+
*/
|
|
9577
|
+
class ScProfstroyActualizationPanelComponent {
|
|
9578
|
+
constructor() {
|
|
9579
|
+
/**
|
|
9580
|
+
* Список ссылок приложения.
|
|
9581
|
+
*/
|
|
9582
|
+
this.urls = inject(SC_URLS);
|
|
9583
|
+
/**
|
|
9584
|
+
* Черновик Профстрой.
|
|
9585
|
+
*/
|
|
9586
|
+
this.draft = input.required();
|
|
9587
|
+
/**
|
|
9588
|
+
* Момент, на который определяется состояние.
|
|
9589
|
+
*/
|
|
9590
|
+
this.now = input(new Date());
|
|
9591
|
+
/**
|
|
9592
|
+
* Признак выполнения действия над черновиком.
|
|
9593
|
+
*/
|
|
9594
|
+
this.busy = input(false);
|
|
9595
|
+
/**
|
|
9596
|
+
* Событие запуска актуализации.
|
|
9597
|
+
*/
|
|
9598
|
+
this.actualize = output();
|
|
9599
|
+
/**
|
|
9600
|
+
* Событие запуска пересборки из файла.
|
|
9601
|
+
*/
|
|
9602
|
+
this.reload = output();
|
|
9603
|
+
/**
|
|
9604
|
+
* Текущее состояние черновика.
|
|
9605
|
+
*/
|
|
9606
|
+
this.state = computed(() => ScProfstroyDraftHelper.getState(this.draft().actualization, this.now()));
|
|
9607
|
+
/**
|
|
9608
|
+
* Данные об отображении состояния.
|
|
9609
|
+
*/
|
|
9610
|
+
this.stateView = computed(() => ScProfstroyDraftHelper.getStateView(this.draft().actualization, this.now()));
|
|
9611
|
+
/**
|
|
9612
|
+
* Признак, что выполняется обработка.
|
|
9613
|
+
*/
|
|
9614
|
+
this.isProcessing = computed(() => this.state() === ScProfstroyDraftState.processing);
|
|
9615
|
+
/**
|
|
9616
|
+
* Признак, что срок действия актуализации ещё не истёк.
|
|
9617
|
+
*/
|
|
9618
|
+
this.isActual = computed(() => this.state() === ScProfstroyDraftState.actual);
|
|
9619
|
+
/**
|
|
9620
|
+
* Абсолютная ссылка на исходный файл заявки. Файл лежит на хосте API.
|
|
9621
|
+
*/
|
|
9622
|
+
this.fileUrl = computed(() => {
|
|
9623
|
+
const url = this.draft().file?.url;
|
|
9624
|
+
return url ? new URL(url, this.urls.apiUrl).href : null;
|
|
9625
|
+
});
|
|
9626
|
+
}
|
|
9627
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: ScProfstroyActualizationPanelComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
9628
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.2.14", type: ScProfstroyActualizationPanelComponent, isStandalone: true, selector: "sc-profstroy-actualization-panel", inputs: { draft: { classPropertyName: "draft", publicName: "draft", isSignal: true, isRequired: true, transformFunction: null }, now: { classPropertyName: "now", publicName: "now", isSignal: true, isRequired: false, transformFunction: null }, busy: { classPropertyName: "busy", publicName: "busy", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { actualize: "actualize", reload: "reload" }, ngImport: i0, template: "@let actualization = draft().actualization;\n@let view = stateView();\n\n<tui-notification\n [appearance]=\"view.appearance\"\n size=\"m\"\n>\n <div class=\"flex flex-col items-start gap-2 text-start\">\n <div class=\"flex items-center justify-start gap-2 text-start font-bold\">\n @if (isProcessing()) {\n <tui-loader size=\"s\" />\n }\n {{ view.label }}\n </div>\n\n <div class=\"flex flex-col items-start gap-1\">\n @if (actualization?.actualizedAt; as actualizedAt) {\n <span>\u0410\u043A\u0442\u0443\u0430\u043B\u0438\u0437\u0438\u0440\u043E\u0432\u0430\u043D {{ actualizedAt | scFormatDate }}</span>\n }\n @if (isActual() && actualization?.expiresAt; as expiresAt) {\n <span>\u0410\u043A\u0442\u0443\u0430\u043B\u0435\u043D \u0434\u043E {{ expiresAt | scFormatDate }}</span>\n }\n @if (view.description) {\n <span>{{ view.description }}</span>\n }\n @if (actualization?.error; as error) {\n <span class=\"font-bold\">{{ error }}</span>\n }\n @if (fileUrl(); as url) {\n <span>\n \u0424\u0430\u0439\u043B \u0437\u0430\u044F\u0432\u043A\u0438:\n <a\n tuiLink\n [href]=\"url\"\n target=\"_blank\"\n rel=\"noopener\"\n >\n {{ draft().file?.originalName ?? '\u0441\u043A\u0430\u0447\u0430\u0442\u044C' }}\n </a>\n </span>\n }\n </div>\n\n <div class=\"flex flex-wrap gap-2\">\n <button\n tuiButton\n type=\"button\"\n size=\"s\"\n appearance=\"secondary\"\n iconStart=\"@tui.refresh-cw\"\n [disabled]=\"isProcessing() || busy()\"\n (click)=\"actualize.emit()\"\n >\n \u0410\u043A\u0442\u0443\u0430\u043B\u0438\u0437\u0438\u0440\u043E\u0432\u0430\u0442\u044C\n </button>\n <button\n tuiButton\n type=\"button\"\n size=\"s\"\n appearance=\"secondary\"\n iconStart=\"@tui.file-up\"\n [disabled]=\"isProcessing() || busy()\"\n (click)=\"reload.emit()\"\n >\n \u0421\u043E\u0431\u0440\u0430\u0442\u044C \u0437\u0430\u043D\u043E\u0432\u043E \u0438\u0437 \u0444\u0430\u0439\u043B\u0430\n </button>\n </div>\n </div>\n</tui-notification>\n", dependencies: [{ kind: "directive", type: TuiNotification, selector: "tui-notification,a[tuiNotification],button[tuiNotification]", inputs: ["appearance", "icon", "size"] }, { kind: "component", type: TuiLoader, selector: "tui-loader", inputs: ["size", "inheritColor", "overlay", "textContent", "showLoader"] }, { kind: "directive", type: TuiButton, selector: "a[tuiButton],button[tuiButton],a[tuiIconButton],button[tuiIconButton]", inputs: ["size"] }, { kind: "directive", type: TuiLink, selector: "a[tuiLink], button[tuiLink]", inputs: ["pseudo"] }, { kind: "pipe", type: ScFormatDatePipe, name: "scFormatDate" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
|
|
9629
|
+
}
|
|
9630
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: ScProfstroyActualizationPanelComponent, decorators: [{
|
|
9631
|
+
type: Component,
|
|
9632
|
+
args: [{ standalone: true, selector: 'sc-profstroy-actualization-panel', imports: [TuiNotification, TuiLoader, TuiButton, TuiLink, ScFormatDatePipe], changeDetection: ChangeDetectionStrategy.OnPush, template: "@let actualization = draft().actualization;\n@let view = stateView();\n\n<tui-notification\n [appearance]=\"view.appearance\"\n size=\"m\"\n>\n <div class=\"flex flex-col items-start gap-2 text-start\">\n <div class=\"flex items-center justify-start gap-2 text-start font-bold\">\n @if (isProcessing()) {\n <tui-loader size=\"s\" />\n }\n {{ view.label }}\n </div>\n\n <div class=\"flex flex-col items-start gap-1\">\n @if (actualization?.actualizedAt; as actualizedAt) {\n <span>\u0410\u043A\u0442\u0443\u0430\u043B\u0438\u0437\u0438\u0440\u043E\u0432\u0430\u043D {{ actualizedAt | scFormatDate }}</span>\n }\n @if (isActual() && actualization?.expiresAt; as expiresAt) {\n <span>\u0410\u043A\u0442\u0443\u0430\u043B\u0435\u043D \u0434\u043E {{ expiresAt | scFormatDate }}</span>\n }\n @if (view.description) {\n <span>{{ view.description }}</span>\n }\n @if (actualization?.error; as error) {\n <span class=\"font-bold\">{{ error }}</span>\n }\n @if (fileUrl(); as url) {\n <span>\n \u0424\u0430\u0439\u043B \u0437\u0430\u044F\u0432\u043A\u0438:\n <a\n tuiLink\n [href]=\"url\"\n target=\"_blank\"\n rel=\"noopener\"\n >\n {{ draft().file?.originalName ?? '\u0441\u043A\u0430\u0447\u0430\u0442\u044C' }}\n </a>\n </span>\n }\n </div>\n\n <div class=\"flex flex-wrap gap-2\">\n <button\n tuiButton\n type=\"button\"\n size=\"s\"\n appearance=\"secondary\"\n iconStart=\"@tui.refresh-cw\"\n [disabled]=\"isProcessing() || busy()\"\n (click)=\"actualize.emit()\"\n >\n \u0410\u043A\u0442\u0443\u0430\u043B\u0438\u0437\u0438\u0440\u043E\u0432\u0430\u0442\u044C\n </button>\n <button\n tuiButton\n type=\"button\"\n size=\"s\"\n appearance=\"secondary\"\n iconStart=\"@tui.file-up\"\n [disabled]=\"isProcessing() || busy()\"\n (click)=\"reload.emit()\"\n >\n \u0421\u043E\u0431\u0440\u0430\u0442\u044C \u0437\u0430\u043D\u043E\u0432\u043E \u0438\u0437 \u0444\u0430\u0439\u043B\u0430\n </button>\n </div>\n </div>\n</tui-notification>\n" }]
|
|
9633
|
+
}] });
|
|
9634
|
+
|
|
9635
|
+
/**
|
|
9636
|
+
* Компонент метки «Профстрой» у черновика или заказа, созданного из файла программы «Профстрой».
|
|
9637
|
+
*/
|
|
9638
|
+
class ScProfstroyBadgeComponent {
|
|
9639
|
+
constructor() {
|
|
9640
|
+
/**
|
|
9641
|
+
* Размер метки.
|
|
9642
|
+
*/
|
|
9643
|
+
this.size = input('m');
|
|
9644
|
+
}
|
|
9645
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: ScProfstroyBadgeComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
9646
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "18.2.14", type: ScProfstroyBadgeComponent, isStandalone: true, selector: "sc-profstroy-badge", inputs: { size: { classPropertyName: "size", publicName: "size", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0, template: "<tui-badge\n class=\"!font-medium\"\n appearance=\"primary\"\n [size]=\"size()\"\n>\n \u041F\u0440\u043E\u0444\u0441\u0442\u0440\u043E\u0439\n</tui-badge>\n", dependencies: [{ kind: "directive", type: TuiBadge, selector: "tui-badge,[tuiBadge]", inputs: ["size"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
|
|
9647
|
+
}
|
|
9648
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: ScProfstroyBadgeComponent, decorators: [{
|
|
9649
|
+
type: Component,
|
|
9650
|
+
args: [{ standalone: true, selector: 'sc-profstroy-badge', imports: [TuiBadge], changeDetection: ChangeDetectionStrategy.OnPush, template: "<tui-badge\n class=\"!font-medium\"\n appearance=\"primary\"\n [size]=\"size()\"\n>\n \u041F\u0440\u043E\u0444\u0441\u0442\u0440\u043E\u0439\n</tui-badge>\n" }]
|
|
9651
|
+
}] });
|
|
9652
|
+
|
|
9653
|
+
/**
|
|
9654
|
+
* Компонент меток черновика Профстрой: признак и текущее состояние обработки.
|
|
9655
|
+
*/
|
|
9656
|
+
class ScProfstroyDraftBadgesComponent {
|
|
9657
|
+
constructor() {
|
|
9658
|
+
/**
|
|
9659
|
+
* Данные об актуализации черновика.
|
|
9660
|
+
*/
|
|
9661
|
+
this.actualization = input();
|
|
9662
|
+
/**
|
|
9663
|
+
* Момент, на который определяется состояние.
|
|
9664
|
+
*/
|
|
9665
|
+
this.now = input(new Date());
|
|
9666
|
+
/**
|
|
9667
|
+
* Данные об отображении состояния.
|
|
9668
|
+
*/
|
|
9669
|
+
this.stateView = computed(() => ScProfstroyDraftHelper.getStateView(this.actualization(), this.now()));
|
|
9670
|
+
}
|
|
9671
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: ScProfstroyDraftBadgesComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
9672
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "18.2.14", type: ScProfstroyDraftBadgesComponent, isStandalone: true, selector: "sc-profstroy-draft-badges", inputs: { actualization: { classPropertyName: "actualization", publicName: "actualization", isSignal: true, isRequired: false, transformFunction: null }, now: { classPropertyName: "now", publicName: "now", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0, template: "<span class=\"inline-flex flex-wrap items-center gap-1\">\n <sc-profstroy-badge />\n <tui-badge\n class=\"!font-medium\"\n [appearance]=\"stateView().appearance\"\n size=\"m\"\n >\n {{ stateView().label }}\n </tui-badge>\n</span>\n", dependencies: [{ kind: "directive", type: TuiBadge, selector: "tui-badge,[tuiBadge]", inputs: ["size"] }, { kind: "component", type: ScProfstroyBadgeComponent, selector: "sc-profstroy-badge", inputs: ["size"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
|
|
9673
|
+
}
|
|
9674
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: ScProfstroyDraftBadgesComponent, decorators: [{
|
|
9675
|
+
type: Component,
|
|
9676
|
+
args: [{ standalone: true, selector: 'sc-profstroy-draft-badges', imports: [TuiBadge, ScProfstroyBadgeComponent], changeDetection: ChangeDetectionStrategy.OnPush, template: "<span class=\"inline-flex flex-wrap items-center gap-1\">\n <sc-profstroy-badge />\n <tui-badge\n class=\"!font-medium\"\n [appearance]=\"stateView().appearance\"\n size=\"m\"\n >\n {{ stateView().label }}\n </tui-badge>\n</span>\n" }]
|
|
9677
|
+
}] });
|
|
9678
|
+
|
|
9679
|
+
/**
|
|
9680
|
+
* Компонент диалога создания черновика заказа из файла программы «Профстрой».
|
|
9681
|
+
*/
|
|
9682
|
+
class ScProfstroyDraftCreateDialogComponent {
|
|
9683
|
+
constructor() {
|
|
9684
|
+
/**
|
|
9685
|
+
* Контекст диалогового окна, в котором открыт компонент.
|
|
9686
|
+
*/
|
|
9687
|
+
this.context = inject(POLYMORPHEUS_CONTEXT);
|
|
9688
|
+
/**
|
|
9689
|
+
* Сервис для работы с черновиками заказов.
|
|
9690
|
+
*/
|
|
9691
|
+
this.draftsService = inject(ScOrderDraftsService);
|
|
9692
|
+
/**
|
|
9693
|
+
* Ссылка для автоматического управления уничтожением зависимостей.
|
|
9694
|
+
*/
|
|
9695
|
+
this.destroyRef = inject(DestroyRef);
|
|
9696
|
+
/**
|
|
9697
|
+
* Допустимые расширения файла.
|
|
9698
|
+
*/
|
|
9699
|
+
this.allowedExtensions = ['.xlsx', '.xls'];
|
|
9700
|
+
/**
|
|
9701
|
+
* Форма создания черновика.
|
|
9702
|
+
*/
|
|
9703
|
+
this.form = new FormGroup({
|
|
9704
|
+
file: new FormControl(null, (control) => Validators.required(control) ?? this.validateExtension(control)),
|
|
9705
|
+
name: new FormControl('', { nonNullable: true }),
|
|
9706
|
+
});
|
|
9707
|
+
/**
|
|
9708
|
+
* Признак выполнения запроса создания.
|
|
9709
|
+
*/
|
|
9710
|
+
this.submitting = signal(false);
|
|
9711
|
+
}
|
|
9712
|
+
/**
|
|
9713
|
+
* Удаляет выбранный файл.
|
|
9714
|
+
*/
|
|
9715
|
+
removeFile() {
|
|
9716
|
+
this.form.controls.file.setValue(null);
|
|
9717
|
+
}
|
|
9718
|
+
/**
|
|
9719
|
+
* Отправляет файл и создаёт черновик.
|
|
9720
|
+
*/
|
|
9721
|
+
submit() {
|
|
9722
|
+
this.form.markAllAsTouched();
|
|
9723
|
+
const file = this.form.controls.file.value;
|
|
9724
|
+
if (this.form.invalid || !file || this.submitting()) {
|
|
9725
|
+
return;
|
|
9726
|
+
}
|
|
9727
|
+
this.submitting.set(true);
|
|
9728
|
+
ScFileHelper.readAsUploadedFile$(file)
|
|
9729
|
+
.pipe(switchMap((uploadedFile) => this.draftsService.createProfstroy$({ file: uploadedFile, name: this.form.controls.name.value.trim() || undefined })), finalize(() => {
|
|
9730
|
+
this.submitting.set(false);
|
|
9731
|
+
}), takeUntilDestroyed(this.destroyRef))
|
|
9732
|
+
.subscribe({
|
|
9733
|
+
next: (draft) => {
|
|
9734
|
+
this.context.completeWith(draft);
|
|
9735
|
+
},
|
|
9736
|
+
error: (error) => {
|
|
9737
|
+
this.applyServerErrors(error);
|
|
9738
|
+
},
|
|
9739
|
+
});
|
|
9740
|
+
}
|
|
9741
|
+
/**
|
|
9742
|
+
* Возвращает ошибку, если расширение файла не входит в список допустимых.
|
|
9743
|
+
*
|
|
9744
|
+
* @param control Контрол файла.
|
|
9745
|
+
*/
|
|
9746
|
+
validateExtension(control) {
|
|
9747
|
+
const name = control.value?.name.toLowerCase();
|
|
9748
|
+
if (!name || this.allowedExtensions.some((extension) => name.endsWith(extension))) {
|
|
9749
|
+
return null;
|
|
9750
|
+
}
|
|
9751
|
+
return { serverResponse: new TuiValidationError(`Файл должен быть в формате ${this.allowedExtensions.join(', ')}`) };
|
|
9752
|
+
}
|
|
9753
|
+
/**
|
|
9754
|
+
* Раскладывает ошибки сервера по полям формы.
|
|
9755
|
+
*
|
|
9756
|
+
* @param error Ошибка запроса.
|
|
9757
|
+
*/
|
|
9758
|
+
applyServerErrors(error) {
|
|
9759
|
+
if (!(error instanceof HttpErrorResponse)) {
|
|
9760
|
+
this.form.controls.file.setErrors({ serverResponse: new TuiValidationError('Не удалось прочитать файл') });
|
|
9761
|
+
return;
|
|
9762
|
+
}
|
|
9763
|
+
const { errors, message } = (error.error ?? {});
|
|
9764
|
+
if (!errors) {
|
|
9765
|
+
this.form.controls.file.setErrors({ serverResponse: new TuiValidationError(message ?? 'Не удалось создать заявку') });
|
|
9766
|
+
return;
|
|
9767
|
+
}
|
|
9768
|
+
Object.entries(errors).forEach(([key, messages]) => {
|
|
9769
|
+
const control = key === 'name' ? this.form.controls.name : this.form.controls.file;
|
|
9770
|
+
control.setErrors({ serverResponse: new TuiValidationError(messages.join(' ')) });
|
|
9771
|
+
control.markAsTouched();
|
|
9772
|
+
});
|
|
9773
|
+
}
|
|
9774
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: ScProfstroyDraftCreateDialogComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
9775
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.2.14", type: ScProfstroyDraftCreateDialogComponent, isStandalone: true, selector: "sc-profstroy-draft-create-dialog", ngImport: i0, template: "<form\n [formGroup]=\"form\"\n class=\"flex flex-col gap-5\"\n (ngSubmit)=\"submit()\"\n>\n <!-- \u0424\u0430\u0439\u043B. -->\n <div class=\"flex flex-col gap-1\">\n @if (!form.controls.file.value) {\n <label tuiInputFiles>\n <input\n tuiInputFiles\n formControlName=\"file\"\n [accept]=\"allowedExtensions.join(',')\"\n />\n </label>\n }\n <tui-files>\n @if (form.controls.file.value; as file) {\n <tui-file\n [file]=\"file\"\n (remove)=\"removeFile()\"\n />\n }\n </tui-files>\n <span class=\"text-body-s text-tui-text-02\">\u0424\u0430\u0439\u043B Excel, \u0432\u044B\u0433\u0440\u0443\u0436\u0435\u043D\u043D\u044B\u0439 \u0438\u0437 \u043F\u0440\u043E\u0433\u0440\u0430\u043C\u043C\u044B \u00AB\u041F\u0440\u043E\u0444\u0441\u0442\u0440\u043E\u0439\u00BB: {{ allowedExtensions.join(', ') }}</span>\n <tui-error\n formControlName=\"file\"\n [error]=\"[] | tuiFieldError | async\"\n />\n </div>\n\n <!-- \u041D\u0430\u0437\u0432\u0430\u043D\u0438\u0435 \u0437\u0430\u044F\u0432\u043A\u0438. -->\n <label tuiLabel>\n \u041D\u0430\u0437\u0432\u0430\u043D\u0438\u0435 \u0437\u0430\u044F\u0432\u043A\u0438\n <tui-input\n formControlName=\"name\"\n [tuiTextfieldLabelOutside]=\"true\"\n >\n \u041D\u0430\u043F\u0440\u0438\u043C\u0435\u0440: \u0411\u0430\u043B\u043A\u043E\u043D\u044B, \u043E\u0431\u044A\u0435\u043A\u0442 \u043D\u0430 \u041B\u0435\u043D\u0438\u043D\u0430\n </tui-input>\n <tui-error\n formControlName=\"name\"\n [error]=\"[] | tuiFieldError | async\"\n />\n </label>\n\n <tui-notification\n appearance=\"info\"\n size=\"m\"\n >\n \u041E\u0431\u0440\u0430\u0431\u043E\u0442\u043A\u0430 \u0444\u0430\u0439\u043B\u0430 \u0432\u044B\u043F\u043E\u043B\u043D\u044F\u0435\u0442\u0441\u044F \u0432 \u0444\u043E\u043D\u0435: \u043F\u043E\u0437\u0438\u0446\u0438\u0438 \u0438 \u0446\u0435\u043D\u044B \u043F\u043E\u044F\u0432\u044F\u0442\u0441\u044F \u0432 \u0447\u0435\u0440\u043D\u043E\u0432\u0438\u043A\u0435 \u0447\u0435\u0440\u0435\u0437 \u043D\u0435\u043A\u043E\u0442\u043E\u0440\u043E\u0435 \u0432\u0440\u0435\u043C\u044F.\n </tui-notification>\n\n <div class=\"flex flex-wrap gap-2\">\n <button\n tuiButton\n type=\"submit\"\n iconStart=\"@tui.sc.send\"\n [loading]=\"submitting()\"\n >\n \u0421\u043E\u0437\u0434\u0430\u0442\u044C \u0437\u0430\u044F\u0432\u043A\u0443\n </button>\n <button\n tuiButton\n type=\"button\"\n appearance=\"secondary\"\n (click)=\"context.$implicit.complete()\"\n >\n \u041E\u0442\u043C\u0435\u043D\u0430\n </button>\n </div>\n</form>\n", dependencies: [{ kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1$1.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i1$1.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { 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: "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: "component", type: i2$1.TuiFile, selector: "tui-file,a[tuiFile],button[tuiFile]", inputs: ["file", "state", "size", "showDelete", "showSize", "leftContent"], outputs: ["remove"] }, { kind: "component", type: i2$1.TuiInputFiles, selector: "label[tuiInputFiles]" }, { kind: "component", type: i2$1.TuiFilesComponent, selector: "tui-files", inputs: ["max", "expanded"], outputs: ["expandedChange"] }, { kind: "directive", type: i2$1.TuiInputFilesDirective, selector: "input[tuiInputFiles]", outputs: ["reject"] }, { kind: "directive", type: TuiLabel, selector: "label[tuiLabel]" }, { kind: "component", type: TuiError, selector: "tui-error", inputs: ["error"] }, { kind: "pipe", type: TuiFieldErrorPipe, name: "tuiFieldError" }, { kind: "ngmodule", type: TuiInputModule }, { kind: "component", type: i3.TuiInputComponent, selector: "tui-input" }, { kind: "directive", type: i3.TuiInputDirective, selector: "tui-input" }, { kind: "ngmodule", type: TuiTextfieldControllerModule }, { kind: "directive", type: i3.TuiTextfieldLabelOutsideDirective, selector: "[tuiTextfieldLabelOutside]", inputs: ["tuiTextfieldLabelOutside"] }, { kind: "directive", type: TuiNotification, selector: "tui-notification,a[tuiNotification],button[tuiNotification]", inputs: ["appearance", "icon", "size"] }, { kind: "directive", type: TuiButton, selector: "a[tuiButton],button[tuiButton],a[tuiIconButton],button[tuiIconButton]", inputs: ["size"] }, { kind: "component", type: TuiButtonLoading, selector: "[tuiButton][loading],[tuiIconButton][loading]", inputs: ["size", "loading"] }, { kind: "pipe", type: AsyncPipe, name: "async" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
|
|
9776
|
+
}
|
|
9777
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: ScProfstroyDraftCreateDialogComponent, decorators: [{
|
|
9778
|
+
type: Component,
|
|
9779
|
+
args: [{ standalone: true, selector: 'sc-profstroy-draft-create-dialog', imports: [
|
|
9780
|
+
ReactiveFormsModule,
|
|
9781
|
+
TuiFiles,
|
|
9782
|
+
TuiLabel,
|
|
9783
|
+
TuiError,
|
|
9784
|
+
TuiFieldErrorPipe,
|
|
9785
|
+
TuiInputModule,
|
|
9786
|
+
TuiTextfieldControllerModule,
|
|
9787
|
+
TuiNotification,
|
|
9788
|
+
TuiButton,
|
|
9789
|
+
TuiButtonLoading,
|
|
9790
|
+
AsyncPipe,
|
|
9791
|
+
], changeDetection: ChangeDetectionStrategy.OnPush, template: "<form\n [formGroup]=\"form\"\n class=\"flex flex-col gap-5\"\n (ngSubmit)=\"submit()\"\n>\n <!-- \u0424\u0430\u0439\u043B. -->\n <div class=\"flex flex-col gap-1\">\n @if (!form.controls.file.value) {\n <label tuiInputFiles>\n <input\n tuiInputFiles\n formControlName=\"file\"\n [accept]=\"allowedExtensions.join(',')\"\n />\n </label>\n }\n <tui-files>\n @if (form.controls.file.value; as file) {\n <tui-file\n [file]=\"file\"\n (remove)=\"removeFile()\"\n />\n }\n </tui-files>\n <span class=\"text-body-s text-tui-text-02\">\u0424\u0430\u0439\u043B Excel, \u0432\u044B\u0433\u0440\u0443\u0436\u0435\u043D\u043D\u044B\u0439 \u0438\u0437 \u043F\u0440\u043E\u0433\u0440\u0430\u043C\u043C\u044B \u00AB\u041F\u0440\u043E\u0444\u0441\u0442\u0440\u043E\u0439\u00BB: {{ allowedExtensions.join(', ') }}</span>\n <tui-error\n formControlName=\"file\"\n [error]=\"[] | tuiFieldError | async\"\n />\n </div>\n\n <!-- \u041D\u0430\u0437\u0432\u0430\u043D\u0438\u0435 \u0437\u0430\u044F\u0432\u043A\u0438. -->\n <label tuiLabel>\n \u041D\u0430\u0437\u0432\u0430\u043D\u0438\u0435 \u0437\u0430\u044F\u0432\u043A\u0438\n <tui-input\n formControlName=\"name\"\n [tuiTextfieldLabelOutside]=\"true\"\n >\n \u041D\u0430\u043F\u0440\u0438\u043C\u0435\u0440: \u0411\u0430\u043B\u043A\u043E\u043D\u044B, \u043E\u0431\u044A\u0435\u043A\u0442 \u043D\u0430 \u041B\u0435\u043D\u0438\u043D\u0430\n </tui-input>\n <tui-error\n formControlName=\"name\"\n [error]=\"[] | tuiFieldError | async\"\n />\n </label>\n\n <tui-notification\n appearance=\"info\"\n size=\"m\"\n >\n \u041E\u0431\u0440\u0430\u0431\u043E\u0442\u043A\u0430 \u0444\u0430\u0439\u043B\u0430 \u0432\u044B\u043F\u043E\u043B\u043D\u044F\u0435\u0442\u0441\u044F \u0432 \u0444\u043E\u043D\u0435: \u043F\u043E\u0437\u0438\u0446\u0438\u0438 \u0438 \u0446\u0435\u043D\u044B \u043F\u043E\u044F\u0432\u044F\u0442\u0441\u044F \u0432 \u0447\u0435\u0440\u043D\u043E\u0432\u0438\u043A\u0435 \u0447\u0435\u0440\u0435\u0437 \u043D\u0435\u043A\u043E\u0442\u043E\u0440\u043E\u0435 \u0432\u0440\u0435\u043C\u044F.\n </tui-notification>\n\n <div class=\"flex flex-wrap gap-2\">\n <button\n tuiButton\n type=\"submit\"\n iconStart=\"@tui.sc.send\"\n [loading]=\"submitting()\"\n >\n \u0421\u043E\u0437\u0434\u0430\u0442\u044C \u0437\u0430\u044F\u0432\u043A\u0443\n </button>\n <button\n tuiButton\n type=\"button\"\n appearance=\"secondary\"\n (click)=\"context.$implicit.complete()\"\n >\n \u041E\u0442\u043C\u0435\u043D\u0430\n </button>\n </div>\n</form>\n" }]
|
|
9792
|
+
}] });
|
|
9793
|
+
|
|
9279
9794
|
/**
|
|
9280
9795
|
* Компонент страницы черновика заказа (аналог корзины для одного черновика).
|
|
9281
9796
|
*/
|
|
9282
9797
|
class ScDraftComponent {
|
|
9798
|
+
/**
|
|
9799
|
+
* Инициализирует экземпляр класса {@link ScDraftComponent}.
|
|
9800
|
+
*/
|
|
9283
9801
|
constructor() {
|
|
9284
9802
|
/**
|
|
9285
9803
|
* Сервис маршрутизации.
|
|
@@ -9293,6 +9811,14 @@ class ScDraftComponent {
|
|
|
9293
9811
|
* Сервис для работы с черновиками заказов.
|
|
9294
9812
|
*/
|
|
9295
9813
|
this.draftsService = inject(ScOrderDraftsService);
|
|
9814
|
+
/**
|
|
9815
|
+
* Интервалы обновления данных.
|
|
9816
|
+
*/
|
|
9817
|
+
this.updateInterval = inject(SC_UPDATE_INTERVAL);
|
|
9818
|
+
/**
|
|
9819
|
+
* Сервис уведомлений.
|
|
9820
|
+
*/
|
|
9821
|
+
this.alerts = inject(TuiAlertService);
|
|
9296
9822
|
/**
|
|
9297
9823
|
* Сигнал с данными текущего черновика заказа (из параметра orderId в URL).
|
|
9298
9824
|
*/
|
|
@@ -9313,6 +9839,47 @@ class ScDraftComponent {
|
|
|
9313
9839
|
* Текущий ключ маршрута.
|
|
9314
9840
|
*/
|
|
9315
9841
|
this.isDraftPage = toSignal(this.route.data.pipe(map((data) => data['routes_key'] === ScRouteKeys.draft), distinctUntilChanged()), { initialValue: false });
|
|
9842
|
+
/**
|
|
9843
|
+
* Функция группировки позиций черновика Профстрой по группам из файла.
|
|
9844
|
+
*/
|
|
9845
|
+
// eslint-disable-next-line @typescript-eslint/unbound-method
|
|
9846
|
+
this.groupByFileGroup = ScProfstroyOrderItem.getGroupTitle;
|
|
9847
|
+
/**
|
|
9848
|
+
* Признак черновика Профстрой.
|
|
9849
|
+
*/
|
|
9850
|
+
this.isProfstroy = computed(() => this.draft()?.isProfstroy === true);
|
|
9851
|
+
/**
|
|
9852
|
+
* Текущий момент для проверки срока актуализации. Обновляется по таймеру, пока открыт черновик Профстрой.
|
|
9853
|
+
*/
|
|
9854
|
+
this.now = signal(new Date());
|
|
9855
|
+
/**
|
|
9856
|
+
* Признак выполнения действия над черновиком Профстрой.
|
|
9857
|
+
*/
|
|
9858
|
+
this.busy = signal(false);
|
|
9859
|
+
/**
|
|
9860
|
+
* Признак, что можно менять состав черновика Профстрой.
|
|
9861
|
+
*/
|
|
9862
|
+
this.canEditProfstroy = computed(() => this.isDraftPage() && !this.busy() && this.draft()?.actualization?.isProcessing === false);
|
|
9863
|
+
/**
|
|
9864
|
+
* Позиции, выбранные для заказа из черновика Профстрой.
|
|
9865
|
+
*/
|
|
9866
|
+
this.selectedProfstroyItems = computed(() => {
|
|
9867
|
+
const ids = new Set(this.selectedItemsIds());
|
|
9868
|
+
return this.draft()?.products.filter((item) => item.isOrderable && ids.has(item.id)) ?? [];
|
|
9869
|
+
});
|
|
9870
|
+
/**
|
|
9871
|
+
* Причина, по которой нельзя оформить заказ из черновика Профстрой, или пустая строка.
|
|
9872
|
+
*/
|
|
9873
|
+
this.profstroyOrderBlockReason = computed(() => {
|
|
9874
|
+
const draft = this.draft();
|
|
9875
|
+
if (!draft?.actualization?.isOrderAllowedAt(this.now())) {
|
|
9876
|
+
return 'Оформление доступно после успешной актуализации.';
|
|
9877
|
+
}
|
|
9878
|
+
if (!draft.products.some((item) => item.isOrderable)) {
|
|
9879
|
+
return 'В заявке нет позиций, которые могут попасть в заказ.';
|
|
9880
|
+
}
|
|
9881
|
+
return this.selectedProfstroyItems().length === 0 ? 'Выберите позиции для заказа.' : '';
|
|
9882
|
+
});
|
|
9316
9883
|
/**
|
|
9317
9884
|
* Ссылка для автоматического управления уничтожением зависимостей.
|
|
9318
9885
|
*/
|
|
@@ -9321,6 +9888,8 @@ class ScDraftComponent {
|
|
|
9321
9888
|
* Сервис установки SEO-данных приложения.
|
|
9322
9889
|
*/
|
|
9323
9890
|
this.seoService = inject(ScSeoService);
|
|
9891
|
+
this.watchProfstroyExpiration();
|
|
9892
|
+
this.watchProfstroyProcessing();
|
|
9324
9893
|
}
|
|
9325
9894
|
/** @inheritDoc */
|
|
9326
9895
|
ngOnInit() {
|
|
@@ -9343,6 +9912,27 @@ class ScDraftComponent {
|
|
|
9343
9912
|
const ids = this.selectedItemsIds().filter((id) => direction.items.some((item) => item.id === id));
|
|
9344
9913
|
this.router.navigate(['orders', 'new', this.draft()?.id, direction.direction.id, 'draft'], { queryParams: { itemsIds: ids } }).catch(noop);
|
|
9345
9914
|
}
|
|
9915
|
+
/**
|
|
9916
|
+
* Переход к оформлению заказа из черновика Профстрой по выбранным позициям.
|
|
9917
|
+
*/
|
|
9918
|
+
goToNewProfstroyOrder() {
|
|
9919
|
+
const ids = this.selectedProfstroyItems().map((item) => item.id);
|
|
9920
|
+
this.router.navigate(['orders', 'new', this.draft()?.id, 'profstroy'], { queryParams: { itemsIds: ids } }).catch(noop);
|
|
9921
|
+
}
|
|
9922
|
+
/**
|
|
9923
|
+
* Запускает актуализацию черновика Профстрой.
|
|
9924
|
+
*/
|
|
9925
|
+
actualizeProfstroy() {
|
|
9926
|
+
this.runProfstroyAction((draftId) => this.draftsService.actualizeProfstroy$(draftId));
|
|
9927
|
+
}
|
|
9928
|
+
/**
|
|
9929
|
+
* Запускает пересборку черновика Профстрой из файла после подтверждения.
|
|
9930
|
+
*/
|
|
9931
|
+
reloadProfstroy() {
|
|
9932
|
+
this.confirm$('Собрать заявку заново?', 'Заявка будет собрана заново из загруженного файла. Изменённое количество и удалённые позиции будут потеряны. Продолжить?', 'Да, собрать заново').subscribe(() => {
|
|
9933
|
+
this.runProfstroyAction((draftId) => this.draftsService.reloadProfstroy$(draftId));
|
|
9934
|
+
});
|
|
9935
|
+
}
|
|
9346
9936
|
/**
|
|
9347
9937
|
* Удаляет черновик и перенаправляет к списку черновиков.
|
|
9348
9938
|
*/
|
|
@@ -9366,23 +9956,107 @@ class ScDraftComponent {
|
|
|
9366
9956
|
this.router.navigate(['/drafts']).catch(noop);
|
|
9367
9957
|
});
|
|
9368
9958
|
}
|
|
9959
|
+
/**
|
|
9960
|
+
* Выполняет действие над черновиком Профстрой. Пока действие выполняется, остальные заблокированы.
|
|
9961
|
+
* При ошибке показывает текст сервера и перезапрашивает черновик, так как его состояние могло смениться.
|
|
9962
|
+
*
|
|
9963
|
+
* @param action Функция, возвращающая запрос действия по идентификатору черновика.
|
|
9964
|
+
*/
|
|
9965
|
+
runProfstroyAction(action) {
|
|
9966
|
+
const draftId = this.draft()?.id;
|
|
9967
|
+
if (draftId === undefined || this.busy()) {
|
|
9968
|
+
return;
|
|
9969
|
+
}
|
|
9970
|
+
this.busy.set(true);
|
|
9971
|
+
action(draftId)
|
|
9972
|
+
.pipe(catchError((error) => {
|
|
9973
|
+
this.showForbiddenError(error);
|
|
9974
|
+
return this.draftsService.fetch$(draftId).pipe(catchError(() => EMPTY));
|
|
9975
|
+
}), finalize(() => {
|
|
9976
|
+
this.busy.set(false);
|
|
9977
|
+
}), takeUntilDestroyed(this.destroyRef))
|
|
9978
|
+
.subscribe((draft) => {
|
|
9979
|
+
this.setDraftIfCurrent(draft);
|
|
9980
|
+
});
|
|
9981
|
+
}
|
|
9982
|
+
/**
|
|
9983
|
+
* Показывает текст ошибки отказа в доступе. Остальные ошибки показывает перехватчик приложения.
|
|
9984
|
+
*
|
|
9985
|
+
* @param error Ошибка запроса.
|
|
9986
|
+
*/
|
|
9987
|
+
showForbiddenError(error) {
|
|
9988
|
+
if (error instanceof HttpErrorResponse && error.status === HttpStatusCode.Forbidden) {
|
|
9989
|
+
const { message } = (error.error ?? {});
|
|
9990
|
+
this.alerts.open(message ?? 'Действие недоступно.', { appearance: 'negative' }).subscribe();
|
|
9991
|
+
}
|
|
9992
|
+
}
|
|
9993
|
+
/**
|
|
9994
|
+
* Открывает подтверждение и возвращает {@link Observable}, который выдаёт значение только при согласии.
|
|
9995
|
+
*
|
|
9996
|
+
* @param label Заголовок.
|
|
9997
|
+
* @param content Текст подтверждения.
|
|
9998
|
+
* @param yes Текст кнопки согласия.
|
|
9999
|
+
*/
|
|
10000
|
+
confirm$(label, content, yes) {
|
|
10001
|
+
return this.dialogService.open(TUI_CONFIRM, { label, data: { content, yes, no: 'Отмена' } }).pipe(filter(Boolean), takeUntilDestroyed(this.destroyRef));
|
|
10002
|
+
}
|
|
10003
|
+
/**
|
|
10004
|
+
* Обновляет черновик, если пришли данные того же черновика, который открыт сейчас.
|
|
10005
|
+
*
|
|
10006
|
+
* @param draft Полученные данные черновика.
|
|
10007
|
+
*/
|
|
10008
|
+
setDraftIfCurrent(draft) {
|
|
10009
|
+
if (this.draft()?.id === draft.id) {
|
|
10010
|
+
this.draft.set(draft);
|
|
10011
|
+
}
|
|
10012
|
+
}
|
|
10013
|
+
/**
|
|
10014
|
+
* Обновляет текущий момент по таймеру, пока открыт черновик Профстрой, чтобы истечение срока актуализации отражалось без перезагрузки.
|
|
10015
|
+
*/
|
|
10016
|
+
watchProfstroyExpiration() {
|
|
10017
|
+
toObservable(this.isProfstroy)
|
|
10018
|
+
.pipe(distinctUntilChanged(), switchMap((isProfstroy) => (isProfstroy ? timer(0, this.updateInterval.orderDraftExpiration) : EMPTY)), takeUntilDestroyed(this.destroyRef))
|
|
10019
|
+
.subscribe(() => {
|
|
10020
|
+
this.now.set(new Date());
|
|
10021
|
+
});
|
|
10022
|
+
}
|
|
10023
|
+
/**
|
|
10024
|
+
* Пока черновик Профстрой в обработке, опрашивает его состояние лёгким запросом списка и после смены статуса перезапрашивает черновик целиком.
|
|
10025
|
+
*/
|
|
10026
|
+
watchProfstroyProcessing() {
|
|
10027
|
+
toObservable(this.draft)
|
|
10028
|
+
.pipe(map((draft) => (draft?.isProfstroy && draft.actualization?.isProcessing ? draft.id : null)), distinctUntilChanged(), switchMap((draftId) => draftId === null
|
|
10029
|
+
? EMPTY
|
|
10030
|
+
: this.draftsService.watchShortList$([draftId]).pipe(map((drafts) => drafts.find((item) => item.id === draftId)), filter((short) => short !== undefined && short.actualization?.status !== ScOrderDraftActualizationStatus.processing), take(1), switchMap(() => this.draftsService.fetch$(draftId).pipe(catchError(() => EMPTY))))), takeUntilDestroyed(this.destroyRef))
|
|
10031
|
+
.subscribe((draft) => {
|
|
10032
|
+
this.setDraftIfCurrent(draft);
|
|
10033
|
+
});
|
|
10034
|
+
}
|
|
9369
10035
|
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: ScDraftComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
9370
10036
|
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.2.14", type: ScDraftComponent, isStandalone: true, selector: "sc-draft", inputs: { draft: { classPropertyName: "draft", publicName: "draft", isSignal: true, isRequired: false, transformFunction: null }, selectedItemsIds: { classPropertyName: "selectedItemsIds", publicName: "selectedItemsIds", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { draft: "draftChange", selectedItemsIds: "selectedItemsIdsChange", deleteEvent: "deleteEvent" }, providers: [
|
|
9371
10037
|
{
|
|
9372
10038
|
provide: SC_ORDER_LOADER,
|
|
9373
10039
|
useExisting: ScOrderDraftsService,
|
|
9374
10040
|
},
|
|
9375
|
-
], ngImport: i0, template: "@let items = draft()?.products;\n\n@if (items) {\n
|
|
10041
|
+
], ngImport: i0, template: "@let currentDraft = draft();\n\n@if (currentDraft && currentDraft.isProfstroy) {\n <div class=\"flex flex-col gap-5\">\n <sc-profstroy-draft-badges\n [actualization]=\"currentDraft.actualization\"\n [now]=\"now()\"\n />\n\n <sc-profstroy-actualization-panel\n [draft]=\"currentDraft\"\n [now]=\"now()\"\n [busy]=\"busy() || !isDraftPage()\"\n (actualize)=\"actualizeProfstroy()\"\n (reload)=\"reloadProfstroy()\"\n />\n\n @if (currentDraft.products.length) {\n <sc-order-items-list\n scOrder\n [orderId]=\"currentDraft.id\"\n [items]=\"currentDraft.products\"\n [groupBy]=\"groupByFileGroup\"\n [markUnavailable]=\"true\"\n [useLinePrice]=\"true\"\n [editable]=\"canEditProfstroy()\"\n [selectable]=\"true\"\n (selectedItemsIdsChange)=\"selectedItemsIds.set($event)\"\n />\n } @else {\n <p class=\"text-base font-bold\">{{ currentDraft.actualization?.isProcessing ? '\u041F\u043E\u0437\u0438\u0446\u0438\u0438 \u043F\u043E\u044F\u0432\u044F\u0442\u0441\u044F \u043F\u043E\u0441\u043B\u0435 \u043E\u0431\u0440\u0430\u0431\u043E\u0442\u043A\u0438 \u0444\u0430\u0439\u043B\u0430.' : '\u0412 \u0437\u0430\u044F\u0432\u043A\u0435 \u043D\u0435\u0442 \u043F\u043E\u0437\u0438\u0446\u0438\u0439.' }}</p>\n }\n\n <div class=\"flex flex-col items-center gap-x-2.5 gap-y-4 sm:flex-row sm:flex-wrap-reverse sm:items-start\">\n <button\n tuiButton\n appearance=\"secondary\"\n iconStart=\"@tui.trash-2\"\n [disabled]=\"busy()\"\n (click)=\"clearDraft()\"\n >\n \u0423\u0434\u0430\u043B\u0438\u0442\u044C \u0447\u0435\u0440\u043D\u043E\u0432\u0438\u043A\n </button>\n\n <div class=\"flex flex-col items-center gap-1 sm:ml-auto sm:items-end\">\n <button\n tuiButton\n type=\"button\"\n iconStart=\"@tui.shopping-cart\"\n [disabled]=\"busy() || !!profstroyOrderBlockReason()\"\n (click)=\"goToNewProfstroyOrder()\"\n >\n \u041E\u0444\u043E\u0440\u043C\u0438\u0442\u044C \u0437\u0430\u043A\u0430\u0437\n </button>\n @if (profstroyOrderBlockReason(); as reason) {\n <span class=\"text-body-s text-tui-text-02\">{{ reason }}</span>\n }\n </div>\n </div>\n </div>\n} @else {\n @let items = draft()?.products;\n\n @if (items) {\n <div class=\"flex flex-col gap-12\">\n <div class=\"flex flex-col gap-5\">\n @if (items.length) {\n <sc-order-items-list-by-directions\n scOrder\n [orderId]=\"draft()?.id\"\n [items]=\"items\"\n [editable]=\"isDraftPage()\"\n [selectable]=\"true\"\n (selectedItemsIdsChange)=\"selectedItemsIds.set($event)\"\n (continueClick)=\"goToNewOrder($event)\"\n >\n <div\n footerActions\n class=\"flex gap-2\"\n >\n <button\n tuiButton\n appearance=\"secondary\"\n (click)=\"clearDraft()\"\n iconStart=\"@tui.trash-2\"\n >\n \u0423\u0434\u0430\u043B\u0438\u0442\u044C \u0447\u0435\u0440\u043D\u043E\u0432\u0438\u043A\n </button>\n </div>\n </sc-order-items-list-by-directions>\n } @else {\n <p class=\"text-base font-bold\">\u0427\u0435\u0440\u043D\u043E\u0432\u0438\u043A \u043F\u0443\u0441\u0442.</p>\n <div\n footerActions\n class=\"flex gap-2\"\n >\n <button\n tuiButton\n appearance=\"secondary\"\n (click)=\"clearDraft()\"\n iconStart=\"@tui.trash-2\"\n >\n \u0423\u0434\u0430\u043B\u0438\u0442\u044C \u0447\u0435\u0440\u043D\u043E\u0432\u0438\u043A\n </button>\n </div>\n }\n </div>\n </div>\n } @else {\n <div class=\"flex flex-col gap-12\">\n <div class=\"flex flex-col gap-5\">\n @for (item of [1, 2, 3, 4]; track item) {\n <div class=\"tui-skeleton flex h-[8.25rem] w-full overflow-hidden rounded-xl\"></div>\n }\n <div class=\"flex gap-2\">\n <div class=\"tui-skeleton h-10 w-40 rounded-md\"></div>\n <div class=\"tui-skeleton h-10 w-36 rounded-md\"></div>\n </div>\n </div>\n </div>\n }\n}\n", dependencies: [{ kind: "component", type: ScOrderItemsListByDirectionsComponent, selector: "sc-order-items-list-by-directions", inputs: ["items", "selectable", "editable", "useLinePrice", "showContinueButton", "continueButtonText", "selectedItemsIds"], outputs: ["continueClick", "selectedItemsIdsChange"] }, { kind: "directive", type: ScOrderAccessorDirective, selector: "[scOrder]", inputs: ["orderId"] }, { kind: "component", type: ScProfstroyActualizationPanelComponent, selector: "sc-profstroy-actualization-panel", inputs: ["draft", "now", "busy"], outputs: ["actualize", "reload"] }, { kind: "component", type: ScProfstroyDraftBadgesComponent, selector: "sc-profstroy-draft-badges", inputs: ["actualization", "now"] }, { kind: "component", type: ScOrderItemsListComponent, selector: "sc-order-items-list", inputs: ["selectable", "editable", "groupBy", "markUnavailable", "useLinePrice", "items"], outputs: ["selectedItemsIdsChange"] }, { kind: "directive", type: TuiButton, selector: "a[tuiButton],button[tuiButton],a[tuiIconButton],button[tuiIconButton]", inputs: ["size"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
|
|
9376
10042
|
}
|
|
9377
10043
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: ScDraftComponent, decorators: [{
|
|
9378
10044
|
type: Component,
|
|
9379
|
-
args: [{ standalone: true, selector: 'sc-draft', imports: [
|
|
10045
|
+
args: [{ standalone: true, selector: 'sc-draft', imports: [
|
|
10046
|
+
ScOrderItemsListByDirectionsComponent,
|
|
10047
|
+
ScOrderAccessorDirective,
|
|
10048
|
+
ScProfstroyActualizationPanelComponent,
|
|
10049
|
+
ScProfstroyDraftBadgesComponent,
|
|
10050
|
+
ScOrderItemsListComponent,
|
|
10051
|
+
TuiButton,
|
|
10052
|
+
TuiIcons,
|
|
10053
|
+
], providers: [
|
|
9380
10054
|
{
|
|
9381
10055
|
provide: SC_ORDER_LOADER,
|
|
9382
10056
|
useExisting: ScOrderDraftsService,
|
|
9383
10057
|
},
|
|
9384
|
-
], changeDetection: ChangeDetectionStrategy.OnPush, template: "@let items = draft()?.products;\n\n@if (items) {\n
|
|
9385
|
-
}] });
|
|
10058
|
+
], changeDetection: ChangeDetectionStrategy.OnPush, template: "@let currentDraft = draft();\n\n@if (currentDraft && currentDraft.isProfstroy) {\n <div class=\"flex flex-col gap-5\">\n <sc-profstroy-draft-badges\n [actualization]=\"currentDraft.actualization\"\n [now]=\"now()\"\n />\n\n <sc-profstroy-actualization-panel\n [draft]=\"currentDraft\"\n [now]=\"now()\"\n [busy]=\"busy() || !isDraftPage()\"\n (actualize)=\"actualizeProfstroy()\"\n (reload)=\"reloadProfstroy()\"\n />\n\n @if (currentDraft.products.length) {\n <sc-order-items-list\n scOrder\n [orderId]=\"currentDraft.id\"\n [items]=\"currentDraft.products\"\n [groupBy]=\"groupByFileGroup\"\n [markUnavailable]=\"true\"\n [useLinePrice]=\"true\"\n [editable]=\"canEditProfstroy()\"\n [selectable]=\"true\"\n (selectedItemsIdsChange)=\"selectedItemsIds.set($event)\"\n />\n } @else {\n <p class=\"text-base font-bold\">{{ currentDraft.actualization?.isProcessing ? '\u041F\u043E\u0437\u0438\u0446\u0438\u0438 \u043F\u043E\u044F\u0432\u044F\u0442\u0441\u044F \u043F\u043E\u0441\u043B\u0435 \u043E\u0431\u0440\u0430\u0431\u043E\u0442\u043A\u0438 \u0444\u0430\u0439\u043B\u0430.' : '\u0412 \u0437\u0430\u044F\u0432\u043A\u0435 \u043D\u0435\u0442 \u043F\u043E\u0437\u0438\u0446\u0438\u0439.' }}</p>\n }\n\n <div class=\"flex flex-col items-center gap-x-2.5 gap-y-4 sm:flex-row sm:flex-wrap-reverse sm:items-start\">\n <button\n tuiButton\n appearance=\"secondary\"\n iconStart=\"@tui.trash-2\"\n [disabled]=\"busy()\"\n (click)=\"clearDraft()\"\n >\n \u0423\u0434\u0430\u043B\u0438\u0442\u044C \u0447\u0435\u0440\u043D\u043E\u0432\u0438\u043A\n </button>\n\n <div class=\"flex flex-col items-center gap-1 sm:ml-auto sm:items-end\">\n <button\n tuiButton\n type=\"button\"\n iconStart=\"@tui.shopping-cart\"\n [disabled]=\"busy() || !!profstroyOrderBlockReason()\"\n (click)=\"goToNewProfstroyOrder()\"\n >\n \u041E\u0444\u043E\u0440\u043C\u0438\u0442\u044C \u0437\u0430\u043A\u0430\u0437\n </button>\n @if (profstroyOrderBlockReason(); as reason) {\n <span class=\"text-body-s text-tui-text-02\">{{ reason }}</span>\n }\n </div>\n </div>\n </div>\n} @else {\n @let items = draft()?.products;\n\n @if (items) {\n <div class=\"flex flex-col gap-12\">\n <div class=\"flex flex-col gap-5\">\n @if (items.length) {\n <sc-order-items-list-by-directions\n scOrder\n [orderId]=\"draft()?.id\"\n [items]=\"items\"\n [editable]=\"isDraftPage()\"\n [selectable]=\"true\"\n (selectedItemsIdsChange)=\"selectedItemsIds.set($event)\"\n (continueClick)=\"goToNewOrder($event)\"\n >\n <div\n footerActions\n class=\"flex gap-2\"\n >\n <button\n tuiButton\n appearance=\"secondary\"\n (click)=\"clearDraft()\"\n iconStart=\"@tui.trash-2\"\n >\n \u0423\u0434\u0430\u043B\u0438\u0442\u044C \u0447\u0435\u0440\u043D\u043E\u0432\u0438\u043A\n </button>\n </div>\n </sc-order-items-list-by-directions>\n } @else {\n <p class=\"text-base font-bold\">\u0427\u0435\u0440\u043D\u043E\u0432\u0438\u043A \u043F\u0443\u0441\u0442.</p>\n <div\n footerActions\n class=\"flex gap-2\"\n >\n <button\n tuiButton\n appearance=\"secondary\"\n (click)=\"clearDraft()\"\n iconStart=\"@tui.trash-2\"\n >\n \u0423\u0434\u0430\u043B\u0438\u0442\u044C \u0447\u0435\u0440\u043D\u043E\u0432\u0438\u043A\n </button>\n </div>\n }\n </div>\n </div>\n } @else {\n <div class=\"flex flex-col gap-12\">\n <div class=\"flex flex-col gap-5\">\n @for (item of [1, 2, 3, 4]; track item) {\n <div class=\"tui-skeleton flex h-[8.25rem] w-full overflow-hidden rounded-xl\"></div>\n }\n <div class=\"flex gap-2\">\n <div class=\"tui-skeleton h-10 w-40 rounded-md\"></div>\n <div class=\"tui-skeleton h-10 w-36 rounded-md\"></div>\n </div>\n </div>\n </div>\n }\n}\n" }]
|
|
10059
|
+
}], ctorParameters: () => [] });
|
|
9386
10060
|
|
|
9387
10061
|
/**
|
|
9388
10062
|
* Компонент статуса оплаты заказа.
|
|
@@ -11491,5 +12165,5 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImpo
|
|
|
11491
12165
|
* Generated bundle index. Do not edit.
|
|
11492
12166
|
*/
|
|
11493
12167
|
|
|
11494
|
-
export { AbstractScPriceCard, AuthMethod, CURRENT_COUNTRY_ID, CostWithDiscountComponent, FilesAndDocumentsComponent, FilesAndDocumentsModule, FinishDateTimeTransformerDirective, IDLE_ITEM_STATE, 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_DATE_FORMATTER, SC_DEBOUNCE_TIME_DEFAULT, SC_DIALOG_SERVICE_TOKEN, SC_ERROR_CHANGE_HANDLER, SC_FAQ_GROUP_QUERY_PARAM, SC_FAQ_QUESTION_ANCHOR_PREFIX, SC_HELP_NOTIFICATION_CLOSE, SC_HELP_NOTIFICATION_LIMIT, SC_HIDDEN_PRINT_ELEMENTS, SC_MANAGER_QR_HANDLER, SC_NOTIFY_WHEN_IN_STOCK_REQUIRED_FIELDS, SC_ORDER_FORM_CONFIG, SC_ORDER_OPTIONS, 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, ScCatalogFilterCollapsibleComponent, ScCatalogFiltersComponent, ScCatalogModule, ScCategoryCardComponent, ScContactsAccordionComponent, ScContactsModule, ScContragentsAccordionComponent, ScContragentsAccordionItemComponent, ScContragentsModule, ScDeliveryAddressAccordionComponent, ScDeliveryAddressAccordionItemComponent, ScDeliveryAddressModule, ScDownloadPriceListComponent, ScDraftComponent, ScEmailLinkDirective, ScErrorBlockStatusComponent, ScErrorHandlerComponent, ScFavoriteButtonComponent, ScFeedbackFormComponent, ScFocusFirstInvalidFieldDirective, ScFormFieldsModule, ScFormatDatePipe, ScFrequentlyAskedQuestionsComponent, ScFrequentlyAskedQuestionsGroupSelectorComponent, ScFrequentlyAskedQuestionsWithGroupsComponent, ScGratitudeComponent, ScHelpNotificationService, ScHoverImageCarouselComponent, ScInputQuantityComponent, ScLinks, ScManagerCardComponent, ScManagerCardPushComponent, ScNewContactFormComponent, ScNewContragentBankAccountsFormComponent, ScNewContragentFormComponent, ScNewsCardComponent, ScNewsCardSkeletonComponent, ScNewsListComponent, ScNewsModule, ScNextInputFocusDirective, ScNextInputFocusModule, ScNoindexDirective, ScNoindexWrapperComponent, ScNotifyWhenInStockDialogComponent, ScOrderAccessorDirective, ScOrderDirectionItemsComponent, ScOrderFormComponent, ScOrderItemComponent, ScOrderItemsByDirection, ScOrderItemsListByDirectionsComponent, ScOrderItemsListByStockComponent, ScOrderItemsListComponent, ScOrderModule, ScPaginationLinksComponent, ScPaymentStatusComponent, ScPersonalDataProcessingPolicyComponent, ScPhoneFormatPipe, ScPreviewSampleComponent, ScPreviewSampleModule, ScPreviewSamplesMosquitoComponent, ScPriceCardComponent, ScPriceCardInlineComponent, ScPriceHistoryComponent, ScPriceListPaginationComponent, ScPriceWarehouseStockComponent, ScPrintDirective, ScPrintService, ScPrivacyPolicyComponent, ScProductInAllWarehousesPipe, ScProfileAccordionsContentComponent, ScProfileModule, ScPublicOfferComponent, ScQRCodeDialogComponent, ScQRCodeModule, ScResetUserPasswordComponent, ScResourcePreviewComponent, ScSandwichComponent, ScSandwichM2Component, ScSandwichM2SkeletonComponent, ScSandwichSkeletonComponent, ScSelectOnFocusinDirective, ScSeoTagsComponent, ScShareButtonComponent, ScShareDialogComponent, ScShareMessengersLinksComponent, ScShareService, ScSignInFormByEmailComponent, ScSignInFormByPhoneComponent, ScSignInFormComponent, ScSignUpFormComponent, ScSimpleSignUpFormComponent, ScSuggestionFieldComponent, ScTelLinkDirective, ScTerminalLinkDirective, ScUpdateUserInfoDialogComponent, ScUserManagersComponent, ScUserModule, ScUserPhoneApproveDialogComponent, ScVerificationModule, ScVerificationPhoneCheckFormComponent, TreeDirective, TreeIconService, TreeLoaderService, TreeTopDirective, cleanupRecaptchaArtifacts, phoneValidator, scAtLeastOneRequiredValidator, scBicValidator, scClientUiIconsName, scCorrespondentAccountValidator, scGetCurrentRoute, scGetFaqGroupQueryParams, scGetFaqQuestionAnchor, scGetFaqQuestionIdFromAnchor, scPasswordConfirmMatchingValidator, stepValidator, tuiDateValueTransformerDefaultProvider };
|
|
12168
|
+
export { AbstractScPriceCard, AuthMethod, CURRENT_COUNTRY_ID, CostWithDiscountComponent, FilesAndDocumentsComponent, FilesAndDocumentsModule, FinishDateTimeTransformerDirective, IDLE_ITEM_STATE, 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_DATE_FORMATTER, SC_DEBOUNCE_TIME_DEFAULT, SC_DIALOG_SERVICE_TOKEN, SC_ERROR_CHANGE_HANDLER, SC_FAQ_GROUP_QUERY_PARAM, SC_FAQ_QUESTION_ANCHOR_PREFIX, SC_HELP_NOTIFICATION_CLOSE, SC_HELP_NOTIFICATION_LIMIT, SC_HIDDEN_PRINT_ELEMENTS, SC_MANAGER_QR_HANDLER, SC_NOTIFY_WHEN_IN_STOCK_REQUIRED_FIELDS, SC_ORDER_FORM_CONFIG, SC_ORDER_OPTIONS, 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, ScCatalogFilterCollapsibleComponent, ScCatalogFiltersComponent, ScCatalogModule, ScCategoryCardComponent, ScContactsAccordionComponent, ScContactsModule, ScContragentsAccordionComponent, ScContragentsAccordionItemComponent, ScContragentsModule, ScDeliveryAddressAccordionComponent, ScDeliveryAddressAccordionItemComponent, ScDeliveryAddressModule, ScDownloadPriceListComponent, ScDraftComponent, ScDraftListHelper, ScEmailLinkDirective, ScErrorBlockStatusComponent, ScErrorHandlerComponent, ScFavoriteButtonComponent, ScFeedbackFormComponent, ScFocusFirstInvalidFieldDirective, ScFormFieldsModule, ScFormatDatePipe, ScFrequentlyAskedQuestionsComponent, ScFrequentlyAskedQuestionsGroupSelectorComponent, ScFrequentlyAskedQuestionsWithGroupsComponent, ScGratitudeComponent, ScHelpNotificationService, ScHoverImageCarouselComponent, ScInputQuantityComponent, ScLinks, ScManagerCardComponent, ScManagerCardPushComponent, ScNewContactFormComponent, ScNewContragentBankAccountsFormComponent, ScNewContragentFormComponent, ScNewsCardComponent, ScNewsCardSkeletonComponent, ScNewsListComponent, ScNewsModule, ScNextInputFocusDirective, ScNextInputFocusModule, ScNoindexDirective, ScNoindexWrapperComponent, ScNotifyWhenInStockDialogComponent, ScOrderAccessorDirective, ScOrderDirectionItemsComponent, ScOrderFormComponent, ScOrderItemComponent, ScOrderItemsByDirection, ScOrderItemsListByDirectionsComponent, ScOrderItemsListByStockComponent, ScOrderItemsListComponent, ScOrderModule, ScPaginationLinksComponent, ScPaymentStatusComponent, ScPersonalDataProcessingPolicyComponent, ScPhoneFormatPipe, ScPreviewSampleComponent, ScPreviewSampleModule, ScPreviewSamplesMosquitoComponent, ScPriceCardComponent, ScPriceCardInlineComponent, ScPriceHistoryComponent, ScPriceListPaginationComponent, ScPriceWarehouseStockComponent, ScPrintDirective, ScPrintService, ScPrivacyPolicyComponent, ScProductInAllWarehousesPipe, ScProfileAccordionsContentComponent, ScProfileModule, ScProfstroyActualizationPanelComponent, ScProfstroyBadgeComponent, ScProfstroyDraftBadgesComponent, ScProfstroyDraftCreateDialogComponent, ScProfstroyDraftHelper, ScProfstroyDraftState, ScPublicOfferComponent, ScQRCodeDialogComponent, ScQRCodeModule, ScResetUserPasswordComponent, ScResourcePreviewComponent, ScSandwichComponent, ScSandwichM2Component, ScSandwichM2SkeletonComponent, ScSandwichSkeletonComponent, ScSelectOnFocusinDirective, ScSeoTagsComponent, ScShareButtonComponent, ScShareDialogComponent, ScShareMessengersLinksComponent, ScShareService, ScSignInFormByEmailComponent, ScSignInFormByPhoneComponent, ScSignInFormComponent, ScSignUpFormComponent, ScSimpleSignUpFormComponent, ScSuggestionFieldComponent, ScTelLinkDirective, ScTerminalLinkDirective, ScUpdateUserInfoDialogComponent, ScUserManagersComponent, ScUserModule, ScUserPhoneApproveDialogComponent, ScVerificationModule, ScVerificationPhoneCheckFormComponent, TreeDirective, TreeIconService, TreeLoaderService, TreeTopDirective, cleanupRecaptchaArtifacts, phoneValidator, scAtLeastOneRequiredValidator, scBicValidator, scClientUiIconsName, scCorrespondentAccountValidator, scGetCurrentRoute, scGetFaqGroupQueryParams, scGetFaqQuestionAnchor, scGetFaqQuestionIdFromAnchor, scPasswordConfirmMatchingValidator, stepValidator, tuiDateValueTransformerDefaultProvider };
|
|
11495
12169
|
//# sourceMappingURL=snabcentr-client-ui.mjs.map
|