@rt-tools/ui-kit-v2 0.23.4 → 0.25.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.
@@ -0,0 +1,295 @@
1
+ import * as i0 from "@angular/core";
2
+ import { ChangeDetectionStrategy, Component, ViewEncapsulation, booleanAttribute, computed, inject, input, output } from "@angular/core";
3
+ import * as i1 from "@angular/forms";
4
+ import { FormsModule } from "@angular/forms";
5
+ import { BlockDirective, ElemDirective } from "@rt-tools/core";
6
+ import { RT_KIT_LABELS, ThemeService } from "@rt-tools/ui-kit-v2/core";
7
+ import { RtMenuItemComponent } from "@rt-tools/ui-kit-v2/menu";
8
+ import { RtSelectComponent } from "@rt-tools/ui-kit-v2/select";
9
+ const BEM_BLOCK = "rt-profile-menu";
10
+ var RtProfileMenuComponent = class RtProfileMenuComponent {
11
+ constructor() {
12
+ this.#theme = inject(ThemeService);
13
+ this.t = inject(RT_KIT_LABELS);
14
+ this.themeIcon = computed(() => this.#theme.isDark() ? "ico-sun" : "moon", ...ngDevMode ? [{ debugName: "themeIcon" }] : /* istanbul ignore next */ []);
15
+ this.avatar = computed(() => this.userName().trim().charAt(0).toUpperCase(), ...ngDevMode ? [{ debugName: "avatar" }] : /* istanbul ignore next */ []);
16
+ this.userName = input("", ...ngDevMode ? [{ debugName: "userName" }] : /* istanbul ignore next */ []);
17
+ this.organizationName = input("", ...ngDevMode ? [{ debugName: "organizationName" }] : /* istanbul ignore next */ []);
18
+ this.organizationChange = input("hidden", ...ngDevMode ? [{ debugName: "organizationChange" }] : /* istanbul ignore next */ []);
19
+ this.passwordChange = input(false, {
20
+ ...ngDevMode ? { debugName: "passwordChange" } : /* istanbul ignore next */ {},
21
+ transform: booleanAttribute
22
+ });
23
+ this.locales = input([], ...ngDevMode ? [{ debugName: "locales" }] : /* istanbul ignore next */ []);
24
+ this.locale = input("", ...ngDevMode ? [{ debugName: "locale" }] : /* istanbul ignore next */ []);
25
+ this.signOutDisabled = input(false, {
26
+ ...ngDevMode ? { debugName: "signOutDisabled" } : /* istanbul ignore next */ {},
27
+ transform: booleanAttribute
28
+ });
29
+ this.changeOrganization = output();
30
+ this.changePassword = output();
31
+ this.localeChange = output();
32
+ this.signOut = output();
33
+ }
34
+ #theme;
35
+ onToggleTheme() {
36
+ this.#theme.toggle();
37
+ }
38
+ static {
39
+ this.ɵfac = i0.ɵɵngDeclareFactory({
40
+ minVersion: "12.0.0",
41
+ version: "22.2.2",
42
+ ngImport: i0,
43
+ type: RtProfileMenuComponent,
44
+ deps: [],
45
+ target: i0.ɵɵFactoryTarget.Component
46
+ });
47
+ }
48
+ static {
49
+ this.ɵcmp = i0.ɵɵngDeclareComponent({
50
+ minVersion: "17.0.0",
51
+ version: "22.2.2",
52
+ type: RtProfileMenuComponent,
53
+ isStandalone: true,
54
+ selector: "rt-profile-menu",
55
+ inputs: {
56
+ userName: {
57
+ classPropertyName: "userName",
58
+ publicName: "userName",
59
+ isSignal: true,
60
+ isRequired: false,
61
+ transformFunction: null
62
+ },
63
+ organizationName: {
64
+ classPropertyName: "organizationName",
65
+ publicName: "organizationName",
66
+ isSignal: true,
67
+ isRequired: false,
68
+ transformFunction: null
69
+ },
70
+ organizationChange: {
71
+ classPropertyName: "organizationChange",
72
+ publicName: "organizationChange",
73
+ isSignal: true,
74
+ isRequired: false,
75
+ transformFunction: null
76
+ },
77
+ passwordChange: {
78
+ classPropertyName: "passwordChange",
79
+ publicName: "passwordChange",
80
+ isSignal: true,
81
+ isRequired: false,
82
+ transformFunction: null
83
+ },
84
+ locales: {
85
+ classPropertyName: "locales",
86
+ publicName: "locales",
87
+ isSignal: true,
88
+ isRequired: false,
89
+ transformFunction: null
90
+ },
91
+ locale: {
92
+ classPropertyName: "locale",
93
+ publicName: "locale",
94
+ isSignal: true,
95
+ isRequired: false,
96
+ transformFunction: null
97
+ },
98
+ signOutDisabled: {
99
+ classPropertyName: "signOutDisabled",
100
+ publicName: "signOutDisabled",
101
+ isSignal: true,
102
+ isRequired: false,
103
+ transformFunction: null
104
+ }
105
+ },
106
+ outputs: {
107
+ changeOrganization: "changeOrganization",
108
+ changePassword: "changePassword",
109
+ localeChange: "localeChange",
110
+ signOut: "signOut"
111
+ },
112
+ host: { classAttribute: "rt-profile-menu" },
113
+ ngImport: i0,
114
+ template: "<ng-container rtBlock=\"rt-profile-menu\">\n <div rtElem=\"user\">\n <span rtElem=\"avatar\" aria-hidden=\"true\">{{ avatar() }}</span>\n <span rtElem=\"name\" qa-dataid=\"profile-user-name\">{{ userName() }}</span>\n @if (organizationName()) {\n <span rtElem=\"organization\" qa-dataid=\"profile-organization\">\n {{ organizationName() }}\n <span rtElem=\"organization-label\">{{ t().profileMenuOrganization }}</span>\n </span>\n }\n </div>\n\n <div rtElem=\"nav\" role=\"menu\">\n @switch (organizationChange()) {\n @case ('allowed') {\n <rt-menu-item\n rtElem=\"item\"\n qa-dataid=\"profile-change-organization\"\n icon=\"refresh\"\n [label]=\"t().profileMenuChangeOrganization\"\n (selected)=\"changeOrganization.emit()\" />\n }\n @case ('denied') {\n <rt-menu-item\n rtElem=\"item\"\n qa-dataid=\"profile-change-organization\"\n icon=\"refresh\"\n disabled\n [label]=\"t().profileMenuChangeOrganization\"\n [tooltip]=\"t().profileMenuChangeOrganizationDenied\" />\n }\n }\n\n @if (passwordChange()) {\n <rt-menu-item\n rtElem=\"item\"\n qa-dataid=\"profile-password-change\"\n icon=\"ico-lock\"\n [label]=\"t().profileMenuChangePassword\"\n (selected)=\"changePassword.emit()\" />\n }\n\n <rt-menu-item\n rtElem=\"item\"\n qa-dataid=\"profile-logout\"\n icon=\"ico-exit\"\n [disabled]=\"signOutDisabled()\"\n [label]=\"t().profileMenuSignOut\"\n (selected)=\"signOut.emit()\" />\n </div>\n\n <!-- Своего правила у переключателя языка нет: ширину ему задаёт колонка блока. -->\n @if (locales().length) {\n <rt-select\n qa-dataid=\"profile-locale-select\"\n name=\"rtProfileMenuLocale\"\n [options]=\"locales()\"\n [ngModel]=\"locale()\"\n (ngModelChange)=\"localeChange.emit($event)\" />\n }\n\n <rt-menu-item\n rtElem=\"theme\"\n qa-dataid=\"profile-theme-toggle\"\n [icon]=\"themeIcon()\"\n [label]=\"t().profileMenuSwitchTheme\"\n (selected)=\"onToggleTheme()\" />\n</ng-container>\n",
115
+ styles: ["@charset \"UTF-8\";@layer rt-kit.components{.rt-profile-menu{display:flex;min-width:var(--rt-profile-menu-min-width);box-sizing:border-box;flex-direction:column;padding:var(--rt-profile-menu-padding);border:var(--rt-profile-menu-border-width) solid var(--rt-nav-panel-color-border);border-radius:var(--rt-profile-menu-radius);background-color:var(--rt-nav-panel-color-bg);box-shadow:var(--rt-profile-menu-shadow);gap:var(--rt-space-2)}.rt-profile-menu__user{display:flex;flex-direction:column;padding-bottom:var(--rt-space-2);gap:var(--rt-space-2)}.rt-profile-menu__avatar{display:inline-flex;width:var(--rt-profile-avatar-size);height:var(--rt-profile-avatar-size);align-items:center;justify-content:center;border:var(--rt-profile-avatar-border-width) solid var(--rt-nav-header-color-bg);border-radius:var(--rt-profile-avatar-radius);color:var(--rt-color-text-primary);font-size:var(--rt-profile-avatar-font-size);font-weight:var(--rt-font-weight-semibold);line-height:var(--rt-leading-none)}.rt-profile-menu__name{color:var(--rt-color-text-primary);font-size:var(--rt-text-md);font-weight:var(--rt-font-weight-semibold);line-height:var(--rt-leading-tight)}.rt-profile-menu__organization{color:var(--rt-nav-panel-item-color);font-size:var(--rt-text-md);font-weight:var(--rt-font-weight-regular);line-height:var(--rt-leading-tight)}.rt-profile-menu__organization-label{color:var(--rt-nav-panel-group-color)}.rt-profile-menu__nav{display:flex;width:calc(100% + var(--rt-profile-row-inset) + var(--rt-profile-row-inset));flex-direction:column;margin-left:calc(-1 * var(--rt-profile-row-inset))}.rt-profile-menu .rt-profile-menu__item,.rt-profile-menu .rt-profile-menu__theme{border-radius:var(--rt-profile-item-radius);color:var(--rt-nav-panel-item-color);font-size:var(--rt-profile-item-font-size);font-weight:var(--rt-profile-item-font-weight);gap:var(--rt-profile-item-content-gap)}.rt-profile-menu .rt-profile-menu__item{padding:var(--rt-profile-item-padding-y) var(--rt-profile-row-inset)}.rt-profile-menu .rt-profile-menu__theme{width:calc(100% + var(--rt-profile-row-inset) + var(--rt-profile-row-inset));padding:var(--rt-profile-row-inset);margin-left:calc(-1 * var(--rt-profile-row-inset));color:var(--rt-color-action-primary)}.rt-profile-menu .rt-profile-menu__theme .rt-menu-item__icon{box-sizing:content-box;padding:var(--rt-profile-theme-icon-padding);border-radius:var(--rt-profile-theme-icon-radius);background-color:var(--rt-color-action-primary-subtle)}}\n"],
116
+ dependencies: [
117
+ {
118
+ kind: "ngmodule",
119
+ type: FormsModule
120
+ },
121
+ {
122
+ kind: "directive",
123
+ type: i1.NgControlStatus,
124
+ selector: "[formControlName],[ngModel],[formControl]"
125
+ },
126
+ {
127
+ kind: "directive",
128
+ type: i1.NgModel,
129
+ selector: "[ngModel]:not([formControlName]):not([formControl])",
130
+ inputs: [
131
+ "name",
132
+ "disabled",
133
+ "ngModel",
134
+ "ngModelOptions"
135
+ ],
136
+ outputs: ["ngModelChange"],
137
+ exportAs: ["ngModel"]
138
+ },
139
+ {
140
+ kind: "directive",
141
+ type: BlockDirective,
142
+ selector: "[rtBlock]",
143
+ inputs: ["rtMod"]
144
+ },
145
+ {
146
+ kind: "directive",
147
+ type: ElemDirective,
148
+ selector: "[rtElem]",
149
+ inputs: ["rtMod"]
150
+ },
151
+ {
152
+ kind: "component",
153
+ type: RtMenuItemComponent,
154
+ selector: "rt-menu-item",
155
+ inputs: [
156
+ "icon",
157
+ "label",
158
+ "danger",
159
+ "success",
160
+ "glyph",
161
+ "fill",
162
+ "current",
163
+ "disabled",
164
+ "confirmMessage",
165
+ "confirmTitle",
166
+ "confirmLabel",
167
+ "confirmCancelLabel",
168
+ "confirmTone",
169
+ "link"
170
+ ],
171
+ outputs: ["selected"]
172
+ },
173
+ {
174
+ kind: "component",
175
+ type: RtSelectComponent,
176
+ selector: "rt-select",
177
+ inputs: [
178
+ "appearance",
179
+ "options",
180
+ "placeholder",
181
+ "iconLeft",
182
+ "filter",
183
+ "filterPlaceholder",
184
+ "panelWidth",
185
+ "panelMaxHeight"
186
+ ],
187
+ outputs: ["selectionChange"]
188
+ }
189
+ ],
190
+ changeDetection: i0.ChangeDetectionStrategy.OnPush,
191
+ encapsulation: i0.ViewEncapsulation.None
192
+ });
193
+ }
194
+ };
195
+ i0.ɵɵngDeclareClassMetadata({
196
+ minVersion: "12.0.0",
197
+ version: "22.2.2",
198
+ ngImport: i0,
199
+ type: RtProfileMenuComponent,
200
+ decorators: [{
201
+ type: Component,
202
+ args: [{
203
+ selector: "rt-profile-menu",
204
+ changeDetection: ChangeDetectionStrategy.OnPush,
205
+ encapsulation: ViewEncapsulation.None,
206
+ imports: [
207
+ FormsModule,
208
+ BlockDirective,
209
+ ElemDirective,
210
+ RtMenuItemComponent,
211
+ RtSelectComponent
212
+ ],
213
+ host: { class: BEM_BLOCK },
214
+ template: "<ng-container rtBlock=\"rt-profile-menu\">\n <div rtElem=\"user\">\n <span rtElem=\"avatar\" aria-hidden=\"true\">{{ avatar() }}</span>\n <span rtElem=\"name\" qa-dataid=\"profile-user-name\">{{ userName() }}</span>\n @if (organizationName()) {\n <span rtElem=\"organization\" qa-dataid=\"profile-organization\">\n {{ organizationName() }}\n <span rtElem=\"organization-label\">{{ t().profileMenuOrganization }}</span>\n </span>\n }\n </div>\n\n <div rtElem=\"nav\" role=\"menu\">\n @switch (organizationChange()) {\n @case ('allowed') {\n <rt-menu-item\n rtElem=\"item\"\n qa-dataid=\"profile-change-organization\"\n icon=\"refresh\"\n [label]=\"t().profileMenuChangeOrganization\"\n (selected)=\"changeOrganization.emit()\" />\n }\n @case ('denied') {\n <rt-menu-item\n rtElem=\"item\"\n qa-dataid=\"profile-change-organization\"\n icon=\"refresh\"\n disabled\n [label]=\"t().profileMenuChangeOrganization\"\n [tooltip]=\"t().profileMenuChangeOrganizationDenied\" />\n }\n }\n\n @if (passwordChange()) {\n <rt-menu-item\n rtElem=\"item\"\n qa-dataid=\"profile-password-change\"\n icon=\"ico-lock\"\n [label]=\"t().profileMenuChangePassword\"\n (selected)=\"changePassword.emit()\" />\n }\n\n <rt-menu-item\n rtElem=\"item\"\n qa-dataid=\"profile-logout\"\n icon=\"ico-exit\"\n [disabled]=\"signOutDisabled()\"\n [label]=\"t().profileMenuSignOut\"\n (selected)=\"signOut.emit()\" />\n </div>\n\n <!-- Своего правила у переключателя языка нет: ширину ему задаёт колонка блока. -->\n @if (locales().length) {\n <rt-select\n qa-dataid=\"profile-locale-select\"\n name=\"rtProfileMenuLocale\"\n [options]=\"locales()\"\n [ngModel]=\"locale()\"\n (ngModelChange)=\"localeChange.emit($event)\" />\n }\n\n <rt-menu-item\n rtElem=\"theme\"\n qa-dataid=\"profile-theme-toggle\"\n [icon]=\"themeIcon()\"\n [label]=\"t().profileMenuSwitchTheme\"\n (selected)=\"onToggleTheme()\" />\n</ng-container>\n",
215
+ styles: ["@charset \"UTF-8\";@layer rt-kit.components{.rt-profile-menu{display:flex;min-width:var(--rt-profile-menu-min-width);box-sizing:border-box;flex-direction:column;padding:var(--rt-profile-menu-padding);border:var(--rt-profile-menu-border-width) solid var(--rt-nav-panel-color-border);border-radius:var(--rt-profile-menu-radius);background-color:var(--rt-nav-panel-color-bg);box-shadow:var(--rt-profile-menu-shadow);gap:var(--rt-space-2)}.rt-profile-menu__user{display:flex;flex-direction:column;padding-bottom:var(--rt-space-2);gap:var(--rt-space-2)}.rt-profile-menu__avatar{display:inline-flex;width:var(--rt-profile-avatar-size);height:var(--rt-profile-avatar-size);align-items:center;justify-content:center;border:var(--rt-profile-avatar-border-width) solid var(--rt-nav-header-color-bg);border-radius:var(--rt-profile-avatar-radius);color:var(--rt-color-text-primary);font-size:var(--rt-profile-avatar-font-size);font-weight:var(--rt-font-weight-semibold);line-height:var(--rt-leading-none)}.rt-profile-menu__name{color:var(--rt-color-text-primary);font-size:var(--rt-text-md);font-weight:var(--rt-font-weight-semibold);line-height:var(--rt-leading-tight)}.rt-profile-menu__organization{color:var(--rt-nav-panel-item-color);font-size:var(--rt-text-md);font-weight:var(--rt-font-weight-regular);line-height:var(--rt-leading-tight)}.rt-profile-menu__organization-label{color:var(--rt-nav-panel-group-color)}.rt-profile-menu__nav{display:flex;width:calc(100% + var(--rt-profile-row-inset) + var(--rt-profile-row-inset));flex-direction:column;margin-left:calc(-1 * var(--rt-profile-row-inset))}.rt-profile-menu .rt-profile-menu__item,.rt-profile-menu .rt-profile-menu__theme{border-radius:var(--rt-profile-item-radius);color:var(--rt-nav-panel-item-color);font-size:var(--rt-profile-item-font-size);font-weight:var(--rt-profile-item-font-weight);gap:var(--rt-profile-item-content-gap)}.rt-profile-menu .rt-profile-menu__item{padding:var(--rt-profile-item-padding-y) var(--rt-profile-row-inset)}.rt-profile-menu .rt-profile-menu__theme{width:calc(100% + var(--rt-profile-row-inset) + var(--rt-profile-row-inset));padding:var(--rt-profile-row-inset);margin-left:calc(-1 * var(--rt-profile-row-inset));color:var(--rt-color-action-primary)}.rt-profile-menu .rt-profile-menu__theme .rt-menu-item__icon{box-sizing:content-box;padding:var(--rt-profile-theme-icon-padding);border-radius:var(--rt-profile-theme-icon-radius);background-color:var(--rt-color-action-primary-subtle)}}\n"]
216
+ }]
217
+ }],
218
+ propDecorators: {
219
+ userName: [{
220
+ type: i0.Input,
221
+ args: [{
222
+ isSignal: true,
223
+ alias: "userName",
224
+ required: false
225
+ }]
226
+ }],
227
+ organizationName: [{
228
+ type: i0.Input,
229
+ args: [{
230
+ isSignal: true,
231
+ alias: "organizationName",
232
+ required: false
233
+ }]
234
+ }],
235
+ organizationChange: [{
236
+ type: i0.Input,
237
+ args: [{
238
+ isSignal: true,
239
+ alias: "organizationChange",
240
+ required: false
241
+ }]
242
+ }],
243
+ passwordChange: [{
244
+ type: i0.Input,
245
+ args: [{
246
+ isSignal: true,
247
+ alias: "passwordChange",
248
+ required: false
249
+ }]
250
+ }],
251
+ locales: [{
252
+ type: i0.Input,
253
+ args: [{
254
+ isSignal: true,
255
+ alias: "locales",
256
+ required: false
257
+ }]
258
+ }],
259
+ locale: [{
260
+ type: i0.Input,
261
+ args: [{
262
+ isSignal: true,
263
+ alias: "locale",
264
+ required: false
265
+ }]
266
+ }],
267
+ signOutDisabled: [{
268
+ type: i0.Input,
269
+ args: [{
270
+ isSignal: true,
271
+ alias: "signOutDisabled",
272
+ required: false
273
+ }]
274
+ }],
275
+ changeOrganization: [{
276
+ type: i0.Output,
277
+ args: ["changeOrganization"]
278
+ }],
279
+ changePassword: [{
280
+ type: i0.Output,
281
+ args: ["changePassword"]
282
+ }],
283
+ localeChange: [{
284
+ type: i0.Output,
285
+ args: ["localeChange"]
286
+ }],
287
+ signOut: [{
288
+ type: i0.Output,
289
+ args: ["signOut"]
290
+ }]
291
+ }
292
+ });
293
+ export { RtProfileMenuComponent };
294
+
295
+ //# sourceMappingURL=rt-tools-ui-kit-v2-profile-menu.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"rt-tools-ui-kit-v2-profile-menu.mjs","names":[],"sources":["../../../projects/ui-kit-v2/src/lib/components/profile-menu/rt-profile-menu.component.ts","../../../projects/ui-kit-v2/src/lib/components/profile-menu/rt-profile-menu.component.html"],"sourcesContent":["import { BooleanInput } from '@angular/cdk/coercion';\nimport {\n booleanAttribute,\n computed,\n inject,\n input,\n output,\n ChangeDetectionStrategy,\n Component,\n InputSignal,\n InputSignalWithTransform,\n OutputEmitterRef,\n Signal,\n ViewEncapsulation,\n} from '@angular/core';\nimport { FormsModule } from '@angular/forms';\n\nimport { BlockDirective, ElemDirective } from '@rt-tools/core';\n\nimport { IRtIcon, RT_KIT_LABELS, ThemeService, TRtKitLabelMap } from '@rt-tools/ui-kit-v2/core';\n\nimport { RtMenuItemComponent } from '@rt-tools/ui-kit-v2/menu';\nimport { RtSelectComponent } from '@rt-tools/ui-kit-v2/select';\nimport { IRtProfileMenu } from './rt-profile-menu.model';\n\nconst BEM_BLOCK: string = 'rt-profile-menu';\n\n/**\n * Содержимое попапа профиля в шапке `rt-page-header`: кто вошёл и в какой организации, действия с\n * учётной записью, язык и тема.\n *\n * Свою панель меню рисует само — фон, рамку, скругление и тень: поповер кита оформления не даёт,\n * и голые пункты в нём легли бы прямо поверх страницы.\n *\n * Тему переключает `ThemeService`, как у `rt-theme-toggle`: служба одна на страницу, и вход\n * только повторял бы её. Куда ведут остальные действия, решает приложение — они уходят выходами.\n *\n * Стили без инкапсуляции: попап рисуется в перекрытии, у конца `<body>`, и правило по классу блока\n * достаёт до него, а до разметки `rt-menu-item` — тоже.\n */\n@Component({\n selector: 'rt-profile-menu',\n templateUrl: './rt-profile-menu.component.html',\n styleUrls: ['./rt-profile-menu.component.scss'],\n changeDetection: ChangeDetectionStrategy.OnPush,\n encapsulation: ViewEncapsulation.None,\n imports: [\n // angular\n FormsModule,\n\n // rt-tools\n BlockDirective,\n ElemDirective,\n\n // standalone components / directives\n RtMenuItemComponent,\n RtSelectComponent,\n ],\n host: {\n class: BEM_BLOCK,\n },\n})\nexport class RtProfileMenuComponent {\n readonly #theme: ThemeService = inject(ThemeService);\n\n /** Подписи кита: сигнал, потому что язык может смениться без перезагрузки. */\n protected readonly t: Signal<TRtKitLabelMap> = inject(RT_KIT_LABELS);\n\n /** Показан значок противоположной темы: нажатие переводит к ней. */\n protected readonly themeIcon: Signal<IRtIcon.Name> = computed((): IRtIcon.Name => (this.#theme.isDark() ? 'ico-sun' : 'moon'));\n\n /** Круг над именем несёт его первую букву: картинки профиля у кита нет. */\n protected readonly avatar: Signal<string> = computed((): string => this.userName().trim().charAt(0).toUpperCase());\n\n public readonly userName: InputSignal<string> = input<string>('');\n\n /** Пустое название — строки организации нет. */\n public readonly organizationName: InputSignal<string> = input<string>('');\n\n public readonly organizationChange: InputSignal<IRtProfileMenu.OrganizationChange> = input<IRtProfileMenu.OrganizationChange>('hidden');\n\n public readonly passwordChange: InputSignalWithTransform<boolean, BooleanInput> = input<boolean, BooleanInput>(false, {\n transform: booleanAttribute,\n });\n\n /** Пустой список — переключателя языка нет. */\n public readonly locales: InputSignal<ReadonlyArray<IRtProfileMenu.Locale>> = input<ReadonlyArray<IRtProfileMenu.Locale>>([]);\n\n public readonly locale: InputSignal<string> = input<string>('');\n\n /** Выход недоступен, пока приложение его уже ведёт. */\n public readonly signOutDisabled: InputSignalWithTransform<boolean, BooleanInput> = input<boolean, BooleanInput>(false, {\n transform: booleanAttribute,\n });\n\n public readonly changeOrganization: OutputEmitterRef<void> = output<void>();\n\n public readonly changePassword: OutputEmitterRef<void> = output<void>();\n\n public readonly localeChange: OutputEmitterRef<string> = output<string>();\n\n public readonly signOut: OutputEmitterRef<void> = output<void>();\n\n public onToggleTheme(): void {\n this.#theme.toggle();\n }\n}\n","<ng-container rtBlock=\"rt-profile-menu\">\n <div rtElem=\"user\">\n <span rtElem=\"avatar\" aria-hidden=\"true\">{{ avatar() }}</span>\n <span rtElem=\"name\" qa-dataid=\"profile-user-name\">{{ userName() }}</span>\n @if (organizationName()) {\n <span rtElem=\"organization\" qa-dataid=\"profile-organization\">\n {{ organizationName() }}\n <span rtElem=\"organization-label\">{{ t().profileMenuOrganization }}</span>\n </span>\n }\n </div>\n\n <div rtElem=\"nav\" role=\"menu\">\n @switch (organizationChange()) {\n @case ('allowed') {\n <rt-menu-item\n rtElem=\"item\"\n qa-dataid=\"profile-change-organization\"\n icon=\"refresh\"\n [label]=\"t().profileMenuChangeOrganization\"\n (selected)=\"changeOrganization.emit()\" />\n }\n @case ('denied') {\n <rt-menu-item\n rtElem=\"item\"\n qa-dataid=\"profile-change-organization\"\n icon=\"refresh\"\n disabled\n [label]=\"t().profileMenuChangeOrganization\"\n [tooltip]=\"t().profileMenuChangeOrganizationDenied\" />\n }\n }\n\n @if (passwordChange()) {\n <rt-menu-item\n rtElem=\"item\"\n qa-dataid=\"profile-password-change\"\n icon=\"ico-lock\"\n [label]=\"t().profileMenuChangePassword\"\n (selected)=\"changePassword.emit()\" />\n }\n\n <rt-menu-item\n rtElem=\"item\"\n qa-dataid=\"profile-logout\"\n icon=\"ico-exit\"\n [disabled]=\"signOutDisabled()\"\n [label]=\"t().profileMenuSignOut\"\n (selected)=\"signOut.emit()\" />\n </div>\n\n <!-- Своего правила у переключателя языка нет: ширину ему задаёт колонка блока. -->\n @if (locales().length) {\n <rt-select\n qa-dataid=\"profile-locale-select\"\n name=\"rtProfileMenuLocale\"\n [options]=\"locales()\"\n [ngModel]=\"locale()\"\n (ngModelChange)=\"localeChange.emit($event)\" />\n }\n\n <rt-menu-item\n rtElem=\"theme\"\n qa-dataid=\"profile-theme-toggle\"\n [icon]=\"themeIcon()\"\n [label]=\"t().profileMenuSwitchTheme\"\n (selected)=\"onToggleTheme()\" />\n</ng-container>\n"],"mappings":"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"}
@@ -2834,7 +2834,7 @@ var RtAiChatComponent = class RtAiChatComponent {
2834
2834
  ],
2835
2835
  ngImport: i0,
2836
2836
  template: "<ng-container rtBlock=\"rt-ai-chat\">\n @if (isThreadColumn()) {\n <aside rtElem=\"thread-column\" qa-dataid=\"ai-chat-thread-column\" [attr.aria-label]=\"t().aiThreads\">\n <div rtElem=\"column-head\">\n <span rtElem=\"column-title\">{{ t().aiThreads }}</span>\n <ng-container [ngTemplateOutlet]=\"newThreadButton\" />\n </div>\n <ng-container [ngTemplateOutlet]=\"threadList\" />\n </aside>\n }\n\n <section rtElem=\"conversation\" qa-dataid=\"ai-chat\" [attr.aria-label]=\"titleText()\">\n <header rtElem=\"header\" [attr.data-rt-icon-preset]=\"headerIconSign()\">\n @if (isThreadPage()) {\n <rt-icon-button\n #back\n qa-dataid=\"ai-chat-back\"\n size=\"sm\"\n iconSize=\"sm\"\n icon=\"arrow-left\"\n [ariaLabel]=\"t().aiBackToChat\"\n [tooltip]=\"t().aiBackToChat\"\n (clicked)=\"onToggleThreads()\" />\n }\n\n <div rtElem=\"heading\">\n <span rtElem=\"title\" qa-dataid=\"ai-chat-title\">\n @if (!isThreadPage()) {\n <rt-icon name=\"sparkle\" size=\"sm\" color=\"primary\" aria-hidden=\"true\" />\n }\n {{ isThreadPage() ? t().aiThreads : titleText() }}\n </span>\n @if (!isThreadPage() && subtitle()) {\n <span rtElem=\"subtitle\" qa-dataid=\"ai-chat-subtitle\">{{ subtitle() }}</span>\n }\n </div>\n\n <div rtElem=\"actions\">\n @if (fullScreenable()) {\n <rt-icon-button\n qa-dataid=\"ai-chat-full-screen\"\n size=\"sm\"\n iconSize=\"sm\"\n [icon]=\"fullScreen() ? 'window-minimize' : 'fullscreen'\"\n [active]=\"fullScreen()\"\n [ariaLabel]=\"fullScreen() ? t().aiExitFullScreen : t().aiFullScreen\"\n [tooltip]=\"fullScreen() ? t().aiExitFullScreen : t().aiFullScreen\"\n (clicked)=\"onToggleFullScreen()\" />\n }\n @if (hasThreads() && !isThreadPage() && !isThreadColumn()) {\n <rt-icon-button\n qa-dataid=\"ai-chat-threads\"\n size=\"sm\"\n iconSize=\"sm\"\n icon=\"history\"\n [ariaLabel]=\"t().aiThreads\"\n [tooltip]=\"t().aiThreads\"\n (clicked)=\"onToggleThreads()\" />\n }\n @if (!isThreadColumn()) {\n <ng-container [ngTemplateOutlet]=\"newThreadButton\" />\n }\n @if (closable()) {\n <rt-icon-button\n qa-dataid=\"ai-chat-close\"\n size=\"sm\"\n iconSize=\"sm\"\n icon=\"close\"\n [ariaLabel]=\"t().aiClose\"\n [tooltip]=\"t().aiClose\"\n (clicked)=\"closed.emit()\" />\n }\n </div>\n </header>\n\n @if (isThreadPage()) {\n <ng-container [ngTemplateOutlet]=\"threadList\" />\n } @else {\n <div #feed rtElem=\"feed\" qa-dataid=\"ai-chat-feed\" aria-live=\"polite\" (scroll)=\"onFeedScroll()\">\n @if (loading() && !messages().length) {\n <rt-spinner rtElem=\"spinner\" appearance=\"arc\" [diameter]=\"32\" />\n } @else if (isEmpty()) {\n <div rtElem=\"empty\" qa-dataid=\"ai-chat-empty\">\n <rt-empty-state icon=\"comments\" [title]=\"emptyTitleText()\" [description]=\"emptyDescriptionText()\" />\n @if (suggestions().length) {\n <div rtElem=\"suggestions\">\n @for (suggestion of suggestions(); track suggestion) {\n <rt-prompt-suggestion\n qa-dataid=\"ai-chat-suggestion\"\n [label]=\"suggestion\"\n [disabled]=\"sending()\"\n (picked)=\"onSuggestion($event)\" />\n }\n </div>\n }\n </div>\n }\n\n @for (message of messages(); track message.id) {\n @if (message.role === 'user') {\n <div rtElem=\"question\" qa-dataid=\"ai-chat-question\">\n <div rtElem=\"bubble\">\n <span rtElem=\"author\">{{ t().aiYou }}</span>\n <p rtElem=\"bubble-text\">{{ message.text }}</p>\n @if (message.time) {\n <span rtElem=\"time\">{{ message.time }}</span>\n }\n </div>\n @if (copyable() && message.text) {\n <div rtElem=\"question-actions\" qa-dataid=\"ai-chat-question-actions\">\n <rt-ai-chat-copy [text]=\"message.text\" />\n </div>\n }\n </div>\n } @else {\n <rt-ai-chat-answer\n qa-dataid=\"ai-chat-answer\"\n [message]=\"message\"\n [copyable]=\"copyable()\"\n [extra]=\"extraTemplate()?.templateRef ?? null\"\n [expanded]=\"openRuns().has(message.id)\"\n (expandedChange)=\"onToggleRun(message.id, $event)\"\n (feedbackChange)=\"onFeedback(message, $event)\" />\n }\n }\n\n @if (error(); as runError) {\n <div rtElem=\"error\" qa-dataid=\"ai-chat-error\" role=\"alert\">\n <rt-message severity=\"danger\">{{ runError.message }}</rt-message>\n @if (runError.referenceId) {\n <rt-copy-value [label]=\"t().aiReference\" [value]=\"runError.referenceId\" [copyLabel]=\"t().aiCopyReference\" />\n }\n @if (runError.retryable) {\n <button\n rtButton\n type=\"button\"\n qa-dataid=\"ai-chat-retry\"\n appearance=\"text\"\n icon=\"sync\"\n size=\"sm\"\n [label]=\"t().aiRetry\"\n [attr.aria-label]=\"t().aiRetry\"\n [disabled]=\"sending()\"\n (click)=\"retry.emit()\"></button>\n }\n </div>\n }\n </div>\n\n <rt-message-composer\n rtElem=\"composer\"\n qa-dataid=\"ai-chat-composer\"\n stoppable\n [placeholder]=\"placeholder()\"\n [sending]=\"sending()\"\n [(text)]=\"draft\"\n (submitted)=\"onSubmitted($event)\"\n (stopped)=\"onStop()\" />\n\n @if (disclaimerText()) {\n <p rtElem=\"disclaimer\" qa-dataid=\"ai-chat-disclaimer\">{{ disclaimerText() }}</p>\n }\n }\n </section>\n</ng-container>\n\n<ng-template #newThreadButton>\n <rt-icon-button\n qa-dataid=\"ai-chat-new-thread\"\n size=\"sm\"\n iconSize=\"sm\"\n icon=\"ico-plus\"\n [disabled]=\"sending()\"\n [ariaLabel]=\"t().aiNewThread\"\n [tooltip]=\"t().aiNewThread\"\n (clicked)=\"onNewThread()\" />\n</ng-template>\n\n<ng-template #threadList>\n <ng-container rtBlock=\"rt-ai-chat\">\n <rt-thread-list\n rtElem=\"threads\"\n qa-dataid=\"ai-chat-thread-list\"\n [rows]=\"threadRows()\"\n [activeId]=\"activeThreadId()\"\n [searchPlaceholder]=\"t().aiSearchThreads\"\n [emptyText]=\"threadsEmptyText()\"\n [emptyPreviewIcons]=\"emptyPreviewIcons()\"\n [loading]=\"threadsLoading()\"\n [fetching]=\"threadsFetching()\"\n [hasMore]=\"threadsHasMore()\"\n (selectRow)=\"onSelectThread($event)\"\n (searchChange)=\"onSearchThreads($event)\"\n (loadMore)=\"loadMoreThreads.emit()\">\n <ng-template let-row [rtThreadListRow]=\"threadRows()\">\n <span rtElem=\"thread-title\" qa-dataid=\"ai-chat-thread-title\" [attr.title]=\"row.title\">\n @for (part of row.titleParts; track $index) {\n <span rtElem=\"thread-part\" [rtMod]=\"{ match: part.matched }\">{{ part.text }}</span>\n }\n </span>\n <span rtElem=\"thread-meta\">\n @if (row.unreadCount) {\n <span rtElem=\"thread-unread\" qa-dataid=\"ai-chat-thread-unread\">{{ row.unreadCount }}</span>\n }\n @if (row.time) {\n <span rtElem=\"thread-time\">{{ row.time }}</span>\n }\n </span>\n </ng-template>\n <ng-template let-row [rtThreadListRowActions]=\"threadRows()\">\n @if (threadMenu()) {\n <rt-menu qa-dataid=\"ai-chat-thread-menu\" icon=\"ellipsis-v\" triggerSize=\"xs\" size=\"sm\" [ariaLabel]=\"t().uiMoreActions\">\n <rt-menu-item\n qa-dataid=\"ai-chat-thread-copy-id\"\n icon=\"copy\"\n [label]=\"t().aiCopyThreadId\"\n (selected)=\"onCopyThreadId(row.id)\" />\n <rt-menu-item\n qa-dataid=\"ai-chat-thread-delete\"\n icon=\"trash\"\n danger\n [label]=\"t().uiRemove\"\n [disabled]=\"sending() && row.id === activeThreadId()\"\n (selected)=\"deleteThread.emit(row.id)\" />\n </rt-menu>\n } @else {\n <rt-icon-button\n qa-dataid=\"ai-chat-delete-thread\"\n size=\"xs\"\n iconSize=\"sm\"\n icon=\"trash\"\n [disabled]=\"sending() && row.id === activeThreadId()\"\n [ariaLabel]=\"t().aiDeleteThread\"\n [tooltip]=\"t().aiDeleteThread\"\n (clicked)=\"deleteThread.emit(row.id)\" />\n }\n </ng-template>\n </rt-thread-list>\n </ng-container>\n</ng-template>\n",
2837
- styles: ["@charset \"UTF-8\";@layer rt-kit.components{.rt-ai-chat{--rt-ai-chat-bubble-radius: var(--rt-radius-xl);--rt-ai-chat-column-border-width: var(--rt-border-width-thin);--rt-ai-chat-column-width: 280px;--rt-ai-chat-match-bg: var(--rt-yellow-400);--rt-ai-chat-match-color: var(--rt-neutral-950);--rt-ai-chat-match-radius: var(--rt-radius-xs);--rt-ai-chat-unread-radius: var(--rt-radius-full);display:flex;overflow:hidden;background:var(--rt-color-bg-surface);block-size:100%;color:var(--rt-color-text-primary);min-block-size:0}.rt-ai-chat__thread-column{display:flex;flex:none;flex-direction:column;border-inline-end:var(--rt-ai-chat-column-border-width) solid var(--rt-color-border-default);inline-size:var(--rt-ai-chat-column-width)}.rt-ai-chat__column-head{display:flex;align-items:center;justify-content:space-between;padding:var(--rt-space-sm) var(--rt-space-md);gap:var(--rt-space-xs)}.rt-ai-chat__column-title{font-size:var(--rt-text-md);font-weight:var(--rt-font-weight-semibold)}.rt-ai-chat__conversation{display:flex;flex:1 1 auto;flex-direction:column;min-block-size:0;min-inline-size:0}.rt-ai-chat__header{display:flex;flex:none;align-items:center;padding:var(--rt-space-sm) var(--rt-space-md);gap:var(--rt-space-xs)}.rt-ai-chat__heading{display:flex;flex:1 1 auto;flex-direction:column;min-inline-size:0}.rt-ai-chat__title{display:inline-flex;align-items:center;font-size:var(--rt-text-md);font-weight:var(--rt-font-weight-semibold);gap:var(--rt-space-xs);line-height:var(--rt-leading-snug)}.rt-ai-chat__subtitle{overflow:hidden;color:var(--rt-color-text-muted);font-size:var(--rt-text-xs);line-height:var(--rt-leading-snug);text-overflow:ellipsis;white-space:nowrap}.rt-ai-chat__actions{display:flex;flex:none;align-items:center;gap:var(--rt-space-xs)}.rt-ai-chat__feed{display:flex;flex:1 1 auto;flex-direction:column;padding:var(--rt-space-md);font-size:var(--rt-text-sm);gap:var(--rt-space-md);min-block-size:0;overflow-y:auto}.rt-ai-chat__spinner{align-self:center;margin:auto}.rt-ai-chat__empty{display:flex;flex-direction:column;justify-content:center;gap:var(--rt-space-lg);margin-block:auto}.rt-ai-chat__suggestions{display:flex;flex-direction:column;gap:var(--rt-space-sm)}.rt-ai-chat__question{display:flex;flex-direction:column;align-items:flex-end;gap:var(--rt-space-2xs)}.rt-ai-chat__question-actions{display:flex;gap:var(--rt-space-xs)}.rt-ai-chat__bubble{display:flex;flex-direction:column;padding:var(--rt-space-sm) var(--rt-space-md);border-radius:var(--rt-ai-chat-bubble-radius);background:var(--rt-color-bg-subtle);gap:var(--rt-space-2xs);max-inline-size:80%}.rt-ai-chat__author,.rt-ai-chat__time{color:var(--rt-color-text-muted);font-size:var(--rt-text-xs);line-height:var(--rt-leading-snug)}.rt-ai-chat__author{font-weight:var(--rt-font-weight-semibold)}.rt-ai-chat__bubble-text{margin:0;line-height:var(--rt-leading-normal);overflow-wrap:anywhere;white-space:pre-wrap}.rt-ai-chat__error{display:flex;flex-direction:column;align-items:flex-start;gap:var(--rt-space-sm)}.rt-ai-chat__error rt-message{align-self:stretch}.rt-ai-chat__composer{box-sizing:border-box;flex:none;padding:var(--rt-space-sm) var(--rt-space-md) 0}.rt-ai-chat__disclaimer{flex:none;padding:var(--rt-space-xs) var(--rt-space-md) var(--rt-space-sm);margin:0;color:var(--rt-color-text-muted);font-size:var(--rt-text-xs);line-height:var(--rt-leading-snug);text-align:center}.rt-ai-chat__threads{flex:1 1 auto;min-block-size:0}.rt-ai-chat__thread-title{overflow:hidden;min-inline-size:0;text-overflow:ellipsis;white-space:nowrap}.rt-ai-chat__thread-part--match{border-radius:var(--rt-ai-chat-match-radius);background:var(--rt-ai-chat-match-bg);color:var(--rt-ai-chat-match-color)}.rt-ai-chat__thread-meta{display:flex;flex:none;align-items:center;gap:var(--rt-space-xs)}.rt-ai-chat__thread-unread{border-radius:var(--rt-ai-chat-unread-radius);background:var(--rt-color-action-primary);color:var(--rt-color-text-inverse);font-size:var(--rt-text-xs);font-weight:var(--rt-font-weight-semibold);line-height:18px;padding-inline:6px}.rt-ai-chat__thread-time{color:var(--rt-color-text-muted);font-size:var(--rt-text-xs)}}\n"],
2837
+ styles: ["@charset \"UTF-8\";@layer rt-kit.components{.rt-ai-chat{--rt-ai-chat-bubble-radius: var(--rt-radius-xl);--rt-ai-chat-column-border-width: var(--rt-border-width-thin);--rt-ai-chat-column-width: 280px;--rt-ai-chat-content-max-width: 100%;--rt-ai-chat-match-bg: var(--rt-yellow-400);--rt-ai-chat-match-color: var(--rt-neutral-950);--rt-ai-chat-match-radius: var(--rt-radius-xs);--rt-ai-chat-unread-radius: var(--rt-radius-full);display:flex;overflow:hidden;background:var(--rt-color-bg-surface);block-size:100%;color:var(--rt-color-text-primary);min-block-size:0}.rt-ai-chat__thread-column{display:flex;flex:none;flex-direction:column;border-inline-end:var(--rt-ai-chat-column-border-width) solid var(--rt-color-border-default);inline-size:var(--rt-ai-chat-column-width)}.rt-ai-chat__column-head{display:flex;align-items:center;justify-content:space-between;padding:var(--rt-space-sm) var(--rt-space-md);gap:var(--rt-space-xs)}.rt-ai-chat__column-title{font-size:var(--rt-text-md);font-weight:var(--rt-font-weight-semibold)}.rt-ai-chat__conversation{display:flex;flex:1 1 auto;flex-direction:column;min-block-size:0;min-inline-size:0}.rt-ai-chat__header{display:flex;flex:none;align-items:center;padding:var(--rt-space-sm) var(--rt-space-md);gap:var(--rt-space-xs)}.rt-ai-chat__heading{display:flex;flex:1 1 auto;flex-direction:column;min-inline-size:0}.rt-ai-chat__title{display:inline-flex;align-items:center;font-size:var(--rt-text-md);font-weight:var(--rt-font-weight-semibold);gap:var(--rt-space-xs);line-height:var(--rt-leading-snug)}.rt-ai-chat__subtitle{overflow:hidden;color:var(--rt-color-text-muted);font-size:var(--rt-text-xs);line-height:var(--rt-leading-snug);text-overflow:ellipsis;white-space:nowrap}.rt-ai-chat__actions{display:flex;flex:none;align-items:center;gap:var(--rt-space-xs)}.rt-ai-chat__feed{display:flex;flex:1 1 auto;flex-direction:column;font-size:var(--rt-text-sm);gap:var(--rt-space-md);min-block-size:0;overflow-y:auto;padding-block:var(--rt-space-md);padding-inline:max(var(--rt-space-md),(100% - var(--rt-ai-chat-content-max-width)) / 2)}.rt-ai-chat__spinner{align-self:center;margin:auto}.rt-ai-chat__empty{display:flex;flex-direction:column;justify-content:center;gap:var(--rt-space-lg);margin-block:auto}.rt-ai-chat__suggestions{display:flex;flex-direction:column;gap:var(--rt-space-sm)}.rt-ai-chat__question{display:flex;flex-direction:column;align-items:flex-end;gap:var(--rt-space-2xs)}.rt-ai-chat__question-actions{display:flex;gap:var(--rt-space-xs)}.rt-ai-chat__bubble{display:flex;flex-direction:column;padding:var(--rt-space-sm) var(--rt-space-md);border-radius:var(--rt-ai-chat-bubble-radius);background:var(--rt-color-bg-subtle);gap:var(--rt-space-2xs);max-inline-size:80%}.rt-ai-chat__author,.rt-ai-chat__time{color:var(--rt-color-text-muted);font-size:var(--rt-text-xs);line-height:var(--rt-leading-snug)}.rt-ai-chat__author{font-weight:var(--rt-font-weight-semibold)}.rt-ai-chat__bubble-text{margin:0;line-height:var(--rt-leading-normal);overflow-wrap:anywhere;white-space:pre-wrap}.rt-ai-chat__error{display:flex;flex-direction:column;align-items:flex-start;gap:var(--rt-space-sm)}.rt-ai-chat__error rt-message{align-self:stretch}.rt-ai-chat__composer{box-sizing:border-box;flex:none;padding-block:var(--rt-space-sm) 0;padding-inline:max(var(--rt-space-md),(100% - var(--rt-ai-chat-content-max-width)) / 2)}.rt-ai-chat__disclaimer{flex:none;margin:0;color:var(--rt-color-text-muted);font-size:var(--rt-text-xs);line-height:var(--rt-leading-snug);padding-block:var(--rt-space-xs) var(--rt-space-sm);padding-inline:max(var(--rt-space-md),(100% - var(--rt-ai-chat-content-max-width)) / 2);text-align:center}.rt-ai-chat__threads{flex:1 1 auto;min-block-size:0}.rt-ai-chat__thread-title{overflow:hidden;min-inline-size:0;text-overflow:ellipsis;white-space:nowrap}.rt-ai-chat__thread-part--match{border-radius:var(--rt-ai-chat-match-radius);background:var(--rt-ai-chat-match-bg);color:var(--rt-ai-chat-match-color)}.rt-ai-chat__thread-meta{display:flex;flex:none;align-items:center;gap:var(--rt-space-xs)}.rt-ai-chat__thread-unread{border-radius:var(--rt-ai-chat-unread-radius);background:var(--rt-color-action-primary);color:var(--rt-color-text-inverse);font-size:var(--rt-text-xs);font-weight:var(--rt-font-weight-semibold);line-height:18px;padding-inline:6px}.rt-ai-chat__thread-time{color:var(--rt-color-text-muted);font-size:var(--rt-text-xs)}}\n"],
2838
2838
  dependencies: [
2839
2839
  {
2840
2840
  kind: "directive",
@@ -3130,7 +3130,7 @@ i0.ɵɵngDeclareClassMetadata({
3130
3130
  ],
3131
3131
  host: { class: BEM_BLOCK },
3132
3132
  template: "<ng-container rtBlock=\"rt-ai-chat\">\n @if (isThreadColumn()) {\n <aside rtElem=\"thread-column\" qa-dataid=\"ai-chat-thread-column\" [attr.aria-label]=\"t().aiThreads\">\n <div rtElem=\"column-head\">\n <span rtElem=\"column-title\">{{ t().aiThreads }}</span>\n <ng-container [ngTemplateOutlet]=\"newThreadButton\" />\n </div>\n <ng-container [ngTemplateOutlet]=\"threadList\" />\n </aside>\n }\n\n <section rtElem=\"conversation\" qa-dataid=\"ai-chat\" [attr.aria-label]=\"titleText()\">\n <header rtElem=\"header\" [attr.data-rt-icon-preset]=\"headerIconSign()\">\n @if (isThreadPage()) {\n <rt-icon-button\n #back\n qa-dataid=\"ai-chat-back\"\n size=\"sm\"\n iconSize=\"sm\"\n icon=\"arrow-left\"\n [ariaLabel]=\"t().aiBackToChat\"\n [tooltip]=\"t().aiBackToChat\"\n (clicked)=\"onToggleThreads()\" />\n }\n\n <div rtElem=\"heading\">\n <span rtElem=\"title\" qa-dataid=\"ai-chat-title\">\n @if (!isThreadPage()) {\n <rt-icon name=\"sparkle\" size=\"sm\" color=\"primary\" aria-hidden=\"true\" />\n }\n {{ isThreadPage() ? t().aiThreads : titleText() }}\n </span>\n @if (!isThreadPage() && subtitle()) {\n <span rtElem=\"subtitle\" qa-dataid=\"ai-chat-subtitle\">{{ subtitle() }}</span>\n }\n </div>\n\n <div rtElem=\"actions\">\n @if (fullScreenable()) {\n <rt-icon-button\n qa-dataid=\"ai-chat-full-screen\"\n size=\"sm\"\n iconSize=\"sm\"\n [icon]=\"fullScreen() ? 'window-minimize' : 'fullscreen'\"\n [active]=\"fullScreen()\"\n [ariaLabel]=\"fullScreen() ? t().aiExitFullScreen : t().aiFullScreen\"\n [tooltip]=\"fullScreen() ? t().aiExitFullScreen : t().aiFullScreen\"\n (clicked)=\"onToggleFullScreen()\" />\n }\n @if (hasThreads() && !isThreadPage() && !isThreadColumn()) {\n <rt-icon-button\n qa-dataid=\"ai-chat-threads\"\n size=\"sm\"\n iconSize=\"sm\"\n icon=\"history\"\n [ariaLabel]=\"t().aiThreads\"\n [tooltip]=\"t().aiThreads\"\n (clicked)=\"onToggleThreads()\" />\n }\n @if (!isThreadColumn()) {\n <ng-container [ngTemplateOutlet]=\"newThreadButton\" />\n }\n @if (closable()) {\n <rt-icon-button\n qa-dataid=\"ai-chat-close\"\n size=\"sm\"\n iconSize=\"sm\"\n icon=\"close\"\n [ariaLabel]=\"t().aiClose\"\n [tooltip]=\"t().aiClose\"\n (clicked)=\"closed.emit()\" />\n }\n </div>\n </header>\n\n @if (isThreadPage()) {\n <ng-container [ngTemplateOutlet]=\"threadList\" />\n } @else {\n <div #feed rtElem=\"feed\" qa-dataid=\"ai-chat-feed\" aria-live=\"polite\" (scroll)=\"onFeedScroll()\">\n @if (loading() && !messages().length) {\n <rt-spinner rtElem=\"spinner\" appearance=\"arc\" [diameter]=\"32\" />\n } @else if (isEmpty()) {\n <div rtElem=\"empty\" qa-dataid=\"ai-chat-empty\">\n <rt-empty-state icon=\"comments\" [title]=\"emptyTitleText()\" [description]=\"emptyDescriptionText()\" />\n @if (suggestions().length) {\n <div rtElem=\"suggestions\">\n @for (suggestion of suggestions(); track suggestion) {\n <rt-prompt-suggestion\n qa-dataid=\"ai-chat-suggestion\"\n [label]=\"suggestion\"\n [disabled]=\"sending()\"\n (picked)=\"onSuggestion($event)\" />\n }\n </div>\n }\n </div>\n }\n\n @for (message of messages(); track message.id) {\n @if (message.role === 'user') {\n <div rtElem=\"question\" qa-dataid=\"ai-chat-question\">\n <div rtElem=\"bubble\">\n <span rtElem=\"author\">{{ t().aiYou }}</span>\n <p rtElem=\"bubble-text\">{{ message.text }}</p>\n @if (message.time) {\n <span rtElem=\"time\">{{ message.time }}</span>\n }\n </div>\n @if (copyable() && message.text) {\n <div rtElem=\"question-actions\" qa-dataid=\"ai-chat-question-actions\">\n <rt-ai-chat-copy [text]=\"message.text\" />\n </div>\n }\n </div>\n } @else {\n <rt-ai-chat-answer\n qa-dataid=\"ai-chat-answer\"\n [message]=\"message\"\n [copyable]=\"copyable()\"\n [extra]=\"extraTemplate()?.templateRef ?? null\"\n [expanded]=\"openRuns().has(message.id)\"\n (expandedChange)=\"onToggleRun(message.id, $event)\"\n (feedbackChange)=\"onFeedback(message, $event)\" />\n }\n }\n\n @if (error(); as runError) {\n <div rtElem=\"error\" qa-dataid=\"ai-chat-error\" role=\"alert\">\n <rt-message severity=\"danger\">{{ runError.message }}</rt-message>\n @if (runError.referenceId) {\n <rt-copy-value [label]=\"t().aiReference\" [value]=\"runError.referenceId\" [copyLabel]=\"t().aiCopyReference\" />\n }\n @if (runError.retryable) {\n <button\n rtButton\n type=\"button\"\n qa-dataid=\"ai-chat-retry\"\n appearance=\"text\"\n icon=\"sync\"\n size=\"sm\"\n [label]=\"t().aiRetry\"\n [attr.aria-label]=\"t().aiRetry\"\n [disabled]=\"sending()\"\n (click)=\"retry.emit()\"></button>\n }\n </div>\n }\n </div>\n\n <rt-message-composer\n rtElem=\"composer\"\n qa-dataid=\"ai-chat-composer\"\n stoppable\n [placeholder]=\"placeholder()\"\n [sending]=\"sending()\"\n [(text)]=\"draft\"\n (submitted)=\"onSubmitted($event)\"\n (stopped)=\"onStop()\" />\n\n @if (disclaimerText()) {\n <p rtElem=\"disclaimer\" qa-dataid=\"ai-chat-disclaimer\">{{ disclaimerText() }}</p>\n }\n }\n </section>\n</ng-container>\n\n<ng-template #newThreadButton>\n <rt-icon-button\n qa-dataid=\"ai-chat-new-thread\"\n size=\"sm\"\n iconSize=\"sm\"\n icon=\"ico-plus\"\n [disabled]=\"sending()\"\n [ariaLabel]=\"t().aiNewThread\"\n [tooltip]=\"t().aiNewThread\"\n (clicked)=\"onNewThread()\" />\n</ng-template>\n\n<ng-template #threadList>\n <ng-container rtBlock=\"rt-ai-chat\">\n <rt-thread-list\n rtElem=\"threads\"\n qa-dataid=\"ai-chat-thread-list\"\n [rows]=\"threadRows()\"\n [activeId]=\"activeThreadId()\"\n [searchPlaceholder]=\"t().aiSearchThreads\"\n [emptyText]=\"threadsEmptyText()\"\n [emptyPreviewIcons]=\"emptyPreviewIcons()\"\n [loading]=\"threadsLoading()\"\n [fetching]=\"threadsFetching()\"\n [hasMore]=\"threadsHasMore()\"\n (selectRow)=\"onSelectThread($event)\"\n (searchChange)=\"onSearchThreads($event)\"\n (loadMore)=\"loadMoreThreads.emit()\">\n <ng-template let-row [rtThreadListRow]=\"threadRows()\">\n <span rtElem=\"thread-title\" qa-dataid=\"ai-chat-thread-title\" [attr.title]=\"row.title\">\n @for (part of row.titleParts; track $index) {\n <span rtElem=\"thread-part\" [rtMod]=\"{ match: part.matched }\">{{ part.text }}</span>\n }\n </span>\n <span rtElem=\"thread-meta\">\n @if (row.unreadCount) {\n <span rtElem=\"thread-unread\" qa-dataid=\"ai-chat-thread-unread\">{{ row.unreadCount }}</span>\n }\n @if (row.time) {\n <span rtElem=\"thread-time\">{{ row.time }}</span>\n }\n </span>\n </ng-template>\n <ng-template let-row [rtThreadListRowActions]=\"threadRows()\">\n @if (threadMenu()) {\n <rt-menu qa-dataid=\"ai-chat-thread-menu\" icon=\"ellipsis-v\" triggerSize=\"xs\" size=\"sm\" [ariaLabel]=\"t().uiMoreActions\">\n <rt-menu-item\n qa-dataid=\"ai-chat-thread-copy-id\"\n icon=\"copy\"\n [label]=\"t().aiCopyThreadId\"\n (selected)=\"onCopyThreadId(row.id)\" />\n <rt-menu-item\n qa-dataid=\"ai-chat-thread-delete\"\n icon=\"trash\"\n danger\n [label]=\"t().uiRemove\"\n [disabled]=\"sending() && row.id === activeThreadId()\"\n (selected)=\"deleteThread.emit(row.id)\" />\n </rt-menu>\n } @else {\n <rt-icon-button\n qa-dataid=\"ai-chat-delete-thread\"\n size=\"xs\"\n iconSize=\"sm\"\n icon=\"trash\"\n [disabled]=\"sending() && row.id === activeThreadId()\"\n [ariaLabel]=\"t().aiDeleteThread\"\n [tooltip]=\"t().aiDeleteThread\"\n (clicked)=\"deleteThread.emit(row.id)\" />\n }\n </ng-template>\n </rt-thread-list>\n </ng-container>\n</ng-template>\n",
3133
- styles: ["@charset \"UTF-8\";@layer rt-kit.components{.rt-ai-chat{--rt-ai-chat-bubble-radius: var(--rt-radius-xl);--rt-ai-chat-column-border-width: var(--rt-border-width-thin);--rt-ai-chat-column-width: 280px;--rt-ai-chat-match-bg: var(--rt-yellow-400);--rt-ai-chat-match-color: var(--rt-neutral-950);--rt-ai-chat-match-radius: var(--rt-radius-xs);--rt-ai-chat-unread-radius: var(--rt-radius-full);display:flex;overflow:hidden;background:var(--rt-color-bg-surface);block-size:100%;color:var(--rt-color-text-primary);min-block-size:0}.rt-ai-chat__thread-column{display:flex;flex:none;flex-direction:column;border-inline-end:var(--rt-ai-chat-column-border-width) solid var(--rt-color-border-default);inline-size:var(--rt-ai-chat-column-width)}.rt-ai-chat__column-head{display:flex;align-items:center;justify-content:space-between;padding:var(--rt-space-sm) var(--rt-space-md);gap:var(--rt-space-xs)}.rt-ai-chat__column-title{font-size:var(--rt-text-md);font-weight:var(--rt-font-weight-semibold)}.rt-ai-chat__conversation{display:flex;flex:1 1 auto;flex-direction:column;min-block-size:0;min-inline-size:0}.rt-ai-chat__header{display:flex;flex:none;align-items:center;padding:var(--rt-space-sm) var(--rt-space-md);gap:var(--rt-space-xs)}.rt-ai-chat__heading{display:flex;flex:1 1 auto;flex-direction:column;min-inline-size:0}.rt-ai-chat__title{display:inline-flex;align-items:center;font-size:var(--rt-text-md);font-weight:var(--rt-font-weight-semibold);gap:var(--rt-space-xs);line-height:var(--rt-leading-snug)}.rt-ai-chat__subtitle{overflow:hidden;color:var(--rt-color-text-muted);font-size:var(--rt-text-xs);line-height:var(--rt-leading-snug);text-overflow:ellipsis;white-space:nowrap}.rt-ai-chat__actions{display:flex;flex:none;align-items:center;gap:var(--rt-space-xs)}.rt-ai-chat__feed{display:flex;flex:1 1 auto;flex-direction:column;padding:var(--rt-space-md);font-size:var(--rt-text-sm);gap:var(--rt-space-md);min-block-size:0;overflow-y:auto}.rt-ai-chat__spinner{align-self:center;margin:auto}.rt-ai-chat__empty{display:flex;flex-direction:column;justify-content:center;gap:var(--rt-space-lg);margin-block:auto}.rt-ai-chat__suggestions{display:flex;flex-direction:column;gap:var(--rt-space-sm)}.rt-ai-chat__question{display:flex;flex-direction:column;align-items:flex-end;gap:var(--rt-space-2xs)}.rt-ai-chat__question-actions{display:flex;gap:var(--rt-space-xs)}.rt-ai-chat__bubble{display:flex;flex-direction:column;padding:var(--rt-space-sm) var(--rt-space-md);border-radius:var(--rt-ai-chat-bubble-radius);background:var(--rt-color-bg-subtle);gap:var(--rt-space-2xs);max-inline-size:80%}.rt-ai-chat__author,.rt-ai-chat__time{color:var(--rt-color-text-muted);font-size:var(--rt-text-xs);line-height:var(--rt-leading-snug)}.rt-ai-chat__author{font-weight:var(--rt-font-weight-semibold)}.rt-ai-chat__bubble-text{margin:0;line-height:var(--rt-leading-normal);overflow-wrap:anywhere;white-space:pre-wrap}.rt-ai-chat__error{display:flex;flex-direction:column;align-items:flex-start;gap:var(--rt-space-sm)}.rt-ai-chat__error rt-message{align-self:stretch}.rt-ai-chat__composer{box-sizing:border-box;flex:none;padding:var(--rt-space-sm) var(--rt-space-md) 0}.rt-ai-chat__disclaimer{flex:none;padding:var(--rt-space-xs) var(--rt-space-md) var(--rt-space-sm);margin:0;color:var(--rt-color-text-muted);font-size:var(--rt-text-xs);line-height:var(--rt-leading-snug);text-align:center}.rt-ai-chat__threads{flex:1 1 auto;min-block-size:0}.rt-ai-chat__thread-title{overflow:hidden;min-inline-size:0;text-overflow:ellipsis;white-space:nowrap}.rt-ai-chat__thread-part--match{border-radius:var(--rt-ai-chat-match-radius);background:var(--rt-ai-chat-match-bg);color:var(--rt-ai-chat-match-color)}.rt-ai-chat__thread-meta{display:flex;flex:none;align-items:center;gap:var(--rt-space-xs)}.rt-ai-chat__thread-unread{border-radius:var(--rt-ai-chat-unread-radius);background:var(--rt-color-action-primary);color:var(--rt-color-text-inverse);font-size:var(--rt-text-xs);font-weight:var(--rt-font-weight-semibold);line-height:18px;padding-inline:6px}.rt-ai-chat__thread-time{color:var(--rt-color-text-muted);font-size:var(--rt-text-xs)}}\n"]
3133
+ styles: ["@charset \"UTF-8\";@layer rt-kit.components{.rt-ai-chat{--rt-ai-chat-bubble-radius: var(--rt-radius-xl);--rt-ai-chat-column-border-width: var(--rt-border-width-thin);--rt-ai-chat-column-width: 280px;--rt-ai-chat-content-max-width: 100%;--rt-ai-chat-match-bg: var(--rt-yellow-400);--rt-ai-chat-match-color: var(--rt-neutral-950);--rt-ai-chat-match-radius: var(--rt-radius-xs);--rt-ai-chat-unread-radius: var(--rt-radius-full);display:flex;overflow:hidden;background:var(--rt-color-bg-surface);block-size:100%;color:var(--rt-color-text-primary);min-block-size:0}.rt-ai-chat__thread-column{display:flex;flex:none;flex-direction:column;border-inline-end:var(--rt-ai-chat-column-border-width) solid var(--rt-color-border-default);inline-size:var(--rt-ai-chat-column-width)}.rt-ai-chat__column-head{display:flex;align-items:center;justify-content:space-between;padding:var(--rt-space-sm) var(--rt-space-md);gap:var(--rt-space-xs)}.rt-ai-chat__column-title{font-size:var(--rt-text-md);font-weight:var(--rt-font-weight-semibold)}.rt-ai-chat__conversation{display:flex;flex:1 1 auto;flex-direction:column;min-block-size:0;min-inline-size:0}.rt-ai-chat__header{display:flex;flex:none;align-items:center;padding:var(--rt-space-sm) var(--rt-space-md);gap:var(--rt-space-xs)}.rt-ai-chat__heading{display:flex;flex:1 1 auto;flex-direction:column;min-inline-size:0}.rt-ai-chat__title{display:inline-flex;align-items:center;font-size:var(--rt-text-md);font-weight:var(--rt-font-weight-semibold);gap:var(--rt-space-xs);line-height:var(--rt-leading-snug)}.rt-ai-chat__subtitle{overflow:hidden;color:var(--rt-color-text-muted);font-size:var(--rt-text-xs);line-height:var(--rt-leading-snug);text-overflow:ellipsis;white-space:nowrap}.rt-ai-chat__actions{display:flex;flex:none;align-items:center;gap:var(--rt-space-xs)}.rt-ai-chat__feed{display:flex;flex:1 1 auto;flex-direction:column;font-size:var(--rt-text-sm);gap:var(--rt-space-md);min-block-size:0;overflow-y:auto;padding-block:var(--rt-space-md);padding-inline:max(var(--rt-space-md),(100% - var(--rt-ai-chat-content-max-width)) / 2)}.rt-ai-chat__spinner{align-self:center;margin:auto}.rt-ai-chat__empty{display:flex;flex-direction:column;justify-content:center;gap:var(--rt-space-lg);margin-block:auto}.rt-ai-chat__suggestions{display:flex;flex-direction:column;gap:var(--rt-space-sm)}.rt-ai-chat__question{display:flex;flex-direction:column;align-items:flex-end;gap:var(--rt-space-2xs)}.rt-ai-chat__question-actions{display:flex;gap:var(--rt-space-xs)}.rt-ai-chat__bubble{display:flex;flex-direction:column;padding:var(--rt-space-sm) var(--rt-space-md);border-radius:var(--rt-ai-chat-bubble-radius);background:var(--rt-color-bg-subtle);gap:var(--rt-space-2xs);max-inline-size:80%}.rt-ai-chat__author,.rt-ai-chat__time{color:var(--rt-color-text-muted);font-size:var(--rt-text-xs);line-height:var(--rt-leading-snug)}.rt-ai-chat__author{font-weight:var(--rt-font-weight-semibold)}.rt-ai-chat__bubble-text{margin:0;line-height:var(--rt-leading-normal);overflow-wrap:anywhere;white-space:pre-wrap}.rt-ai-chat__error{display:flex;flex-direction:column;align-items:flex-start;gap:var(--rt-space-sm)}.rt-ai-chat__error rt-message{align-self:stretch}.rt-ai-chat__composer{box-sizing:border-box;flex:none;padding-block:var(--rt-space-sm) 0;padding-inline:max(var(--rt-space-md),(100% - var(--rt-ai-chat-content-max-width)) / 2)}.rt-ai-chat__disclaimer{flex:none;margin:0;color:var(--rt-color-text-muted);font-size:var(--rt-text-xs);line-height:var(--rt-leading-snug);padding-block:var(--rt-space-xs) var(--rt-space-sm);padding-inline:max(var(--rt-space-md),(100% - var(--rt-ai-chat-content-max-width)) / 2);text-align:center}.rt-ai-chat__threads{flex:1 1 auto;min-block-size:0}.rt-ai-chat__thread-title{overflow:hidden;min-inline-size:0;text-overflow:ellipsis;white-space:nowrap}.rt-ai-chat__thread-part--match{border-radius:var(--rt-ai-chat-match-radius);background:var(--rt-ai-chat-match-bg);color:var(--rt-ai-chat-match-color)}.rt-ai-chat__thread-meta{display:flex;flex:none;align-items:center;gap:var(--rt-space-xs)}.rt-ai-chat__thread-unread{border-radius:var(--rt-ai-chat-unread-radius);background:var(--rt-color-action-primary);color:var(--rt-color-text-inverse);font-size:var(--rt-text-xs);font-weight:var(--rt-font-weight-semibold);line-height:18px;padding-inline:6px}.rt-ai-chat__thread-time{color:var(--rt-color-text-muted);font-size:var(--rt-text-xs)}}\n"]
3134
3134
  }]
3135
3135
  }],
3136
3136
  ctorParameters: () => [],