@snabcentr/client-ui 3.30.0 → 3.31.1
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/cart/add-or-editing-cart-item-dialog/add-or-editing-cart-item-form/sc-add-or-editing-cart-item-form.component.d.ts +102 -0
- package/cart/add-or-editing-cart-item-dialog/index.d.ts +2 -0
- package/cart/add-or-editing-cart-item-dialog/sc-add-or-editing-cart-item-dialog.component.d.ts +48 -0
- package/cart/index.d.ts +1 -0
- package/directives/index.d.ts +1 -0
- package/directives/select-on-focusin/sc-select-on-focusin.directive.d.ts +14 -0
- package/esm2022/cart/add-or-editing-cart-item-dialog/add-or-editing-cart-item-form/sc-add-or-editing-cart-item-form.component.mjs +230 -0
- package/esm2022/cart/add-or-editing-cart-item-dialog/index.mjs +3 -0
- package/esm2022/cart/add-or-editing-cart-item-dialog/sc-add-or-editing-cart-item-dialog.component.mjs +74 -0
- package/esm2022/cart/index.mjs +2 -1
- package/esm2022/directives/index.mjs +2 -1
- package/esm2022/directives/select-on-focusin/sc-select-on-focusin.directive.mjs +31 -0
- package/fesm2022/snabcentr-client-ui.mjs +309 -7
- package/fesm2022/snabcentr-client-ui.mjs.map +1 -1
- package/package.json +1 -1
- package/release_notes.tmp +2 -2
- package/styles/tailwind/tailwind.scss +5 -0
@@ -4,4 +4,5 @@ export * from './abstract-price-card/abstract-sc-price-card.directive';
|
|
4
4
|
export * from './terminal-link/sc-terminal-link.directive';
|
5
5
|
export * from './links';
|
6
6
|
export * from './sc-date-value-transformer.directive';
|
7
|
-
|
7
|
+
export * from './select-on-focusin/sc-select-on-focusin.directive';
|
8
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi9wcm9qZWN0cy9jbGllbnQtdWkvZGlyZWN0aXZlcy9pbmRleC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxjQUFjLGtEQUFrRCxDQUFDO0FBQ2pFLGNBQWMsK0NBQStDLENBQUM7QUFDOUQsY0FBYyx3REFBd0QsQ0FBQztBQUN2RSxjQUFjLDRDQUE0QyxDQUFDO0FBQzNELGNBQWMsU0FBUyxDQUFDO0FBQ3hCLGNBQWMsdUNBQXVDLENBQUM7QUFDdEQsY0FBYyxvREFBb0QsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbImV4cG9ydCAqIGZyb20gJy4vbmV4dC1pbnB1dC1mb2N1cy9zYy1uZXh0LWlucHV0LWZvY3VzLmRpcmVjdGl2ZSc7XG5leHBvcnQgKiBmcm9tICcuL25leHQtaW5wdXQtZm9jdXMvc2MtbmV4dC1pbnB1dC1mb2N1cy5tb2R1bGUnO1xuZXhwb3J0ICogZnJvbSAnLi9hYnN0cmFjdC1wcmljZS1jYXJkL2Fic3RyYWN0LXNjLXByaWNlLWNhcmQuZGlyZWN0aXZlJztcbmV4cG9ydCAqIGZyb20gJy4vdGVybWluYWwtbGluay9zYy10ZXJtaW5hbC1saW5rLmRpcmVjdGl2ZSc7XG5leHBvcnQgKiBmcm9tICcuL2xpbmtzJztcbmV4cG9ydCAqIGZyb20gJy4vc2MtZGF0ZS12YWx1ZS10cmFuc2Zvcm1lci5kaXJlY3RpdmUnO1xuZXhwb3J0ICogZnJvbSAnLi9zZWxlY3Qtb24tZm9jdXNpbi9zYy1zZWxlY3Qtb24tZm9jdXNpbi5kaXJlY3RpdmUnO1xuIl19
|
@@ -0,0 +1,31 @@
|
|
1
|
+
import { Directive } from '@angular/core';
|
2
|
+
import * as i0 from "@angular/core";
|
3
|
+
/**
|
4
|
+
* Директива для обработки события фокуса поля ввода, для последующего выделения содержимого поля ввода.
|
5
|
+
*/
|
6
|
+
export class ScSelectOnFocusinDirective {
|
7
|
+
/**
|
8
|
+
* Слушатель и обработчик события `focusin`.
|
9
|
+
*
|
10
|
+
* @param target Целевой объект события `focusin`.
|
11
|
+
*/
|
12
|
+
// eslint-disable-next-line class-methods-use-this
|
13
|
+
onFocusIn(target) {
|
14
|
+
if (target instanceof HTMLInputElement) {
|
15
|
+
target.select();
|
16
|
+
}
|
17
|
+
}
|
18
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: ScSelectOnFocusinDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
|
19
|
+
static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "18.2.13", type: ScSelectOnFocusinDirective, isStandalone: true, selector: "tui-input-number, tui-input, tui-input-phone, tui-input-date, tui-input-password, input[tuiInputNumber]", host: { listeners: { "focusin": "onFocusIn($event.target)" } }, ngImport: i0 }); }
|
20
|
+
}
|
21
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: ScSelectOnFocusinDirective, decorators: [{
|
22
|
+
type: Directive,
|
23
|
+
args: [{
|
24
|
+
standalone: true,
|
25
|
+
selector: 'tui-input-number, tui-input, tui-input-phone, tui-input-date, tui-input-password, input[tuiInputNumber]',
|
26
|
+
host: {
|
27
|
+
'(focusin)': 'onFocusIn($event.target)',
|
28
|
+
},
|
29
|
+
}]
|
30
|
+
}] });
|
31
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic2Mtc2VsZWN0LW9uLWZvY3VzaW4uZGlyZWN0aXZlLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vcHJvamVjdHMvY2xpZW50LXVpL2RpcmVjdGl2ZXMvc2VsZWN0LW9uLWZvY3VzaW4vc2Mtc2VsZWN0LW9uLWZvY3VzaW4uZGlyZWN0aXZlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBRSxTQUFTLEVBQUUsTUFBTSxlQUFlLENBQUM7O0FBRTFDOztHQUVHO0FBUUgsTUFBTSxPQUFPLDBCQUEwQjtJQUNuQzs7OztPQUlHO0lBQ0gsa0RBQWtEO0lBQ3hDLFNBQVMsQ0FBQyxNQUFtQjtRQUNuQyxJQUFJLE1BQU0sWUFBWSxnQkFBZ0IsRUFBRSxDQUFDO1lBQ3JDLE1BQU0sQ0FBQyxNQUFNLEVBQUUsQ0FBQztRQUNwQixDQUFDO0lBQ0wsQ0FBQzsrR0FYUSwwQkFBMEI7bUdBQTFCLDBCQUEwQjs7NEZBQTFCLDBCQUEwQjtrQkFQdEMsU0FBUzttQkFBQztvQkFDUCxVQUFVLEVBQUUsSUFBSTtvQkFDaEIsUUFBUSxFQUFFLHlHQUF5RztvQkFDbkgsSUFBSSxFQUFFO3dCQUNGLFdBQVcsRUFBRSwwQkFBMEI7cUJBQzFDO2lCQUNKIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgRGlyZWN0aXZlIH0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5cbi8qKlxuICog0JTQuNGA0LXQutGC0LjQstCwINC00LvRjyDQvtCx0YDQsNCx0L7RgtC60Lgg0YHQvtCx0YvRgtC40Y8g0YTQvtC60YPRgdCwINC/0L7Qu9GPINCy0LLQvtC00LAsINC00LvRjyDQv9C+0YHQu9C10LTRg9GO0YnQtdCz0L4g0LLRi9C00LXQu9C10L3QuNGPINGB0L7QtNC10YDQttC40LzQvtCz0L4g0L/QvtC70Y8g0LLQstC+0LTQsC5cbiAqL1xuQERpcmVjdGl2ZSh7XG4gICAgc3RhbmRhbG9uZTogdHJ1ZSxcbiAgICBzZWxlY3RvcjogJ3R1aS1pbnB1dC1udW1iZXIsIHR1aS1pbnB1dCwgdHVpLWlucHV0LXBob25lLCB0dWktaW5wdXQtZGF0ZSwgdHVpLWlucHV0LXBhc3N3b3JkLCBpbnB1dFt0dWlJbnB1dE51bWJlcl0nLFxuICAgIGhvc3Q6IHtcbiAgICAgICAgJyhmb2N1c2luKSc6ICdvbkZvY3VzSW4oJGV2ZW50LnRhcmdldCknLFxuICAgIH0sXG59KVxuZXhwb3J0IGNsYXNzIFNjU2VsZWN0T25Gb2N1c2luRGlyZWN0aXZlIHtcbiAgICAvKipcbiAgICAgKiDQodC70YPRiNCw0YLQtdC70Ywg0Lgg0L7QsdGA0LDQsdC+0YLRh9C40Log0YHQvtCx0YvRgtC40Y8gYGZvY3VzaW5gLlxuICAgICAqXG4gICAgICogQHBhcmFtIHRhcmdldCDQptC10LvQtdCy0L7QuSDQvtCx0YrQtdC60YIg0YHQvtCx0YvRgtC40Y8gYGZvY3VzaW5gLlxuICAgICAqL1xuICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBjbGFzcy1tZXRob2RzLXVzZS10aGlzXG4gICAgcHJvdGVjdGVkIG9uRm9jdXNJbih0YXJnZXQ6IEhUTUxFbGVtZW50KTogdm9pZCB7XG4gICAgICAgIGlmICh0YXJnZXQgaW5zdGFuY2VvZiBIVE1MSW5wdXRFbGVtZW50KSB7XG4gICAgICAgICAgICB0YXJnZXQuc2VsZWN0KCk7XG4gICAgICAgIH1cbiAgICB9XG59XG4iXX0=
|
@@ -1,9 +1,9 @@
|
|
1
1
|
import * as i0 from '@angular/core';
|
2
|
-
import { inject, Injectable, Directive, ContentChildren, HostListener, NgModule, EventEmitter, signal, ChangeDetectorRef, Input, Output, Component, ChangeDetectionStrategy, Inject, HostBinding, ElementRef, Pipe, Renderer2, input, model, output, SkipSelf, DestroyRef, effect, ContentChild, ViewChild, Optional, computed, forwardRef } from '@angular/core';
|
2
|
+
import { inject, Injectable, Directive, ContentChildren, HostListener, NgModule, EventEmitter, signal, ChangeDetectorRef, Input, Output, Component, ChangeDetectionStrategy, Inject, HostBinding, ElementRef, Pipe, Renderer2, input, model, output, SkipSelf, DestroyRef, effect, ContentChild, ViewChild, Optional, computed, viewChild, forwardRef } from '@angular/core';
|
3
3
|
import * as i1 from '@snabcentr/client-core';
|
4
4
|
import { ScContactsService, ScUserService, ScAuthService, SEARCH_TERM, ScUnitsHelper, ScImageHelper, SC_PATH_IMAGE_NOT_FOUND, IS_RUNNING_ON_TERMINAL, ScPhoneService, ScUserMetrikaService, ScUserMetrikaGoalsEnum, ScVCardService, ScVerificationService, ScISuggestionType, SC_MIN_LENGTH_SEARCH_TERM, ScConvertersService, ScOpfList, ScLocationsService, ScWarehouseService, SEARCH_TERM_PROVIDERS, ScCartService, ScUploadedFile, ScMimeTypes, ScCatalogService, SC_URLS, ScPaginationService, SC_NEXT_PAGE_PAGINATION_CLICK, SC_PRODUCT_PAGINATION_OPTIONS, ScIconTypesEnum, ScDocumentInfoTypesEnum, ScFrequentlyAskedQuestionsService, ScFeedbackService } from '@snabcentr/client-core';
|
5
5
|
import * as i6 from 'rxjs';
|
6
|
-
import { EMPTY, BehaviorSubject, switchMap, of, shareReplay, Subject, map, filter, tap, catchError, finalize, startWith, share, timer, scan, takeWhile, endWith, distinctUntilChanged, debounceTime, throwError, combineLatest, Observable, noop, first, merge, skip } from 'rxjs';
|
6
|
+
import { EMPTY, BehaviorSubject, switchMap, of, shareReplay, Subject, map, filter, tap, catchError, finalize, startWith, share, timer, scan, takeWhile, endWith, distinctUntilChanged, debounceTime, throwError, combineLatest, Observable, pairwise, noop, first, merge, skip } from 'rxjs';
|
7
7
|
import * as i7 from '@taiga-ui/cdk';
|
8
8
|
import { tuiCreateToken, tuiCreateTokenFromFactory, TUI_IS_MOBILE, TuiValueTransformer, TuiDay, tuiControlValue, tuiIsPresent, tuiMarkControlAsTouchedAndValidate, tuiIsFalsy, TuiLet, TuiAutoFocus, TuiRepeatTimes, TuiTime, TuiHovered, TuiDayRange, TuiMonth, tuiPure, TUI_WINDOW_SIZE, TuiValidationError, TUI_TRUE_HANDLER } from '@taiga-ui/cdk';
|
9
9
|
import { HttpClient, HttpErrorResponse } from '@angular/common/http';
|
@@ -11,19 +11,19 @@ import { toSignal, outputFromObservable, takeUntilDestroyed } from '@angular/cor
|
|
11
11
|
import * as i2$3 from '@angular/forms';
|
12
12
|
import { FormControl, FormGroupDirective, NgControl, FormGroup, Validators, FormArray, FormsModule, ReactiveFormsModule } from '@angular/forms';
|
13
13
|
import * as i1$1 from '@taiga-ui/core';
|
14
|
-
import { TuiButton, TuiDialog, TuiDialogService, TuiLink, TuiFallbackSrcPipe, TuiInitialsPipe, TuiIcon, TuiAppearance, TuiWithAppearance, TuiIcons, TuiWithIcons, TUI_DATA_LIST_HOST, tuiDropdownOptionsProvider, TuiLabel, TuiError, TuiLoader, TuiDataList, TuiNotification, TuiTextfield, TuiTitle, TuiHint, TuiFormatNumberPipe, TUI_MONTHS, TuiSurface, tuiFadeIn } from '@taiga-ui/core';
|
14
|
+
import { TuiButton, TuiDialog, TuiDialogService, TuiLink, TuiFallbackSrcPipe, TuiInitialsPipe, TuiIcon, TuiAppearance, TuiWithAppearance, TuiIcons, TuiWithIcons, TUI_DATA_LIST_HOST, tuiDropdownOptionsProvider, TuiLabel, TuiError, TuiLoader, TuiDataList, TuiNotification, TuiTextfield, TuiTitle, TuiHint, TuiFormatNumberPipe, TuiNumberFormat, TUI_MONTHS, TuiSurface, tuiFadeIn } from '@taiga-ui/core';
|
15
15
|
import { isValidPhoneNumber, getCountries } from 'libphonenumber-js';
|
16
16
|
import * as i4 from '@taiga-ui/legacy/components/primitive-textfield';
|
17
17
|
import * as i5 from '@taiga-ui/legacy';
|
18
18
|
import { AbstractTuiControl, TuiInputModule, TuiTextfieldControllerModule, TuiComboBoxModule, TuiInputPhoneModule, TuiSelectModule, TuiInputPasswordModule, AbstractTuiNullableControl, TuiInputNumberComponent, TuiInputNumberModule, TuiIslandDirective, TuiTextareaModule } from '@taiga-ui/legacy';
|
19
|
-
import { isNil } from 'lodash-es';
|
19
|
+
import { isNil, isUndefined, isObject } from 'lodash-es';
|
20
20
|
import * as i2$2 from '@angular/common';
|
21
21
|
import { CommonModule, NgIf, AsyncPipe, NgFor, NgClass } from '@angular/common';
|
22
22
|
import * as i4$1 from '@taiga-ui/core/components/label';
|
23
23
|
import * as i8 from '@maskito/angular';
|
24
24
|
import { MaskitoDirective } from '@maskito/angular';
|
25
25
|
import * as i2$1 from '@taiga-ui/kit';
|
26
|
-
import { TuiPreview, TUI_DATE_VALUE_TRANSFORMER, TuiAvatar, TuiAccordionItem, TuiElasticContainer, TuiAccordion, TuiFieldErrorPipe, TuiFilterByInputPipe, TuiStringifyContentPipe, TuiDataListWrapper, TuiButtonLoading, TuiSortCountriesPipe, TuiCarousel, TuiPush, TuiCheckbox, TuiStepper, TuiBadge, TuiPreviewDialogService, TuiHighlight, TuiFiles, TuiLineClamp, TuiTreeService, TuiTreeItemContent, TUI_TREE_START, TUI_TREE_CONTENT, TUI_TREE_LOADING, TUI_TREE_LOADER, TuiTree, tuiItemsHandlersProvider, TuiPagination,
|
26
|
+
import { TuiPreview, TUI_DATE_VALUE_TRANSFORMER, TuiAvatar, TuiAccordionItem, TuiElasticContainer, TuiAccordion, TuiFieldErrorPipe, TuiFilterByInputPipe, TuiStringifyContentPipe, TuiDataListWrapper, TuiButtonLoading, TuiSortCountriesPipe, TuiCarousel, TuiPush, TuiCheckbox, TuiStepper, TuiBadge, TuiPreviewDialogService, TuiHighlight, TuiFiles, TuiChip, TuiInputNumber, TuiLineClamp, TuiTreeService, TuiTreeItemContent, TUI_TREE_START, TUI_TREE_CONTENT, TUI_TREE_LOADING, TUI_TREE_LOADER, TuiTree, tuiItemsHandlersProvider, TuiPagination, tuiFilesAccepted } from '@taiga-ui/kit';
|
27
27
|
import * as i2$4 from '@taiga-ui/polymorpheus';
|
28
28
|
import { POLYMORPHEUS_CONTEXT, PolymorpheusComponent, PolymorpheusTemplate, PolymorpheusOutlet, injectContext } from '@taiga-ui/polymorpheus';
|
29
29
|
import * as i2 from 'angularx-qrcode';
|
@@ -36,8 +36,10 @@ import * as i3$1 from '@ng-web-apis/intersection-observer';
|
|
36
36
|
import { IntersectionObserverService, WaIntersectionObserver } from '@ng-web-apis/intersection-observer';
|
37
37
|
import * as i2$5 from '@angular/router';
|
38
38
|
import { RouterModule, ActivatedRoute, RouterLink, Router, NavigationStart } from '@angular/router';
|
39
|
-
import { TuiCurrencyPipe } from '@taiga-ui/addon-commerce';
|
39
|
+
import { TuiCurrencyPipe, TuiAmountPipe } from '@taiga-ui/addon-commerce';
|
40
40
|
import { WA_WINDOW } from '@ng-web-apis/common';
|
41
|
+
import { TuiAppearance as TuiAppearance$1, TuiWithAppearance as TuiWithAppearance$1 } from '@taiga-ui/core/directives/appearance';
|
42
|
+
import { TuiIcons as TuiIcons$1, TuiWithIcons as TuiWithIcons$1 } from '@taiga-ui/core/directives/icons';
|
41
43
|
import { __decorate } from 'tslib';
|
42
44
|
import * as i5$1 from '@taiga-ui/addon-charts';
|
43
45
|
import { TuiLineDaysChart, TuiLineDaysChartHint, TuiAxes } from '@taiga-ui/addon-charts';
|
@@ -832,6 +834,35 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImpo
|
|
832
834
|
}]
|
833
835
|
}] });
|
834
836
|
|
837
|
+
/**
|
838
|
+
* Директива для обработки события фокуса поля ввода, для последующего выделения содержимого поля ввода.
|
839
|
+
*/
|
840
|
+
class ScSelectOnFocusinDirective {
|
841
|
+
/**
|
842
|
+
* Слушатель и обработчик события `focusin`.
|
843
|
+
*
|
844
|
+
* @param target Целевой объект события `focusin`.
|
845
|
+
*/
|
846
|
+
// eslint-disable-next-line class-methods-use-this
|
847
|
+
onFocusIn(target) {
|
848
|
+
if (target instanceof HTMLInputElement) {
|
849
|
+
target.select();
|
850
|
+
}
|
851
|
+
}
|
852
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: ScSelectOnFocusinDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
|
853
|
+
static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "18.2.13", type: ScSelectOnFocusinDirective, isStandalone: true, selector: "tui-input-number, tui-input, tui-input-phone, tui-input-date, tui-input-password, input[tuiInputNumber]", host: { listeners: { "focusin": "onFocusIn($event.target)" } }, ngImport: i0 }); }
|
854
|
+
}
|
855
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: ScSelectOnFocusinDirective, decorators: [{
|
856
|
+
type: Directive,
|
857
|
+
args: [{
|
858
|
+
standalone: true,
|
859
|
+
selector: 'tui-input-number, tui-input, tui-input-phone, tui-input-date, tui-input-password, input[tuiInputNumber]',
|
860
|
+
host: {
|
861
|
+
'(focusin)': 'onFocusIn($event.target)',
|
862
|
+
},
|
863
|
+
}]
|
864
|
+
}] });
|
865
|
+
|
835
866
|
/**
|
836
867
|
* Токен для обработчика QR кода менеджера.
|
837
868
|
*/
|
@@ -4252,6 +4283,277 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImpo
|
|
4252
4283
|
args: [{ standalone: true, selector: 'sc-car-add-products-from-csv-dialog', imports: [TuiLink, TuiLoader, TuiFiles, ReactiveFormsModule, NgIf, TuiButton, TuiButtonLoading], changeDetection: ChangeDetectionStrategy.OnPush, template: "<div class=\"flex flex-col items-center gap-8\">\n <tui-loader\n [overlay]=\"true\"\n [showLoader]=\"isDownloadLoading()\"\n size=\"s\"\n class=\"mt-8\"\n >\n <button\n tuiLink\n [pseudo]=\"true\"\n type=\"button\"\n (click)=\"onDownloadClick.next()\"\n >\n \u041F\u0440\u0438\u043C\u0435\u0440 .csv \u0444\u0430\u0439\u043B\u0430\n </button>\n </tui-loader>\n\n <div class=\"flex w-full flex-col gap-1\">\n <label\n tuiInputFiles\n class=\"w-full\"\n >\n <input\n accept=\"text/csv\"\n tuiInputFiles\n [formControl]=\"control\"\n />\n </label>\n\n <tui-files class=\"tui-space_top-1\">\n <tui-file\n *ngIf=\"control.value as file\"\n [file]=\"file\"\n (remove)=\"removeFile()\"\n />\n </tui-files>\n </div>\n <div class=\"flex gap-2\">\n <button\n tuiButton\n [disabled]=\"!control.value\"\n [loading]=\"isSubmitLoading()\"\n iconStart=\"@tui.sc.send\"\n class=\"self-center\"\n (click)=\"onSubmit$.next()\"\n >\n \u0417\u0430\u0433\u0440\u0443\u0437\u0438\u0442\u044C\n </button>\n <button\n tuiButton\n (click)=\"context.$implicit.complete()\"\n type=\"button\"\n appearance=\"secondary\"\n >\n \u041E\u0442\u043C\u0435\u043D\u0430\n </button>\n </div>\n</div>\n" }]
|
4253
4284
|
}] });
|
4254
4285
|
|
4286
|
+
/* eslint-disable sonarjs/no-nested-template-literals,@typescript-eslint/unbound-method */
|
4287
|
+
/**
|
4288
|
+
* Компонент добавления / изменения товара в корзине.
|
4289
|
+
*/
|
4290
|
+
class ScAddOrEditingCartItemFormComponent {
|
4291
|
+
constructor() {
|
4292
|
+
/**
|
4293
|
+
* Группа полей добавления / изменения товара в корзине.
|
4294
|
+
*/
|
4295
|
+
this.form = new FormGroup({
|
4296
|
+
quantity: new FormControl(null, Validators.required),
|
4297
|
+
marker: new FormControl(''),
|
4298
|
+
});
|
4299
|
+
/**
|
4300
|
+
* Данные о товаре.
|
4301
|
+
*/
|
4302
|
+
this.product = input.required();
|
4303
|
+
/**
|
4304
|
+
* Признак того, что для указанной категории или продукта действует конфигуратор длины.
|
4305
|
+
*/
|
4306
|
+
this.isLengthConfigurator = computed(() => Boolean(this.product().properties?.['isLengthConfigurator']));
|
4307
|
+
/**
|
4308
|
+
* Данные о товаре в корзине.
|
4309
|
+
*/
|
4310
|
+
this.cartItem = input();
|
4311
|
+
/**
|
4312
|
+
* Признак загрузки данных.
|
4313
|
+
*/
|
4314
|
+
this.isLoading = input(false);
|
4315
|
+
/**
|
4316
|
+
* Признак возможности продажи товара на метраж.
|
4317
|
+
*/
|
4318
|
+
this.productIsMeasurable = computed(() => this.unitsHelper.productIsMeasurable(this.product()));
|
4319
|
+
/**
|
4320
|
+
* Кратность количества для товара.
|
4321
|
+
*/
|
4322
|
+
this.productMultiplicity = computed(() => this.unitsHelper.productMultiplicity(this.product()));
|
4323
|
+
/**
|
4324
|
+
* Минимальный метраж для товара.
|
4325
|
+
*/
|
4326
|
+
this.minLength = computed(() => this.product().properties?.minLength ?? (this.product().ignoreMinCountCheck ? 0 : this.product().minCount) ?? 1);
|
4327
|
+
/**
|
4328
|
+
* Максимальный метраж для товара.
|
4329
|
+
*/
|
4330
|
+
this.maxLength = computed(() => this.product().properties?.maxLength);
|
4331
|
+
/**
|
4332
|
+
* Шаг изменения метража.
|
4333
|
+
*/
|
4334
|
+
this.lengthStep = computed(() => this.product().properties?.lengthStep ?? (this.product().ignoreMinCountCheck ? 0 : this.product().minCount));
|
4335
|
+
/**
|
4336
|
+
* Подсказка по минимальному и максимальному метражу товара.
|
4337
|
+
*/
|
4338
|
+
this.lengthHint = computed(() => {
|
4339
|
+
const min = this.minLength();
|
4340
|
+
const max = this.maxLength();
|
4341
|
+
// eslint-disable-next-line sonarjs/no-nested-conditional, @typescript-eslint/no-unnecessary-condition
|
4342
|
+
return (min ?? max) ? `(${min ? `от ${min}` : ''}${min && max ? ' ' : ''}${max ? `до ${max}` : ''} ${this.product().unit})` : '';
|
4343
|
+
});
|
4344
|
+
/**
|
4345
|
+
* {@link Output} события добавления товара в корзину.
|
4346
|
+
*/
|
4347
|
+
this.addToCart = output();
|
4348
|
+
/**
|
4349
|
+
* {@link Output} события редактирования товара в корзине.
|
4350
|
+
*/
|
4351
|
+
this.editCartItem = output();
|
4352
|
+
/**
|
4353
|
+
* Объект-помощник для работы со значениями единиц измерения товара.
|
4354
|
+
*/
|
4355
|
+
this.unitsHelper = inject(ScUnitsHelper);
|
4356
|
+
/**
|
4357
|
+
* Сервис для сбора метрик о действиях пользователей.
|
4358
|
+
*/
|
4359
|
+
this.userMetrikaService = inject(ScUserMetrikaService);
|
4360
|
+
/**
|
4361
|
+
* Сервис конвертации данных.
|
4362
|
+
*/
|
4363
|
+
this.convertersService = inject(ScConvertersService);
|
4364
|
+
}
|
4365
|
+
/** @inheritDoc */
|
4366
|
+
ngOnInit() {
|
4367
|
+
this.userMetrikaService.emitUserMetrikaEvent({
|
4368
|
+
target: ScUserMetrikaGoalsEnum.cartItemAddShow,
|
4369
|
+
params: { product_id: this.product().id },
|
4370
|
+
});
|
4371
|
+
if (this.productIsMeasurable()) {
|
4372
|
+
// Добавляем поле ввода длины, если товар измеряемый.
|
4373
|
+
this.form.addControl('length', new FormControl(this.cartItem()?.length ?? this.minLength(), [Validators.required, Validators.min(0.01)]));
|
4374
|
+
}
|
4375
|
+
// Устанавливаем количество из корзины или кратности товара.
|
4376
|
+
this.form.controls.quantity.patchValue(this.cartItem()?.quantity ?? this.unitsHelper.productMultiplicity(this.product()));
|
4377
|
+
const step = this.lengthStep();
|
4378
|
+
if (this.isLengthConfigurator() && this.lengthStep() && this.form.controls.quantity.value && step) {
|
4379
|
+
// Если есть конфигуратор длины, рассчитываем начально значение длины.
|
4380
|
+
this.form.controls.length?.patchValue(this.form.controls.quantity.value * step);
|
4381
|
+
}
|
4382
|
+
// Добавляем валидацию шага для количества.
|
4383
|
+
this.form.controls.quantity.addValidators(stepValidator(this.unitsHelper.productStepForValidator(this.product())));
|
4384
|
+
// Добавляем валидацию шага для длины.
|
4385
|
+
this.form.get('length')?.addValidators(stepValidator(this.product().properties?.lengthStep ?? (this.product().ignoreMinCountCheck ? 0 : (this.product().minCount ?? 0))));
|
4386
|
+
// Считаем итоговую стоимость заказа.
|
4387
|
+
this.totalCost$ = tuiControlValue(this.form).pipe(debounceTime(0), // Исправляем ошибку NG0950.
|
4388
|
+
filter(() => this.form.valid), distinctUntilChanged((previous, current) => previous.length === current.length && previous.quantity === current.quantity), // Только при изменении значений
|
4389
|
+
startWith(this.form.value), pairwise(), map(([previous, current]) => {
|
4390
|
+
const lengthControl = this.form.get('length');
|
4391
|
+
// Если нет конфигуратора длины или некорректные данные — возвращаем без изменений.
|
4392
|
+
if (!this.isLengthConfigurator() || isUndefined(current.length) || !lengthControl || this.form.invalid || !step) {
|
4393
|
+
return current;
|
4394
|
+
}
|
4395
|
+
// Если изменилось количество — пересчитываем длину.
|
4396
|
+
if (previous.quantity !== current.quantity && this.form.controls.quantity.value) {
|
4397
|
+
const newValue = this.form.controls.quantity.value * step;
|
4398
|
+
lengthControl.patchValue(newValue);
|
4399
|
+
}
|
4400
|
+
// Если изменилась длина — пересчитываем количество и возвращаем значение длины.
|
4401
|
+
if (previous.length !== current.length && lengthControl.value) {
|
4402
|
+
const newValue = lengthControl.value / step;
|
4403
|
+
this.form.controls.quantity.patchValue(newValue);
|
4404
|
+
return { length: step, quantity: newValue };
|
4405
|
+
}
|
4406
|
+
// Возвращаем итоговые значения для расчёта стоимости.
|
4407
|
+
return { length: step, quantity: current.quantity };
|
4408
|
+
}),
|
4409
|
+
// Считаем стоимость: цена * длина * количество.
|
4410
|
+
map(({ length, quantity }) => (this.product().costRub ?? 0) * (length ?? 1) * quantity), map((sum) => Math.round(sum * 100) / 100));
|
4411
|
+
}
|
4412
|
+
/**
|
4413
|
+
* Обработчик события шага метража.
|
4414
|
+
*
|
4415
|
+
* @param step Шаг.
|
4416
|
+
*/
|
4417
|
+
onStepLength(step) {
|
4418
|
+
const lengthControl = this.form.get('length');
|
4419
|
+
if (!this.productIsMeasurable() || !lengthControl) {
|
4420
|
+
return;
|
4421
|
+
}
|
4422
|
+
const length = lengthControl.value ?? 0;
|
4423
|
+
let newLength = Math.max(this.minLength(), length + step);
|
4424
|
+
// Округляем до ближайшего кратного числа.
|
4425
|
+
newLength = Math.round(newLength / step) * step;
|
4426
|
+
lengthControl.setValue(Number(newLength.toFixed(2)));
|
4427
|
+
}
|
4428
|
+
/**
|
4429
|
+
* Обработчик события шага количества.
|
4430
|
+
*
|
4431
|
+
* @param step Шаг.
|
4432
|
+
*/
|
4433
|
+
onStepQuantity(step) {
|
4434
|
+
const quantity = this.form.controls.quantity.value ?? 0;
|
4435
|
+
this.form.controls.quantity.setValue(Math.max(this.productMultiplicity(), quantity - (quantity % step) + step));
|
4436
|
+
}
|
4437
|
+
/**
|
4438
|
+
* Обработчик события отправки формы.
|
4439
|
+
*/
|
4440
|
+
onSubmit() {
|
4441
|
+
// Удаляем null-поля из значения формы.
|
4442
|
+
const value = this.convertersService.removeNull(this.form.value);
|
4443
|
+
// Если это добавление нового товара — добавляем productId.
|
4444
|
+
if (!this.cartItem()) {
|
4445
|
+
value.productId = this.product().id;
|
4446
|
+
}
|
4447
|
+
const step = this.lengthStep();
|
4448
|
+
// Если товар измеряемый и есть конфигуратор длины — устанавливаем длину по шагу (количество уже будет вычислено по формуле Метраж/min-count)
|
4449
|
+
if (this.productIsMeasurable() && this.isLengthConfigurator() && step) {
|
4450
|
+
value.length = step;
|
4451
|
+
}
|
4452
|
+
// Помечаем все поля формы как "touch" и запускаем валидацию для отображения ошибок с сервера.
|
4453
|
+
tuiMarkControlAsTouchedAndValidate(this.form);
|
4454
|
+
// В зависимости от режима — редактируем или добавляем товар.
|
4455
|
+
if (this.cartItem()) {
|
4456
|
+
this.editCartItem.emit(value);
|
4457
|
+
}
|
4458
|
+
else {
|
4459
|
+
this.addToCart.emit(value);
|
4460
|
+
}
|
4461
|
+
}
|
4462
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: ScAddOrEditingCartItemFormComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
4463
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.2.13", type: ScAddOrEditingCartItemFormComponent, isStandalone: true, selector: "sc-add-or-editing-cart-item-form", inputs: { product: { classPropertyName: "product", publicName: "product", isSignal: true, isRequired: true, transformFunction: null }, cartItem: { classPropertyName: "cartItem", publicName: "cartItem", isSignal: true, isRequired: false, transformFunction: null }, isLoading: { classPropertyName: "isLoading", publicName: "isLoading", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { addToCart: "addToCart", editCartItem: "editCartItem" }, ngImport: i0, template: "<!-- \u0424\u043E\u0440\u043C\u0430 \u0434\u043E\u0431\u0430\u0432\u043B\u0435\u043D\u0438\u044F \u0438\u0437\u043C\u0435\u0440\u044F\u0435\u043C\u043E\u0433\u043E \u0442\u043E\u0432\u0430\u0440\u0430. -->\n<form\n *ngIf=\"product\"\n [formGroup]=\"form\"\n (ngSubmit)=\"onSubmit()\"\n ScNextInputFocus\n class=\"flex flex-col gap-2\"\n>\n @let step = lengthStep();\n\n <!-- \u0414\u043B\u0438\u043D\u0430 \u0442\u043E\u0432\u0430\u0440\u0430 (\u043C\u0435\u0442\u0440\u0430\u0436) -->\n <label\n *ngIf=\"productIsMeasurable()\"\n tuiLabel\n >\n \u041C\u0435\u0442\u0440\u0430\u0436, {{ product().unit }}\n @if (!step || maxLength()) {\n {{ lengthHint() }}\n }\n\n <tui-textfield>\n <input\n tuiInputNumber\n formControlName=\"length\"\n [tuiNumberFormat]=\"{ precision: 2 }\"\n [max]=\"maxLength() || null\"\n [min]=\"minLength() || null\"\n (keydown.arrowDown)=\"onStepLength(-(lengthStep() ?? 0.01))\"\n (keydown.arrowUp)=\"onStepLength(lengthStep() ?? 0.01)\"\n autocomplete=\"length\"\n />\n </tui-textfield>\n <tui-error\n formControlName=\"length\"\n [error]=\"[] | tuiFieldError | async\"\n />\n <p\n *ngIf=\"lengthStep()\"\n class=\"tui-form__field-note\"\n >\n \u041C\u0435\u0442\u0440\u0430\u0436 \u0434\u043E\u043B\u0436\u0435\u043D \u0431\u044B\u0442\u044C \u043A\u0440\u0430\u0442\u0435\u043D {{ lengthStep() }}\n </p>\n </label>\n\n <!-- \u041A\u043E\u043B\u0438\u0447\u0435\u0441\u0442\u0432\u043E \u0442\u043E\u0432\u0430\u0440\u0430 -->\n <label tuiLabel>\n \u041A\u043E\u043B\u0438\u0447\u0435\u0441\u0442\u0432\u043E, \u0448\u0442.\n <tui-textfield>\n <tui-chip\n *ngIf=\"isLengthConfigurator() && productMultiplicity() && step\"\n size=\"s\"\n appearance=\"negative\"\n class=\"font-bold\"\n >\n x {{ step }} {{ product().unit }}\n </tui-chip>\n\n <input\n placeholder=\"\u041A\u043E\u043B\u0438\u0447\u0435\u0441\u0442\u0432\u043E\"\n tuiInputNumber\n [tuiNumberFormat]=\"{ decimalMode: 'not-zero' }\"\n [min]=\"productMultiplicity()\"\n (keydown.arrowDown)=\"onStepQuantity(-productMultiplicity())\"\n (keydown.arrowUp)=\"onStepQuantity(productMultiplicity())\"\n formControlName=\"quantity\"\n autocomplete=\"quantity\"\n />\n </tui-textfield>\n <p class=\"tui-form__field-note\">\u041A\u043E\u043B\u0438\u0447\u0435\u0441\u0442\u0432\u043E \u0434\u043E\u043B\u0436\u043D\u043E \u0431\u044B\u0442\u044C \u043A\u0440\u0430\u0442\u043D\u043E {{ productMultiplicity() }}</p>\n <tui-error\n formControlName=\"quantity\"\n [error]=\"[] | tuiFieldError | async\"\n />\n </label>\n\n <!-- \u041C\u0430\u0440\u043A\u0438\u0440\u043E\u0432\u043A\u0430 -->\n <label tuiLabel>\n \u041C\u0430\u0440\u043A\u0438\u0440\u043E\u0432\u043A\u0430\n <tui-input formControlName=\"marker\">\n \u041C\u0430\u0440\u043A\u0438\u0440\u043E\u0432\u043A\u0430\n <input\n tuiTextfieldLegacy\n autocomplete=\"marker\"\n />\n </tui-input>\n <tui-error\n formControlName=\"marker\"\n [error]=\"[] | tuiFieldError | async\"\n />\n </label>\n\n <!-- \u041A\u043D\u043E\u043F\u043A\u0430 \u0434\u043E\u0431\u0430\u0432\u043B\u0435\u043D\u0438\u044F / \u0440\u0435\u0434\u0430\u043A\u0442\u0438\u0440\u043E\u0432\u0430\u043D\u0438\u044F \u0442\u043E\u0432\u0430\u0440\u0430 \u0432 \u043A\u043E\u0440\u0437\u0438\u043D\u0443 -->\n <div class=\"flex flex-col items-center\">\n @let cost = totalCost$ | async;\n\n <div *ngIf=\"cost\">\n \u0418\u0442\u043E\u0433\u043E:<span class=\"text-2xl font-bold\">\n {{ cost | tuiAmount | async }}\n {{ product().currency }}\n </span>\n </div>\n\n <!-- \u041A\u043D\u043E\u043F\u043A\u0430 \u0434\u043E\u0431\u0430\u0432\u043B\u0435\u043D\u0438\u044F / \u0440\u0435\u0434\u0430\u043A\u0442\u0438\u0440\u043E\u0432\u0430\u043D\u0438\u044F \u0442\u043E\u0432\u0430\u0440\u0430 \u0432 \u043A\u043E\u0440\u0437\u0438\u043D\u0443 -->\n <button\n tuiButton\n iconStart=\"@tui.check\"\n [disabled]=\"form.invalid\"\n [loading]=\"isLoading()\"\n type=\"submit\"\n class=\"mt-2\"\n >\n {{ cartItem() ? '\u0418\u0437\u043C\u0435\u043D\u0438\u0442\u044C' : '\u0414\u043E\u0431\u0430\u0432\u0438\u0442\u044C \u0432 \u043A\u043E\u0440\u0437\u0438\u043D\u0443' }}\n </button>\n </div>\n</form>\n", dependencies: [{ kind: "directive", type: NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i2$3.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i2$3.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: i2$3.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i2$3.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "ngmodule", type: ScNextInputFocusModule }, { kind: "directive", type: ScNextInputFocusDirective, selector: "form[ScNextInputFocus]" }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i2$3.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i2$3.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { kind: "directive", type: TuiLabel, selector: "label[tuiLabel]" }, { kind: "directive", type: ScSelectOnFocusinDirective, selector: "tui-input-number, tui-input, tui-input-phone, tui-input-date, tui-input-password, input[tuiInputNumber]" }, { kind: "directive", type: TuiNumberFormat, selector: "[tuiNumberFormat]", inputs: ["tuiNumberFormat"] }, { kind: "component", type: TuiError, selector: "tui-error", inputs: ["error"] }, { kind: "ngmodule", type: TuiInputModule }, { kind: "component", type: i5.TuiInputComponent, selector: "tui-input" }, { kind: "directive", type: i5.TuiInputDirective, selector: "tui-input" }, { kind: "component", type: i4.TuiTextfieldComponent, selector: "input[tuiTextfieldLegacy], textarea[tuiTextfieldLegacy]" }, { 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" }, { kind: "pipe", type: TuiFieldErrorPipe, name: "tuiFieldError" }, { kind: "directive", type: i2$1.TuiInputNumberDirective, selector: "input[tuiInputNumber]", inputs: ["min", "max", "prefix", "postfix"] }, { kind: "component", type: i1$1.TuiTextfieldComponent, selector: "tui-textfield", inputs: ["content", "filler"] }, { kind: "pipe", type: TuiAmountPipe, name: "tuiAmount" }, { kind: "directive", type: TuiChip, selector: "tui-chip,[tuiChip]", inputs: ["size"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
|
4464
|
+
}
|
4465
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: ScAddOrEditingCartItemFormComponent, decorators: [{
|
4466
|
+
type: Component,
|
4467
|
+
args: [{ standalone: true, selector: 'sc-add-or-editing-cart-item-form', imports: [
|
4468
|
+
NgIf,
|
4469
|
+
FormsModule,
|
4470
|
+
ScNextInputFocusModule,
|
4471
|
+
ReactiveFormsModule,
|
4472
|
+
TuiLabel,
|
4473
|
+
ScSelectOnFocusinDirective,
|
4474
|
+
TuiNumberFormat,
|
4475
|
+
TuiError,
|
4476
|
+
TuiInputModule,
|
4477
|
+
TuiAppearance$1,
|
4478
|
+
TuiWithAppearance$1,
|
4479
|
+
TuiIcons$1,
|
4480
|
+
TuiWithIcons$1,
|
4481
|
+
TuiButton,
|
4482
|
+
TuiButtonLoading,
|
4483
|
+
AsyncPipe,
|
4484
|
+
TuiFieldErrorPipe,
|
4485
|
+
TuiInputNumber,
|
4486
|
+
TuiNumberFormat,
|
4487
|
+
TuiTextfield,
|
4488
|
+
TuiAmountPipe,
|
4489
|
+
TuiChip,
|
4490
|
+
], changeDetection: ChangeDetectionStrategy.OnPush, template: "<!-- \u0424\u043E\u0440\u043C\u0430 \u0434\u043E\u0431\u0430\u0432\u043B\u0435\u043D\u0438\u044F \u0438\u0437\u043C\u0435\u0440\u044F\u0435\u043C\u043E\u0433\u043E \u0442\u043E\u0432\u0430\u0440\u0430. -->\n<form\n *ngIf=\"product\"\n [formGroup]=\"form\"\n (ngSubmit)=\"onSubmit()\"\n ScNextInputFocus\n class=\"flex flex-col gap-2\"\n>\n @let step = lengthStep();\n\n <!-- \u0414\u043B\u0438\u043D\u0430 \u0442\u043E\u0432\u0430\u0440\u0430 (\u043C\u0435\u0442\u0440\u0430\u0436) -->\n <label\n *ngIf=\"productIsMeasurable()\"\n tuiLabel\n >\n \u041C\u0435\u0442\u0440\u0430\u0436, {{ product().unit }}\n @if (!step || maxLength()) {\n {{ lengthHint() }}\n }\n\n <tui-textfield>\n <input\n tuiInputNumber\n formControlName=\"length\"\n [tuiNumberFormat]=\"{ precision: 2 }\"\n [max]=\"maxLength() || null\"\n [min]=\"minLength() || null\"\n (keydown.arrowDown)=\"onStepLength(-(lengthStep() ?? 0.01))\"\n (keydown.arrowUp)=\"onStepLength(lengthStep() ?? 0.01)\"\n autocomplete=\"length\"\n />\n </tui-textfield>\n <tui-error\n formControlName=\"length\"\n [error]=\"[] | tuiFieldError | async\"\n />\n <p\n *ngIf=\"lengthStep()\"\n class=\"tui-form__field-note\"\n >\n \u041C\u0435\u0442\u0440\u0430\u0436 \u0434\u043E\u043B\u0436\u0435\u043D \u0431\u044B\u0442\u044C \u043A\u0440\u0430\u0442\u0435\u043D {{ lengthStep() }}\n </p>\n </label>\n\n <!-- \u041A\u043E\u043B\u0438\u0447\u0435\u0441\u0442\u0432\u043E \u0442\u043E\u0432\u0430\u0440\u0430 -->\n <label tuiLabel>\n \u041A\u043E\u043B\u0438\u0447\u0435\u0441\u0442\u0432\u043E, \u0448\u0442.\n <tui-textfield>\n <tui-chip\n *ngIf=\"isLengthConfigurator() && productMultiplicity() && step\"\n size=\"s\"\n appearance=\"negative\"\n class=\"font-bold\"\n >\n x {{ step }} {{ product().unit }}\n </tui-chip>\n\n <input\n placeholder=\"\u041A\u043E\u043B\u0438\u0447\u0435\u0441\u0442\u0432\u043E\"\n tuiInputNumber\n [tuiNumberFormat]=\"{ decimalMode: 'not-zero' }\"\n [min]=\"productMultiplicity()\"\n (keydown.arrowDown)=\"onStepQuantity(-productMultiplicity())\"\n (keydown.arrowUp)=\"onStepQuantity(productMultiplicity())\"\n formControlName=\"quantity\"\n autocomplete=\"quantity\"\n />\n </tui-textfield>\n <p class=\"tui-form__field-note\">\u041A\u043E\u043B\u0438\u0447\u0435\u0441\u0442\u0432\u043E \u0434\u043E\u043B\u0436\u043D\u043E \u0431\u044B\u0442\u044C \u043A\u0440\u0430\u0442\u043D\u043E {{ productMultiplicity() }}</p>\n <tui-error\n formControlName=\"quantity\"\n [error]=\"[] | tuiFieldError | async\"\n />\n </label>\n\n <!-- \u041C\u0430\u0440\u043A\u0438\u0440\u043E\u0432\u043A\u0430 -->\n <label tuiLabel>\n \u041C\u0430\u0440\u043A\u0438\u0440\u043E\u0432\u043A\u0430\n <tui-input formControlName=\"marker\">\n \u041C\u0430\u0440\u043A\u0438\u0440\u043E\u0432\u043A\u0430\n <input\n tuiTextfieldLegacy\n autocomplete=\"marker\"\n />\n </tui-input>\n <tui-error\n formControlName=\"marker\"\n [error]=\"[] | tuiFieldError | async\"\n />\n </label>\n\n <!-- \u041A\u043D\u043E\u043F\u043A\u0430 \u0434\u043E\u0431\u0430\u0432\u043B\u0435\u043D\u0438\u044F / \u0440\u0435\u0434\u0430\u043A\u0442\u0438\u0440\u043E\u0432\u0430\u043D\u0438\u044F \u0442\u043E\u0432\u0430\u0440\u0430 \u0432 \u043A\u043E\u0440\u0437\u0438\u043D\u0443 -->\n <div class=\"flex flex-col items-center\">\n @let cost = totalCost$ | async;\n\n <div *ngIf=\"cost\">\n \u0418\u0442\u043E\u0433\u043E:<span class=\"text-2xl font-bold\">\n {{ cost | tuiAmount | async }}\n {{ product().currency }}\n </span>\n </div>\n\n <!-- \u041A\u043D\u043E\u043F\u043A\u0430 \u0434\u043E\u0431\u0430\u0432\u043B\u0435\u043D\u0438\u044F / \u0440\u0435\u0434\u0430\u043A\u0442\u0438\u0440\u043E\u0432\u0430\u043D\u0438\u044F \u0442\u043E\u0432\u0430\u0440\u0430 \u0432 \u043A\u043E\u0440\u0437\u0438\u043D\u0443 -->\n <button\n tuiButton\n iconStart=\"@tui.check\"\n [disabled]=\"form.invalid\"\n [loading]=\"isLoading()\"\n type=\"submit\"\n class=\"mt-2\"\n >\n {{ cartItem() ? '\u0418\u0437\u043C\u0435\u043D\u0438\u0442\u044C' : '\u0414\u043E\u0431\u0430\u0432\u0438\u0442\u044C \u0432 \u043A\u043E\u0440\u0437\u0438\u043D\u0443' }}\n </button>\n </div>\n</form>\n" }]
|
4491
|
+
}] });
|
4492
|
+
|
4493
|
+
/* eslint-disable sonarjs/no-nested-template-literals,@typescript-eslint/unbound-method,@typescript-eslint/no-unused-vars */
|
4494
|
+
/**
|
4495
|
+
* Компонент добавления / изменения товара в корзине.
|
4496
|
+
*/
|
4497
|
+
class ScAddOrEditingCartItemDialogComponent {
|
4498
|
+
constructor() {
|
4499
|
+
/**
|
4500
|
+
* Компонент формы добавления / изменения товара в корзине.
|
4501
|
+
*/
|
4502
|
+
this.formComponent = viewChild.required(ScAddOrEditingCartItemFormComponent);
|
4503
|
+
/**
|
4504
|
+
* {@link Subject} события отправки формы.
|
4505
|
+
*/
|
4506
|
+
this.onSubmit = new Subject();
|
4507
|
+
/**
|
4508
|
+
* {@link Observable} запроса добавления / изменения товара в корзине.
|
4509
|
+
*/
|
4510
|
+
this.submit$ = this.onSubmit.pipe(switchMap((value) => (this.cartItem && !('productId' in value) ? this.cartService.patchCartItem$(this.cartItem.id, value) : this.cartService.addToCart$(value)).pipe(tap(() => {
|
4511
|
+
this.context.$implicit.complete();
|
4512
|
+
}), catchError((error) => {
|
4513
|
+
if (error instanceof HttpErrorResponse) {
|
4514
|
+
const { errors, message } = error.error;
|
4515
|
+
if (errors && isObject(errors)) {
|
4516
|
+
Object.entries(errors).forEach(([k, v]) => {
|
4517
|
+
this.formComponent().form.get(k)?.setErrors({ serverResponse: v });
|
4518
|
+
});
|
4519
|
+
}
|
4520
|
+
if (message) {
|
4521
|
+
this.formComponent().form.setErrors({ serverResponse: [message] });
|
4522
|
+
}
|
4523
|
+
this.formComponent().form.updateValueAndValidity();
|
4524
|
+
this.formComponent().form.markAsDirty();
|
4525
|
+
}
|
4526
|
+
return of();
|
4527
|
+
}), startWith(null))), startWith(), share());
|
4528
|
+
/**
|
4529
|
+
* {@link Observable} изменения состояния загрузки данных.
|
4530
|
+
*/
|
4531
|
+
this.loading = toSignal(this.submit$.pipe(map(tuiIsFalsy)), { initialValue: false });
|
4532
|
+
/**
|
4533
|
+
* Контекст диалогового окна.
|
4534
|
+
*/
|
4535
|
+
this.context = injectContext();
|
4536
|
+
/**
|
4537
|
+
* Данные о товаре.
|
4538
|
+
*/
|
4539
|
+
this.product = this.context.data.product;
|
4540
|
+
/**
|
4541
|
+
* Данные о товаре в корзине.
|
4542
|
+
*/
|
4543
|
+
this.cartItem = this.context.data.cartItem;
|
4544
|
+
/**
|
4545
|
+
* Сервис для работы с корзиной.
|
4546
|
+
*/
|
4547
|
+
this.cartService = inject(ScCartService);
|
4548
|
+
}
|
4549
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: ScAddOrEditingCartItemDialogComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
4550
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.2.13", type: ScAddOrEditingCartItemDialogComponent, isStandalone: true, selector: "sc-add-or-editing-cart-item-dialog", viewQueries: [{ propertyName: "formComponent", first: true, predicate: ScAddOrEditingCartItemFormComponent, descendants: true, isSignal: true }], ngImport: i0, template: "@if (product) {\n <sc-add-or-editing-cart-item-form\n [product]=\"product\"\n [cartItem]=\"cartItem\"\n (addToCart)=\"onSubmit.next($event)\"\n (editCartItem)=\"onSubmit.next($event)\"\n [isLoading]=\"loading()\"\n ></sc-add-or-editing-cart-item-form>\n}\n", dependencies: [{ kind: "component", type: ScAddOrEditingCartItemFormComponent, selector: "sc-add-or-editing-cart-item-form", inputs: ["product", "cartItem", "isLoading"], outputs: ["addToCart", "editCartItem"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
|
4551
|
+
}
|
4552
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: ScAddOrEditingCartItemDialogComponent, decorators: [{
|
4553
|
+
type: Component,
|
4554
|
+
args: [{ standalone: true, selector: 'sc-add-or-editing-cart-item-dialog', imports: [ScAddOrEditingCartItemFormComponent], changeDetection: ChangeDetectionStrategy.OnPush, template: "@if (product) {\n <sc-add-or-editing-cart-item-form\n [product]=\"product\"\n [cartItem]=\"cartItem\"\n (addToCart)=\"onSubmit.next($event)\"\n (editCartItem)=\"onSubmit.next($event)\"\n [isLoading]=\"loading()\"\n ></sc-add-or-editing-cart-item-form>\n}\n" }]
|
4555
|
+
}] });
|
4556
|
+
|
4255
4557
|
/**
|
4256
4558
|
* Компонент скачивания каталога.
|
4257
4559
|
*/
|
@@ -7460,5 +7762,5 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImpo
|
|
7460
7762
|
* Generated bundle index. Do not edit.
|
7461
7763
|
*/
|
7462
7764
|
|
7463
|
-
export { AbstractScPriceCard, AuthMethod, CURRENT_COUNTRY_ID, FilesAndDocumentsComponent, FilesAndDocumentsModule, FinishDateTimeTransformerDirective, IS_DEFAULT_COUNTRY, MAX_FILES_IN_FORM_INPUT, SC_ALLOW_SELECT_TERMINATED, SC_DATE_FORMATTER, SC_ERROR_CHANGE_HANDLER, SC_HELP_NOTIFICATION_CLOSE, SC_HELP_NOTIFICATION_LIMIT, SC_MANAGER_QR_HANDLER, 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, ScAddressesSelectionFieldComponent, ScAuthModule, ScBannerComponent, ScBannerModule, ScBrandsListComponent, ScBrandsListModule, ScCarAddProductsFromCsvDialogComponent, ScCartItemComponent, ScCatalogModule, ScCategoryCardComponent, ScContactsAccordionComponent, ScContactsModule, ScContragentsAccordionComponent, ScContragentsAccordionItemComponent, ScContragentsModule, ScDeliveryAddressAccordionComponent, ScDeliveryAddressAccordionItemComponent, ScDeliveryAddressModule, ScDownloadPriceListComponent, ScEmailLinkDirective, ScErrorBlockStatusComponent, ScErrorHandlerComponent, ScFavoriteButtonComponent, ScFeedbackFormComponent, ScFormFieldsModule, ScFormatDatePipe, ScFrequentlyAskedQuestionsComponent, ScFrequentlyAskedQuestionsGroupSelectorComponent, ScFrequentlyAskedQuestionsWithGroupsComponent, ScGratitudeComponent, ScHelpNotificationService, ScInputQuantityComponent, ScLinks, ScManagerCardComponent, ScManagerCardPushComponent, ScNewContactFormComponent, ScNewContragentBankAccountsFormComponent, ScNewContragentFormComponent, ScNewsCardComponent, ScNewsCardSkeletonComponent, ScNewsModule, ScNextInputFocusDirective, ScNextInputFocusModule, ScNotifyWhenInStockDialogComponent, ScOrderItemMobileComponent, ScOrderModule, ScPaymentStatusComponent, ScPhoneFormatPipe, ScPreviewSampleComponent, ScPreviewSampleModule, ScPreviewSamplesMosquitoComponent, ScPriceCardComponent, ScPriceCardInlineComponent, ScPriceHistoryComponent, ScPriceListPaginationComponent, ScPriceWarehouseStockComponent, ScProductInAllWarehousesPipe, ScProfileAccordionsContentComponent, ScProfileModule, ScQRCodeDialogComponent, ScQRCodeModule, ScResetUserPasswordComponent, ScResourcePreviewComponent, ScShareButtonComponent, ScShareButtonModule, ScSignInFormByEmailComponent, ScSignInFormByPhoneComponent, ScSignInFormComponent, ScSignUpFormComponent, ScSimpleSignUpFormComponent, ScSuggestionFieldComponent, ScTelLinkDirective, ScTerminalLinkDirective, ScUpdateUserInfoDialogComponent, ScUserManagersComponent, ScUserModule, ScUserPhoneApproveDialogComponent, ScVerificationModule, ScVerificationPhoneCheckFormComponent, TreeDirective, TreeIconService, TreeLoaderService, TreeTopDirective, phoneValidator, scAtLeastOneRequiredValidator, scBicValidator, scClientUiIconsName, scCorrespondentAccountValidator, scPasswordConfirmMatchingValidator, stepValidator, tuiDateValueTransformerDefaultProvider };
|
7765
|
+
export { AbstractScPriceCard, AuthMethod, CURRENT_COUNTRY_ID, FilesAndDocumentsComponent, FilesAndDocumentsModule, FinishDateTimeTransformerDirective, IS_DEFAULT_COUNTRY, MAX_FILES_IN_FORM_INPUT, SC_ALLOW_SELECT_TERMINATED, SC_DATE_FORMATTER, SC_ERROR_CHANGE_HANDLER, SC_HELP_NOTIFICATION_CLOSE, SC_HELP_NOTIFICATION_LIMIT, SC_MANAGER_QR_HANDLER, 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, ScCarAddProductsFromCsvDialogComponent, ScCartItemComponent, ScCatalogModule, ScCategoryCardComponent, ScContactsAccordionComponent, ScContactsModule, ScContragentsAccordionComponent, ScContragentsAccordionItemComponent, ScContragentsModule, ScDeliveryAddressAccordionComponent, ScDeliveryAddressAccordionItemComponent, ScDeliveryAddressModule, ScDownloadPriceListComponent, ScEmailLinkDirective, ScErrorBlockStatusComponent, ScErrorHandlerComponent, ScFavoriteButtonComponent, ScFeedbackFormComponent, ScFormFieldsModule, ScFormatDatePipe, ScFrequentlyAskedQuestionsComponent, ScFrequentlyAskedQuestionsGroupSelectorComponent, ScFrequentlyAskedQuestionsWithGroupsComponent, ScGratitudeComponent, ScHelpNotificationService, ScInputQuantityComponent, ScLinks, ScManagerCardComponent, ScManagerCardPushComponent, ScNewContactFormComponent, ScNewContragentBankAccountsFormComponent, ScNewContragentFormComponent, ScNewsCardComponent, ScNewsCardSkeletonComponent, ScNewsModule, ScNextInputFocusDirective, ScNextInputFocusModule, ScNotifyWhenInStockDialogComponent, ScOrderItemMobileComponent, ScOrderModule, ScPaymentStatusComponent, ScPhoneFormatPipe, ScPreviewSampleComponent, ScPreviewSampleModule, ScPreviewSamplesMosquitoComponent, ScPriceCardComponent, ScPriceCardInlineComponent, ScPriceHistoryComponent, ScPriceListPaginationComponent, ScPriceWarehouseStockComponent, ScProductInAllWarehousesPipe, ScProfileAccordionsContentComponent, ScProfileModule, ScQRCodeDialogComponent, ScQRCodeModule, ScResetUserPasswordComponent, ScResourcePreviewComponent, ScSelectOnFocusinDirective, ScShareButtonComponent, ScShareButtonModule, ScSignInFormByEmailComponent, ScSignInFormByPhoneComponent, ScSignInFormComponent, ScSignUpFormComponent, ScSimpleSignUpFormComponent, ScSuggestionFieldComponent, ScTelLinkDirective, ScTerminalLinkDirective, ScUpdateUserInfoDialogComponent, ScUserManagersComponent, ScUserModule, ScUserPhoneApproveDialogComponent, ScVerificationModule, ScVerificationPhoneCheckFormComponent, TreeDirective, TreeIconService, TreeLoaderService, TreeTopDirective, phoneValidator, scAtLeastOneRequiredValidator, scBicValidator, scClientUiIconsName, scCorrespondentAccountValidator, scPasswordConfirmMatchingValidator, stepValidator, tuiDateValueTransformerDefaultProvider };
|
7464
7766
|
//# sourceMappingURL=snabcentr-client-ui.mjs.map
|