@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.
- package/fesm2022/rt-tools-ui-kit-v2-bottom-sheet.mjs +2 -2
- package/fesm2022/rt-tools-ui-kit-v2-bottom-sheet.mjs.map +1 -1
- package/fesm2022/rt-tools-ui-kit-v2-core.mjs +12 -0
- package/fesm2022/rt-tools-ui-kit-v2-core.mjs.map +1 -1
- package/fesm2022/rt-tools-ui-kit-v2-profile-menu.mjs +295 -0
- package/fesm2022/rt-tools-ui-kit-v2-profile-menu.mjs.map +1 -0
- package/fesm2022/rt-tools-ui-kit-v2-rich-editor.mjs +2 -2
- package/fesm2022/rt-tools-ui-kit-v2-rich-editor.mjs.map +1 -1
- package/package.json +5 -1
- package/src/lib/components/bottom-sheet/rt-bottom-sheet.component.scss +2 -1
- package/src/lib/components/profile-menu/CONTEXT.md +32 -0
- package/src/lib/components/profile-menu/rt-profile-menu.component.scss +104 -0
- package/src/rich-editor/lib/components/ai-chat/CONTEXT.md +3 -0
- package/src/rich-editor/lib/components/ai-chat/rt-ai-chat.component.scss +7 -3
- package/src/styles/_semantic.scss +5 -0
- package/styles/tokens.css +40 -0
- package/types/rt-tools-ui-kit-v2-core.d.ts +8 -2
- package/types/rt-tools-ui-kit-v2-profile-menu.d.ts +103 -0
|
@@ -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;
|
|
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;
|
|
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: () => [],
|