@snabcentr/client-ui 0.30.1 → 0.31.0
Sign up to get free protection for your applications and to get access to all the features.
- package/catalog/categories-list/sc-categories-list.component.d.ts +4 -2
- package/esm2020/catalog/categories-list/sc-categories-list.component.mjs +20 -12
- package/esm2020/delivery-address/add-delivery-address-dialog/sc-add-delivery-address-dialog.component.mjs +17 -11
- package/fesm2015/snabcentr-client-ui.mjs +33 -22
- package/fesm2015/snabcentr-client-ui.mjs.map +1 -1
- package/fesm2020/snabcentr-client-ui.mjs +32 -20
- package/fesm2020/snabcentr-client-ui.mjs.map +1 -1
- package/package.json +1 -1
- package/styles/tailwind/tailwind.scss +8 -0
@@ -1,7 +1,7 @@
|
|
1
1
|
import * as i0 from '@angular/core';
|
2
2
|
import { EventEmitter, Component, ChangeDetectionStrategy, Inject, Input, Output, SkipSelf, Directive, HostBinding, ContentChild, ViewChild, NgModule, Optional, Injectable, ElementRef, ContentChildren, HostListener, ChangeDetectorRef, Self, inject, InjectionToken, forwardRef } from '@angular/core';
|
3
3
|
import * as i1 from '@snabcentr/client-core';
|
4
|
-
import { ScUserMetrikaGoalsEnum, ScISuggestionType, ScOpfList, SC_URLS, SC_PATH_IMAGE_NOT_FOUND, ScWarehouseService, ScAuthService, SEARCH_TERM, ScImageHelper, SEARCH_TERM_PROVIDERS, ScCatalogService, ScCartService, ScIconTypesEnum, ScUserService } from '@snabcentr/client-core';
|
4
|
+
import { ScUserMetrikaGoalsEnum, ScISuggestionType, ScOpfList, SC_URLS, SC_PATH_IMAGE_NOT_FOUND, IS_RUNNING_ON_TERMINAL, TERMINAL_PROVIDERS, ScWarehouseService, ScAuthService, SEARCH_TERM, ScImageHelper, SEARCH_TERM_PROVIDERS, ScCatalogService, ScCartService, ScIconTypesEnum, ScUserService } from '@snabcentr/client-core';
|
5
5
|
import * as i5 from 'rxjs';
|
6
6
|
import { Subject, map, filter, switchMap, tap, catchError, of, finalize, startWith, share, timer, scan, takeWhile, endWith, distinctUntilChanged, combineLatest, debounceTime, throwError, shareReplay, interval, takeUntil, skip, merge } from 'rxjs';
|
7
7
|
import * as i2 from '@angular/common';
|
@@ -2920,11 +2920,13 @@ let ScCategoriesListComponent = class ScCategoriesListComponent {
|
|
2920
2920
|
* Инициализирует экземпляр класса {@link ScCategoriesListComponent}.
|
2921
2921
|
*
|
2922
2922
|
* @param urls объект информации о базовом списке ссылок приложения.
|
2923
|
+
* @param terminal Данные о запуске приложения на терминале.
|
2923
2924
|
* @param favoriteService Сервис для работы с корзиной.
|
2924
2925
|
* @param cdr Объект для работы с обнаружением изменений.
|
2925
2926
|
*/
|
2926
|
-
constructor(urls, favoriteService, cdr) {
|
2927
|
+
constructor(urls, terminal, favoriteService, cdr) {
|
2927
2928
|
this.urls = urls;
|
2929
|
+
this.terminal = terminal;
|
2928
2930
|
this.favoriteService = favoriteService;
|
2929
2931
|
this.cdr = cdr;
|
2930
2932
|
/**
|
@@ -2939,12 +2941,14 @@ let ScCategoriesListComponent = class ScCategoriesListComponent {
|
|
2939
2941
|
/** @inheritDoc */
|
2940
2942
|
ngOnInit() {
|
2941
2943
|
this.favoriteService.categories$
|
2942
|
-
.pipe(filter(() => !!this.categories &&
|
2943
|
-
this.categories
|
2944
|
-
category.isFavorite = categories.findIndex(item => category.id === item.id) !== -1;
|
2944
|
+
.pipe(filter(() => !!this.categories && this.categories.length > 0 && 'id' in this.categories[0]), tap((categories) => {
|
2945
|
+
this.categories.forEach((category) => {
|
2946
|
+
category.isFavorite = categories.findIndex((item) => category.id === item.id) !== -1;
|
2945
2947
|
});
|
2946
2948
|
}), untilDestroyed(this))
|
2947
|
-
.subscribe(() =>
|
2949
|
+
.subscribe(() => {
|
2950
|
+
this.cdr.markForCheck();
|
2951
|
+
});
|
2948
2952
|
}
|
2949
2953
|
/**
|
2950
2954
|
* Возвращает путь до изображения на сервере.
|
@@ -2952,7 +2956,7 @@ let ScCategoriesListComponent = class ScCategoriesListComponent {
|
|
2952
2956
|
* @param imgPath путь, где хранится изображение.
|
2953
2957
|
*/
|
2954
2958
|
getCategoryImage(imgPath) {
|
2955
|
-
return this.urls.imgServerUrl
|
2959
|
+
return `${this.urls.imgServerUrl}/${imgPath}`;
|
2956
2960
|
}
|
2957
2961
|
/**
|
2958
2962
|
* Проверяет наличие хотя бы одного изображения.
|
@@ -2964,8 +2968,8 @@ let ScCategoriesListComponent = class ScCategoriesListComponent {
|
|
2964
2968
|
return categories.some((item) => item.properties?.image);
|
2965
2969
|
}
|
2966
2970
|
};
|
2967
|
-
ScCategoriesListComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: ScCategoriesListComponent, deps: [{ token: SC_URLS }, { token: i1.ScFavoriteService }, { token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Component });
|
2968
|
-
ScCategoriesListComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.3.0", type: ScCategoriesListComponent, selector: "sc-categories-list", inputs: { categories: "categories" }, outputs: { clickCategoryEvent: "clickCategoryEvent" }, ngImport: i0, template: "<div class=\"grid grid-cols-[repeat(auto-fill,minmax(21rem,1fr))] gap-x-8 gap-y-2\">\n <ng-container *ngIf=\"categories; else categoriesSkeleton\">\n <button\n *ngFor=\"let item of $any(categories)\"\n class=\"group flex h-11 items-center gap-2 rounded-xl bg-tui-base-02 px-3 py-1.5 text-left ring-tui-primary duration-150 hover-hover:hover:ring-2 hover-none:active:ring-2\"\n (click)=\"clickCategoryEvent.emit(item)\"\n >\n <img\n *ngIf=\"item.properties?.image as image\"\n [src]=\"getCategoryImage(image)\"\n [alt]=\"item.name\"\n class=\"size-8 rounded bg-tui-base-03 object-cover\"\n />\n\n <tui-svg\n *ngIf=\"!item.properties?.image && checkImagesExists(categories)\"\n src=\"tuiIconCameraOffLarge\"\n class=\"!h-8 !w-8 rounded bg-tui-base-03 text-tui-base-05\"\n ></tui-svg>\n <div class=\"flex grow flex-col truncate\">\n <div class=\"flex grow truncate\">\n <p class=\"truncate text-base font-bold\">{{ item.name }}</p>\n <tui-svg\n *ngIf=\"item.isFavorite\"\n src=\"scIconFavoriteFill\"\n class=\"mr-auto !text-sm text-tui-primary\"\n ></tui-svg>\n </div>\n <p\n *ngIf=\"item.m2Price as m2Price\"\n class=\"text-xs font-medium text-tui-text-02\"\n >\n \u0421\u0440\u0435\u0434\u043D\u044F\u044F \u0441\u0442\u043E\u0438\u043C\u043E\u0441\u0442\u044C <span [innerHTML]=\"m2Price\"></span>\n </p>\n </div>\n\n <tui-svg\n src=\"tuiIconChevronRightLarge\"\n class=\"duration-150 hover-hover:group-hover:text-tui-primary hover-none:group-active:text-tui-primary\"\n ></tui-svg>\n </button>\n </ng-container>\n</div>\n\n<ng-template #categoriesSkeleton>\n <button\n *tuiRepeatTimes=\"let index of isMobile ? 3 : 6\"\n class=\"group flex h-11 items-center gap-2 rounded-xl bg-tui-base-02 px-3 py-1.5 text-left ring-tui-base-05 duration-150 hover-hover:hover:ring-2 hover-none:active:ring-2\"\n >\n <div class=\"tui-skeleton size-8\"></div>\n <div class=\"tui-skeleton h-4 grow\"></div>\n <tui-svg\n src=\"tuiIconChevronRightLarge\"\n class=\"tui-skeleton duration-150 hover-hover:group-hover:text-tui-primary hover-none:group-active:text-tui-primary\"\n ></tui-svg>\n </button>\n</ng-template>\n", dependencies: [{ kind: "directive", type: i2.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i2.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "component", type: i4.TuiSvgComponent, selector: "tui-svg", inputs: ["src"] }, { kind: "directive", type: i6.TuiRepeatTimesDirective, selector: "[tuiRepeatTimes][tuiRepeatTimesOf]", inputs: ["tuiRepeatTimesOf"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
2971
|
+
ScCategoriesListComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: ScCategoriesListComponent, deps: [{ token: SC_URLS }, { token: IS_RUNNING_ON_TERMINAL }, { token: i1.ScFavoriteService }, { token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Component });
|
2972
|
+
ScCategoriesListComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.3.0", type: ScCategoriesListComponent, selector: "sc-categories-list", inputs: { categories: "categories" }, outputs: { clickCategoryEvent: "clickCategoryEvent" }, providers: [TERMINAL_PROVIDERS], ngImport: i0, template: "<div\n [ngClass]=\"{ '!flex !flex-col': terminal.isRunningOnTerminal }\"\n class=\"grid grid-cols-[repeat(auto-fill,minmax(21rem,1fr))] gap-x-8 gap-y-2\"\n>\n <ng-container *ngIf=\"categories; else categoriesSkeleton\">\n <button\n *ngFor=\"let item of $any(categories)\"\n class=\"group flex h-11 items-center gap-2 rounded-xl bg-tui-base-02 px-3 py-1.5 text-left ring-tui-primary duration-150 hover-hover:hover:ring-2 hover-none:active:ring-2\"\n (click)=\"clickCategoryEvent.emit(item)\"\n >\n <img\n *ngIf=\"item.properties?.image as image\"\n [src]=\"getCategoryImage(image)\"\n [alt]=\"item.name\"\n class=\"size-8 rounded bg-tui-base-03 object-cover\"\n />\n\n <tui-svg\n *ngIf=\"!item.properties?.image && checkImagesExists(categories)\"\n src=\"tuiIconCameraOffLarge\"\n class=\"!h-8 !w-8 rounded bg-tui-base-03 text-tui-base-05\"\n ></tui-svg>\n <div class=\"flex grow flex-col truncate\">\n <div class=\"flex grow truncate\">\n <p class=\"truncate text-base font-bold\">{{ item.name }}</p>\n <tui-svg\n *ngIf=\"item.isFavorite\"\n src=\"scIconFavoriteFill\"\n class=\"mr-auto !text-sm text-tui-primary\"\n ></tui-svg>\n </div>\n <p\n *ngIf=\"item.m2Price as m2Price\"\n class=\"text-xs font-medium text-tui-text-02\"\n >\n \u0421\u0440\u0435\u0434\u043D\u044F\u044F \u0441\u0442\u043E\u0438\u043C\u043E\u0441\u0442\u044C <span [innerHTML]=\"m2Price\"></span>\n </p>\n </div>\n\n <tui-svg\n src=\"tuiIconChevronRightLarge\"\n class=\"duration-150 hover-hover:group-hover:text-tui-primary hover-none:group-active:text-tui-primary\"\n ></tui-svg>\n </button>\n </ng-container>\n</div>\n\n<ng-template #categoriesSkeleton>\n <button\n *tuiRepeatTimes=\"let index of isMobile ? 3 : 6\"\n class=\"group flex h-11 items-center gap-2 rounded-xl bg-tui-base-02 px-3 py-1.5 text-left ring-tui-base-05 duration-150 hover-hover:hover:ring-2 hover-none:active:ring-2\"\n >\n <div class=\"tui-skeleton size-8\"></div>\n <div class=\"tui-skeleton h-4 grow\"></div>\n <tui-svg\n src=\"tuiIconChevronRightLarge\"\n class=\"tui-skeleton duration-150 hover-hover:group-hover:text-tui-primary hover-none:group-active:text-tui-primary\"\n ></tui-svg>\n </button>\n</ng-template>\n", dependencies: [{ kind: "directive", type: i2.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i2.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i2.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "component", type: i4.TuiSvgComponent, selector: "tui-svg", inputs: ["src"] }, { kind: "directive", type: i6.TuiRepeatTimesDirective, selector: "[tuiRepeatTimes][tuiRepeatTimesOf]", inputs: ["tuiRepeatTimesOf"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
2969
2973
|
__decorate([
|
2970
2974
|
tuiPure
|
2971
2975
|
], ScCategoriesListComponent.prototype, "checkImagesExists", null);
|
@@ -2974,10 +2978,13 @@ ScCategoriesListComponent = __decorate([
|
|
2974
2978
|
], ScCategoriesListComponent);
|
2975
2979
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: ScCategoriesListComponent, decorators: [{
|
2976
2980
|
type: Component,
|
2977
|
-
args: [{ selector: 'sc-categories-list', changeDetection: ChangeDetectionStrategy.OnPush, template: "<div class=\"grid grid-cols-[repeat(auto-fill,minmax(21rem,1fr))] gap-x-8 gap-y-2\">\n <ng-container *ngIf=\"categories; else categoriesSkeleton\">\n <button\n *ngFor=\"let item of $any(categories)\"\n class=\"group flex h-11 items-center gap-2 rounded-xl bg-tui-base-02 px-3 py-1.5 text-left ring-tui-primary duration-150 hover-hover:hover:ring-2 hover-none:active:ring-2\"\n (click)=\"clickCategoryEvent.emit(item)\"\n >\n <img\n *ngIf=\"item.properties?.image as image\"\n [src]=\"getCategoryImage(image)\"\n [alt]=\"item.name\"\n class=\"size-8 rounded bg-tui-base-03 object-cover\"\n />\n\n <tui-svg\n *ngIf=\"!item.properties?.image && checkImagesExists(categories)\"\n src=\"tuiIconCameraOffLarge\"\n class=\"!h-8 !w-8 rounded bg-tui-base-03 text-tui-base-05\"\n ></tui-svg>\n <div class=\"flex grow flex-col truncate\">\n <div class=\"flex grow truncate\">\n <p class=\"truncate text-base font-bold\">{{ item.name }}</p>\n <tui-svg\n *ngIf=\"item.isFavorite\"\n src=\"scIconFavoriteFill\"\n class=\"mr-auto !text-sm text-tui-primary\"\n ></tui-svg>\n </div>\n <p\n *ngIf=\"item.m2Price as m2Price\"\n class=\"text-xs font-medium text-tui-text-02\"\n >\n \u0421\u0440\u0435\u0434\u043D\u044F\u044F \u0441\u0442\u043E\u0438\u043C\u043E\u0441\u0442\u044C <span [innerHTML]=\"m2Price\"></span>\n </p>\n </div>\n\n <tui-svg\n src=\"tuiIconChevronRightLarge\"\n class=\"duration-150 hover-hover:group-hover:text-tui-primary hover-none:group-active:text-tui-primary\"\n ></tui-svg>\n </button>\n </ng-container>\n</div>\n\n<ng-template #categoriesSkeleton>\n <button\n *tuiRepeatTimes=\"let index of isMobile ? 3 : 6\"\n class=\"group flex h-11 items-center gap-2 rounded-xl bg-tui-base-02 px-3 py-1.5 text-left ring-tui-base-05 duration-150 hover-hover:hover:ring-2 hover-none:active:ring-2\"\n >\n <div class=\"tui-skeleton size-8\"></div>\n <div class=\"tui-skeleton h-4 grow\"></div>\n <tui-svg\n src=\"tuiIconChevronRightLarge\"\n class=\"tui-skeleton duration-150 hover-hover:group-hover:text-tui-primary hover-none:group-active:text-tui-primary\"\n ></tui-svg>\n </button>\n</ng-template>\n" }]
|
2981
|
+
args: [{ selector: 'sc-categories-list', providers: [TERMINAL_PROVIDERS], changeDetection: ChangeDetectionStrategy.OnPush, template: "<div\n [ngClass]=\"{ '!flex !flex-col': terminal.isRunningOnTerminal }\"\n class=\"grid grid-cols-[repeat(auto-fill,minmax(21rem,1fr))] gap-x-8 gap-y-2\"\n>\n <ng-container *ngIf=\"categories; else categoriesSkeleton\">\n <button\n *ngFor=\"let item of $any(categories)\"\n class=\"group flex h-11 items-center gap-2 rounded-xl bg-tui-base-02 px-3 py-1.5 text-left ring-tui-primary duration-150 hover-hover:hover:ring-2 hover-none:active:ring-2\"\n (click)=\"clickCategoryEvent.emit(item)\"\n >\n <img\n *ngIf=\"item.properties?.image as image\"\n [src]=\"getCategoryImage(image)\"\n [alt]=\"item.name\"\n class=\"size-8 rounded bg-tui-base-03 object-cover\"\n />\n\n <tui-svg\n *ngIf=\"!item.properties?.image && checkImagesExists(categories)\"\n src=\"tuiIconCameraOffLarge\"\n class=\"!h-8 !w-8 rounded bg-tui-base-03 text-tui-base-05\"\n ></tui-svg>\n <div class=\"flex grow flex-col truncate\">\n <div class=\"flex grow truncate\">\n <p class=\"truncate text-base font-bold\">{{ item.name }}</p>\n <tui-svg\n *ngIf=\"item.isFavorite\"\n src=\"scIconFavoriteFill\"\n class=\"mr-auto !text-sm text-tui-primary\"\n ></tui-svg>\n </div>\n <p\n *ngIf=\"item.m2Price as m2Price\"\n class=\"text-xs font-medium text-tui-text-02\"\n >\n \u0421\u0440\u0435\u0434\u043D\u044F\u044F \u0441\u0442\u043E\u0438\u043C\u043E\u0441\u0442\u044C <span [innerHTML]=\"m2Price\"></span>\n </p>\n </div>\n\n <tui-svg\n src=\"tuiIconChevronRightLarge\"\n class=\"duration-150 hover-hover:group-hover:text-tui-primary hover-none:group-active:text-tui-primary\"\n ></tui-svg>\n </button>\n </ng-container>\n</div>\n\n<ng-template #categoriesSkeleton>\n <button\n *tuiRepeatTimes=\"let index of isMobile ? 3 : 6\"\n class=\"group flex h-11 items-center gap-2 rounded-xl bg-tui-base-02 px-3 py-1.5 text-left ring-tui-base-05 duration-150 hover-hover:hover:ring-2 hover-none:active:ring-2\"\n >\n <div class=\"tui-skeleton size-8\"></div>\n <div class=\"tui-skeleton h-4 grow\"></div>\n <tui-svg\n src=\"tuiIconChevronRightLarge\"\n class=\"tui-skeleton duration-150 hover-hover:group-hover:text-tui-primary hover-none:group-active:text-tui-primary\"\n ></tui-svg>\n </button>\n</ng-template>\n" }]
|
2978
2982
|
}], ctorParameters: function () { return [{ type: undefined, decorators: [{
|
2979
2983
|
type: Inject,
|
2980
2984
|
args: [SC_URLS]
|
2985
|
+
}] }, { type: undefined, decorators: [{
|
2986
|
+
type: Inject,
|
2987
|
+
args: [IS_RUNNING_ON_TERMINAL]
|
2981
2988
|
}] }, { type: i1.ScFavoriteService }, { type: i0.ChangeDetectorRef }]; }, propDecorators: { categories: [{
|
2982
2989
|
type: Input
|
2983
2990
|
}], clickCategoryEvent: [{
|
@@ -3774,6 +3781,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImpor
|
|
3774
3781
|
}]
|
3775
3782
|
}] });
|
3776
3783
|
|
3784
|
+
/* eslint-disable @typescript-eslint/unbound-method,lodash/prefer-lodash-method */
|
3777
3785
|
/**
|
3778
3786
|
* Компонент добавления адреса доставки.
|
3779
3787
|
*
|
@@ -3810,17 +3818,21 @@ class ScAddDeliveryAddressDialogComponent {
|
|
3810
3818
|
*/
|
3811
3819
|
this.request$ = this.onSubmit$.pipe(tap(() => {
|
3812
3820
|
tuiMarkControlAsTouchedAndValidate(this.form);
|
3813
|
-
}), filter(() => this.form.valid), map(() => this.form.value), switchMap((value) => this.deliveryAddressService.createDeliveryAddress$(this.convertersService.removeNullRecursive(value)).pipe(
|
3814
|
-
const errorResponse = error.error;
|
3815
|
-
for (const key in errorResponse.errors) {
|
3816
|
-
this.form.get(key)?.setErrors({ serverResponse: errorResponse.errors[key] });
|
3817
|
-
}
|
3818
|
-
if (!errorResponse.errors && errorResponse.message) {
|
3819
|
-
this.form.setErrors({ serverResponse: [errorResponse.message] });
|
3820
|
-
}
|
3821
|
-
return of();
|
3822
|
-
}), tap(() => {
|
3821
|
+
}), filter(() => this.form.valid), map(() => this.form.value), switchMap((value) => this.deliveryAddressService.createDeliveryAddress$(this.convertersService.removeNullRecursive(value)).pipe(tap(() => {
|
3823
3822
|
this.context.completeWith();
|
3823
|
+
}), catchError((error) => {
|
3824
|
+
if (error instanceof HttpErrorResponse) {
|
3825
|
+
const { errors, message } = error.error;
|
3826
|
+
if (errors) {
|
3827
|
+
Object.keys(errors).forEach((key) => {
|
3828
|
+
this.form.get(key)?.setErrors({ serverResponse: errors[key] });
|
3829
|
+
});
|
3830
|
+
}
|
3831
|
+
else if (message) {
|
3832
|
+
this.form.setErrors({ serverResponse: [message] });
|
3833
|
+
}
|
3834
|
+
}
|
3835
|
+
return of({});
|
3824
3836
|
}), startWith(null))), share());
|
3825
3837
|
/**
|
3826
3838
|
* {@link Observable} изменения состояния загрузки данных.
|