@snabcentr/client-ui 3.51.15 → 3.52.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/configurators/index.d.ts +1 -0
- package/configurators/models/index.d.ts +1 -0
- package/configurators/models/sandwich_m2/sc-i-sandwich-m2-settings.d.ts +18 -0
- package/configurators/sandwich/sc-sandwich.component.d.ts +24 -0
- package/configurators/sandwich_m2/index.d.ts +4 -0
- package/configurators/sandwich_m2/sandwich-m2-skeleton/sc-sandwich-m2-skeleton.component.d.ts +8 -0
- package/configurators/sandwich_m2/sc-i-new-cart-item-sandwich-m2.d.ts +23 -0
- package/configurators/sandwich_m2/sc-sandwich-m2-item-submit-state.d.ts +13 -0
- package/configurators/sandwich_m2/sc-sandwich-m2.component.d.ts +267 -0
- package/esm2022/configurators/index.mjs +2 -1
- package/esm2022/configurators/models/index.mjs +2 -1
- package/esm2022/configurators/models/sandwich_m2/sc-i-sandwich-m2-settings.mjs +2 -0
- package/esm2022/configurators/sandwich/sc-sandwich.component.mjs +57 -6
- package/esm2022/configurators/sandwich_m2/index.mjs +5 -0
- package/esm2022/configurators/sandwich_m2/sandwich-m2-skeleton/sc-sandwich-m2-skeleton.component.mjs +14 -0
- package/esm2022/configurators/sandwich_m2/sc-i-new-cart-item-sandwich-m2.mjs +2 -0
- package/esm2022/configurators/sandwich_m2/sc-sandwich-m2-item-submit-state.mjs +5 -0
- package/esm2022/configurators/sandwich_m2/sc-sandwich-m2.component.mjs +560 -0
- package/fesm2022/snabcentr-client-ui.mjs +613 -6
- package/fesm2022/snabcentr-client-ui.mjs.map +1 -1
- package/package.json +1 -1
- package/release_notes.tmp +6 -2
- package/styles/tailwind/tailwind.scss +72 -0
|
@@ -3,7 +3,7 @@ import { InjectionToken, inject, Injectable, NgZone, signal, EventEmitter, Chang
|
|
|
3
3
|
import * as i1 from '@snabcentr/client-core';
|
|
4
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, ScCartService, ScUploadedFile, SC_ORDER_LOADER, ScMimeTypes, ScCatalogService, SC_URLS, IS_SERVER, ScWarehouseService, SEARCH_TERM_PROVIDERS, ScPaginationService, SC_NEXT_PAGE_PAGINATION_CLICK, SC_PRODUCT_PAGINATION_OPTIONS, ScCatalogFilterService, ScIdOrSlugPipe, SC_CATEGORY_INFO, ScConfiguratorService, RESPONSE, ScIconTypesEnum, ScDocumentInfoTypesEnum, ScOrderDraftsService, ScRouteKeys, ScSeoService, scOrderIsLoaded, ScFrequentlyAskedQuestionsService, 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, merge, noop, first
|
|
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, merge, skip, from, concatMap, noop, first } 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';
|
|
@@ -25,7 +25,7 @@ import * as i5 from '@taiga-ui/core/components/label';
|
|
|
25
25
|
import * as i8 from '@maskito/angular';
|
|
26
26
|
import { MaskitoDirective } from '@maskito/angular';
|
|
27
27
|
import * as i2$2 from '@angular/common';
|
|
28
|
-
import { DOCUMENT, CommonModule, NgIf, AsyncPipe, NgFor, NgClass } from '@angular/common';
|
|
28
|
+
import { DOCUMENT, CommonModule, NgIf, AsyncPipe, DecimalPipe, NgFor, NgClass } from '@angular/common';
|
|
29
29
|
import * as i2$3 from '@taiga-ui/polymorpheus';
|
|
30
30
|
import { POLYMORPHEUS_CONTEXT, PolymorpheusComponent, PolymorpheusTemplate, PolymorpheusOutlet, injectContext } from '@taiga-ui/polymorpheus';
|
|
31
31
|
import * as i2 from 'angularx-qrcode';
|
|
@@ -5870,14 +5870,22 @@ class ScSandwichComponent {
|
|
|
5870
5870
|
* Выбранный продукт (материал для раскроя).
|
|
5871
5871
|
*/
|
|
5872
5872
|
this.product = new FormControl(null, { validators: Validators.required });
|
|
5873
|
+
/**
|
|
5874
|
+
* Сигнал текущего выбранного продукта — используется в шаблоне для диапазонов и кнопок.
|
|
5875
|
+
*/
|
|
5876
|
+
this.productSignal = toSignal(tuiControlValue(this.product), { initialValue: null });
|
|
5873
5877
|
/**
|
|
5874
5878
|
* Субъект для ручного запуска расчёта.
|
|
5875
5879
|
*/
|
|
5876
5880
|
this.calculateTrigger$ = new Subject();
|
|
5881
|
+
/**
|
|
5882
|
+
* Источник начального результата расчёта для режима редактирования.
|
|
5883
|
+
*/
|
|
5884
|
+
this.seedCalculateResult$ = new BehaviorSubject(undefined);
|
|
5877
5885
|
/**
|
|
5878
5886
|
* {@link Observable} расчета оптимизации раскладки.
|
|
5879
5887
|
*/
|
|
5880
|
-
this.calculate$ = merge(merge(tuiControlValue(this.product), tuiControlValue(this.items)).pipe(
|
|
5888
|
+
this.calculate$ = merge(this.seedCalculateResult$, merge(tuiControlValue(this.product).pipe(skip(1)), tuiControlValue(this.items).pipe(skip(1))).pipe(
|
|
5881
5889
|
// eslint-disable-next-line unicorn/no-useless-undefined
|
|
5882
5890
|
map(() => undefined)), this.calculateTrigger$.pipe(switchMap(() => {
|
|
5883
5891
|
const productId = this.product.value?.id ?? null;
|
|
@@ -5906,6 +5914,14 @@ class ScSandwichComponent {
|
|
|
5906
5914
|
* Валидатор для длины изделия.
|
|
5907
5915
|
*/
|
|
5908
5916
|
this.validatorLength$ = tuiControlValue(this.product).pipe(map((product) => Validators.min(product?.properties?.length ?? 0)));
|
|
5917
|
+
/**
|
|
5918
|
+
* Текст ограничения по ширине («от … до …»), пока выбран товар.
|
|
5919
|
+
*/
|
|
5920
|
+
this.widthRangeText = computed(() => this.formatRange(this.settings()?.minWidth ?? null, this.productSignal()?.properties?.width ?? null, 'мм'));
|
|
5921
|
+
/**
|
|
5922
|
+
* Текст ограничения по длине («от … до …»), пока выбран товар.
|
|
5923
|
+
*/
|
|
5924
|
+
this.lengthRangeText = computed(() => this.formatRange(this.settings()?.minLength ?? null, this.productSignal()?.properties?.length ?? null, 'мм'));
|
|
5909
5925
|
/**
|
|
5910
5926
|
* Признак того, что выполняется запрос на отправку данных выполняется.
|
|
5911
5927
|
*/
|
|
@@ -6039,6 +6055,28 @@ class ScSandwichComponent {
|
|
|
6039
6055
|
}))
|
|
6040
6056
|
.subscribe();
|
|
6041
6057
|
}
|
|
6058
|
+
/**
|
|
6059
|
+
* Форматирование диапазона «от … до …» с учётом отсутствующих границ.
|
|
6060
|
+
*
|
|
6061
|
+
* @param min Нижняя граница.
|
|
6062
|
+
* @param max Верхняя граница.
|
|
6063
|
+
* @param unit Единица измерения.
|
|
6064
|
+
*/
|
|
6065
|
+
// eslint-disable-next-line class-methods-use-this
|
|
6066
|
+
formatRange(min, max, unit) {
|
|
6067
|
+
const hasMin = min != null && min > 0;
|
|
6068
|
+
const hasMax = max != null && max > 0;
|
|
6069
|
+
if (!hasMin && !hasMax) {
|
|
6070
|
+
return null;
|
|
6071
|
+
}
|
|
6072
|
+
if (hasMin && hasMax) {
|
|
6073
|
+
return `от ${min} ${unit} до ${max} ${unit}`;
|
|
6074
|
+
}
|
|
6075
|
+
if (hasMin) {
|
|
6076
|
+
return `от ${min} ${unit}`;
|
|
6077
|
+
}
|
|
6078
|
+
return `до ${max} ${unit}`;
|
|
6079
|
+
}
|
|
6042
6080
|
/**
|
|
6043
6081
|
* Устанавливает начальные значения для полей формы.
|
|
6044
6082
|
*/
|
|
@@ -6058,6 +6096,19 @@ class ScSandwichComponent {
|
|
|
6058
6096
|
if (!configuratorParameters?.items.length) {
|
|
6059
6097
|
this.addItem();
|
|
6060
6098
|
}
|
|
6099
|
+
// Сбрасываем seed и при наличии сохранённого calculationId восстанавливаем результат расчёта —
|
|
6100
|
+
// чтобы в режиме редактирования сразу была видна кнопка «Изменить», а не «Рассчитать».
|
|
6101
|
+
// eslint-disable-next-line unicorn/no-useless-undefined
|
|
6102
|
+
this.seedCalculateResult$.next(undefined);
|
|
6103
|
+
const existingCalculationId = configuratorParameters?.calculationId;
|
|
6104
|
+
const existingQuantity = this.orderItem()?.quantity;
|
|
6105
|
+
if (existingCalculationId && existingQuantity != null && existingQuantity > 0) {
|
|
6106
|
+
this.seedCalculateResult$.next({
|
|
6107
|
+
id: existingCalculationId,
|
|
6108
|
+
quantity: existingQuantity,
|
|
6109
|
+
sheets: [],
|
|
6110
|
+
});
|
|
6111
|
+
}
|
|
6061
6112
|
}
|
|
6062
6113
|
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: ScSandwichComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
6063
6114
|
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.2.14", type: ScSandwichComponent, isStandalone: true, selector: "sc-sandwich", inputs: { settings: { classPropertyName: "settings", publicName: "settings", isSignal: true, isRequired: false, transformFunction: null }, categoryId: { classPropertyName: "categoryId", publicName: "categoryId", isSignal: true, isRequired: true, transformFunction: null }, editor: { classPropertyName: "editor", publicName: "editor", isSignal: true, isRequired: true, transformFunction: null }, orderItem: { classPropertyName: "orderItem", publicName: "orderItem", isSignal: true, isRequired: true, transformFunction: null }, orderId: { classPropertyName: "orderId", publicName: "orderId", isSignal: false, isRequired: false, transformFunction: null } }, outputs: { toggleShowEvent: "toggleShowEvent" }, providers: [
|
|
@@ -6069,7 +6120,7 @@ class ScSandwichComponent {
|
|
|
6069
6120
|
stringify: signal((x) => x.name),
|
|
6070
6121
|
identityMatcher: signal((a, b) => a.id === b.id),
|
|
6071
6122
|
}),
|
|
6072
|
-
], ngImport: i0, template: "@if (!orderItem() && settings()?.allowShowTable) {\n <div class=\"mb-5 flex justify-center\">\n <button\n tuiButton\n appearance=\"secondary\"\n (click)=\"toggleShowEvent.emit()\"\n type=\"button\"\n iconStart=\"@tui.layout-list\"\n >\n \u041F\u043E\u043A\u0430\u0437\u0430\u0442\u044C \u0432 \u0432\u0438\u0434\u0435 \u0441\u043F\u0438\u0441\u043A\u0430\n </button>\n </div>\n}\n<div class=\"\">\n @let calculateResult = calculateResult$ | async;\n @let products = products$ | async;\n @let productValue = product.value;\n @let validatorWidth = validatorWidth$ | async;\n @let validatorLength = validatorLength$ | async;\n\n <form\n [formGroup]=\"form\"\n (ngSubmit)=\"onSubmit(calculateResult)\"\n ScNextInputFocus\n class=\"flex flex-col gap-3\"\n >\n <label\n tuiLabel\n class=\"grow\"\n >\n \u0422\u043E\u0432\u0430\u0440\n <tui-textfield\n tuiChevron\n [tuiTextfieldCleaner]=\"false\"\n >\n <input\n tuiChevron\n tuiSelect\n [formControl]=\"product\"\n placeholder=\"\u0412\u044B\u0431\u0435\u0440\u0438\u0442\u0435 \u043C\u0430\u0442\u0435\u0440\u0438\u0430\u043B\"\n />\n\n <tui-data-list-wrapper\n *tuiTextfieldDropdown\n new\n [items]=\"products\"\n />\n </tui-textfield>\n @if (productValue) {\n <div class=\"ml-2 text-tui-text-secondary\">\n \u0421\u0442\u043E\u0438\u043C\u043E\u0441\u0442\u044C:\n <span class=\"font-bold\">{{ productValue.costRub?.toLocaleString() }} {{ productValue.currency.symbol }}/\u0448\u0442.</span>\n </div>\n }\n <tui-error\n [formControl]=\"product\"\n [error]=\"[] | tuiFieldError | async\"\n />\n </label>\n\n @if (product.value && validatorWidth && validatorLength) {\n <p class=\"w-full font-bold\">\u0420\u0430\u0437\u043C\u0435\u0440\u044B \u0438\u0437\u0434\u0435\u043B\u0438\u0439</p>\n <p class=\"w-full\">\n \u041C\u0438\u043D\u0438\u043C\u0430\u043B\u044C\u043D\u0430\u044F \u0448\u0438\u0440\u0438\u043D\u0430: {{ settings()?.minWidth }} \u043C\u043C.\n <br />\n \u041C\u0430\u043A\u0441\u0438\u043C\u0430\u043B\u044C\u043D\u0430\u044F \u0448\u0438\u0440\u0438\u043D\u0430: {{ product.value.properties?.width }} \u043C\u043C.\n <br />\n \u041C\u0438\u043D\u0438\u043C\u0430\u043B\u044C\u043D\u0430\u044F \u0434\u043B\u0438\u043D\u0430: {{ settings()?.minLength }} \u043C\u043C.\n <br />\n \u041C\u0430\u043A\u0441\u0438\u043C\u0430\u043B\u044C\u043D\u0430\u044F \u0434\u043B\u0438\u043D\u0430: {{ product.value.properties?.length }} \u043C\u043C.\n <br />\n </p>\n <div\n formArrayName=\"items\"\n class=\"flex flex-col gap-3\"\n >\n @for (item of items.controls; track item) {\n <div\n class=\"flex grow gap-2\"\n [formGroupName]=\"$index\"\n >\n <div class=\"grid grow grid-cols-3 gap-2\">\n <label tuiLabel>\n \u0428\u0438\u0440\u0438\u043D\u0430, \u043C\u043C\n <tui-textfield>\n <input\n tuiInputSlider\n formControlName=\"width\"\n [min]=\"settings()?.minWidth ?? 0\"\n [max]=\"product.value.properties?.width ?? 0\"\n [tuiNumberFormat]=\"{ precision: 0 }\"\n placeholder=\"\u0428\u0438\u0440\u0438\u043D\u0430\"\n autocomplete=\"off\"\n />\n @if (product.value) {\n <input\n tuiSlider\n type=\"range\"\n />\n }\n </tui-textfield>\n @if (product.value) {\n <div class=\"slider-ticks-labels\">\n <span> 0 </span>\n <span>{{ product.value.properties?.width }}</span>\n </div>\n }\n <tui-error\n formControlName=\"width\"\n [error]=\"[] | tuiFieldError | async\"\n />\n </label>\n\n <label tuiLabel>\n \u0414\u043B\u0438\u043D\u0430, \u043C\u043C\n <tui-textfield>\n <input\n tuiInputSlider\n formControlName=\"length\"\n [min]=\"settings()?.minLength ?? 0\"\n [max]=\"product.value.properties?.length ?? 0\"\n [tuiNumberFormat]=\"{ precision: 0 }\"\n placeholder=\"\u0414\u043B\u0438\u043D\u0430\"\n autocomplete=\"off\"\n />\n @if (product.value) {\n <input\n tuiSlider\n type=\"range\"\n />\n }\n </tui-textfield>\n @if (product.value) {\n <div class=\"slider-ticks-labels\">\n <span> 0 </span>\n <span>{{ product.value.properties?.length }}</span>\n </div>\n }\n <tui-error\n formControlName=\"length\"\n [error]=\"[] | tuiFieldError | async\"\n />\n </label>\n <label tuiLabel>\n <span class=\"whitespace-nowrap\">\u041A\u043E\u043B\u0438\u0447\u0435\u0441\u0442\u0432\u043E, \u0448\u0442</span>\n <tui-textfield [tuiTextfieldCleaner]=\"false\">\n <input\n tuiInputNumber\n formControlName=\"count\"\n [min]=\"1\"\n [tuiNumberFormat]=\"{ precision: 0 }\"\n placeholder=\"\u041A\u043E\u043B\u0438\u0447\u0435\u0441\u0442\u0432\u043E\"\n autocomplete=\"off\"\n />\n </tui-textfield>\n <tui-error\n formControlName=\"count\"\n [error]=\"[] | tuiFieldError | async\"\n />\n </label>\n </div>\n <button\n tuiIconButton\n (click)=\"removeItem($index)\"\n [disabled]=\"items.length <= 1\"\n size=\"m\"\n type=\"button\"\n iconStart=\"@tui.trash-2\"\n appearance=\"secondary\"\n class=\"mt-6\"\n [style.flex]=\"'0 0 auto'\"\n ></button>\n </div>\n }\n </div>\n <button\n tuiButton\n appearance=\"secondary\"\n [disabled]=\"items.invalid\"\n (click)=\"addItem()\"\n type=\"button\"\n class=\"self-center\"\n iconStart=\"@tui.plus\"\n >\n \u0414\u043E\u0431\u0430\u0432\u0438\u0442\u044C \u0438\u0437\u0434\u0435\u043B\u0438\u0435\n </button>\n } @else if (product.value) {\n <tui-error error=\"\u0420\u0430\u0441\u0447\u0435\u0442 \u043F\u043E \u043F\u0440\u043E\u0434\u0443\u043A\u0442\u0443 \u043D\u0435\u0432\u043E\u0437\u043C\u043E\u0436\u0435\u043D. \u041E\u0431\u0440\u0430\u0442\u0438\u0442\u0435\u0441\u044C \u043A \u043C\u0435\u043D\u0435\u0434\u0436\u0435\u0440\u0443\" />\n }\n\n <label tuiLabel>\n \u041C\u0430\u0440\u043A\u0438\u0440\u043E\u0432\u043A\u0430 \u0440\u0430\u0441\u043F\u0438\u043B\u0430\n <tui-textfield>\n <input\n tuiTextfield\n formControlName=\"marker\"\n placeholder=\"\u041C\u0430\u0440\u043A\u0438\u0440\u043E\u0432\u043A\u0430 \u0440\u0430\u0441\u043F\u0438\u043B\u0430\"\n autocomplete=\"marker\"\n />\n </tui-textfield>\n\n <tui-error\n formControlName=\"marker\"\n [error]=\"[] | tuiFieldError | async\"\n />\n </label>\n\n @if (product.value) {\n <tui-loader [showLoader]=\"isCalculateLoading()\">\n @if (calculateResult) {\n <div class=\"mt-2 flex flex-wrap items-end gap-2\">\n <div>\n \u0418\u0442\u043E\u0433\u043E: <span class=\"whitespace-nowrap text-xl font-bold\">{{ getTotalCost(calculateResult).toLocaleString() }} {{ product.value.currency.symbol }}</span>\n </div>\n @if (calculateResult?.quantity && productValue) {\n <div class=\"whitespace-nowrap text-lg text-sc-dark-grey\">\n <span class=\"font-bold\">({{ calculateResult.quantity }} \u0448\u0442.</span> x\n <span class=\"font-bold\">{{ productValue.costRub?.toLocaleString() }} {{ productValue.currency.symbol }}/\u0448\u0442.)</span>\n </div>\n }\n </div>\n }\n </tui-loader>\n }\n\n <tui-error [error]=\"[] | tuiFieldError | async\" />\n @if (!calculateResult) {\n <button\n tuiButton\n appearance=\"secondary\"\n [disabled]=\"items.invalid || isCalculateLoading()\"\n (click)=\"triggerCalculate()\"\n type=\"button\"\n class=\"self-center\"\n iconStart=\"@tui.calculator\"\n >\n \u0420\u0430\u0441\u0441\u0447\u0438\u0442\u0430\u0442\u044C\n </button>\n } @else {\n <button\n [disabled]=\"form.invalid || isSubmitLoading()\"\n [loading]=\"isSubmitLoading()\"\n tuiButton\n class=\"self-center\"\n iconStart=\"@tui.check\"\n >\n {{ !orderItem() ? '\u0414\u043E\u0431\u0430\u0432\u0438\u0442\u044C \u0432 \u043A\u043E\u0440\u0437\u0438\u043D\u0443' : '\u0418\u0437\u043C\u0435\u043D\u0438\u0442\u044C' }}\n </button>\n }\n </form>\n</div>\n", styles: [":host{display:block;width:100%;max-width:30rem}.slider-ticks-labels{--t-offset: calc($thumb / 2);display:flex;font:var(--tui-font-text-s);margin-inline-start:var(--t-offset);margin-inline-end:var(--t-offset);color:var(--tui-text-secondary)}.slider-ticks-labels>*{position:relative;flex:2;text-align:center}.slider-ticks-labels>*:first-child{left:calc(-1 * var(--t-offset));inset-inline-start:calc(-1 * var(--t-offset));flex:1;text-align:start}.slider-ticks-labels>*:last-child{right:calc(-1 * var(--t-offset));flex:1;text-align:end}@supports (inset-inline-end: 0){.slider-ticks-labels>*:last-child{right:unset;inset-inline-end:calc(-1 * var(--t-offset))}}tui-input-slider+.slider-ticks-labels{margin-inline-start:calc(var(--tui-radius-m) / 2 + var(--t-offset))}tui-textfield+.slider-ticks-labels{--t-offset: calc(var(--tui-radius-m) / 2 + $thumb / 2)}tui-textfield[data-size=l]+.slider-ticks-labels{--t-offset: calc(var(--tui-radius-l) / 2 + $thumb / 2)}tui-input-range:not([new])+.slider-ticks-labels,tui-range+.slider-ticks-labels{--t-offset: $thumb}tui-input-range[new]+.slider-ticks-labels{--t-offset: calc(map-get($track-inset, $input-size) + $thumb)}\n"], dependencies: [{ kind: "directive", type: TuiButton, selector: "a[tuiButton],button[tuiButton],a[tuiIconButton],button[tuiIconButton]", inputs: ["size"] }, { kind: "ngmodule", type: FormsModule }, { 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: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1$1.FormControlDirective, selector: "[formControl]", inputs: ["formControl", "disabled", "ngModel"], outputs: ["ngModelChange"], exportAs: ["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: "directive", type: i1$1.FormGroupName, selector: "[formGroupName]", inputs: ["formGroupName"] }, { kind: "directive", type: i1$1.FormArrayName, selector: "[formArrayName]", inputs: ["formArrayName"] }, { kind: "ngmodule", type: ScNextInputFocusModule }, { kind: "directive", type: ScNextInputFocusDirective, selector: "form[ScNextInputFocus]" }, { kind: "directive", type: TuiLabel, selector: "label[tuiLabel]" }, { kind: "component", type: TuiDataListWrapperComponent, selector: "tui-data-list-wrapper:not([labels]), tui-data-list-wrapper:not([labels])[new]", inputs: ["items", "disabledItemHandler", "emptyContent", "size", "itemContent"], outputs: ["itemClick"] }, { kind: "component", type: TuiError, selector: "tui-error", inputs: ["error"] }, { kind: "component", type: i1$2.TuiTextfieldComponent, selector: "tui-textfield:not([multi])" }, { kind: "directive", type: i1$2.TuiTextfieldDirective, selector: "input[tuiTextfield]:not([tuiInputCard]):not([tuiInputExpire]):not([tuiInputCVC])" }, { kind: "directive", type: i1$2.TuiTextfieldOptionsDirective, selector: "[tuiTextfieldAppearance],[tuiTextfieldSize],[tuiTextfieldCleaner]", inputs: ["tuiTextfieldAppearance", "tuiTextfieldSize", "tuiTextfieldCleaner"] }, { kind: "directive", type: i1$2.TuiTextfieldDropdownDirective, selector: "ng-template[tuiTextfieldDropdown]" }, { kind: "directive", type: TuiChevron, selector: "[tuiChevron]", inputs: ["tuiChevron"] }, { kind: "directive", type: i2$1.TuiSelectDirective, selector: "input[tuiSelect]" }, { kind: "directive", type: i2$1.TuiInputNumberDirective, selector: "input[tuiInputNumber]", inputs: ["min", "max", "prefix", "postfix"] }, { kind: "directive", type: TuiNumberFormat, selector: "[tuiNumberFormat]", inputs: ["tuiNumberFormat"] }, { kind: "pipe", type: AsyncPipe, name: "async" }, { kind: "pipe", type: TuiFieldErrorPipe, name: "tuiFieldError" }, { kind: "component", type: i5$2.TuiSliderComponent, selector: "input[type=range][tuiSlider]", inputs: ["size", "segments"] }, { kind: "directive", type: i2$1.TuiInputSliderDirective, selector: "input[tuiInputSlider]" }, { kind: "directive", type: ScSelectOnFocusinDirective, selector: "tui-input-number, tui-input, tui-input-phone, tui-input-date, tui-input-password, input[tuiInputNumber], input[tuiTextfield], input[tuiInputSlider]" }, { kind: "component", type: TuiLoader, selector: "tui-loader", inputs: ["size", "inheritColor", "overlay", "textContent", "showLoader"] }, { kind: "component", type: TuiButtonLoading, selector: "[tuiButton][loading],[tuiIconButton][loading]", inputs: ["size", "loading"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
|
|
6123
|
+
], ngImport: i0, template: "@if (!orderItem() && settings()?.allowShowTable) {\n <div class=\"mb-5 flex justify-center\">\n <button\n tuiButton\n appearance=\"secondary\"\n (click)=\"toggleShowEvent.emit()\"\n type=\"button\"\n iconStart=\"@tui.layout-list\"\n >\n \u041F\u043E\u043A\u0430\u0437\u0430\u0442\u044C \u0432 \u0432\u0438\u0434\u0435 \u0441\u043F\u0438\u0441\u043A\u0430\n </button>\n </div>\n}\n<div>\n @let calculateResult = calculateResult$ | async;\n @let products = products$ | async;\n @let productValue = product.value;\n @let validatorWidth = validatorWidth$ | async;\n @let validatorLength = validatorLength$ | async;\n\n <form\n [formGroup]=\"form\"\n (ngSubmit)=\"onSubmit(calculateResult)\"\n ScNextInputFocus\n class=\"flex flex-col gap-3\"\n >\n <label\n tuiLabel\n class=\"grow\"\n >\n \u0422\u043E\u0432\u0430\u0440\n <tui-textfield\n tuiChevron\n [tuiTextfieldCleaner]=\"false\"\n >\n <input\n tuiChevron\n tuiSelect\n [formControl]=\"product\"\n placeholder=\"\u0412\u044B\u0431\u0435\u0440\u0438\u0442\u0435 \u043C\u0430\u0442\u0435\u0440\u0438\u0430\u043B\"\n />\n\n <tui-data-list-wrapper\n *tuiTextfieldDropdown\n new\n [items]=\"products\"\n />\n </tui-textfield>\n <tui-error\n [formControl]=\"product\"\n [error]=\"[] | tuiFieldError | async\"\n />\n </label>\n\n @if (productValue && productValue.costRub) {\n <div class=\"-mt-1 text-sm text-tui-text-secondary\">\n <span class=\"font-bold\">{{ productValue.code }}</span>\n \u2014 {{ productValue.costRub.toLocaleString() }} {{ productValue.currency.symbol }}/\u0448\u0442.\n </div>\n }\n\n @if (product.value && validatorWidth && validatorLength) {\n <div class=\"mt-4 flex flex-col gap-1.5\">\n <div class=\"w-full font-bold\">\u0420\u0430\u0437\u043C\u0435\u0440\u044B \u0438\u0437\u0434\u0435\u043B\u0438\u0439</div>\n <div class=\"flex flex-col gap-1 text-sm text-tui-text-secondary\">\n @if (widthRangeText()) {\n <div>\u0428\u0438\u0440\u0438\u043D\u0430 {{ widthRangeText() }}.</div>\n }\n @if (lengthRangeText()) {\n <div>\u0414\u043B\u0438\u043D\u0430 {{ lengthRangeText() }}.</div>\n }\n </div>\n </div>\n } @else if (product.value) {\n <tui-error error=\"\u0420\u0430\u0441\u0447\u0435\u0442 \u043F\u043E \u043F\u0440\u043E\u0434\u0443\u043A\u0442\u0443 \u043D\u0435\u0432\u043E\u0437\u043C\u043E\u0436\u0435\u043D. \u041E\u0431\u0440\u0430\u0442\u0438\u0442\u0435\u0441\u044C \u043A \u043C\u0435\u043D\u0435\u0434\u0436\u0435\u0440\u0443\" />\n }\n\n <div\n formArrayName=\"items\"\n class=\"flex flex-col gap-3\"\n >\n @for (item of items.controls; track item) {\n <div\n class=\"flex grow gap-2\"\n [formGroupName]=\"$index\"\n >\n <div class=\"grid grow grid-cols-1 items-start gap-2 sm:grid-cols-3\">\n <label tuiLabel>\n \u0428\u0438\u0440\u0438\u043D\u0430, \u043C\u043C\n <tui-textfield>\n <input\n tuiInputSlider\n formControlName=\"width\"\n [min]=\"settings()?.minWidth ?? 0\"\n [max]=\"product.value?.properties?.width ?? 0\"\n [tuiNumberFormat]=\"{ precision: 0 }\"\n [readOnly]=\"!product.value\"\n placeholder=\"\u0428\u0438\u0440\u0438\u043D\u0430\"\n autocomplete=\"off\"\n />\n @if (product.value) {\n <input\n tuiSlider\n type=\"range\"\n />\n }\n </tui-textfield>\n @if (product.value) {\n <div class=\"slider-ticks-labels\">\n <span> 0 </span>\n <span>{{ product.value.properties?.width }}</span>\n </div>\n }\n <tui-error\n formControlName=\"width\"\n [error]=\"[] | tuiFieldError | async\"\n />\n </label>\n\n <label tuiLabel>\n \u0414\u043B\u0438\u043D\u0430, \u043C\u043C\n <tui-textfield>\n <input\n tuiInputSlider\n formControlName=\"length\"\n [min]=\"settings()?.minLength ?? 0\"\n [max]=\"product.value?.properties?.length ?? 0\"\n [tuiNumberFormat]=\"{ precision: 0 }\"\n [readOnly]=\"!product.value\"\n placeholder=\"\u0414\u043B\u0438\u043D\u0430\"\n autocomplete=\"off\"\n />\n @if (product.value) {\n <input\n tuiSlider\n type=\"range\"\n />\n }\n </tui-textfield>\n @if (product.value) {\n <div class=\"slider-ticks-labels\">\n <span> 0 </span>\n <span>{{ product.value.properties?.length }}</span>\n </div>\n }\n <tui-error\n formControlName=\"length\"\n [error]=\"[] | tuiFieldError | async\"\n />\n </label>\n <label tuiLabel>\n <span class=\"whitespace-nowrap\">\u041A\u043E\u043B\u0438\u0447\u0435\u0441\u0442\u0432\u043E, \u0448\u0442</span>\n <tui-textfield [tuiTextfieldCleaner]=\"false\">\n <input\n tuiInputNumber\n formControlName=\"count\"\n [min]=\"1\"\n [tuiNumberFormat]=\"{ precision: 0 }\"\n [readOnly]=\"!product.value\"\n placeholder=\"\u041A\u043E\u043B\u0438\u0447\u0435\u0441\u0442\u0432\u043E\"\n autocomplete=\"off\"\n />\n </tui-textfield>\n <tui-error\n formControlName=\"count\"\n [error]=\"[] | tuiFieldError | async\"\n />\n </label>\n </div>\n <button\n tuiIconButton\n (click)=\"removeItem($index)\"\n [disabled]=\"!product.value || items.length <= 1\"\n size=\"m\"\n type=\"button\"\n iconStart=\"@tui.trash-2\"\n appearance=\"secondary\"\n class=\"mt-6\"\n [style.flex]=\"'0 0 auto'\"\n ></button>\n </div>\n }\n </div>\n @if (product.value) {\n <button\n tuiButton\n appearance=\"secondary\"\n [disabled]=\"items.invalid\"\n (click)=\"addItem()\"\n type=\"button\"\n class=\"self-center\"\n iconStart=\"@tui.plus\"\n >\n \u0414\u043E\u0431\u0430\u0432\u0438\u0442\u044C \u0438\u0437\u0434\u0435\u043B\u0438\u0435\n </button>\n }\n\n <label tuiLabel>\n \u041C\u0430\u0440\u043A\u0438\u0440\u043E\u0432\u043A\u0430 \u0440\u0430\u0441\u043F\u0438\u043B\u0430\n <tui-textfield>\n <input\n tuiTextfield\n formControlName=\"marker\"\n placeholder=\"\u041C\u0430\u0440\u043A\u0438\u0440\u043E\u0432\u043A\u0430 \u0440\u0430\u0441\u043F\u0438\u043B\u0430\"\n autocomplete=\"marker\"\n />\n </tui-textfield>\n\n <tui-error\n formControlName=\"marker\"\n [error]=\"[] | tuiFieldError | async\"\n />\n </label>\n\n @if (product.value) {\n <tui-loader [showLoader]=\"isCalculateLoading()\">\n @if (calculateResult) {\n <div class=\"mt-2 flex flex-wrap items-end gap-2\">\n <div>\n \u0418\u0442\u043E\u0433\u043E: <span class=\"whitespace-nowrap text-xl font-bold\">{{ getTotalCost(calculateResult).toLocaleString() }} {{ product.value.currency.symbol }}</span>\n </div>\n @if (calculateResult?.quantity && productValue) {\n <div class=\"whitespace-nowrap text-lg text-sc-dark-grey\">\n <span class=\"font-bold\">({{ calculateResult.quantity }} \u0448\u0442.</span> x\n <span class=\"font-bold\">{{ productValue.costRub?.toLocaleString() }} {{ productValue.currency.symbol }}/\u0448\u0442.)</span>\n </div>\n }\n </div>\n }\n </tui-loader>\n }\n\n <tui-error [error]=\"[] | tuiFieldError | async\" />\n @if (!calculateResult) {\n <button\n tuiButton\n appearance=\"secondary\"\n [disabled]=\"items.invalid || isCalculateLoading()\"\n (click)=\"triggerCalculate()\"\n type=\"button\"\n class=\"self-center\"\n iconStart=\"@tui.calculator\"\n >\n \u0420\u0430\u0441\u0441\u0447\u0438\u0442\u0430\u0442\u044C\n </button>\n } @else {\n <button\n [disabled]=\"form.invalid || isSubmitLoading()\"\n [loading]=\"isSubmitLoading()\"\n tuiButton\n class=\"self-center\"\n iconStart=\"@tui.check\"\n >\n {{ !orderItem() ? '\u0414\u043E\u0431\u0430\u0432\u0438\u0442\u044C \u0432 \u043A\u043E\u0440\u0437\u0438\u043D\u0443' : '\u0418\u0437\u043C\u0435\u043D\u0438\u0442\u044C' }}\n </button>\n }\n </form>\n</div>\n", styles: [":host{display:block;width:100%;max-width:30rem}.slider-ticks-labels{--t-offset: calc($thumb / 2);display:flex;font:var(--tui-font-text-s);margin-inline-start:var(--t-offset);margin-inline-end:var(--t-offset);color:var(--tui-text-secondary)}.slider-ticks-labels>*{position:relative;flex:2;text-align:center}.slider-ticks-labels>*:first-child{left:calc(-1 * var(--t-offset));inset-inline-start:calc(-1 * var(--t-offset));flex:1;text-align:start}.slider-ticks-labels>*:last-child{right:calc(-1 * var(--t-offset));flex:1;text-align:end}@supports (inset-inline-end: 0){.slider-ticks-labels>*:last-child{right:unset;inset-inline-end:calc(-1 * var(--t-offset))}}tui-input-slider+.slider-ticks-labels{margin-inline-start:calc(var(--tui-radius-m) / 2 + var(--t-offset))}tui-textfield+.slider-ticks-labels{--t-offset: calc(var(--tui-radius-m) / 2 + $thumb / 2)}tui-textfield[data-size=l]+.slider-ticks-labels{--t-offset: calc(var(--tui-radius-l) / 2 + $thumb / 2)}tui-input-range:not([new])+.slider-ticks-labels,tui-range+.slider-ticks-labels{--t-offset: $thumb}tui-input-range[new]+.slider-ticks-labels{--t-offset: calc(map-get($track-inset, $input-size) + $thumb)}\n"], dependencies: [{ kind: "directive", type: TuiButton, selector: "a[tuiButton],button[tuiButton],a[tuiIconButton],button[tuiIconButton]", inputs: ["size"] }, { kind: "ngmodule", type: FormsModule }, { 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: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1$1.FormControlDirective, selector: "[formControl]", inputs: ["formControl", "disabled", "ngModel"], outputs: ["ngModelChange"], exportAs: ["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: "directive", type: i1$1.FormGroupName, selector: "[formGroupName]", inputs: ["formGroupName"] }, { kind: "directive", type: i1$1.FormArrayName, selector: "[formArrayName]", inputs: ["formArrayName"] }, { kind: "ngmodule", type: ScNextInputFocusModule }, { kind: "directive", type: ScNextInputFocusDirective, selector: "form[ScNextInputFocus]" }, { kind: "directive", type: TuiLabel, selector: "label[tuiLabel]" }, { kind: "component", type: TuiDataListWrapperComponent, selector: "tui-data-list-wrapper:not([labels]), tui-data-list-wrapper:not([labels])[new]", inputs: ["items", "disabledItemHandler", "emptyContent", "size", "itemContent"], outputs: ["itemClick"] }, { kind: "component", type: TuiError, selector: "tui-error", inputs: ["error"] }, { kind: "component", type: i1$2.TuiTextfieldComponent, selector: "tui-textfield:not([multi])" }, { kind: "directive", type: i1$2.TuiTextfieldDirective, selector: "input[tuiTextfield]:not([tuiInputCard]):not([tuiInputExpire]):not([tuiInputCVC])" }, { kind: "directive", type: i1$2.TuiTextfieldOptionsDirective, selector: "[tuiTextfieldAppearance],[tuiTextfieldSize],[tuiTextfieldCleaner]", inputs: ["tuiTextfieldAppearance", "tuiTextfieldSize", "tuiTextfieldCleaner"] }, { kind: "directive", type: i1$2.TuiTextfieldDropdownDirective, selector: "ng-template[tuiTextfieldDropdown]" }, { kind: "directive", type: TuiChevron, selector: "[tuiChevron]", inputs: ["tuiChevron"] }, { kind: "directive", type: i2$1.TuiSelectDirective, selector: "input[tuiSelect]" }, { kind: "directive", type: i2$1.TuiInputNumberDirective, selector: "input[tuiInputNumber]", inputs: ["min", "max", "prefix", "postfix"] }, { kind: "directive", type: TuiNumberFormat, selector: "[tuiNumberFormat]", inputs: ["tuiNumberFormat"] }, { kind: "pipe", type: AsyncPipe, name: "async" }, { kind: "pipe", type: TuiFieldErrorPipe, name: "tuiFieldError" }, { kind: "component", type: i5$2.TuiSliderComponent, selector: "input[type=range][tuiSlider]", inputs: ["size", "segments"] }, { kind: "directive", type: i2$1.TuiInputSliderDirective, selector: "input[tuiInputSlider]" }, { kind: "directive", type: ScSelectOnFocusinDirective, selector: "tui-input-number, tui-input, tui-input-phone, tui-input-date, tui-input-password, input[tuiInputNumber], input[tuiTextfield], input[tuiInputSlider]" }, { kind: "component", type: TuiLoader, selector: "tui-loader", inputs: ["size", "inheritColor", "overlay", "textContent", "showLoader"] }, { kind: "component", type: TuiButtonLoading, selector: "[tuiButton][loading],[tuiIconButton][loading]", inputs: ["size", "loading"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
|
|
6073
6124
|
}
|
|
6074
6125
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: ScSandwichComponent, decorators: [{
|
|
6075
6126
|
type: Component,
|
|
@@ -6101,7 +6152,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImpo
|
|
|
6101
6152
|
stringify: signal((x) => x.name),
|
|
6102
6153
|
identityMatcher: signal((a, b) => a.id === b.id),
|
|
6103
6154
|
}),
|
|
6104
|
-
], changeDetection: ChangeDetectionStrategy.OnPush, template: "@if (!orderItem() && settings()?.allowShowTable) {\n <div class=\"mb-5 flex justify-center\">\n <button\n tuiButton\n appearance=\"secondary\"\n (click)=\"toggleShowEvent.emit()\"\n type=\"button\"\n iconStart=\"@tui.layout-list\"\n >\n \u041F\u043E\u043A\u0430\u0437\u0430\u0442\u044C \u0432 \u0432\u0438\u0434\u0435 \u0441\u043F\u0438\u0441\u043A\u0430\n </button>\n </div>\n}\n<div class=\"\">\n @let calculateResult = calculateResult$ | async;\n @let products = products$ | async;\n @let productValue = product.value;\n @let validatorWidth = validatorWidth$ | async;\n @let validatorLength = validatorLength$ | async;\n\n <form\n [formGroup]=\"form\"\n (ngSubmit)=\"onSubmit(calculateResult)\"\n ScNextInputFocus\n class=\"flex flex-col gap-3\"\n >\n <label\n tuiLabel\n class=\"grow\"\n >\n \u0422\u043E\u0432\u0430\u0440\n <tui-textfield\n tuiChevron\n [tuiTextfieldCleaner]=\"false\"\n >\n <input\n tuiChevron\n tuiSelect\n [formControl]=\"product\"\n placeholder=\"\u0412\u044B\u0431\u0435\u0440\u0438\u0442\u0435 \u043C\u0430\u0442\u0435\u0440\u0438\u0430\u043B\"\n />\n\n <tui-data-list-wrapper\n *tuiTextfieldDropdown\n new\n [items]=\"products\"\n />\n </tui-textfield>\n @if (productValue) {\n <div class=\"ml-2 text-tui-text-secondary\">\n \u0421\u0442\u043E\u0438\u043C\u043E\u0441\u0442\u044C:\n <span class=\"font-bold\">{{ productValue.costRub?.toLocaleString() }} {{ productValue.currency.symbol }}/\u0448\u0442.</span>\n </div>\n }\n <tui-error\n [formControl]=\"product\"\n [error]=\"[] | tuiFieldError | async\"\n />\n </label>\n\n @if (product.value && validatorWidth && validatorLength) {\n <p class=\"w-full font-bold\">\u0420\u0430\u0437\u043C\u0435\u0440\u044B \u0438\u0437\u0434\u0435\u043B\u0438\u0439</p>\n <p class=\"w-full\">\n \u041C\u0438\u043D\u0438\u043C\u0430\u043B\u044C\u043D\u0430\u044F \u0448\u0438\u0440\u0438\u043D\u0430: {{ settings()?.minWidth }} \u043C\u043C.\n <br />\n \u041C\u0430\u043A\u0441\u0438\u043C\u0430\u043B\u044C\u043D\u0430\u044F \u0448\u0438\u0440\u0438\u043D\u0430: {{ product.value.properties?.width }} \u043C\u043C.\n <br />\n \u041C\u0438\u043D\u0438\u043C\u0430\u043B\u044C\u043D\u0430\u044F \u0434\u043B\u0438\u043D\u0430: {{ settings()?.minLength }} \u043C\u043C.\n <br />\n \u041C\u0430\u043A\u0441\u0438\u043C\u0430\u043B\u044C\u043D\u0430\u044F \u0434\u043B\u0438\u043D\u0430: {{ product.value.properties?.length }} \u043C\u043C.\n <br />\n </p>\n <div\n formArrayName=\"items\"\n class=\"flex flex-col gap-3\"\n >\n @for (item of items.controls; track item) {\n <div\n class=\"flex grow gap-2\"\n [formGroupName]=\"$index\"\n >\n <div class=\"grid grow grid-cols-3 gap-2\">\n <label tuiLabel>\n \u0428\u0438\u0440\u0438\u043D\u0430, \u043C\u043C\n <tui-textfield>\n <input\n tuiInputSlider\n formControlName=\"width\"\n [min]=\"settings()?.minWidth ?? 0\"\n [max]=\"product.value.properties?.width ?? 0\"\n [tuiNumberFormat]=\"{ precision: 0 }\"\n placeholder=\"\u0428\u0438\u0440\u0438\u043D\u0430\"\n autocomplete=\"off\"\n />\n @if (product.value) {\n <input\n tuiSlider\n type=\"range\"\n />\n }\n </tui-textfield>\n @if (product.value) {\n <div class=\"slider-ticks-labels\">\n <span> 0 </span>\n <span>{{ product.value.properties?.width }}</span>\n </div>\n }\n <tui-error\n formControlName=\"width\"\n [error]=\"[] | tuiFieldError | async\"\n />\n </label>\n\n <label tuiLabel>\n \u0414\u043B\u0438\u043D\u0430, \u043C\u043C\n <tui-textfield>\n <input\n tuiInputSlider\n formControlName=\"length\"\n [min]=\"settings()?.minLength ?? 0\"\n [max]=\"product.value.properties?.length ?? 0\"\n [tuiNumberFormat]=\"{ precision: 0 }\"\n placeholder=\"\u0414\u043B\u0438\u043D\u0430\"\n autocomplete=\"off\"\n />\n @if (product.value) {\n <input\n tuiSlider\n type=\"range\"\n />\n }\n </tui-textfield>\n @if (product.value) {\n <div class=\"slider-ticks-labels\">\n <span> 0 </span>\n <span>{{ product.value.properties?.length }}</span>\n </div>\n }\n <tui-error\n formControlName=\"length\"\n [error]=\"[] | tuiFieldError | async\"\n />\n </label>\n <label tuiLabel>\n <span class=\"whitespace-nowrap\">\u041A\u043E\u043B\u0438\u0447\u0435\u0441\u0442\u0432\u043E, \u0448\u0442</span>\n <tui-textfield [tuiTextfieldCleaner]=\"false\">\n <input\n tuiInputNumber\n formControlName=\"count\"\n [min]=\"1\"\n [tuiNumberFormat]=\"{ precision: 0 }\"\n placeholder=\"\u041A\u043E\u043B\u0438\u0447\u0435\u0441\u0442\u0432\u043E\"\n autocomplete=\"off\"\n />\n </tui-textfield>\n <tui-error\n formControlName=\"count\"\n [error]=\"[] | tuiFieldError | async\"\n />\n </label>\n </div>\n <button\n tuiIconButton\n (click)=\"removeItem($index)\"\n [disabled]=\"items.length <= 1\"\n size=\"m\"\n type=\"button\"\n iconStart=\"@tui.trash-2\"\n appearance=\"secondary\"\n class=\"mt-6\"\n [style.flex]=\"'0 0 auto'\"\n ></button>\n </div>\n }\n </div>\n <button\n tuiButton\n appearance=\"secondary\"\n [disabled]=\"items.invalid\"\n (click)=\"addItem()\"\n type=\"button\"\n class=\"self-center\"\n iconStart=\"@tui.plus\"\n >\n \u0414\u043E\u0431\u0430\u0432\u0438\u0442\u044C \u0438\u0437\u0434\u0435\u043B\u0438\u0435\n </button>\n } @else if (product.value) {\n <tui-error error=\"\u0420\u0430\u0441\u0447\u0435\u0442 \u043F\u043E \u043F\u0440\u043E\u0434\u0443\u043A\u0442\u0443 \u043D\u0435\u0432\u043E\u0437\u043C\u043E\u0436\u0435\u043D. \u041E\u0431\u0440\u0430\u0442\u0438\u0442\u0435\u0441\u044C \u043A \u043C\u0435\u043D\u0435\u0434\u0436\u0435\u0440\u0443\" />\n }\n\n <label tuiLabel>\n \u041C\u0430\u0440\u043A\u0438\u0440\u043E\u0432\u043A\u0430 \u0440\u0430\u0441\u043F\u0438\u043B\u0430\n <tui-textfield>\n <input\n tuiTextfield\n formControlName=\"marker\"\n placeholder=\"\u041C\u0430\u0440\u043A\u0438\u0440\u043E\u0432\u043A\u0430 \u0440\u0430\u0441\u043F\u0438\u043B\u0430\"\n autocomplete=\"marker\"\n />\n </tui-textfield>\n\n <tui-error\n formControlName=\"marker\"\n [error]=\"[] | tuiFieldError | async\"\n />\n </label>\n\n @if (product.value) {\n <tui-loader [showLoader]=\"isCalculateLoading()\">\n @if (calculateResult) {\n <div class=\"mt-2 flex flex-wrap items-end gap-2\">\n <div>\n \u0418\u0442\u043E\u0433\u043E: <span class=\"whitespace-nowrap text-xl font-bold\">{{ getTotalCost(calculateResult).toLocaleString() }} {{ product.value.currency.symbol }}</span>\n </div>\n @if (calculateResult?.quantity && productValue) {\n <div class=\"whitespace-nowrap text-lg text-sc-dark-grey\">\n <span class=\"font-bold\">({{ calculateResult.quantity }} \u0448\u0442.</span> x\n <span class=\"font-bold\">{{ productValue.costRub?.toLocaleString() }} {{ productValue.currency.symbol }}/\u0448\u0442.)</span>\n </div>\n }\n </div>\n }\n </tui-loader>\n }\n\n <tui-error [error]=\"[] | tuiFieldError | async\" />\n @if (!calculateResult) {\n <button\n tuiButton\n appearance=\"secondary\"\n [disabled]=\"items.invalid || isCalculateLoading()\"\n (click)=\"triggerCalculate()\"\n type=\"button\"\n class=\"self-center\"\n iconStart=\"@tui.calculator\"\n >\n \u0420\u0430\u0441\u0441\u0447\u0438\u0442\u0430\u0442\u044C\n </button>\n } @else {\n <button\n [disabled]=\"form.invalid || isSubmitLoading()\"\n [loading]=\"isSubmitLoading()\"\n tuiButton\n class=\"self-center\"\n iconStart=\"@tui.check\"\n >\n {{ !orderItem() ? '\u0414\u043E\u0431\u0430\u0432\u0438\u0442\u044C \u0432 \u043A\u043E\u0440\u0437\u0438\u043D\u0443' : '\u0418\u0437\u043C\u0435\u043D\u0438\u0442\u044C' }}\n </button>\n }\n </form>\n</div>\n", styles: [":host{display:block;width:100%;max-width:30rem}.slider-ticks-labels{--t-offset: calc($thumb / 2);display:flex;font:var(--tui-font-text-s);margin-inline-start:var(--t-offset);margin-inline-end:var(--t-offset);color:var(--tui-text-secondary)}.slider-ticks-labels>*{position:relative;flex:2;text-align:center}.slider-ticks-labels>*:first-child{left:calc(-1 * var(--t-offset));inset-inline-start:calc(-1 * var(--t-offset));flex:1;text-align:start}.slider-ticks-labels>*:last-child{right:calc(-1 * var(--t-offset));flex:1;text-align:end}@supports (inset-inline-end: 0){.slider-ticks-labels>*:last-child{right:unset;inset-inline-end:calc(-1 * var(--t-offset))}}tui-input-slider+.slider-ticks-labels{margin-inline-start:calc(var(--tui-radius-m) / 2 + var(--t-offset))}tui-textfield+.slider-ticks-labels{--t-offset: calc(var(--tui-radius-m) / 2 + $thumb / 2)}tui-textfield[data-size=l]+.slider-ticks-labels{--t-offset: calc(var(--tui-radius-l) / 2 + $thumb / 2)}tui-input-range:not([new])+.slider-ticks-labels,tui-range+.slider-ticks-labels{--t-offset: $thumb}tui-input-range[new]+.slider-ticks-labels{--t-offset: calc(map-get($track-inset, $input-size) + $thumb)}\n"] }]
|
|
6155
|
+
], changeDetection: ChangeDetectionStrategy.OnPush, template: "@if (!orderItem() && settings()?.allowShowTable) {\n <div class=\"mb-5 flex justify-center\">\n <button\n tuiButton\n appearance=\"secondary\"\n (click)=\"toggleShowEvent.emit()\"\n type=\"button\"\n iconStart=\"@tui.layout-list\"\n >\n \u041F\u043E\u043A\u0430\u0437\u0430\u0442\u044C \u0432 \u0432\u0438\u0434\u0435 \u0441\u043F\u0438\u0441\u043A\u0430\n </button>\n </div>\n}\n<div>\n @let calculateResult = calculateResult$ | async;\n @let products = products$ | async;\n @let productValue = product.value;\n @let validatorWidth = validatorWidth$ | async;\n @let validatorLength = validatorLength$ | async;\n\n <form\n [formGroup]=\"form\"\n (ngSubmit)=\"onSubmit(calculateResult)\"\n ScNextInputFocus\n class=\"flex flex-col gap-3\"\n >\n <label\n tuiLabel\n class=\"grow\"\n >\n \u0422\u043E\u0432\u0430\u0440\n <tui-textfield\n tuiChevron\n [tuiTextfieldCleaner]=\"false\"\n >\n <input\n tuiChevron\n tuiSelect\n [formControl]=\"product\"\n placeholder=\"\u0412\u044B\u0431\u0435\u0440\u0438\u0442\u0435 \u043C\u0430\u0442\u0435\u0440\u0438\u0430\u043B\"\n />\n\n <tui-data-list-wrapper\n *tuiTextfieldDropdown\n new\n [items]=\"products\"\n />\n </tui-textfield>\n <tui-error\n [formControl]=\"product\"\n [error]=\"[] | tuiFieldError | async\"\n />\n </label>\n\n @if (productValue && productValue.costRub) {\n <div class=\"-mt-1 text-sm text-tui-text-secondary\">\n <span class=\"font-bold\">{{ productValue.code }}</span>\n \u2014 {{ productValue.costRub.toLocaleString() }} {{ productValue.currency.symbol }}/\u0448\u0442.\n </div>\n }\n\n @if (product.value && validatorWidth && validatorLength) {\n <div class=\"mt-4 flex flex-col gap-1.5\">\n <div class=\"w-full font-bold\">\u0420\u0430\u0437\u043C\u0435\u0440\u044B \u0438\u0437\u0434\u0435\u043B\u0438\u0439</div>\n <div class=\"flex flex-col gap-1 text-sm text-tui-text-secondary\">\n @if (widthRangeText()) {\n <div>\u0428\u0438\u0440\u0438\u043D\u0430 {{ widthRangeText() }}.</div>\n }\n @if (lengthRangeText()) {\n <div>\u0414\u043B\u0438\u043D\u0430 {{ lengthRangeText() }}.</div>\n }\n </div>\n </div>\n } @else if (product.value) {\n <tui-error error=\"\u0420\u0430\u0441\u0447\u0435\u0442 \u043F\u043E \u043F\u0440\u043E\u0434\u0443\u043A\u0442\u0443 \u043D\u0435\u0432\u043E\u0437\u043C\u043E\u0436\u0435\u043D. \u041E\u0431\u0440\u0430\u0442\u0438\u0442\u0435\u0441\u044C \u043A \u043C\u0435\u043D\u0435\u0434\u0436\u0435\u0440\u0443\" />\n }\n\n <div\n formArrayName=\"items\"\n class=\"flex flex-col gap-3\"\n >\n @for (item of items.controls; track item) {\n <div\n class=\"flex grow gap-2\"\n [formGroupName]=\"$index\"\n >\n <div class=\"grid grow grid-cols-1 items-start gap-2 sm:grid-cols-3\">\n <label tuiLabel>\n \u0428\u0438\u0440\u0438\u043D\u0430, \u043C\u043C\n <tui-textfield>\n <input\n tuiInputSlider\n formControlName=\"width\"\n [min]=\"settings()?.minWidth ?? 0\"\n [max]=\"product.value?.properties?.width ?? 0\"\n [tuiNumberFormat]=\"{ precision: 0 }\"\n [readOnly]=\"!product.value\"\n placeholder=\"\u0428\u0438\u0440\u0438\u043D\u0430\"\n autocomplete=\"off\"\n />\n @if (product.value) {\n <input\n tuiSlider\n type=\"range\"\n />\n }\n </tui-textfield>\n @if (product.value) {\n <div class=\"slider-ticks-labels\">\n <span> 0 </span>\n <span>{{ product.value.properties?.width }}</span>\n </div>\n }\n <tui-error\n formControlName=\"width\"\n [error]=\"[] | tuiFieldError | async\"\n />\n </label>\n\n <label tuiLabel>\n \u0414\u043B\u0438\u043D\u0430, \u043C\u043C\n <tui-textfield>\n <input\n tuiInputSlider\n formControlName=\"length\"\n [min]=\"settings()?.minLength ?? 0\"\n [max]=\"product.value?.properties?.length ?? 0\"\n [tuiNumberFormat]=\"{ precision: 0 }\"\n [readOnly]=\"!product.value\"\n placeholder=\"\u0414\u043B\u0438\u043D\u0430\"\n autocomplete=\"off\"\n />\n @if (product.value) {\n <input\n tuiSlider\n type=\"range\"\n />\n }\n </tui-textfield>\n @if (product.value) {\n <div class=\"slider-ticks-labels\">\n <span> 0 </span>\n <span>{{ product.value.properties?.length }}</span>\n </div>\n }\n <tui-error\n formControlName=\"length\"\n [error]=\"[] | tuiFieldError | async\"\n />\n </label>\n <label tuiLabel>\n <span class=\"whitespace-nowrap\">\u041A\u043E\u043B\u0438\u0447\u0435\u0441\u0442\u0432\u043E, \u0448\u0442</span>\n <tui-textfield [tuiTextfieldCleaner]=\"false\">\n <input\n tuiInputNumber\n formControlName=\"count\"\n [min]=\"1\"\n [tuiNumberFormat]=\"{ precision: 0 }\"\n [readOnly]=\"!product.value\"\n placeholder=\"\u041A\u043E\u043B\u0438\u0447\u0435\u0441\u0442\u0432\u043E\"\n autocomplete=\"off\"\n />\n </tui-textfield>\n <tui-error\n formControlName=\"count\"\n [error]=\"[] | tuiFieldError | async\"\n />\n </label>\n </div>\n <button\n tuiIconButton\n (click)=\"removeItem($index)\"\n [disabled]=\"!product.value || items.length <= 1\"\n size=\"m\"\n type=\"button\"\n iconStart=\"@tui.trash-2\"\n appearance=\"secondary\"\n class=\"mt-6\"\n [style.flex]=\"'0 0 auto'\"\n ></button>\n </div>\n }\n </div>\n @if (product.value) {\n <button\n tuiButton\n appearance=\"secondary\"\n [disabled]=\"items.invalid\"\n (click)=\"addItem()\"\n type=\"button\"\n class=\"self-center\"\n iconStart=\"@tui.plus\"\n >\n \u0414\u043E\u0431\u0430\u0432\u0438\u0442\u044C \u0438\u0437\u0434\u0435\u043B\u0438\u0435\n </button>\n }\n\n <label tuiLabel>\n \u041C\u0430\u0440\u043A\u0438\u0440\u043E\u0432\u043A\u0430 \u0440\u0430\u0441\u043F\u0438\u043B\u0430\n <tui-textfield>\n <input\n tuiTextfield\n formControlName=\"marker\"\n placeholder=\"\u041C\u0430\u0440\u043A\u0438\u0440\u043E\u0432\u043A\u0430 \u0440\u0430\u0441\u043F\u0438\u043B\u0430\"\n autocomplete=\"marker\"\n />\n </tui-textfield>\n\n <tui-error\n formControlName=\"marker\"\n [error]=\"[] | tuiFieldError | async\"\n />\n </label>\n\n @if (product.value) {\n <tui-loader [showLoader]=\"isCalculateLoading()\">\n @if (calculateResult) {\n <div class=\"mt-2 flex flex-wrap items-end gap-2\">\n <div>\n \u0418\u0442\u043E\u0433\u043E: <span class=\"whitespace-nowrap text-xl font-bold\">{{ getTotalCost(calculateResult).toLocaleString() }} {{ product.value.currency.symbol }}</span>\n </div>\n @if (calculateResult?.quantity && productValue) {\n <div class=\"whitespace-nowrap text-lg text-sc-dark-grey\">\n <span class=\"font-bold\">({{ calculateResult.quantity }} \u0448\u0442.</span> x\n <span class=\"font-bold\">{{ productValue.costRub?.toLocaleString() }} {{ productValue.currency.symbol }}/\u0448\u0442.)</span>\n </div>\n }\n </div>\n }\n </tui-loader>\n }\n\n <tui-error [error]=\"[] | tuiFieldError | async\" />\n @if (!calculateResult) {\n <button\n tuiButton\n appearance=\"secondary\"\n [disabled]=\"items.invalid || isCalculateLoading()\"\n (click)=\"triggerCalculate()\"\n type=\"button\"\n class=\"self-center\"\n iconStart=\"@tui.calculator\"\n >\n \u0420\u0430\u0441\u0441\u0447\u0438\u0442\u0430\u0442\u044C\n </button>\n } @else {\n <button\n [disabled]=\"form.invalid || isSubmitLoading()\"\n [loading]=\"isSubmitLoading()\"\n tuiButton\n class=\"self-center\"\n iconStart=\"@tui.check\"\n >\n {{ !orderItem() ? '\u0414\u043E\u0431\u0430\u0432\u0438\u0442\u044C \u0432 \u043A\u043E\u0440\u0437\u0438\u043D\u0443' : '\u0418\u0437\u043C\u0435\u043D\u0438\u0442\u044C' }}\n </button>\n }\n </form>\n</div>\n", styles: [":host{display:block;width:100%;max-width:30rem}.slider-ticks-labels{--t-offset: calc($thumb / 2);display:flex;font:var(--tui-font-text-s);margin-inline-start:var(--t-offset);margin-inline-end:var(--t-offset);color:var(--tui-text-secondary)}.slider-ticks-labels>*{position:relative;flex:2;text-align:center}.slider-ticks-labels>*:first-child{left:calc(-1 * var(--t-offset));inset-inline-start:calc(-1 * var(--t-offset));flex:1;text-align:start}.slider-ticks-labels>*:last-child{right:calc(-1 * var(--t-offset));flex:1;text-align:end}@supports (inset-inline-end: 0){.slider-ticks-labels>*:last-child{right:unset;inset-inline-end:calc(-1 * var(--t-offset))}}tui-input-slider+.slider-ticks-labels{margin-inline-start:calc(var(--tui-radius-m) / 2 + var(--t-offset))}tui-textfield+.slider-ticks-labels{--t-offset: calc(var(--tui-radius-m) / 2 + $thumb / 2)}tui-textfield[data-size=l]+.slider-ticks-labels{--t-offset: calc(var(--tui-radius-l) / 2 + $thumb / 2)}tui-input-range:not([new])+.slider-ticks-labels,tui-range+.slider-ticks-labels{--t-offset: $thumb}tui-input-range[new]+.slider-ticks-labels{--t-offset: calc(map-get($track-inset, $input-size) + $thumb)}\n"] }]
|
|
6105
6156
|
}], propDecorators: { orderId: [{
|
|
6106
6157
|
type: Input
|
|
6107
6158
|
}] } });
|
|
@@ -6118,6 +6169,562 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImpo
|
|
|
6118
6169
|
args: [{ standalone: true, selector: 'sc-sandwich-skeleton', template: "<div class=\"w-100\">\n <div class=\"flex flex-col gap-3\">\n <!-- \u041F\u043E\u043B\u0435 \u0432\u044B\u0431\u043E\u0440\u0430 \u0442\u043E\u0432\u0430\u0440\u0430. -->\n <div class=\"mb-4 mt-2 h-10 w-full rounded-sm bg-sc-light-grey\"></div>\n\n <!-- \u0417\u0430\u0433\u043E\u043B\u043E\u0432\u043E\u043A \"\u0420\u0430\u0437\u043C\u0435\u0440\u044B \u0438\u0437\u0434\u0435\u043B\u0438\u0439\". -->\n <div class=\"my-1.5 h-5 w-1/3 rounded bg-sc-light-grey\"></div>\n\n <!-- \u0422\u0435\u043A\u0441\u0442 \u0441 \u043F\u0430\u0440\u0430\u043C\u0435\u0442\u0440\u0430\u043C\u0438. -->\n <div class=\"flex flex-col gap-1\">\n <div class=\"my-1 h-3 w-2/3 rounded bg-sc-light-grey\"></div>\n <div class=\"my-1 h-3 w-2/3 rounded bg-sc-light-grey\"></div>\n <div class=\"my-1 h-3 w-2/3 rounded bg-sc-light-grey\"></div>\n <div class=\"my-1 h-3 w-2/3 rounded bg-sc-light-grey\"></div>\n </div>\n\n <!-- \u0411\u043B\u043E\u043A \u0441 \u0438\u0437\u0434\u0435\u043B\u0438\u044F\u043C\u0438. -->\n <div class=\"flex flex-col gap-3\">\n <!-- \u041F\u0435\u0440\u0432\u043E\u0435 \u0438\u0437\u0434\u0435\u043B\u0438\u0435. -->\n <div class=\"flex grow gap-4\">\n <div class=\"grid grow grid-cols-3 gap-4\">\n <!-- \u0428\u0438\u0440\u0438\u043D\u0430. -->\n <div class=\"flex flex-col gap-1\">\n <div class=\"my-1 h-3 w-1/2 rounded bg-sc-light-grey\"></div>\n <div class=\"mb-4 mt-2 h-10 w-full rounded-sm bg-sc-light-grey\"></div>\n <div class=\"my-1 h-3 w-1/3 rounded bg-sc-light-grey\"></div>\n <div class=\"my-1 h-2 w-2/3 rounded bg-sc-light-grey\"></div>\n </div>\n <!-- \u0414\u043B\u0438\u043D\u0430. -->\n <div class=\"flex flex-col gap-1\">\n <div class=\"my-1 h-3 w-1/2 rounded bg-sc-light-grey\"></div>\n <div class=\"mb-4 mt-2 h-10 w-full rounded-sm bg-sc-light-grey\"></div>\n <div class=\"my-1 h-3 w-1/3 rounded bg-sc-light-grey\"></div>\n <div class=\"my-1 h-2 w-2/3 rounded bg-sc-light-grey\"></div>\n </div>\n <!-- \u041A\u043E\u043B\u0438\u0447\u0435\u0441\u0442\u0432\u043E. -->\n <div class=\"flex flex-col gap-1\">\n <div class=\"my-1 h-3 w-1/2 rounded bg-sc-light-grey\"></div>\n <div class=\"mb-4 mt-2 h-10 w-full rounded-sm bg-sc-light-grey\"></div>\n </div>\n </div>\n <div class=\"mt-6 size-8 shrink-0 rounded-sm bg-sc-light-grey\"></div>\n </div>\n </div>\n\n <!-- \u041A\u043D\u043E\u043F\u043A\u0430 \"\u0414\u043E\u0431\u0430\u0432\u0438\u0442\u044C \u0438\u0437\u0434\u0435\u043B\u0438\u0435\". -->\n <button\n tuiButton\n appearance=\"secondary\"\n class=\"sc-skeleton self-center\"\n ></button>\n\n <!-- \u041F\u043E\u043B\u0435 \"\u0418\u0442\u043E\u0433\u043E\u0432\u043E\u0435 \u043A\u043E\u043B\u0438\u0447\u0435\u0441\u0442\u0432\u043E \u043B\u0438\u0441\u0442\u043E\u0432\". -->\n <div class=\"mb-4 mt-2 h-10 w-full rounded-sm bg-sc-light-grey\"></div>\n\n <!-- \u041F\u043E\u043B\u0435 \"\u041C\u0430\u0440\u043A\u0438\u0440\u043E\u0432\u043A\u0430\". -->\n <div class=\"mb-4 mt-2 h-10 w-full rounded-sm bg-sc-light-grey\"></div>\n\n <!-- \u0418\u0442\u043E\u0433\u043E\u0432\u0430\u044F \u0441\u0442\u043E\u0438\u043C\u043E\u0441\u0442\u044C. -->\n <div class=\"my-2.5 h-6 w-1/3 rounded bg-sc-light-grey\"></div>\n\n <!-- \u041A\u043D\u043E\u043F\u043A\u0430 \u043E\u0442\u043F\u0440\u0430\u0432\u043A\u0438. -->\n <button\n tuiButton\n class=\"sc-skeleton self-center\"\n ></button>\n </div>\n</div>\n" }]
|
|
6119
6170
|
}] });
|
|
6120
6171
|
|
|
6172
|
+
/**
|
|
6173
|
+
* Начальное состояние позиции — используется при инициализации и сбросе формы.
|
|
6174
|
+
*/
|
|
6175
|
+
const IDLE_ITEM_STATE = 'idle';
|
|
6176
|
+
|
|
6177
|
+
/* eslint-disable security/detect-object-injection,@typescript-eslint/unbound-method */
|
|
6178
|
+
/**
|
|
6179
|
+
* Конфигуратор распила сэндвич-панелей по площади.
|
|
6180
|
+
*/
|
|
6181
|
+
class ScSandwichM2Component {
|
|
6182
|
+
constructor() {
|
|
6183
|
+
/**
|
|
6184
|
+
* Настройки для конфигуратора распила сэндвич-панелей по площади.
|
|
6185
|
+
*/
|
|
6186
|
+
this.settings = input();
|
|
6187
|
+
/**
|
|
6188
|
+
* Идентификатор категории.
|
|
6189
|
+
*/
|
|
6190
|
+
this.categoryId = input.required();
|
|
6191
|
+
/**
|
|
6192
|
+
* Название конфигуратора.
|
|
6193
|
+
*/
|
|
6194
|
+
this.editor = input.required();
|
|
6195
|
+
/**
|
|
6196
|
+
* Позиция товара/услуги в корзине.
|
|
6197
|
+
*/
|
|
6198
|
+
this.orderItem = input.required();
|
|
6199
|
+
/**
|
|
6200
|
+
* Событие переключения отображения товаров.
|
|
6201
|
+
*/
|
|
6202
|
+
this.toggleShowEvent = output();
|
|
6203
|
+
/**
|
|
6204
|
+
* Форма добавления/редактирования продукта в корзине.
|
|
6205
|
+
*/
|
|
6206
|
+
this.form = new FormGroup({
|
|
6207
|
+
productCategoryId: new FormControl(null, { validators: Validators.required }),
|
|
6208
|
+
configurator: new FormControl(null, { validators: Validators.required }),
|
|
6209
|
+
items: new FormArray([]),
|
|
6210
|
+
});
|
|
6211
|
+
/**
|
|
6212
|
+
* Сервис получения и редактирования списка товаров заказа (корзина / заказ / черновик = заказ).
|
|
6213
|
+
*/
|
|
6214
|
+
this.orderService = inject(SC_ORDER_LOADER);
|
|
6215
|
+
/**
|
|
6216
|
+
* Сервис конвертации данных.
|
|
6217
|
+
*/
|
|
6218
|
+
this.convertersService = inject(ScConvertersService);
|
|
6219
|
+
/**
|
|
6220
|
+
* Контекст диалогового окна, в котором открыт компонент.
|
|
6221
|
+
*/
|
|
6222
|
+
this.context = inject(POLYMORPHEUS_CONTEXT, { optional: true });
|
|
6223
|
+
/**
|
|
6224
|
+
* Сервис для работы с каталогом.
|
|
6225
|
+
*/
|
|
6226
|
+
this.catalogService = inject(ScCatalogService);
|
|
6227
|
+
/**
|
|
6228
|
+
* {@link Observable} списка товаров категории.
|
|
6229
|
+
*/
|
|
6230
|
+
this.products$ = toObservable(this.categoryId).pipe(switchMap((categoryId) => {
|
|
6231
|
+
if (!categoryId) {
|
|
6232
|
+
return of([]);
|
|
6233
|
+
}
|
|
6234
|
+
return this.catalogService.getProductsCategoryCached$({ categoryId: Number(categoryId) }).pipe(map((products) => products ?? []));
|
|
6235
|
+
}));
|
|
6236
|
+
/**
|
|
6237
|
+
* Выбранный продукт.
|
|
6238
|
+
*/
|
|
6239
|
+
this.product = new FormControl(null, { validators: Validators.required });
|
|
6240
|
+
/**
|
|
6241
|
+
* Сигнал текущего выбранного продукта — обновляется при `valueChanges` контрола `product`.
|
|
6242
|
+
*/
|
|
6243
|
+
this.productSignal = toSignal(tuiControlValue(this.product), { initialValue: null });
|
|
6244
|
+
/**
|
|
6245
|
+
* Сигнал содержимого FormArray позиций — пересчитывается при любом изменении значений.
|
|
6246
|
+
*/
|
|
6247
|
+
this.itemsValue = toSignal(tuiControlValue(this.items).pipe(map(() => this.items.controls.map((c) => c.getRawValue()))), {
|
|
6248
|
+
initialValue: [],
|
|
6249
|
+
});
|
|
6250
|
+
/**
|
|
6251
|
+
* Признак того, что выполняется запрос на отправку данных.
|
|
6252
|
+
*/
|
|
6253
|
+
this.isSubmitLoading = computed(() => this.itemStates().includes('loading'));
|
|
6254
|
+
/**
|
|
6255
|
+
* Состояние отправки каждой позиции — параллельный массив к контролу `items` формы.
|
|
6256
|
+
*/
|
|
6257
|
+
this.itemStates = signal([]);
|
|
6258
|
+
/**
|
|
6259
|
+
* Признак режима редактирования существующей позиции — `orderItem` задан.
|
|
6260
|
+
*/
|
|
6261
|
+
this.isEditingExistingItem = computed(() => this.orderItem() != null);
|
|
6262
|
+
/**
|
|
6263
|
+
* Признак того, что отправлять больше нечего — все позиции либо успешно
|
|
6264
|
+
* отправлены, либо находятся в процессе отправки.
|
|
6265
|
+
*/
|
|
6266
|
+
this.hasNoPendingItems = computed(() => {
|
|
6267
|
+
const states = this.itemStates();
|
|
6268
|
+
if (this.items.length === 0) {
|
|
6269
|
+
return true;
|
|
6270
|
+
}
|
|
6271
|
+
return this.items.controls.every((_, index) => {
|
|
6272
|
+
const state = states[index] ?? IDLE_ITEM_STATE;
|
|
6273
|
+
return state === 'success' || state === 'loading';
|
|
6274
|
+
});
|
|
6275
|
+
});
|
|
6276
|
+
/**
|
|
6277
|
+
* Суммарная площадь всех позиций (м²), рассчитанная локально.
|
|
6278
|
+
*/
|
|
6279
|
+
this.totalAreaM2 = computed(() => {
|
|
6280
|
+
let total = 0;
|
|
6281
|
+
this.itemsValue().forEach((value) => {
|
|
6282
|
+
total += this.rowTotalPartsAreaM2(value);
|
|
6283
|
+
});
|
|
6284
|
+
return total;
|
|
6285
|
+
});
|
|
6286
|
+
/**
|
|
6287
|
+
* Итоговая стоимость по всем позициям (локальный расчёт).
|
|
6288
|
+
*/
|
|
6289
|
+
this.totalCost = computed(() => {
|
|
6290
|
+
const cost = this.productSignal()?.costRub ?? 0;
|
|
6291
|
+
const area = this.totalAreaM2();
|
|
6292
|
+
return Math.round(area * cost * 100) / 100;
|
|
6293
|
+
});
|
|
6294
|
+
/**
|
|
6295
|
+
* Текст ограничения по ширине («от … до …»), пока есть выбранный товар.
|
|
6296
|
+
*/
|
|
6297
|
+
this.widthRangeText = computed(() => this.formatRange(this.settings()?.minWidth ?? null, this.productSignal()?.properties?.width ?? null, 'мм'));
|
|
6298
|
+
/**
|
|
6299
|
+
* Текст ограничения по длине («от … до …»), пока есть выбранный товар.
|
|
6300
|
+
*/
|
|
6301
|
+
this.lengthRangeText = computed(() => this.formatRange(this.settings()?.minLength ?? null, this.productSignal()?.properties?.length ?? null, 'мм'));
|
|
6302
|
+
/**
|
|
6303
|
+
* Ссылка для автоматического управления уничтожением зависимостей.
|
|
6304
|
+
*/
|
|
6305
|
+
this.destroyRef = inject(DestroyRef);
|
|
6306
|
+
}
|
|
6307
|
+
/**
|
|
6308
|
+
* Валидаторы ширины/длины: пока товар не выбран — не накладываем min/max каталога (поля read-only без товара).
|
|
6309
|
+
*
|
|
6310
|
+
* @param min Нижняя граница размера из настроек конфигуратора.
|
|
6311
|
+
* @param maxUpper Верхняя граница из свойств выбранного товара.
|
|
6312
|
+
*/
|
|
6313
|
+
dimensionValidators(min, maxUpper) {
|
|
6314
|
+
const chosenProduct = this.product.value;
|
|
6315
|
+
if (!chosenProduct) {
|
|
6316
|
+
return [];
|
|
6317
|
+
}
|
|
6318
|
+
return [Validators.required, Validators.min(min), ...(maxUpper != null && maxUpper > 0 ? [Validators.max(maxUpper)] : []), stepValidator(1)];
|
|
6319
|
+
}
|
|
6320
|
+
/**
|
|
6321
|
+
* Обновляет валидаторы размерных полей после смены товара или настроек.
|
|
6322
|
+
*/
|
|
6323
|
+
updateItemsValidators() {
|
|
6324
|
+
const settings = this.settings();
|
|
6325
|
+
const minWidth = settings?.minWidth ?? 0.01;
|
|
6326
|
+
const minLength = settings?.minLength ?? 0.01;
|
|
6327
|
+
const chosenProduct = this.product.value;
|
|
6328
|
+
this.items.controls.forEach((group) => {
|
|
6329
|
+
group.get('width')?.setValidators(this.dimensionValidators(minWidth, chosenProduct?.properties?.width));
|
|
6330
|
+
group.get('length')?.setValidators(this.dimensionValidators(minLength, chosenProduct?.properties?.length));
|
|
6331
|
+
group.get('width')?.updateValueAndValidity({ emitEvent: false });
|
|
6332
|
+
group.get('length')?.updateValueAndValidity({ emitEvent: false });
|
|
6333
|
+
});
|
|
6334
|
+
}
|
|
6335
|
+
/**
|
|
6336
|
+
* Форматирование диапазона «от … до …» с учётом отсутствующих границ.
|
|
6337
|
+
*
|
|
6338
|
+
* @param min Нижняя граница диапазона.
|
|
6339
|
+
* @param max Верхняя граница диапазона.
|
|
6340
|
+
* @param unit Единица измерения для подписи.
|
|
6341
|
+
*/
|
|
6342
|
+
// eslint-disable-next-line class-methods-use-this
|
|
6343
|
+
formatRange(min, max, unit) {
|
|
6344
|
+
const hasMin = min != null && min > 0;
|
|
6345
|
+
const hasMax = max != null && max > 0;
|
|
6346
|
+
if (!hasMin && !hasMax) {
|
|
6347
|
+
return null;
|
|
6348
|
+
}
|
|
6349
|
+
if (hasMin && hasMax) {
|
|
6350
|
+
return `от ${min} ${unit} до ${max} ${unit}`;
|
|
6351
|
+
}
|
|
6352
|
+
if (hasMin) {
|
|
6353
|
+
return `от ${min} ${unit}`;
|
|
6354
|
+
}
|
|
6355
|
+
return `до ${max} ${unit}`;
|
|
6356
|
+
}
|
|
6357
|
+
/**
|
|
6358
|
+
* Массив изделий.
|
|
6359
|
+
*/
|
|
6360
|
+
get items() {
|
|
6361
|
+
return this.form.controls.items;
|
|
6362
|
+
}
|
|
6363
|
+
/**
|
|
6364
|
+
* {@inheritDoc}
|
|
6365
|
+
*/
|
|
6366
|
+
ngOnInit() {
|
|
6367
|
+
this.setDefaultFormValue();
|
|
6368
|
+
this.products$.pipe(takeUntilDestroyed(this.destroyRef)).subscribe((products) => {
|
|
6369
|
+
if (this.product.value != null || products.length === 0) {
|
|
6370
|
+
return;
|
|
6371
|
+
}
|
|
6372
|
+
/* При загрузке списка автоматически выбираем первый материал. */
|
|
6373
|
+
this.product.setValue(products[0], { emitEvent: true });
|
|
6374
|
+
});
|
|
6375
|
+
this.product.valueChanges.pipe(takeUntilDestroyed(this.destroyRef)).subscribe((chosenProduct) => {
|
|
6376
|
+
this.updateItemsValidators();
|
|
6377
|
+
if (chosenProduct) {
|
|
6378
|
+
this.items.controls.forEach((item) => {
|
|
6379
|
+
const value = item.getRawValue();
|
|
6380
|
+
const maxW = chosenProduct.properties?.width;
|
|
6381
|
+
const maxL = chosenProduct.properties?.length;
|
|
6382
|
+
item.patchValue({
|
|
6383
|
+
width: maxW ? Math.min(value.width, maxW) : value.width,
|
|
6384
|
+
length: maxL ? Math.min(value.length, maxL) : value.length,
|
|
6385
|
+
});
|
|
6386
|
+
});
|
|
6387
|
+
/*
|
|
6388
|
+
* Смена продукта — сбрасываем состояние позиций: границы каталога изменились,
|
|
6389
|
+
* успешная отправка больше не отражает текущее состояние.
|
|
6390
|
+
*/
|
|
6391
|
+
this.resetAllItemStates();
|
|
6392
|
+
}
|
|
6393
|
+
});
|
|
6394
|
+
}
|
|
6395
|
+
/**
|
|
6396
|
+
* Создает группу для изделия.
|
|
6397
|
+
*
|
|
6398
|
+
* @param item Параметры изделия.
|
|
6399
|
+
* @param item.width Ширина изделия.
|
|
6400
|
+
* @param item.length Длина изделия.
|
|
6401
|
+
* @param item.count Количество изделий.
|
|
6402
|
+
* @param item.marker Маркер позиции.
|
|
6403
|
+
*/
|
|
6404
|
+
createItemGroup(item) {
|
|
6405
|
+
const group = new FormGroup({
|
|
6406
|
+
width: new FormControl(item?.width ?? 0, { nonNullable: true }),
|
|
6407
|
+
length: new FormControl(item?.length ?? 0, { nonNullable: true }),
|
|
6408
|
+
count: new FormControl(item?.count ?? 1, {
|
|
6409
|
+
validators: [Validators.required, Validators.min(1), stepValidator(1)],
|
|
6410
|
+
nonNullable: true,
|
|
6411
|
+
}),
|
|
6412
|
+
marker: new FormControl(item?.marker ?? null),
|
|
6413
|
+
});
|
|
6414
|
+
// Любое изменение значений позиции сбрасывает её состояние отправки —
|
|
6415
|
+
// ранее успешный submit становится неактуальным при правке полей,
|
|
6416
|
+
// ошибку валидации сервера тоже сбрасываем.
|
|
6417
|
+
group.valueChanges.pipe(takeUntilDestroyed(this.destroyRef)).subscribe(() => {
|
|
6418
|
+
const index = this.items.controls.indexOf(group);
|
|
6419
|
+
if (index !== -1) {
|
|
6420
|
+
this.resetItemState(index);
|
|
6421
|
+
['width', 'length', 'count', 'marker'].forEach((field) => {
|
|
6422
|
+
const control = group.get(field);
|
|
6423
|
+
if (control?.hasError('serverResponse')) {
|
|
6424
|
+
const errors = { ...control.errors };
|
|
6425
|
+
delete errors['serverResponse'];
|
|
6426
|
+
control.setErrors(Object.keys(errors).length > 0 ? errors : null);
|
|
6427
|
+
}
|
|
6428
|
+
});
|
|
6429
|
+
}
|
|
6430
|
+
});
|
|
6431
|
+
return group;
|
|
6432
|
+
}
|
|
6433
|
+
/**
|
|
6434
|
+
* Сбрасывает состояние одной позиции на `idle`, если оно было `success`/`error`.
|
|
6435
|
+
*
|
|
6436
|
+
* @param index Индекс позиции.
|
|
6437
|
+
*/
|
|
6438
|
+
resetItemState(index) {
|
|
6439
|
+
const states = this.itemStates();
|
|
6440
|
+
const current = states[index];
|
|
6441
|
+
if (current === 'success' || current === 'error') {
|
|
6442
|
+
const updated = [...states];
|
|
6443
|
+
updated[index] = 'idle';
|
|
6444
|
+
this.itemStates.set(updated);
|
|
6445
|
+
}
|
|
6446
|
+
}
|
|
6447
|
+
/**
|
|
6448
|
+
* Сбрасывает состояния всех позиций на `idle`.
|
|
6449
|
+
*/
|
|
6450
|
+
resetAllItemStates() {
|
|
6451
|
+
this.itemStates.set(this.items.controls.map(() => IDLE_ITEM_STATE));
|
|
6452
|
+
}
|
|
6453
|
+
/**
|
|
6454
|
+
* Возвращает состояние позиции по индексу (по умолчанию `idle`).
|
|
6455
|
+
*
|
|
6456
|
+
* @param index Индекс позиции.
|
|
6457
|
+
*/
|
|
6458
|
+
getItemState(index) {
|
|
6459
|
+
return this.itemStates()[index] ?? IDLE_ITEM_STATE;
|
|
6460
|
+
}
|
|
6461
|
+
/**
|
|
6462
|
+
* Признак того, что позиция отправляется (поля должны быть заблокированы).
|
|
6463
|
+
*
|
|
6464
|
+
* @param index Индекс позиции.
|
|
6465
|
+
*/
|
|
6466
|
+
isItemLoading(index) {
|
|
6467
|
+
return this.getItemState(index) === 'loading';
|
|
6468
|
+
}
|
|
6469
|
+
/**
|
|
6470
|
+
* Признак того, что позиция успешно отправлена и её поля нужно заблокировать.
|
|
6471
|
+
*
|
|
6472
|
+
* @param index Индекс позиции.
|
|
6473
|
+
*/
|
|
6474
|
+
isItemLocked(index) {
|
|
6475
|
+
return this.getItemState(index) === 'success';
|
|
6476
|
+
}
|
|
6477
|
+
/**
|
|
6478
|
+
* Добавляет новое изделие в форму.
|
|
6479
|
+
*/
|
|
6480
|
+
addItem() {
|
|
6481
|
+
this.items.push(this.createItemGroup());
|
|
6482
|
+
this.itemStates.update((states) => [...states, 'idle']);
|
|
6483
|
+
this.updateItemsValidators();
|
|
6484
|
+
}
|
|
6485
|
+
/**
|
|
6486
|
+
* Удаляет изделие из формы.
|
|
6487
|
+
*
|
|
6488
|
+
* @param index Индекс изделия.
|
|
6489
|
+
*/
|
|
6490
|
+
removeItem(index) {
|
|
6491
|
+
this.items.removeAt(index);
|
|
6492
|
+
this.itemStates.update((states) => {
|
|
6493
|
+
const updated = [...states];
|
|
6494
|
+
updated.splice(index, 1);
|
|
6495
|
+
return updated;
|
|
6496
|
+
});
|
|
6497
|
+
this.updateItemsValidators();
|
|
6498
|
+
}
|
|
6499
|
+
/**
|
|
6500
|
+
* Площадь одной единицы изделия без учёта количества, м².
|
|
6501
|
+
*
|
|
6502
|
+
* @param value Значения размеров изделия.
|
|
6503
|
+
* @param value.width Ширина изделия.
|
|
6504
|
+
* @param value.length Длина изделия.
|
|
6505
|
+
*/
|
|
6506
|
+
// eslint-disable-next-line class-methods-use-this
|
|
6507
|
+
pieceAreaM2(value) {
|
|
6508
|
+
const { width, length } = value;
|
|
6509
|
+
if (!width || !length) {
|
|
6510
|
+
return 0;
|
|
6511
|
+
}
|
|
6512
|
+
return (width * length) / 1_000_000;
|
|
6513
|
+
}
|
|
6514
|
+
/**
|
|
6515
|
+
* Суммарная площадь по строке позиции: площадь единицы × количество, м².
|
|
6516
|
+
*
|
|
6517
|
+
* @param value Значения позиции.
|
|
6518
|
+
* @param value.width Ширина изделия.
|
|
6519
|
+
* @param value.length Длина изделия.
|
|
6520
|
+
* @param value.count Количество изделий.
|
|
6521
|
+
*/
|
|
6522
|
+
rowTotalPartsAreaM2(value) {
|
|
6523
|
+
const qty = value.count;
|
|
6524
|
+
if (!qty || !value.width || value.length === 0) {
|
|
6525
|
+
return 0;
|
|
6526
|
+
}
|
|
6527
|
+
return this.pieceAreaM2(value) * qty;
|
|
6528
|
+
}
|
|
6529
|
+
/**
|
|
6530
|
+
* Возвращает приблизительную стоимость строки (локальный расчёт — на всю строку позиции).
|
|
6531
|
+
*
|
|
6532
|
+
* @param value Значения изделия.
|
|
6533
|
+
* @param value.width Ширина изделия.
|
|
6534
|
+
* @param value.length Длина изделия.
|
|
6535
|
+
* @param value.count Количество изделий.
|
|
6536
|
+
*/
|
|
6537
|
+
rowCost(value) {
|
|
6538
|
+
const area = this.rowTotalPartsAreaM2(value);
|
|
6539
|
+
const cost = this.product.value?.costRub ?? 0;
|
|
6540
|
+
return Math.round(area * cost * 100) / 100;
|
|
6541
|
+
}
|
|
6542
|
+
/**
|
|
6543
|
+
* Обновляет состояние позиции на указанное значение.
|
|
6544
|
+
*
|
|
6545
|
+
* @param index Индекс позиции.
|
|
6546
|
+
* @param state Новое состояние.
|
|
6547
|
+
*/
|
|
6548
|
+
setItemState(index, state) {
|
|
6549
|
+
this.itemStates.update((states) => {
|
|
6550
|
+
const updated = [...states];
|
|
6551
|
+
updated[index] = state;
|
|
6552
|
+
return updated;
|
|
6553
|
+
});
|
|
6554
|
+
}
|
|
6555
|
+
/**
|
|
6556
|
+
* Применяет ошибки серверной валидации к контролам формы.
|
|
6557
|
+
* Сервер возвращает ключи вида `items.0.<field>` — переводим в фактический индекс позиции.
|
|
6558
|
+
*
|
|
6559
|
+
* @param error Ответ сервера.
|
|
6560
|
+
* @param index Индекс позиции в форме.
|
|
6561
|
+
*/
|
|
6562
|
+
applyServerValidationErrors(error, index) {
|
|
6563
|
+
if (!(error instanceof HttpErrorResponse)) {
|
|
6564
|
+
return;
|
|
6565
|
+
}
|
|
6566
|
+
const { errors, message } = error.error;
|
|
6567
|
+
if (errors) {
|
|
6568
|
+
Object.keys(errors).forEach((key) => {
|
|
6569
|
+
this.form.get(['items', index, key])?.setErrors({ serverResponse: errors[key] });
|
|
6570
|
+
});
|
|
6571
|
+
}
|
|
6572
|
+
else if (message) {
|
|
6573
|
+
this.form.setErrors({ serverResponse: [message] });
|
|
6574
|
+
}
|
|
6575
|
+
}
|
|
6576
|
+
/**
|
|
6577
|
+
* Обработчик добавления/редактирования продукта в корзине.
|
|
6578
|
+
*/
|
|
6579
|
+
onSubmit() {
|
|
6580
|
+
if (this.form.invalid || !this.product.value) {
|
|
6581
|
+
return;
|
|
6582
|
+
}
|
|
6583
|
+
const productId = this.product.value.id;
|
|
6584
|
+
const productCategoryId = Number(this.categoryId());
|
|
6585
|
+
const configurator = this.editor();
|
|
6586
|
+
const orderData = this.orderItem();
|
|
6587
|
+
const indexesToSubmit = this.items.controls
|
|
6588
|
+
.map((_, index) => index)
|
|
6589
|
+
.filter((index) => {
|
|
6590
|
+
const state = this.getItemState(index);
|
|
6591
|
+
return state !== 'success' && state !== 'loading';
|
|
6592
|
+
});
|
|
6593
|
+
if (indexesToSubmit.length === 0) {
|
|
6594
|
+
return;
|
|
6595
|
+
}
|
|
6596
|
+
// Позиции отправляются последовательно: каждая следующая — только после ответа предыдущей.
|
|
6597
|
+
// При ошибке цепочка прерывается; диалог не закрывается.
|
|
6598
|
+
from(indexesToSubmit)
|
|
6599
|
+
.pipe(concatMap((index, position) => {
|
|
6600
|
+
// Editing-режим: первая позиция (index 0) обновляется, остальные добавляются.
|
|
6601
|
+
const isEdit = orderData != null && index === 0 && position === 0;
|
|
6602
|
+
this.setItemState(index, 'loading');
|
|
6603
|
+
return this.buildItemRequest$(index, productId, productCategoryId, configurator, isEdit, orderData).pipe(tap(() => {
|
|
6604
|
+
this.setItemState(index, 'success');
|
|
6605
|
+
}), catchError((error) => {
|
|
6606
|
+
this.applyServerValidationErrors(error, index);
|
|
6607
|
+
this.setItemState(index, 'error');
|
|
6608
|
+
return throwError(() => error);
|
|
6609
|
+
}));
|
|
6610
|
+
}), takeUntilDestroyed(this.destroyRef))
|
|
6611
|
+
.subscribe({
|
|
6612
|
+
complete: () => {
|
|
6613
|
+
if (this.context) {
|
|
6614
|
+
this.context.$implicit.complete();
|
|
6615
|
+
}
|
|
6616
|
+
else {
|
|
6617
|
+
this.setDefaultFormValue();
|
|
6618
|
+
}
|
|
6619
|
+
},
|
|
6620
|
+
});
|
|
6621
|
+
}
|
|
6622
|
+
/**
|
|
6623
|
+
* Формирует HTTP-запрос для одной позиции формы.
|
|
6624
|
+
*
|
|
6625
|
+
* @param index Индекс позиции в форме.
|
|
6626
|
+
* @param productId Идентификатор выбранного продукта.
|
|
6627
|
+
* @param productCategoryId Идентификатор категории.
|
|
6628
|
+
* @param configurator Название конфигуратора.
|
|
6629
|
+
* @param isEdit Режим обновления существующей позиции.
|
|
6630
|
+
* @param orderData Текущая позиция заказа (только в режиме редактирования).
|
|
6631
|
+
*/
|
|
6632
|
+
buildItemRequest$(index, productId, productCategoryId, configurator, isEdit, orderData) {
|
|
6633
|
+
const itemValue = this.items.at(index).getRawValue();
|
|
6634
|
+
const payload = this.convertersService.removeNull({
|
|
6635
|
+
productCategoryId,
|
|
6636
|
+
configurator,
|
|
6637
|
+
productId,
|
|
6638
|
+
width: itemValue.width,
|
|
6639
|
+
length: itemValue.length,
|
|
6640
|
+
quantity: itemValue.count,
|
|
6641
|
+
marker: itemValue.marker,
|
|
6642
|
+
});
|
|
6643
|
+
return isEdit && orderData != null
|
|
6644
|
+
? this.orderService.updateProduct$(orderData.id, payload, this.orderId)
|
|
6645
|
+
: this.orderService.addProduct$(payload, this.orderId);
|
|
6646
|
+
}
|
|
6647
|
+
/**
|
|
6648
|
+
* Устанавливает начальные значения для полей формы.
|
|
6649
|
+
*/
|
|
6650
|
+
setDefaultFormValue() {
|
|
6651
|
+
this.form.reset({
|
|
6652
|
+
productCategoryId: Number(this.categoryId()),
|
|
6653
|
+
configurator: this.editor(),
|
|
6654
|
+
});
|
|
6655
|
+
this.items.clear();
|
|
6656
|
+
const orderItem = this.orderItem();
|
|
6657
|
+
this.items.push(this.createItemGroup({
|
|
6658
|
+
width: (orderItem?.width ?? 0) * 1000,
|
|
6659
|
+
length: (orderItem?.length ?? 0) * 1000,
|
|
6660
|
+
count: orderItem?.quantity ?? 1,
|
|
6661
|
+
marker: orderItem?.marker ?? null,
|
|
6662
|
+
}));
|
|
6663
|
+
this.itemStates.set(this.items.controls.map(() => IDLE_ITEM_STATE));
|
|
6664
|
+
this.updateItemsValidators();
|
|
6665
|
+
this.form.markAsUntouched();
|
|
6666
|
+
}
|
|
6667
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: ScSandwichM2Component, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
6668
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.2.14", type: ScSandwichM2Component, isStandalone: true, selector: "sc-sandwich-m2", inputs: { settings: { classPropertyName: "settings", publicName: "settings", isSignal: true, isRequired: false, transformFunction: null }, categoryId: { classPropertyName: "categoryId", publicName: "categoryId", isSignal: true, isRequired: true, transformFunction: null }, editor: { classPropertyName: "editor", publicName: "editor", isSignal: true, isRequired: true, transformFunction: null }, orderItem: { classPropertyName: "orderItem", publicName: "orderItem", isSignal: true, isRequired: true, transformFunction: null }, orderId: { classPropertyName: "orderId", publicName: "orderId", isSignal: false, isRequired: false, transformFunction: null } }, outputs: { toggleShowEvent: "toggleShowEvent" }, providers: [
|
|
6669
|
+
tuiNumberFormatProvider({ precision: 0 }),
|
|
6670
|
+
tuiInputNumberOptionsProvider({
|
|
6671
|
+
min: 0,
|
|
6672
|
+
}),
|
|
6673
|
+
tuiItemsHandlersProvider({
|
|
6674
|
+
stringify: signal((x) => x.name),
|
|
6675
|
+
identityMatcher: signal((a, b) => a.id === b.id),
|
|
6676
|
+
}),
|
|
6677
|
+
], ngImport: i0, template: "@if (!orderItem() && settings()?.allowShowTable) {\n <div class=\"mb-5 flex justify-center\">\n <button\n tuiButton\n appearance=\"secondary\"\n (click)=\"toggleShowEvent.emit()\"\n type=\"button\"\n iconStart=\"@tui.layout-list\"\n >\n \u041F\u043E\u043A\u0430\u0437\u0430\u0442\u044C \u0432 \u0432\u0438\u0434\u0435 \u0441\u043F\u0438\u0441\u043A\u0430\n </button>\n </div>\n}\n<div class=\"\">\n @let products = products$ | async;\n @let productValue = product.value;\n\n <form\n [formGroup]=\"form\"\n (ngSubmit)=\"onSubmit()\"\n ScNextInputFocus\n class=\"flex flex-col gap-2\"\n >\n <label\n tuiLabel\n class=\"grow\"\n >\n \u0422\u043E\u0432\u0430\u0440\n <tui-textfield\n tuiChevron\n [tuiTextfieldCleaner]=\"false\"\n >\n <input\n tuiChevron\n tuiSelect\n [formControl]=\"product\"\n placeholder=\"\u0412\u044B\u0431\u0435\u0440\u0438\u0442\u0435 \u043C\u0430\u0442\u0435\u0440\u0438\u0430\u043B\"\n />\n\n <tui-data-list-wrapper\n *tuiTextfieldDropdown\n new\n [items]=\"products\"\n />\n </tui-textfield>\n <tui-error\n [formControl]=\"product\"\n [error]=\"[] | tuiFieldError | async\"\n />\n </label>\n\n @if (productValue && productValue.costRub !== undefined) {\n <div class=\"-mt-1 text-sm text-tui-text-secondary\">\n <span class=\"font-bold\">{{ productValue.code }}</span>\n \u2014\n {{ productValue.costRub.toLocaleString() }} {{ productValue.currency.symbol }}/\u043C\u00B2\n </div>\n }\n\n @if (productValue) {\n <div class=\"mt-4 flex flex-col gap-1.5\">\n <div class=\"w-full font-bold\">\u0420\u0430\u0437\u043C\u0435\u0440\u044B \u0438\u0437\u0434\u0435\u043B\u0438\u0439</div>\n <div class=\"flex flex-col gap-1 text-sm text-tui-text-secondary\">\n @let wt = widthRangeText();\n @let lt = lengthRangeText();\n @if (wt) {\n <div>\u0428\u0438\u0440\u0438\u043D\u0430 {{ wt }}.</div>\n }\n @if (lt) {\n <div>\u0414\u043B\u0438\u043D\u0430 {{ lt }}.</div>\n }\n </div>\n </div>\n }\n\n <div class=\"flex flex-col gap-3\">\n <div\n formArrayName=\"items\"\n class=\"flex flex-col gap-3\"\n >\n @for (item of items.controls; track item) {\n @if ($index > 0) {\n <hr class=\"border-sc-grey h-px\" />\n }\n @let itemIndex = $index;\n <div\n class=\"relative flex flex-col gap-1\"\n [formGroupName]=\"itemIndex\"\n >\n @if (isItemLocked(itemIndex)) {\n <div class=\"pointer-events-none absolute right-3 bottom-0 z-10 flex size-8 items-center justify-center\">\n <tui-icon\n icon=\"@tui.check\"\n class=\"text-tui-status-positive\"\n />\n </div>\n }\n <tui-loader [showLoader]=\"isItemLoading(itemIndex)\">\n <div\n [class.opacity-70]=\"isItemLocked(itemIndex)\"\n class=\"flex min-w-0 items-start gap-2\"\n >\n <div class=\"flex min-w-0 flex-1 flex-col gap-3\">\n <div class=\"flex flex-col gap-3 lg:!flex-row lg:!items-start lg:!gap-6\">\n <!-- \u0413\u0440\u0443\u043F\u043F\u0430 1: \u0448\u0438\u0440\u0438\u043D\u0430 + \u0434\u043B\u0438\u043D\u0430 -->\n <div class=\"grid grid-cols-1 gap-2 sm:grid-cols-2 lg:!flex-[2]\">\n <label tuiLabel>\n \u0428\u0438\u0440\u0438\u043D\u0430, \u043C\u043C\n <tui-textfield>\n <input\n tuiInputSlider\n formControlName=\"width\"\n [min]=\"settings()?.minWidth ?? 0\"\n [max]=\"product.value?.properties?.width ?? 0\"\n [tuiNumberFormat]=\"{ precision: 0 }\"\n [readOnly]=\"!product.value || isItemLocked(itemIndex) || isItemLoading(itemIndex)\"\n placeholder=\"\u0428\u0438\u0440\u0438\u043D\u0430\"\n autocomplete=\"off\"\n />\n @if (product.value) {\n <input\n tuiSlider\n type=\"range\"\n />\n }\n </tui-textfield>\n <tui-error\n formControlName=\"width\"\n [error]=\"[] | tuiFieldError | async\"\n />\n </label>\n\n <label tuiLabel>\n \u0414\u043B\u0438\u043D\u0430, \u043C\u043C\n <tui-textfield>\n <input\n tuiInputSlider\n formControlName=\"length\"\n [min]=\"settings()?.minLength ?? 0\"\n [max]=\"product.value?.properties?.length ?? 0\"\n [tuiNumberFormat]=\"{ precision: 0 }\"\n [readOnly]=\"!product.value || isItemLocked(itemIndex) || isItemLoading(itemIndex)\"\n placeholder=\"\u0414\u043B\u0438\u043D\u0430\"\n autocomplete=\"off\"\n />\n @if (product.value) {\n <input\n tuiSlider\n type=\"range\"\n />\n }\n </tui-textfield>\n <tui-error\n formControlName=\"length\"\n [error]=\"[] | tuiFieldError | async\"\n />\n </label>\n </div>\n\n <!-- \u0413\u0440\u0443\u043F\u043F\u0430 2: \u043A\u043E\u043B\u0438\u0447\u0435\u0441\u0442\u0432\u043E + \u043C\u0430\u0440\u043A\u0438\u0440\u043E\u0432\u043A\u0430 (\u043D\u0430 lg 1fr | 2fr) -->\n <div class=\"grid grid-cols-1 gap-2 sm:grid-cols-2 lg:!grid-cols-[1fr_2fr] lg:!flex-[3]\">\n <label tuiLabel>\n <span class=\"whitespace-nowrap\">\u041A\u043E\u043B\u0438\u0447\u0435\u0441\u0442\u0432\u043E, \u0448\u0442</span>\n <tui-textfield [tuiTextfieldCleaner]=\"false\">\n <input\n tuiInputNumber\n formControlName=\"count\"\n [min]=\"1\"\n [tuiNumberFormat]=\"{ precision: 0 }\"\n [readOnly]=\"!product.value || isItemLocked(itemIndex) || isItemLoading(itemIndex)\"\n placeholder=\"\u041A\u043E\u043B\u0438\u0447\u0435\u0441\u0442\u0432\u043E\"\n autocomplete=\"off\"\n />\n </tui-textfield>\n <tui-error\n formControlName=\"count\"\n [error]=\"[] | tuiFieldError | async\"\n />\n </label>\n\n <label tuiLabel>\n \u041C\u0430\u0440\u043A\u0438\u0440\u043E\u0432\u043A\u0430\n <tui-textfield>\n <input\n tuiTextfield\n formControlName=\"marker\"\n [readOnly]=\"!product.value || isItemLocked(itemIndex) || isItemLoading(itemIndex)\"\n placeholder=\"\u041C\u0430\u0440\u043A\u0438\u0440\u043E\u0432\u043A\u0430\"\n autocomplete=\"off\"\n />\n </tui-textfield>\n <tui-error\n formControlName=\"marker\"\n [error]=\"[] | tuiFieldError | async\"\n />\n </label>\n </div>\n </div>\n\n @let rowVal = item.getRawValue();\n\n @if (rowVal.width > 0 && rowVal.length > 0) {\n <div class=\"mt-1 flex flex-col gap-y-1 text-sm lg:!flex-row lg:!gap-6\">\n @if (pieceAreaM2(rowVal) > 0) {\n <div class=\"lg:!flex-[2]\">\n \u041F\u043B\u043E\u0449\u0430\u0434\u044C (S) =\n <span class=\"font-bold\">{{ pieceAreaM2(rowVal) | number: '1.0-4' }} \u043C\u00B2</span>\n </div>\n }\n @if (productValue && rowCost(rowVal) > 0) {\n <div class=\"lg:!flex-[3]\">\n \u0418\u0442\u043E\u0433\u043E:\n <span class=\"font-bold\">{{ rowCost(rowVal).toLocaleString() }} {{ productValue.currency.symbol }}</span>\n </div>\n }\n </div>\n }\n </div>\n\n @if (!isEditingExistingItem()) {\n <button\n tuiIconButton\n title=\"\u0423\u0434\u0430\u043B\u0438\u0442\u044C \u0438\u0437\u0434\u0435\u043B\u0438\u0435\"\n (click)=\"removeItem(itemIndex)\"\n [disabled]=\"items.length <= 1 || !product.value || isItemLoading(itemIndex)\"\n size=\"m\"\n type=\"button\"\n iconStart=\"@tui.trash-2\"\n appearance=\"secondary\"\n class=\"mt-6 shrink-0 lg:!ml-4\"\n [style.flex]=\"'0 0 auto'\"\n ></button>\n }\n </div>\n </tui-loader>\n </div>\n }\n </div>\n\n @if (productValue) {\n <hr class=\"border-sc-grey h-px\" />\n <div class=\"flex flex-wrap items-end gap-4 pt-2\">\n @if (!isEditingExistingItem()) {\n <button\n tuiButton\n appearance=\"secondary\"\n [disabled]=\"!product.value || items.invalid\"\n (click)=\"addItem()\"\n type=\"button\"\n class=\"self-start\"\n iconStart=\"@tui.plus\"\n >\n \u0414\u043E\u0431\u0430\u0432\u0438\u0442\u044C \u0438\u0437\u0434\u0435\u043B\u0438\u0435\n </button>\n }\n\n <div class=\"ml-auto min-w-0 gap-1 text-right\">\n @if (totalAreaM2() > 0) {\n <div>\n \u041E\u0431\u0449\u0430\u044F \u043F\u043B\u043E\u0449\u0430\u0434\u044C:\n <span class=\"font-bold\">{{ totalAreaM2() | number: '1.0-4' }} \u043C\u00B2</span>\n </div>\n }\n @if (productValue.costRub && totalCost() > 0) {\n <div>\n \u0418\u0442\u043E\u0433\u043E:\n <span class=\"whitespace-nowrap text-xl font-bold\"> {{ totalCost().toLocaleString() }} {{ productValue.currency.symbol }} </span>\n </div>\n }\n </div>\n </div>\n }\n </div>\n\n <tui-error [error]=\"[] | tuiFieldError | async\" />\n\n <button\n type=\"submit\"\n [disabled]=\"form.invalid || isSubmitLoading() || hasNoPendingItems()\"\n [loading]=\"isSubmitLoading()\"\n tuiButton\n class=\"self-start\"\n iconStart=\"@tui.check\"\n >\n {{ !orderItem() ? '\u0412 \u043A\u043E\u0440\u0437\u0438\u043D\u0443' : '\u0418\u0437\u043C\u0435\u043D\u0438\u0442\u044C' }}\n </button>\n </form>\n</div>\n", styles: [":host{display:block;width:100%;max-width:36rem}.row-summary{color:var(--tui-text-secondary);font-size:.75rem}\n"], dependencies: [{ kind: "directive", type: TuiButton, selector: "a[tuiButton],button[tuiButton],a[tuiIconButton],button[tuiIconButton]", inputs: ["size"] }, { kind: "ngmodule", type: FormsModule }, { 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: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1$1.FormControlDirective, selector: "[formControl]", inputs: ["formControl", "disabled", "ngModel"], outputs: ["ngModelChange"], exportAs: ["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: "directive", type: i1$1.FormGroupName, selector: "[formGroupName]", inputs: ["formGroupName"] }, { kind: "directive", type: i1$1.FormArrayName, selector: "[formArrayName]", inputs: ["formArrayName"] }, { kind: "ngmodule", type: ScNextInputFocusModule }, { kind: "directive", type: ScNextInputFocusDirective, selector: "form[ScNextInputFocus]" }, { kind: "directive", type: TuiLabel, selector: "label[tuiLabel]" }, { kind: "component", type: TuiDataListWrapperComponent, selector: "tui-data-list-wrapper:not([labels]), tui-data-list-wrapper:not([labels])[new]", inputs: ["items", "disabledItemHandler", "emptyContent", "size", "itemContent"], outputs: ["itemClick"] }, { kind: "component", type: TuiError, selector: "tui-error", inputs: ["error"] }, { kind: "component", type: i1$2.TuiTextfieldComponent, selector: "tui-textfield:not([multi])" }, { kind: "directive", type: i1$2.TuiTextfieldDirective, selector: "input[tuiTextfield]:not([tuiInputCard]):not([tuiInputExpire]):not([tuiInputCVC])" }, { kind: "directive", type: i1$2.TuiTextfieldOptionsDirective, selector: "[tuiTextfieldAppearance],[tuiTextfieldSize],[tuiTextfieldCleaner]", inputs: ["tuiTextfieldAppearance", "tuiTextfieldSize", "tuiTextfieldCleaner"] }, { kind: "directive", type: i1$2.TuiTextfieldDropdownDirective, selector: "ng-template[tuiTextfieldDropdown]" }, { kind: "directive", type: TuiChevron, selector: "[tuiChevron]", inputs: ["tuiChevron"] }, { kind: "directive", type: i2$1.TuiSelectDirective, selector: "input[tuiSelect]" }, { kind: "directive", type: i2$1.TuiInputNumberDirective, selector: "input[tuiInputNumber]", inputs: ["min", "max", "prefix", "postfix"] }, { kind: "directive", type: TuiNumberFormat, selector: "[tuiNumberFormat]", inputs: ["tuiNumberFormat"] }, { kind: "pipe", type: AsyncPipe, name: "async" }, { kind: "pipe", type: DecimalPipe, name: "number" }, { kind: "pipe", type: TuiFieldErrorPipe, name: "tuiFieldError" }, { kind: "component", type: i5$2.TuiSliderComponent, selector: "input[type=range][tuiSlider]", inputs: ["size", "segments"] }, { kind: "directive", type: i2$1.TuiInputSliderDirective, selector: "input[tuiInputSlider]" }, { kind: "directive", type: ScSelectOnFocusinDirective, selector: "tui-input-number, tui-input, tui-input-phone, tui-input-date, tui-input-password, input[tuiInputNumber], input[tuiTextfield], input[tuiInputSlider]" }, { kind: "component", type: TuiLoader, selector: "tui-loader", inputs: ["size", "inheritColor", "overlay", "textContent", "showLoader"] }, { kind: "component", type: TuiButtonLoading, selector: "[tuiButton][loading],[tuiIconButton][loading]", inputs: ["size", "loading"] }, { kind: "component", type: TuiIcon, selector: "tui-icon", inputs: ["icon", "background"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
|
|
6678
|
+
}
|
|
6679
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: ScSandwichM2Component, decorators: [{
|
|
6680
|
+
type: Component,
|
|
6681
|
+
args: [{ standalone: true, selector: 'sc-sandwich-m2', imports: [
|
|
6682
|
+
TuiButton,
|
|
6683
|
+
FormsModule,
|
|
6684
|
+
ReactiveFormsModule,
|
|
6685
|
+
ScNextInputFocusModule,
|
|
6686
|
+
TuiLabel,
|
|
6687
|
+
TuiDataListWrapperComponent,
|
|
6688
|
+
TuiError,
|
|
6689
|
+
TuiTextfield,
|
|
6690
|
+
TuiChevron,
|
|
6691
|
+
TuiSelect,
|
|
6692
|
+
TuiInputNumber,
|
|
6693
|
+
TuiNumberFormat,
|
|
6694
|
+
AsyncPipe,
|
|
6695
|
+
DecimalPipe,
|
|
6696
|
+
TuiFieldErrorPipe,
|
|
6697
|
+
TuiInputSlider,
|
|
6698
|
+
ScSelectOnFocusinDirective,
|
|
6699
|
+
TuiLoader,
|
|
6700
|
+
TuiButtonLoading,
|
|
6701
|
+
TuiIcon,
|
|
6702
|
+
], providers: [
|
|
6703
|
+
tuiNumberFormatProvider({ precision: 0 }),
|
|
6704
|
+
tuiInputNumberOptionsProvider({
|
|
6705
|
+
min: 0,
|
|
6706
|
+
}),
|
|
6707
|
+
tuiItemsHandlersProvider({
|
|
6708
|
+
stringify: signal((x) => x.name),
|
|
6709
|
+
identityMatcher: signal((a, b) => a.id === b.id),
|
|
6710
|
+
}),
|
|
6711
|
+
], changeDetection: ChangeDetectionStrategy.OnPush, template: "@if (!orderItem() && settings()?.allowShowTable) {\n <div class=\"mb-5 flex justify-center\">\n <button\n tuiButton\n appearance=\"secondary\"\n (click)=\"toggleShowEvent.emit()\"\n type=\"button\"\n iconStart=\"@tui.layout-list\"\n >\n \u041F\u043E\u043A\u0430\u0437\u0430\u0442\u044C \u0432 \u0432\u0438\u0434\u0435 \u0441\u043F\u0438\u0441\u043A\u0430\n </button>\n </div>\n}\n<div class=\"\">\n @let products = products$ | async;\n @let productValue = product.value;\n\n <form\n [formGroup]=\"form\"\n (ngSubmit)=\"onSubmit()\"\n ScNextInputFocus\n class=\"flex flex-col gap-2\"\n >\n <label\n tuiLabel\n class=\"grow\"\n >\n \u0422\u043E\u0432\u0430\u0440\n <tui-textfield\n tuiChevron\n [tuiTextfieldCleaner]=\"false\"\n >\n <input\n tuiChevron\n tuiSelect\n [formControl]=\"product\"\n placeholder=\"\u0412\u044B\u0431\u0435\u0440\u0438\u0442\u0435 \u043C\u0430\u0442\u0435\u0440\u0438\u0430\u043B\"\n />\n\n <tui-data-list-wrapper\n *tuiTextfieldDropdown\n new\n [items]=\"products\"\n />\n </tui-textfield>\n <tui-error\n [formControl]=\"product\"\n [error]=\"[] | tuiFieldError | async\"\n />\n </label>\n\n @if (productValue && productValue.costRub !== undefined) {\n <div class=\"-mt-1 text-sm text-tui-text-secondary\">\n <span class=\"font-bold\">{{ productValue.code }}</span>\n \u2014\n {{ productValue.costRub.toLocaleString() }} {{ productValue.currency.symbol }}/\u043C\u00B2\n </div>\n }\n\n @if (productValue) {\n <div class=\"mt-4 flex flex-col gap-1.5\">\n <div class=\"w-full font-bold\">\u0420\u0430\u0437\u043C\u0435\u0440\u044B \u0438\u0437\u0434\u0435\u043B\u0438\u0439</div>\n <div class=\"flex flex-col gap-1 text-sm text-tui-text-secondary\">\n @let wt = widthRangeText();\n @let lt = lengthRangeText();\n @if (wt) {\n <div>\u0428\u0438\u0440\u0438\u043D\u0430 {{ wt }}.</div>\n }\n @if (lt) {\n <div>\u0414\u043B\u0438\u043D\u0430 {{ lt }}.</div>\n }\n </div>\n </div>\n }\n\n <div class=\"flex flex-col gap-3\">\n <div\n formArrayName=\"items\"\n class=\"flex flex-col gap-3\"\n >\n @for (item of items.controls; track item) {\n @if ($index > 0) {\n <hr class=\"border-sc-grey h-px\" />\n }\n @let itemIndex = $index;\n <div\n class=\"relative flex flex-col gap-1\"\n [formGroupName]=\"itemIndex\"\n >\n @if (isItemLocked(itemIndex)) {\n <div class=\"pointer-events-none absolute right-3 bottom-0 z-10 flex size-8 items-center justify-center\">\n <tui-icon\n icon=\"@tui.check\"\n class=\"text-tui-status-positive\"\n />\n </div>\n }\n <tui-loader [showLoader]=\"isItemLoading(itemIndex)\">\n <div\n [class.opacity-70]=\"isItemLocked(itemIndex)\"\n class=\"flex min-w-0 items-start gap-2\"\n >\n <div class=\"flex min-w-0 flex-1 flex-col gap-3\">\n <div class=\"flex flex-col gap-3 lg:!flex-row lg:!items-start lg:!gap-6\">\n <!-- \u0413\u0440\u0443\u043F\u043F\u0430 1: \u0448\u0438\u0440\u0438\u043D\u0430 + \u0434\u043B\u0438\u043D\u0430 -->\n <div class=\"grid grid-cols-1 gap-2 sm:grid-cols-2 lg:!flex-[2]\">\n <label tuiLabel>\n \u0428\u0438\u0440\u0438\u043D\u0430, \u043C\u043C\n <tui-textfield>\n <input\n tuiInputSlider\n formControlName=\"width\"\n [min]=\"settings()?.minWidth ?? 0\"\n [max]=\"product.value?.properties?.width ?? 0\"\n [tuiNumberFormat]=\"{ precision: 0 }\"\n [readOnly]=\"!product.value || isItemLocked(itemIndex) || isItemLoading(itemIndex)\"\n placeholder=\"\u0428\u0438\u0440\u0438\u043D\u0430\"\n autocomplete=\"off\"\n />\n @if (product.value) {\n <input\n tuiSlider\n type=\"range\"\n />\n }\n </tui-textfield>\n <tui-error\n formControlName=\"width\"\n [error]=\"[] | tuiFieldError | async\"\n />\n </label>\n\n <label tuiLabel>\n \u0414\u043B\u0438\u043D\u0430, \u043C\u043C\n <tui-textfield>\n <input\n tuiInputSlider\n formControlName=\"length\"\n [min]=\"settings()?.minLength ?? 0\"\n [max]=\"product.value?.properties?.length ?? 0\"\n [tuiNumberFormat]=\"{ precision: 0 }\"\n [readOnly]=\"!product.value || isItemLocked(itemIndex) || isItemLoading(itemIndex)\"\n placeholder=\"\u0414\u043B\u0438\u043D\u0430\"\n autocomplete=\"off\"\n />\n @if (product.value) {\n <input\n tuiSlider\n type=\"range\"\n />\n }\n </tui-textfield>\n <tui-error\n formControlName=\"length\"\n [error]=\"[] | tuiFieldError | async\"\n />\n </label>\n </div>\n\n <!-- \u0413\u0440\u0443\u043F\u043F\u0430 2: \u043A\u043E\u043B\u0438\u0447\u0435\u0441\u0442\u0432\u043E + \u043C\u0430\u0440\u043A\u0438\u0440\u043E\u0432\u043A\u0430 (\u043D\u0430 lg 1fr | 2fr) -->\n <div class=\"grid grid-cols-1 gap-2 sm:grid-cols-2 lg:!grid-cols-[1fr_2fr] lg:!flex-[3]\">\n <label tuiLabel>\n <span class=\"whitespace-nowrap\">\u041A\u043E\u043B\u0438\u0447\u0435\u0441\u0442\u0432\u043E, \u0448\u0442</span>\n <tui-textfield [tuiTextfieldCleaner]=\"false\">\n <input\n tuiInputNumber\n formControlName=\"count\"\n [min]=\"1\"\n [tuiNumberFormat]=\"{ precision: 0 }\"\n [readOnly]=\"!product.value || isItemLocked(itemIndex) || isItemLoading(itemIndex)\"\n placeholder=\"\u041A\u043E\u043B\u0438\u0447\u0435\u0441\u0442\u0432\u043E\"\n autocomplete=\"off\"\n />\n </tui-textfield>\n <tui-error\n formControlName=\"count\"\n [error]=\"[] | tuiFieldError | async\"\n />\n </label>\n\n <label tuiLabel>\n \u041C\u0430\u0440\u043A\u0438\u0440\u043E\u0432\u043A\u0430\n <tui-textfield>\n <input\n tuiTextfield\n formControlName=\"marker\"\n [readOnly]=\"!product.value || isItemLocked(itemIndex) || isItemLoading(itemIndex)\"\n placeholder=\"\u041C\u0430\u0440\u043A\u0438\u0440\u043E\u0432\u043A\u0430\"\n autocomplete=\"off\"\n />\n </tui-textfield>\n <tui-error\n formControlName=\"marker\"\n [error]=\"[] | tuiFieldError | async\"\n />\n </label>\n </div>\n </div>\n\n @let rowVal = item.getRawValue();\n\n @if (rowVal.width > 0 && rowVal.length > 0) {\n <div class=\"mt-1 flex flex-col gap-y-1 text-sm lg:!flex-row lg:!gap-6\">\n @if (pieceAreaM2(rowVal) > 0) {\n <div class=\"lg:!flex-[2]\">\n \u041F\u043B\u043E\u0449\u0430\u0434\u044C (S) =\n <span class=\"font-bold\">{{ pieceAreaM2(rowVal) | number: '1.0-4' }} \u043C\u00B2</span>\n </div>\n }\n @if (productValue && rowCost(rowVal) > 0) {\n <div class=\"lg:!flex-[3]\">\n \u0418\u0442\u043E\u0433\u043E:\n <span class=\"font-bold\">{{ rowCost(rowVal).toLocaleString() }} {{ productValue.currency.symbol }}</span>\n </div>\n }\n </div>\n }\n </div>\n\n @if (!isEditingExistingItem()) {\n <button\n tuiIconButton\n title=\"\u0423\u0434\u0430\u043B\u0438\u0442\u044C \u0438\u0437\u0434\u0435\u043B\u0438\u0435\"\n (click)=\"removeItem(itemIndex)\"\n [disabled]=\"items.length <= 1 || !product.value || isItemLoading(itemIndex)\"\n size=\"m\"\n type=\"button\"\n iconStart=\"@tui.trash-2\"\n appearance=\"secondary\"\n class=\"mt-6 shrink-0 lg:!ml-4\"\n [style.flex]=\"'0 0 auto'\"\n ></button>\n }\n </div>\n </tui-loader>\n </div>\n }\n </div>\n\n @if (productValue) {\n <hr class=\"border-sc-grey h-px\" />\n <div class=\"flex flex-wrap items-end gap-4 pt-2\">\n @if (!isEditingExistingItem()) {\n <button\n tuiButton\n appearance=\"secondary\"\n [disabled]=\"!product.value || items.invalid\"\n (click)=\"addItem()\"\n type=\"button\"\n class=\"self-start\"\n iconStart=\"@tui.plus\"\n >\n \u0414\u043E\u0431\u0430\u0432\u0438\u0442\u044C \u0438\u0437\u0434\u0435\u043B\u0438\u0435\n </button>\n }\n\n <div class=\"ml-auto min-w-0 gap-1 text-right\">\n @if (totalAreaM2() > 0) {\n <div>\n \u041E\u0431\u0449\u0430\u044F \u043F\u043B\u043E\u0449\u0430\u0434\u044C:\n <span class=\"font-bold\">{{ totalAreaM2() | number: '1.0-4' }} \u043C\u00B2</span>\n </div>\n }\n @if (productValue.costRub && totalCost() > 0) {\n <div>\n \u0418\u0442\u043E\u0433\u043E:\n <span class=\"whitespace-nowrap text-xl font-bold\"> {{ totalCost().toLocaleString() }} {{ productValue.currency.symbol }} </span>\n </div>\n }\n </div>\n </div>\n }\n </div>\n\n <tui-error [error]=\"[] | tuiFieldError | async\" />\n\n <button\n type=\"submit\"\n [disabled]=\"form.invalid || isSubmitLoading() || hasNoPendingItems()\"\n [loading]=\"isSubmitLoading()\"\n tuiButton\n class=\"self-start\"\n iconStart=\"@tui.check\"\n >\n {{ !orderItem() ? '\u0412 \u043A\u043E\u0440\u0437\u0438\u043D\u0443' : '\u0418\u0437\u043C\u0435\u043D\u0438\u0442\u044C' }}\n </button>\n </form>\n</div>\n", styles: [":host{display:block;width:100%;max-width:36rem}.row-summary{color:var(--tui-text-secondary);font-size:.75rem}\n"] }]
|
|
6712
|
+
}], propDecorators: { orderId: [{
|
|
6713
|
+
type: Input
|
|
6714
|
+
}] } });
|
|
6715
|
+
|
|
6716
|
+
/**
|
|
6717
|
+
* Skeleton конфигуратора распила сэндвич-панелей по площади.
|
|
6718
|
+
*/
|
|
6719
|
+
class ScSandwichM2SkeletonComponent {
|
|
6720
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: ScSandwichM2SkeletonComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
6721
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.14", type: ScSandwichM2SkeletonComponent, isStandalone: true, selector: "sc-sandwich-m2-skeleton", ngImport: i0, template: "<div class=\"w-100\">\n <div class=\"flex flex-col gap-3\">\n <!-- \u041F\u043E\u043B\u0435 \u0432\u044B\u0431\u043E\u0440\u0430 \u0442\u043E\u0432\u0430\u0440\u0430. -->\n <div class=\"mb-4 mt-2 h-10 w-full rounded-sm bg-sc-light-grey\"></div>\n\n <!-- \u0417\u0430\u0433\u043E\u043B\u043E\u0432\u043E\u043A \"\u0420\u0430\u0437\u043C\u0435\u0440\u044B \u0438\u0437\u0434\u0435\u043B\u0438\u0439\". -->\n <div class=\"my-1.5 h-5 w-1/3 rounded bg-sc-light-grey\"></div>\n\n <!-- \u0422\u0435\u043A\u0441\u0442 \u0441 \u043F\u0430\u0440\u0430\u043C\u0435\u0442\u0440\u0430\u043C\u0438. -->\n <div class=\"flex flex-col gap-1\">\n <div class=\"my-1 h-3 w-2/3 rounded bg-sc-light-grey\"></div>\n <div class=\"my-1 h-3 w-2/3 rounded bg-sc-light-grey\"></div>\n <div class=\"my-1 h-3 w-2/3 rounded bg-sc-light-grey\"></div>\n <div class=\"my-1 h-3 w-2/3 rounded bg-sc-light-grey\"></div>\n </div>\n\n <!-- \u0411\u043B\u043E\u043A \u0441 \u0438\u0437\u0434\u0435\u043B\u0438\u044F\u043C\u0438. -->\n <div class=\"flex flex-col gap-3\">\n <div class=\"flex grow gap-4\">\n <div class=\"grid grow grid-cols-4 gap-4\">\n <div class=\"flex flex-col gap-1\">\n <div class=\"my-1 h-3 w-1/2 rounded bg-sc-light-grey\"></div>\n <div class=\"mb-4 mt-2 h-10 w-full rounded-sm bg-sc-light-grey\"></div>\n </div>\n <div class=\"flex flex-col gap-1\">\n <div class=\"my-1 h-3 w-1/2 rounded bg-sc-light-grey\"></div>\n <div class=\"mb-4 mt-2 h-10 w-full rounded-sm bg-sc-light-grey\"></div>\n </div>\n <div class=\"flex flex-col gap-1\">\n <div class=\"my-1 h-3 w-1/2 rounded bg-sc-light-grey\"></div>\n <div class=\"mb-4 mt-2 h-10 w-full rounded-sm bg-sc-light-grey\"></div>\n </div>\n <div class=\"flex flex-col gap-1\">\n <div class=\"my-1 h-3 w-1/2 rounded bg-sc-light-grey\"></div>\n <div class=\"mb-4 mt-2 h-10 w-full rounded-sm bg-sc-light-grey\"></div>\n </div>\n </div>\n <div class=\"mt-6 size-8 shrink-0 rounded-sm bg-sc-light-grey\"></div>\n </div>\n </div>\n\n <!-- \u041A\u043D\u043E\u043F\u043A\u0430 \"\u0414\u043E\u0431\u0430\u0432\u0438\u0442\u044C \u0438\u0437\u0434\u0435\u043B\u0438\u0435\". -->\n <button\n tuiButton\n appearance=\"secondary\"\n class=\"sc-skeleton self-center\"\n ></button>\n\n <!-- \u0418\u0442\u043E\u0433\u043E\u0432\u0430\u044F \u043F\u043B\u043E\u0449\u0430\u0434\u044C \u0438 \u0441\u0442\u043E\u0438\u043C\u043E\u0441\u0442\u044C. -->\n <div class=\"my-2.5 h-6 w-1/3 rounded bg-sc-light-grey\"></div>\n\n <!-- \u041A\u043D\u043E\u043F\u043A\u0430 \u043E\u0442\u043F\u0440\u0430\u0432\u043A\u0438. -->\n <button\n tuiButton\n class=\"sc-skeleton self-center\"\n ></button>\n </div>\n</div>\n", changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
|
|
6722
|
+
}
|
|
6723
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: ScSandwichM2SkeletonComponent, decorators: [{
|
|
6724
|
+
type: Component,
|
|
6725
|
+
args: [{ standalone: true, selector: 'sc-sandwich-m2-skeleton', changeDetection: ChangeDetectionStrategy.OnPush, template: "<div class=\"w-100\">\n <div class=\"flex flex-col gap-3\">\n <!-- \u041F\u043E\u043B\u0435 \u0432\u044B\u0431\u043E\u0440\u0430 \u0442\u043E\u0432\u0430\u0440\u0430. -->\n <div class=\"mb-4 mt-2 h-10 w-full rounded-sm bg-sc-light-grey\"></div>\n\n <!-- \u0417\u0430\u0433\u043E\u043B\u043E\u0432\u043E\u043A \"\u0420\u0430\u0437\u043C\u0435\u0440\u044B \u0438\u0437\u0434\u0435\u043B\u0438\u0439\". -->\n <div class=\"my-1.5 h-5 w-1/3 rounded bg-sc-light-grey\"></div>\n\n <!-- \u0422\u0435\u043A\u0441\u0442 \u0441 \u043F\u0430\u0440\u0430\u043C\u0435\u0442\u0440\u0430\u043C\u0438. -->\n <div class=\"flex flex-col gap-1\">\n <div class=\"my-1 h-3 w-2/3 rounded bg-sc-light-grey\"></div>\n <div class=\"my-1 h-3 w-2/3 rounded bg-sc-light-grey\"></div>\n <div class=\"my-1 h-3 w-2/3 rounded bg-sc-light-grey\"></div>\n <div class=\"my-1 h-3 w-2/3 rounded bg-sc-light-grey\"></div>\n </div>\n\n <!-- \u0411\u043B\u043E\u043A \u0441 \u0438\u0437\u0434\u0435\u043B\u0438\u044F\u043C\u0438. -->\n <div class=\"flex flex-col gap-3\">\n <div class=\"flex grow gap-4\">\n <div class=\"grid grow grid-cols-4 gap-4\">\n <div class=\"flex flex-col gap-1\">\n <div class=\"my-1 h-3 w-1/2 rounded bg-sc-light-grey\"></div>\n <div class=\"mb-4 mt-2 h-10 w-full rounded-sm bg-sc-light-grey\"></div>\n </div>\n <div class=\"flex flex-col gap-1\">\n <div class=\"my-1 h-3 w-1/2 rounded bg-sc-light-grey\"></div>\n <div class=\"mb-4 mt-2 h-10 w-full rounded-sm bg-sc-light-grey\"></div>\n </div>\n <div class=\"flex flex-col gap-1\">\n <div class=\"my-1 h-3 w-1/2 rounded bg-sc-light-grey\"></div>\n <div class=\"mb-4 mt-2 h-10 w-full rounded-sm bg-sc-light-grey\"></div>\n </div>\n <div class=\"flex flex-col gap-1\">\n <div class=\"my-1 h-3 w-1/2 rounded bg-sc-light-grey\"></div>\n <div class=\"mb-4 mt-2 h-10 w-full rounded-sm bg-sc-light-grey\"></div>\n </div>\n </div>\n <div class=\"mt-6 size-8 shrink-0 rounded-sm bg-sc-light-grey\"></div>\n </div>\n </div>\n\n <!-- \u041A\u043D\u043E\u043F\u043A\u0430 \"\u0414\u043E\u0431\u0430\u0432\u0438\u0442\u044C \u0438\u0437\u0434\u0435\u043B\u0438\u0435\". -->\n <button\n tuiButton\n appearance=\"secondary\"\n class=\"sc-skeleton self-center\"\n ></button>\n\n <!-- \u0418\u0442\u043E\u0433\u043E\u0432\u0430\u044F \u043F\u043B\u043E\u0449\u0430\u0434\u044C \u0438 \u0441\u0442\u043E\u0438\u043C\u043E\u0441\u0442\u044C. -->\n <div class=\"my-2.5 h-6 w-1/3 rounded bg-sc-light-grey\"></div>\n\n <!-- \u041A\u043D\u043E\u043F\u043A\u0430 \u043E\u0442\u043F\u0440\u0430\u0432\u043A\u0438. -->\n <button\n tuiButton\n class=\"sc-skeleton self-center\"\n ></button>\n </div>\n</div>\n" }]
|
|
6726
|
+
}] });
|
|
6727
|
+
|
|
6121
6728
|
/**
|
|
6122
6729
|
* Компонент карточки менеджера Push-уведомлений.
|
|
6123
6730
|
*/
|
|
@@ -9294,5 +9901,5 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImpo
|
|
|
9294
9901
|
* Generated bundle index. Do not edit.
|
|
9295
9902
|
*/
|
|
9296
9903
|
|
|
9297
|
-
export { AbstractScPriceCard, AuthMethod, CURRENT_COUNTRY_ID, CostWithDiscountComponent, FilesAndDocumentsComponent, FilesAndDocumentsModule, FinishDateTimeTransformerDirective, IS_DEFAULT_COUNTRY, MAX_FILES_IN_FORM_INPUT, SC_ALLOW_SELECT_TERMINATED, SC_BANNER_DURATION, SC_CATALOG_PRODUCTS_FILTERS, SC_CATALOG_SHOW_PRODUCTS_RECURSIVELY, SC_DATE_FORMATTER, SC_DEBOUNCE_TIME_DEFAULT, SC_DIALOG_SERVICE_TOKEN, SC_ERROR_CHANGE_HANDLER, 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_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, 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, ScNewsModule, ScNextInputFocusDirective, ScNextInputFocusModule, ScNoindexDirective, ScNoindexWrapperComponent, ScNotifyWhenInStockDialogComponent, ScOrderAccessorDirective, ScOrderItemComponent, ScOrderItemsByDirection, ScOrderItemsListByDirectionsComponent, ScOrderItemsListByStockComponent, ScOrderItemsListComponent, ScOrderModule, ScPaymentStatusComponent, ScPersonalDataProcessingPolicyComponent, ScPhoneFormatPipe, ScPreviewSampleComponent, ScPreviewSampleModule, ScPreviewSamplesMosquitoComponent, ScPriceCardComponent, ScPriceCardInlineComponent, ScPriceHistoryComponent, ScPriceListPaginationComponent, ScPriceWarehouseStockComponent, ScPrintDirective, ScPrintService, ScPrivacyPolicyComponent, ScProductInAllWarehousesPipe, ScProfileAccordionsContentComponent, ScProfileModule, ScPublicOfferComponent, ScQRCodeDialogComponent, ScQRCodeModule, ScResetUserPasswordComponent, ScResourcePreviewComponent, ScSandwichComponent, ScSandwichSkeletonComponent, ScSelectOnFocusinDirective, ScSeoTagsComponent, ScShareButtonComponent, ScShareButtonModule, ScSignInFormByEmailComponent, ScSignInFormByPhoneComponent, ScSignInFormComponent, ScSignUpFormComponent, ScSimpleSignUpFormComponent, ScSuggestionFieldComponent, ScTelLinkDirective, ScTerminalLinkDirective, ScUpdateUserInfoDialogComponent, ScUserManagersComponent, ScUserModule, ScUserPhoneApproveDialogComponent, ScVerificationModule, ScVerificationPhoneCheckFormComponent, TreeDirective, TreeIconService, TreeLoaderService, TreeTopDirective, phoneValidator, scAtLeastOneRequiredValidator, scBicValidator, scClientUiIconsName, scCorrespondentAccountValidator, scGetCurrentRoute, scPasswordConfirmMatchingValidator, stepValidator, tuiDateValueTransformerDefaultProvider };
|
|
9904
|
+
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_HELP_NOTIFICATION_CLOSE, SC_HELP_NOTIFICATION_LIMIT, SC_HIDDEN_PRINT_ELEMENTS, SC_MANAGER_QR_HANDLER, SC_NOTIFY_WHEN_IN_STOCK_REQUIRED_FIELDS, 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, 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, ScNewsModule, ScNextInputFocusDirective, ScNextInputFocusModule, ScNoindexDirective, ScNoindexWrapperComponent, ScNotifyWhenInStockDialogComponent, ScOrderAccessorDirective, ScOrderItemComponent, ScOrderItemsByDirection, ScOrderItemsListByDirectionsComponent, ScOrderItemsListByStockComponent, ScOrderItemsListComponent, ScOrderModule, 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, ScShareButtonModule, ScSignInFormByEmailComponent, ScSignInFormByPhoneComponent, ScSignInFormComponent, ScSignUpFormComponent, ScSimpleSignUpFormComponent, ScSuggestionFieldComponent, ScTelLinkDirective, ScTerminalLinkDirective, ScUpdateUserInfoDialogComponent, ScUserManagersComponent, ScUserModule, ScUserPhoneApproveDialogComponent, ScVerificationModule, ScVerificationPhoneCheckFormComponent, TreeDirective, TreeIconService, TreeLoaderService, TreeTopDirective, phoneValidator, scAtLeastOneRequiredValidator, scBicValidator, scClientUiIconsName, scCorrespondentAccountValidator, scGetCurrentRoute, scPasswordConfirmMatchingValidator, stepValidator, tuiDateValueTransformerDefaultProvider };
|
|
9298
9905
|
//# sourceMappingURL=snabcentr-client-ui.mjs.map
|