@snabcentr/client-ui 4.21.0 → 4.24.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.
Files changed (104) hide show
  1. package/alerts/confirm-alert/sc-confirm-alert.component.d.ts +22 -0
  2. package/alerts/index.d.ts +1 -0
  3. package/cart/add-or-editing-cart-item-dialog/sc-add-or-editing-cart-item-dialog.component.d.ts +1 -1
  4. package/cart/sc-cart-add-products-from-csv-dialog/sc-cart-add-products-from-csv-dialog.component.d.ts +3 -3
  5. package/catalog/input-quantity/sc-input-quantity.component.d.ts +17 -1
  6. package/esm2022/alerts/confirm-alert/sc-confirm-alert.component.mjs +29 -0
  7. package/esm2022/alerts/index.mjs +2 -0
  8. package/esm2022/cart/add-or-editing-cart-item-dialog/sc-add-or-editing-cart-item-dialog.component.mjs +4 -3
  9. package/esm2022/cart/sc-cart-add-products-from-csv-dialog/sc-cart-add-products-from-csv-dialog.component.mjs +5 -16
  10. package/esm2022/catalog/input-quantity/sc-input-quantity.component.mjs +24 -4
  11. package/esm2022/feedback/feedback-form/sc-feedback-form.component.mjs +21 -11
  12. package/esm2022/helpers/sc-api-error-helper.mjs +25 -0
  13. package/esm2022/helpers/sc-file-helper.mjs +29 -0
  14. package/esm2022/order/draft/helpers/sc-draft-list-helper.mjs +83 -0
  15. package/esm2022/order/draft/models/sc-i-draft-list-item.mjs +2 -0
  16. package/esm2022/order/draft/profstroy/actualization-panel/sc-profstroy-actualization-panel.component.mjs +73 -0
  17. package/esm2022/order/draft/profstroy/badge/sc-profstroy-badge.component.mjs +21 -0
  18. package/esm2022/order/draft/profstroy/badges/sc-profstroy-draft-badges.component.mjs +31 -0
  19. package/esm2022/order/draft/profstroy/create-dialog/sc-profstroy-draft-create-dialog.component.mjs +139 -0
  20. package/esm2022/order/draft/profstroy/enums/sc-profstroy-draft-state.mjs +32 -0
  21. package/esm2022/order/draft/profstroy/helpers/sc-profstroy-draft-helper.mjs +94 -0
  22. package/esm2022/order/draft/profstroy/index.mjs +8 -0
  23. package/esm2022/order/draft/profstroy/models/sc-i-profstroy-draft-state-view.mjs +2 -0
  24. package/esm2022/order/draft/sc-draft.component.mjs +148 -14
  25. package/esm2022/order/draft/services/sc-draft-expiration-clock.service.mjs +42 -0
  26. package/esm2022/order/draft/services/sc-draft-list-updates.service.mjs +288 -0
  27. package/esm2022/order/index.mjs +6 -1
  28. package/esm2022/order/new-order-items/sc-new-order-items.component.mjs +11 -3
  29. package/esm2022/order/order-form/sc-order-form.component.mjs +4 -2
  30. package/esm2022/order/order-item/sc-order-item.component.mjs +37 -5
  31. package/esm2022/order/order-items-list/sc-order-items-list.component.mjs +254 -47
  32. package/esm2022/order/order-items-list-by-stock/sc-order-items-list-by-stock.component.mjs +1 -1
  33. package/esm2022/order/order-items-list-with-actions/sc-order-items-list-with-actions.component.mjs +15 -3
  34. package/esm2022/pipes/sc-format-date.mjs +1 -1
  35. package/esm2022/providers/cleanup-recaptcha-artifacts.mjs +30 -0
  36. package/esm2022/providers/index.mjs +2 -1
  37. package/esm2022/providers/sc-date-formatter.mjs +1 -1
  38. package/esm2022/public-api.mjs +2 -2
  39. package/esm2022/samples/sc-sample.module.mjs +10 -3
  40. package/esm2022/services/index.mjs +1 -2
  41. package/feedback/feedback-form/sc-feedback-form.component.d.ts +1 -1
  42. package/fesm2022/snabcentr-client-ui.mjs +1399 -477
  43. package/fesm2022/snabcentr-client-ui.mjs.map +1 -1
  44. package/helpers/sc-api-error-helper.d.ts +18 -0
  45. package/helpers/sc-file-helper.d.ts +13 -0
  46. package/order/draft/helpers/sc-draft-list-helper.d.ts +51 -0
  47. package/order/draft/models/sc-i-draft-list-item.d.ts +14 -0
  48. package/order/draft/profstroy/actualization-panel/sc-profstroy-actualization-panel.component.d.ts +58 -0
  49. package/order/draft/profstroy/badge/sc-profstroy-badge.component.d.ts +12 -0
  50. package/order/draft/profstroy/badges/sc-profstroy-draft-badges.component.d.ts +21 -0
  51. package/order/draft/profstroy/create-dialog/sc-profstroy-draft-create-dialog.component.d.ts +65 -0
  52. package/order/draft/profstroy/enums/sc-profstroy-draft-state.d.ts +29 -0
  53. package/order/draft/profstroy/helpers/sc-profstroy-draft-helper.d.ts +33 -0
  54. package/order/draft/profstroy/index.d.ts +7 -0
  55. package/order/draft/profstroy/models/sc-i-profstroy-draft-state-view.d.ts +17 -0
  56. package/order/draft/sc-draft.component.d.ts +73 -1
  57. package/order/draft/services/sc-draft-expiration-clock.service.d.ts +29 -0
  58. package/order/draft/services/sc-draft-list-updates.service.d.ts +158 -0
  59. package/order/index.d.ts +5 -0
  60. package/order/new-order-items/sc-new-order-items.component.d.ts +9 -1
  61. package/order/order-form/sc-order-form.component.d.ts +1 -0
  62. package/order/order-item/sc-order-item.component.d.ts +25 -1
  63. package/order/order-items-list/sc-order-items-list.component.d.ts +132 -9
  64. package/order/order-items-list-with-actions/sc-order-items-list-with-actions.component.d.ts +13 -1
  65. package/package.json +3 -2
  66. package/pipes/sc-format-date.d.ts +1 -1
  67. package/providers/cleanup-recaptcha-artifacts.d.ts +7 -0
  68. package/providers/index.d.ts +1 -0
  69. package/providers/sc-date-formatter.d.ts +1 -1
  70. package/public-api.d.ts +1 -1
  71. package/release_notes.tmp +2 -10
  72. package/samples/sc-sample.module.d.ts +2 -1
  73. package/services/index.d.ts +0 -1
  74. package/styles/tailwind/tailwind.scss +43 -40
  75. package/esm2022/services/sc-scripts.service.mjs +0 -106
  76. package/esm2022/smart-captcha/index.mjs +0 -5
  77. package/esm2022/smart-captcha/interfaces/index.mjs +0 -6
  78. package/esm2022/smart-captcha/interfaces/sc-smart-captcha-api.mjs +0 -2
  79. package/esm2022/smart-captcha/interfaces/sc-smart-captcha-event.mjs +0 -2
  80. package/esm2022/smart-captcha/interfaces/sc-smart-captcha-language.mjs +0 -2
  81. package/esm2022/smart-captcha/interfaces/sc-smart-captcha-render-params.mjs +0 -2
  82. package/esm2022/smart-captcha/interfaces/sc-smart-captcha-settings.mjs +0 -2
  83. package/esm2022/smart-captcha/interfaces/sc-smart-captcha-window.mjs +0 -2
  84. package/esm2022/smart-captcha/sc-smart-captcha.component.mjs +0 -167
  85. package/esm2022/smart-captcha/services/index.mjs +0 -2
  86. package/esm2022/smart-captcha/services/sc-smart-captcha-loader.service.mjs +0 -87
  87. package/esm2022/smart-captcha/tokens/index.mjs +0 -3
  88. package/esm2022/smart-captcha/tokens/sc-smart-captcha-load-timeout.token.mjs +0 -8
  89. package/esm2022/smart-captcha/tokens/sc-smart-captcha-settings.token.mjs +0 -6
  90. package/services/sc-scripts.service.d.ts +0 -51
  91. package/smart-captcha/index.d.ts +0 -4
  92. package/smart-captcha/interfaces/index.d.ts +0 -5
  93. package/smart-captcha/interfaces/sc-smart-captcha-api.d.ts +0 -36
  94. package/smart-captcha/interfaces/sc-smart-captcha-event.d.ts +0 -4
  95. package/smart-captcha/interfaces/sc-smart-captcha-language.d.ts +0 -4
  96. package/smart-captcha/interfaces/sc-smart-captcha-render-params.d.ts +0 -16
  97. package/smart-captcha/interfaces/sc-smart-captcha-settings.d.ts +0 -16
  98. package/smart-captcha/interfaces/sc-smart-captcha-window.d.ts +0 -14
  99. package/smart-captcha/sc-smart-captcha.component.d.ts +0 -92
  100. package/smart-captcha/services/index.d.ts +0 -1
  101. package/smart-captcha/services/sc-smart-captcha-loader.service.d.ts +0 -50
  102. package/smart-captcha/tokens/index.d.ts +0 -2
  103. package/smart-captcha/tokens/sc-smart-captcha-load-timeout.token.d.ts +0 -5
  104. package/smart-captcha/tokens/sc-smart-captcha-settings.token.d.ts +0 -6
package/order/index.d.ts CHANGED
@@ -7,6 +7,11 @@ export * from './order-item/sc-order-item.component';
7
7
  export * from './order-items-list/sc-order-items-list.component';
8
8
  export * from './order-items-list-with-actions/sc-order-items-list-with-actions.component';
9
9
  export * from './order-items-list-by-stock/sc-order-items-list-by-stock.component';
10
+ export * from './draft/helpers/sc-draft-list-helper';
11
+ export * from './draft/models/sc-i-draft-list-item';
12
+ export * from './draft/services/sc-draft-expiration-clock.service';
13
+ export * from './draft/services/sc-draft-list-updates.service';
14
+ export * from './draft/profstroy';
10
15
  export * from './draft/sc-draft.component';
11
16
  export * from './sc-payment-status/sc-payment-status.component';
12
17
  export * from './sc-order.module';
@@ -16,6 +16,14 @@ export declare class ScNewOrderItemsComponent {
16
16
  * Включить выбор позиций чекбоксами.
17
17
  */
18
18
  readonly selectable: import("@angular/core").InputSignal<boolean>;
19
+ /**
20
+ * Признак, что цена за единицу берётся из позиции, а не из текущей цены товара.
21
+ */
22
+ readonly useLinePrice: import("@angular/core").InputSignal<boolean>;
23
+ /**
24
+ * Подпись итоговой суммы.
25
+ */
26
+ readonly totalLabel: import("@angular/core").InputSignal<string>;
19
27
  /**
20
28
  * Время обработки и принятия заказов (из настроек окружения приложения).
21
29
  */
@@ -25,5 +33,5 @@ export declare class ScNewOrderItemsComponent {
25
33
  */
26
34
  readonly selectedItemsIdsChange: import("@angular/core").OutputEmitterRef<string[]>;
27
35
  static ɵfac: i0.ɵɵFactoryDeclaration<ScNewOrderItemsComponent, never>;
28
- static ɵcmp: i0.ɵɵComponentDeclaration<ScNewOrderItemsComponent, "sc-new-order-items", never, { "items": { "alias": "items"; "required": true; "isSignal": true; }; "editable": { "alias": "editable"; "required": false; "isSignal": true; }; "selectable": { "alias": "selectable"; "required": false; "isSignal": true; }; "orderProcessingAcceptanceTime": { "alias": "orderProcessingAcceptanceTime"; "required": false; "isSignal": true; }; }, { "selectedItemsIdsChange": "selectedItemsIdsChange"; }, never, ["[footerActions]"], true, never>;
36
+ static ɵcmp: i0.ɵɵComponentDeclaration<ScNewOrderItemsComponent, "sc-new-order-items", never, { "items": { "alias": "items"; "required": true; "isSignal": true; }; "editable": { "alias": "editable"; "required": false; "isSignal": true; }; "selectable": { "alias": "selectable"; "required": false; "isSignal": true; }; "useLinePrice": { "alias": "useLinePrice"; "required": false; "isSignal": true; }; "totalLabel": { "alias": "totalLabel"; "required": false; "isSignal": true; }; "orderProcessingAcceptanceTime": { "alias": "orderProcessingAcceptanceTime"; "required": false; "isSignal": true; }; }, { "selectedItemsIdsChange": "selectedItemsIdsChange"; }, never, ["[footerActions]"], true, never>;
29
37
  }
@@ -201,6 +201,7 @@ export declare class ScOrderFormComponent implements OnInit {
201
201
  stringify(items: readonly SelectType[]): TuiStringHandler<TuiContext<number>>;
202
202
  /**
203
203
  * Обрабатывает отправку формы: валидирует и эмитит данные заказа родителю.
204
+ * Общая ошибка сервера с прошлой отправки (например, 409) не мешает отправить форму снова, ошибки полей остаются до их исправления.
204
205
  */
205
206
  submit(): void;
206
207
  /**
@@ -26,6 +26,30 @@ export declare class ScOrderItemComponent extends AbstractScPriceCard {
26
26
  * Признак, что необходимо отобразить элементы редактирования.
27
27
  */
28
28
  readonly isShowEditControls: import("@angular/core").InputSignal<boolean>;
29
+ /**
30
+ * Признак, что цена за единицу берётся из позиции, а не из текущей цены товара (например, цена, зафиксированная в заявке).
31
+ */
32
+ readonly useLinePrice: import("@angular/core").InputSignal<boolean>;
33
+ /**
34
+ * Признак, что позиция, которая не попадёт в заказ, помечается примечанием, а неактивная позиция зачёркивается.
35
+ */
36
+ readonly markUnavailable: import("@angular/core").InputSignal<boolean>;
37
+ /**
38
+ * Признак, что изменение позиции ждёт очереди или выполняется.
39
+ */
40
+ readonly isPending: import("@angular/core").InputSignal<boolean>;
41
+ /**
42
+ * Признак, что параметры позиции можно изменить в диалоге, даже если они ещё не заданы.
43
+ */
44
+ readonly settingsAvailable: import("@angular/core").InputSignal<boolean>;
45
+ /**
46
+ * Оформление примечания к позиции: группа, которая не участвует в заказе, серым, остальные причины жёлтым.
47
+ */
48
+ protected get unavailableReasonAppearance(): string;
49
+ /**
50
+ * Подсказка к количеству, когда поля количества нет: где его изменить. У неактивной позиции с примечанием количество не меняется, и подсказки нет.
51
+ */
52
+ protected get quantityHint(): string;
29
53
  /**
30
54
  * Отображает спецификацию.
31
55
  *
@@ -39,5 +63,5 @@ export declare class ScOrderItemComponent extends AbstractScPriceCard {
39
63
  */
40
64
  protected configuratorHintVisible(visible: boolean): void;
41
65
  static ɵfac: i0.ɵɵFactoryDeclaration<ScOrderItemComponent, never>;
42
- static ɵcmp: i0.ɵɵComponentDeclaration<ScOrderItemComponent, "sc-order-item", never, { "isShowEditControls": { "alias": "isShowEditControls"; "required": false; "isSignal": true; }; }, { "clickSettings": "clickSettings"; }, never, never, true, never>;
66
+ static ɵcmp: i0.ɵɵComponentDeclaration<ScOrderItemComponent, "sc-order-item", never, { "isShowEditControls": { "alias": "isShowEditControls"; "required": false; "isSignal": true; }; "useLinePrice": { "alias": "useLinePrice"; "required": false; "isSignal": true; }; "markUnavailable": { "alias": "markUnavailable"; "required": false; "isSignal": true; }; "isPending": { "alias": "isPending"; "required": false; "isSignal": true; }; "settingsAvailable": { "alias": "settingsAvailable"; "required": false; "isSignal": true; }; }, { "clickSettings": "clickSettings"; }, never, never, true, never>;
43
67
  }
@@ -1,5 +1,5 @@
1
1
  import { FormControl, FormGroup } from '@angular/forms';
2
- import { ScIOrderEditorLoader, ScIOrderLoader, ScOrderItem } from '@snabcentr/client-core';
2
+ import { ScIOrderEditorLoader, ScIOrderItemsGroup, ScIOrderLoader, ScOrderItem } from '@snabcentr/client-core';
3
3
  import { AbstractScPriceCard } from '../../directives';
4
4
  import { ScOrderOptions } from '../directives/sc-order-options';
5
5
  import * as i0 from "@angular/core";
@@ -7,6 +7,14 @@ import * as i0 from "@angular/core";
7
7
  * Компонент списка товаров корзины, заказа или черновика.
8
8
  */
9
9
  export declare class ScOrderItemsListComponent {
10
+ /**
11
+ * Возвращает копию набора с добавленными или убранными ключами.
12
+ *
13
+ * @param keys Набор.
14
+ * @param changed Ключи.
15
+ * @param isIncluded Признак добавления.
16
+ */
17
+ private static withKeys;
10
18
  /**
11
19
  * Внутренний сигнал списка элементов корзины (товаров).
12
20
  */
@@ -19,6 +27,48 @@ export declare class ScOrderItemsListComponent {
19
27
  * Включить редактирование позиций.
20
28
  */
21
29
  readonly editable: import("@angular/core").InputSignal<boolean>;
30
+ /**
31
+ * Признак вывода позиций по группам (группа позиции или «Без группы») с заголовками и итогами. Без признака позиции выводятся одним списком без заголовков.
32
+ */
33
+ readonly grouped: import("@angular/core").InputSignal<boolean>;
34
+ /**
35
+ * Признак, что позиции, которые не попадут в заказ, помечаются примечанием и не выбираются. Неактивные позиции приглушаются и зачёркиваются.
36
+ */
37
+ readonly markUnavailable: import("@angular/core").InputSignal<boolean>;
38
+ /**
39
+ * Признак, что цена за единицу берётся из позиции, а не из текущей цены товара.
40
+ */
41
+ readonly useLinePrice: import("@angular/core").InputSignal<boolean>;
42
+ /**
43
+ * Признак, что параметры позиции меняются в диалоге товара: диалог доступен у любой активной позиции, а количество и метраж измеряемых товаров
44
+ * меняются только в нём, даже если метраж ещё не задан.
45
+ */
46
+ readonly measuredInDialog: import("@angular/core").InputSignal<boolean>;
47
+ /**
48
+ * Откуда удаляется позиция для текста подтверждения, например «из черновика». Если не задано, позиция удаляется без подтверждения.
49
+ * Тот же текст используется в предупреждении о нулевом количестве.
50
+ */
51
+ readonly deleteConfirmationTarget: import("@angular/core").InputSignal<string | null>;
52
+ /**
53
+ * Подпись итоговой суммы.
54
+ */
55
+ readonly totalLabel: import("@angular/core").InputSignal<string>;
56
+ /**
57
+ * Позиции, разбитые на группы. Без группировки все позиции идут одной группой без заголовка.
58
+ */
59
+ protected readonly groups: import("@angular/core").Signal<ScIOrderItemsGroup[]>;
60
+ /**
61
+ * Идентификаторы позиций, изменение или удаление которых ждёт очереди или выполняется.
62
+ */
63
+ protected readonly pendingItemsIds: import("@angular/core").WritableSignal<ReadonlySet<string>>;
64
+ /**
65
+ * Названия удаляемых групп.
66
+ */
67
+ protected readonly deletingGroupsNames: import("@angular/core").WritableSignal<ReadonlySet<string>>;
68
+ /**
69
+ * Названия групп с позициями, ждущими ответа: такие группы удалить нельзя.
70
+ */
71
+ protected readonly pendingGroupsNames: import("@angular/core").Signal<ReadonlySet<string>>;
22
72
  /**
23
73
  * Внутренняя группа формы для выбора позиций.
24
74
  */
@@ -32,7 +82,8 @@ export declare class ScOrderItemsListComponent {
32
82
  */
33
83
  protected readonly itemsIds: import("@angular/core").Signal<[string, boolean][]>;
34
84
  /**
35
- * Состояние флага «Выбрать все»: `true`, если выбраны все позиции, `false`, если ни одной, и `null`, если только часть.
85
+ * Состояние флага «Выбрать все»: `true`, если выбраны все доступные для выбора позиции, `false`, если ни одной или выбирать нечего,
86
+ * и `null`, если только часть.
36
87
  */
37
88
  protected readonly allItemsSelected: import("@angular/core").Signal<boolean | null>;
38
89
  /**
@@ -56,6 +107,10 @@ export declare class ScOrderItemsListComponent {
56
107
  * Признак, что можно редактировать позиции.
57
108
  */
58
109
  protected readonly canEdit: import("@angular/core").Signal<boolean>;
110
+ /**
111
+ * Признак, что группу можно удалить целиком.
112
+ */
113
+ protected readonly canDeleteGroups: import("@angular/core").Signal<boolean>;
59
114
  /**
60
115
  * Настройки вывода сумм в рублях.
61
116
  */
@@ -69,29 +124,60 @@ export declare class ScOrderItemsListComponent {
69
124
  * Предоставляется родителем через токен {@link SC_DIALOG_SERVICE_TOKEN}.
70
125
  */
71
126
  private readonly scDialogService;
127
+ /**
128
+ * Сервис диалоговых окон Taiga для подтверждений.
129
+ */
130
+ private readonly dialogService;
131
+ /**
132
+ * Сервис уведомлений.
133
+ */
134
+ private readonly alerts;
135
+ /**
136
+ * Инициализирует экземпляр класса {@link ScOrderItemsListComponent}.
137
+ * Входы выбора и пометки недоступных позиций могут прийти после списка позиций, поэтому при их изменении выбор синхронизируется заново.
138
+ */
139
+ constructor();
72
140
  /**
73
141
  * Список элементов корзины (товаров). При установке синхронно обновляет контролы выбора в форме.
74
142
  */
75
143
  set items(value: ScOrderItem[]);
76
144
  /**
77
145
  * Синхронизирует контролы формы выбора с текущим списком товаров: удаляет контролы для отсутствующих id, добавляет для новых.
146
+ * Контролы меняются без событий, а значение группы пересчитывается один раз в конце: на заявках в сотни позиций это заметно.
78
147
  */
79
148
  private syncSelectionControls;
80
149
  /**
81
- * Выбирает все позиции или снимает выбор со всех.
150
+ * Выбирает все доступные для выбора позиции или снимает выбор со всех.
82
151
  *
83
152
  * @param event Событие изменения флага выбора всех позиций.
84
153
  */
85
154
  protected selectAllChangeHandler(event: Event): void;
86
155
  /**
87
- * Удаляет позицию.
156
+ * Возвращает признак, что позиция приглушена: она неактивна или не выбрана для заказа.
157
+ *
158
+ * @param item Позиция.
159
+ */
160
+ protected isItemDimmed(item: ScOrderItem): boolean;
161
+ /**
162
+ * Возвращает признак, что количество и метраж товара позиции меняются в диалоге товара.
163
+ *
164
+ * @param item Позиция.
165
+ */
166
+ protected isEditedInDialog(item: ScOrderItem): boolean;
167
+ /**
168
+ * Удаляет позицию, при необходимости после подтверждения. Сообщение об ошибке показывает перехватчик приложения.
88
169
  *
89
170
  * @param item Позиция товара для удаления.
90
- * @param priceCard Компонент карточки товара.
91
171
  */
92
- protected deleteItem(item: ScOrderItem, priceCard: AbstractScPriceCard): void;
172
+ protected deleteItem(item: ScOrderItem): void;
173
+ /**
174
+ * Удаляет все позиции группы после подтверждения. Состав берётся на момент подтверждения.
175
+ *
176
+ * @param group Группа позиций.
177
+ */
178
+ protected deleteGroup(group: ScIOrderItemsGroup): void;
93
179
  /**
94
- * Обновляет количество товара.
180
+ * Обновляет количество товара. Количество неактивной позиции не меняется. Пустое или нулевое значение возвращается к сохранённому количеству.
95
181
  *
96
182
  * @param newQuantity Новое значение количества товара.
97
183
  * @param priceCard Компонент карточки товара.
@@ -106,7 +192,7 @@ export declare class ScOrderItemsListComponent {
106
192
  */
107
193
  protected openProductInfoDialog(product: ScOrderItem['product'], orderItem?: ScOrderItem, orderId?: number): void;
108
194
  /**
109
- * Открывает модальное окно изменения товара или его конфигуратора.
195
+ * Открывает модальное окно изменения товара или его конфигуратора. Если параметры позиции меняются в диалоге, окно товара открывается и у штучного товара.
110
196
  *
111
197
  * @param item Позиция товара.
112
198
  */
@@ -117,6 +203,43 @@ export declare class ScOrderItemsListComponent {
117
203
  * @param product Товар/услуга, для которого необходимо отобразить график изменения стоимости.
118
204
  */
119
205
  protected openPriceHistoryChartDialog(product: ScOrderItem['product']): void;
206
+ /**
207
+ * Возвращает {@link Observable}, который выдаёт значение, когда удаление позиции подтверждено или подтверждение не требуется.
208
+ *
209
+ * @param item Удаляемая позиция.
210
+ */
211
+ private confirmDelete$;
212
+ /**
213
+ * Возвращает {@link Observable}, который выдаёт значение, когда удаление группы подтверждено.
214
+ *
215
+ * @param group Группа позиций.
216
+ */
217
+ private confirmGroupDelete$;
218
+ /**
219
+ * Возвращает {@link Observable}, который выдаёт значение, когда удаление подтверждено.
220
+ *
221
+ * @param label Вопрос.
222
+ */
223
+ private confirmRemoval$;
224
+ /**
225
+ * Отмечает позицию как ожидающую ответа или снимает отметку.
226
+ *
227
+ * @param id Идентификатор позиции.
228
+ * @param isPending Признак ожидания.
229
+ */
230
+ private setItemPending;
231
+ /**
232
+ * Ставит или снимает отметку ожидания у позиций.
233
+ *
234
+ * @param itemsIds Идентификаторы позиций.
235
+ * @param isPending Признак ожидания.
236
+ */
237
+ private setItemsPending;
238
+ /**
239
+ * Предупреждает, что количество не может быть пустым или нулевым, а убрать позицию можно удалением. Поле возвращается к сохранённому количеству
240
+ * в любом списке, предупреждение показывается только в списках с подтверждением удаления.
241
+ */
242
+ private warnEmptyQuantity;
120
243
  static ɵfac: i0.ɵɵFactoryDeclaration<ScOrderItemsListComponent, never>;
121
- static ɵcmp: i0.ɵɵComponentDeclaration<ScOrderItemsListComponent, "sc-order-items-list", never, { "selectable": { "alias": "selectable"; "required": false; "isSignal": true; }; "editable": { "alias": "editable"; "required": false; "isSignal": true; }; "items": { "alias": "items"; "required": true; }; }, { "selectedItemsIdsChange": "selectedItemsIdsChange"; }, never, never, true, never>;
244
+ static ɵcmp: i0.ɵɵComponentDeclaration<ScOrderItemsListComponent, "sc-order-items-list", never, { "selectable": { "alias": "selectable"; "required": false; "isSignal": true; }; "editable": { "alias": "editable"; "required": false; "isSignal": true; }; "grouped": { "alias": "grouped"; "required": false; "isSignal": true; }; "markUnavailable": { "alias": "markUnavailable"; "required": false; "isSignal": true; }; "useLinePrice": { "alias": "useLinePrice"; "required": false; "isSignal": true; }; "measuredInDialog": { "alias": "measuredInDialog"; "required": false; "isSignal": true; }; "deleteConfirmationTarget": { "alias": "deleteConfirmationTarget"; "required": false; "isSignal": true; }; "totalLabel": { "alias": "totalLabel"; "required": false; "isSignal": true; }; "items": { "alias": "items"; "required": true; }; }, { "selectedItemsIdsChange": "selectedItemsIdsChange"; }, never, never, true, never>;
122
245
  }
@@ -16,6 +16,18 @@ export declare class ScOrderItemsListWithActionsComponent {
16
16
  * Включить редактирование позиций.
17
17
  */
18
18
  readonly editable: import("@angular/core").InputSignal<boolean>;
19
+ /**
20
+ * Признак, что цена за единицу берётся из позиции, а не из текущей цены товара.
21
+ */
22
+ readonly useLinePrice: import("@angular/core").InputSignal<boolean>;
23
+ /**
24
+ * Откуда удаляется позиция для текста подтверждения, например «из черновика». Если не задано, позиция удаляется без подтверждения.
25
+ */
26
+ readonly deleteConfirmationTarget: import("@angular/core").InputSignal<string | null>;
27
+ /**
28
+ * Подпись итоговой суммы.
29
+ */
30
+ readonly totalLabel: import("@angular/core").InputSignal<string>;
19
31
  /**
20
32
  * Позиции, доступные для заказа.
21
33
  */
@@ -33,5 +45,5 @@ export declare class ScOrderItemsListWithActionsComponent {
33
45
  */
34
46
  constructor();
35
47
  static ɵfac: i0.ɵɵFactoryDeclaration<ScOrderItemsListWithActionsComponent, never>;
36
- static ɵcmp: i0.ɵɵComponentDeclaration<ScOrderItemsListWithActionsComponent, "sc-order-items-list-with-actions", never, { "items": { "alias": "items"; "required": true; "isSignal": true; }; "selectable": { "alias": "selectable"; "required": false; "isSignal": true; }; "editable": { "alias": "editable"; "required": false; "isSignal": true; }; "selectedItemsIds": { "alias": "selectedItemsIds"; "required": false; "isSignal": true; }; }, { "selectedItemsIds": "selectedItemsIdsChange"; }, never, ["[footerActions]"], true, never>;
48
+ static ɵcmp: i0.ɵɵComponentDeclaration<ScOrderItemsListWithActionsComponent, "sc-order-items-list-with-actions", never, { "items": { "alias": "items"; "required": true; "isSignal": true; }; "selectable": { "alias": "selectable"; "required": false; "isSignal": true; }; "editable": { "alias": "editable"; "required": false; "isSignal": true; }; "useLinePrice": { "alias": "useLinePrice"; "required": false; "isSignal": true; }; "deleteConfirmationTarget": { "alias": "deleteConfirmationTarget"; "required": false; "isSignal": true; }; "totalLabel": { "alias": "totalLabel"; "required": false; "isSignal": true; }; "selectedItemsIds": { "alias": "selectedItemsIds"; "required": false; "isSignal": true; }; }, { "selectedItemsIds": "selectedItemsIdsChange"; }, never, ["[footerActions]"], true, never>;
37
49
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@snabcentr/client-ui",
3
- "version": "4.21.0",
3
+ "version": "4.24.0",
4
4
  "author": "Snabcentr Ltd.",
5
5
  "repository": "https://gitlab.snabcentr.met/web/angular/snabcentr-client-ui-lib",
6
6
  "license": "Commercial",
@@ -16,7 +16,7 @@
16
16
  "@maskito/core": "^3.11.1",
17
17
  "@ng-web-apis/intersection-observer": "^4.14.0",
18
18
  "@ng-web-apis/common": "^4.14.0",
19
- "@snabcentr/client-core": "^3.23.6",
19
+ "@snabcentr/client-core": "^3.26.1",
20
20
  "@taiga-ui/addon-charts": "^4.66.0",
21
21
  "@taiga-ui/addon-commerce": "^4.66.0",
22
22
  "@taiga-ui/cdk": "^4.66.0",
@@ -31,6 +31,7 @@
31
31
  "@taiga-ui/experimental": "^4.66.0",
32
32
  "@taiga-ui/styles": "^4.66.0",
33
33
  "@tailwindcss/container-queries": "^0.1.1",
34
+ "ng-recaptcha-2": "^14.0.0",
34
35
  "angular8-yandex-maps": "^18.2.0",
35
36
  "date-fns": "^4.1.0",
36
37
  "libphonenumber-js": "^1.12.7",
@@ -14,7 +14,7 @@ export declare class ScFormatDatePipe implements PipeTransform {
14
14
  * @param timeString - Строка времени.
15
15
  * @returns Форматированная дата и время.
16
16
  */
17
- transform(timeString?: string): string | undefined;
17
+ transform(timeString?: string | Date): string | undefined;
18
18
  static ɵfac: i0.ɵɵFactoryDeclaration<ScFormatDatePipe, never>;
19
19
  static ɵpipe: i0.ɵɵPipeDeclaration<ScFormatDatePipe, "scFormatDate", true>;
20
20
  }
@@ -0,0 +1,7 @@
1
+ /**
2
+ * Освобождает ресурсы reCAPTCHA и удаляет осиротевшие iframe после смены маршрута.
3
+ *
4
+ * @param documentReference Объект документа.
5
+ * @param windowReference Объект окна браузера.
6
+ */
7
+ export declare function cleanupRecaptchaArtifacts(documentReference: Document, windowReference: Window): void;
@@ -14,3 +14,4 @@ export * from './sc-notify-when-in-stock-required-fields';
14
14
  export * from './sc-banner-duration';
15
15
  export * from './sc-debounce-time-default';
16
16
  export * from './sc-hidden-print-elements.token';
17
+ export * from './cleanup-recaptcha-artifacts';
@@ -3,4 +3,4 @@ import { InjectionToken } from '@angular/core';
3
3
  * Токен для функции форматирования даты и времени.
4
4
  * По умолчанию используется формат 'DD.MM.YYYY HH:MM'.
5
5
  */
6
- export declare const SC_DATE_FORMATTER: InjectionToken<(date: string) => string>;
6
+ export declare const SC_DATE_FORMATTER: InjectionToken<(date: string | Date) => string>;
package/public-api.d.ts CHANGED
@@ -2,6 +2,7 @@ export * from './models';
2
2
  export * from './services';
3
3
  export * from './auth';
4
4
  export * from './accordion';
5
+ export * from './alerts';
5
6
  export * from './banner';
6
7
  export * from './cart';
7
8
  export * from './catalog';
@@ -29,7 +30,6 @@ export * from './providers';
29
30
  export * from './feedback';
30
31
  export * from './qrcode';
31
32
  export * from './share';
32
- export * from './smart-captcha';
33
33
  export * from './user';
34
34
  export * from './validators';
35
35
  export * from './verification';
package/release_notes.tmp CHANGED
@@ -1,12 +1,4 @@
1
- ## 4.21.0 (2026-10-21)
1
+ ## 4.24.0 (2026-11-02)
2
2
 
3
- ### added (2 changes)
4
-
5
- - [#14126: В плашке наличия товара выводится планируемая дата производства](web_soft/libs/angular/snabcentr-client-ui-lib@c18fb9b58935c49697a12bc850acdaf66fa1b69a) ([merge request](web_soft/libs/angular/snabcentr-client-ui-lib!468))
6
- - [#14112: Добавлен флаг «Выбрать все» для выделения и снятия выделения всех позиций заказа](web_soft/libs/angular/snabcentr-client-ui-lib@22ce6a6e367bb7b36dcd423603bde295befa3358) ([merge request](web_soft/libs/angular/snabcentr-client-ui-lib!466))
7
-
8
- ### changed (2 changes)
9
-
10
- - [#14054: Неполный адрес помечается жёлтым предупреждением без блокировки отправки форм](web_soft/libs/angular/snabcentr-client-ui-lib@e34e300bd2bf15fb62106e7afe41428794d3db96) ([merge request](web_soft/libs/angular/snabcentr-client-ui-lib!467))
11
- - [#14054, #14052: Перенос полноты адреса и ОГРН в линию 4.16 для релизной ветки приложений](web_soft/libs/angular/snabcentr-client-ui-lib@964028db16138c0532f54a1311e92084191c70a8) ([merge request](web_soft/libs/angular/snabcentr-client-ui-lib!465))
3
+ No changes.
12
4
 
@@ -8,11 +8,12 @@ import * as i6 from "../form-fields/form-fields.module";
8
8
  import * as i7 from "@taiga-ui/legacy";
9
9
  import * as i8 from "@taiga-ui/cdk/directives/item";
10
10
  import * as i9 from "@taiga-ui/cdk";
11
+ import * as i10 from "ng-recaptcha-2";
11
12
  /**
12
13
  * Модуль представления образцов товара.
13
14
  */
14
15
  export declare class ScPreviewSampleModule {
15
16
  static ɵfac: i0.ɵɵFactoryDeclaration<ScPreviewSampleModule, never>;
16
- static ɵmod: i0.ɵɵNgModuleDeclaration<ScPreviewSampleModule, [typeof i1.ScPreviewSampleComponent], [typeof i2.CommonModule, typeof i3.ReactiveFormsModule, typeof i4.TuiError, typeof i5.TuiFieldErrorPipe, typeof i6.ScFormFieldsModule, typeof i7.TuiInputModule, typeof i7.TuiInputPhoneModule, typeof i8.TuiItem, typeof i5.TuiCarouselComponent, typeof i5.TuiCarouselDirective, typeof i5.TuiCarouselAutoscroll, typeof i5.TuiCarouselButtons, typeof i5.TuiCarouselScroll, typeof i5.TuiAvatar, typeof i9.TuiHovered, typeof i4.TuiButton, typeof i5.TuiButtonLoading, typeof i4.TuiLabel], [typeof i1.ScPreviewSampleComponent]>;
17
+ static ɵmod: i0.ɵɵNgModuleDeclaration<ScPreviewSampleModule, [typeof i1.ScPreviewSampleComponent], [typeof i2.CommonModule, typeof i3.ReactiveFormsModule, typeof i4.TuiError, typeof i5.TuiFieldErrorPipe, typeof i6.ScFormFieldsModule, typeof i7.TuiInputModule, typeof i7.TuiInputPhoneModule, typeof i8.TuiItem, typeof i5.TuiCarouselComponent, typeof i5.TuiCarouselDirective, typeof i5.TuiCarouselAutoscroll, typeof i5.TuiCarouselButtons, typeof i5.TuiCarouselScroll, typeof i5.TuiAvatar, typeof i9.TuiHovered, typeof i4.TuiButton, typeof i5.TuiButtonLoading, typeof i4.TuiLabel, typeof i10.RecaptchaFormsModule, typeof i10.RecaptchaModule], [typeof i1.ScPreviewSampleComponent]>;
17
18
  static ɵinj: i0.ɵɵInjectorDeclaration<ScPreviewSampleModule>;
18
19
  }
@@ -1,3 +1,2 @@
1
1
  export * from './sc-help-notification.service';
2
2
  export * from './print.service';
3
- export * from './sc-scripts.service';
@@ -554,40 +554,6 @@ video {
554
554
  display: none;
555
555
  }
556
556
 
557
- .container {
558
- width: 100%;
559
- }
560
-
561
- @media (min-width: 640px) {
562
- .container {
563
- max-width: 640px;
564
- }
565
- }
566
-
567
- @media (min-width: 768px) {
568
- .container {
569
- max-width: 768px;
570
- }
571
- }
572
-
573
- @media (min-width: 1024px) {
574
- .container {
575
- max-width: 1024px;
576
- }
577
- }
578
-
579
- @media (min-width: 1280px) {
580
- .container {
581
- max-width: 1280px;
582
- }
583
- }
584
-
585
- @media (min-width: 1536px) {
586
- .container {
587
- max-width: 1536px;
588
- }
589
- }
590
-
591
557
  .pointer-events-none {
592
558
  pointer-events: none;
593
559
  }
@@ -907,6 +873,10 @@ video {
907
873
  height: 5rem !important;
908
874
  }
909
875
 
876
+ .\!h-auto {
877
+ height: auto !important;
878
+ }
879
+
910
880
  .h-10 {
911
881
  height: 2.5rem;
912
882
  }
@@ -959,18 +929,14 @@ video {
959
929
  max-height: 0px !important;
960
930
  }
961
931
 
962
- .max-h-\[7\.5rem\] {
963
- max-height: 7.5rem;
932
+ .max-h-20 {
933
+ max-height: 5rem;
964
934
  }
965
935
 
966
936
  .min-h-8 {
967
937
  min-height: 2rem;
968
938
  }
969
939
 
970
- .min-h-\[7\.375rem\] {
971
- min-height: 7.375rem;
972
- }
973
-
974
940
  .\!w-auto {
975
941
  width: auto !important;
976
942
  }
@@ -1060,6 +1026,10 @@ video {
1060
1026
  max-width: 24rem;
1061
1027
  }
1062
1028
 
1029
+ .max-w-full {
1030
+ max-width: 100%;
1031
+ }
1032
+
1063
1033
  .max-w-min {
1064
1034
  max-width: -moz-min-content;
1065
1035
  max-width: min-content;
@@ -1186,10 +1156,18 @@ video {
1186
1156
  align-items: center;
1187
1157
  }
1188
1158
 
1159
+ .items-baseline {
1160
+ align-items: baseline;
1161
+ }
1162
+
1189
1163
  .\!justify-start {
1190
1164
  justify-content: flex-start !important;
1191
1165
  }
1192
1166
 
1167
+ .justify-start {
1168
+ justify-content: flex-start;
1169
+ }
1170
+
1193
1171
  .justify-end {
1194
1172
  justify-content: flex-end;
1195
1173
  }
@@ -1306,6 +1284,14 @@ video {
1306
1284
  white-space: nowrap;
1307
1285
  }
1308
1286
 
1287
+ .break-words {
1288
+ overflow-wrap: break-word;
1289
+ }
1290
+
1291
+ .break-all {
1292
+ word-break: break-all;
1293
+ }
1294
+
1309
1295
  .\!rounded-xl {
1310
1296
  border-radius: 0.75rem !important;
1311
1297
  }
@@ -1529,6 +1515,11 @@ video {
1529
1515
  padding-right: 1.5rem;
1530
1516
  }
1531
1517
 
1518
+ .py-0\.5 {
1519
+ padding-top: 0.125rem;
1520
+ padding-bottom: 0.125rem;
1521
+ }
1522
+
1532
1523
  .py-14 {
1533
1524
  padding-top: 3.5rem;
1534
1525
  padding-bottom: 3.5rem;
@@ -1548,6 +1539,10 @@ video {
1548
1539
  padding-bottom: 0.25rem;
1549
1540
  }
1550
1541
 
1542
+ .pb-2 {
1543
+ padding-bottom: 0.5rem;
1544
+ }
1545
+
1551
1546
  .pb-4 {
1552
1547
  padding-bottom: 1rem;
1553
1548
  }
@@ -1833,6 +1828,10 @@ video {
1833
1828
  text-decoration-line: underline;
1834
1829
  }
1835
1830
 
1831
+ .\!line-through {
1832
+ text-decoration-line: line-through !important;
1833
+ }
1834
+
1836
1835
  .line-through {
1837
1836
  text-decoration-line: line-through;
1838
1837
  }
@@ -2004,6 +2003,10 @@ video {
2004
2003
  align-items: flex-start;
2005
2004
  }
2006
2005
 
2006
+ .sm\:items-end {
2007
+ align-items: flex-end;
2008
+ }
2009
+
2007
2010
  .sm\:border-32 {
2008
2011
  border-width: 2rem;
2009
2012
  }