@memberjunction/ng-conversations 5.11.0 → 5.12.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/dist/lib/components/active-tasks/active-tasks-panel.component.js +2 -2
- package/dist/lib/components/active-tasks/active-tasks-panel.component.js.map +1 -1
- package/dist/lib/components/artifact/artifact-share-modal.component.js +2 -2
- package/dist/lib/components/attachment/image-viewer.component.js +2 -2
- package/dist/lib/components/collection/artifact-collection-picker-modal.component.js +4 -4
- package/dist/lib/components/collection/artifact-collection-picker-modal.component.js.map +1 -1
- package/dist/lib/components/collection/artifact-create-modal.component.js +2 -2
- package/dist/lib/components/collection/artifact-create-modal.component.js.map +1 -1
- package/dist/lib/components/collection/collection-artifact-card.component.js +2 -2
- package/dist/lib/components/collection/collection-artifact-card.component.js.map +1 -1
- package/dist/lib/components/collection/collection-form-modal.component.js +2 -2
- package/dist/lib/components/collection/collection-form-modal.component.js.map +1 -1
- package/dist/lib/components/collection/collection-share-modal.component.js +2 -2
- package/dist/lib/components/collection/collection-tree.component.js +2 -2
- package/dist/lib/components/collection/collection-tree.component.js.map +1 -1
- package/dist/lib/components/collection/collection-view.component.js +2 -2
- package/dist/lib/components/collection/collection-view.component.js.map +1 -1
- package/dist/lib/components/collection/collections-full-view.component.js +2 -2
- package/dist/lib/components/collection/collections-full-view.component.js.map +1 -1
- package/dist/lib/components/conversation/conversation-chat-area.component.d.ts +9 -1
- package/dist/lib/components/conversation/conversation-chat-area.component.d.ts.map +1 -1
- package/dist/lib/components/conversation/conversation-chat-area.component.js +32 -6
- package/dist/lib/components/conversation/conversation-chat-area.component.js.map +1 -1
- package/dist/lib/components/conversation/conversation-empty-state.component.d.ts +6 -0
- package/dist/lib/components/conversation/conversation-empty-state.component.d.ts.map +1 -1
- package/dist/lib/components/conversation/conversation-empty-state.component.js +26 -5
- package/dist/lib/components/conversation/conversation-empty-state.component.js.map +1 -1
- package/dist/lib/components/conversation/conversation-list.component.js +2 -2
- package/dist/lib/components/conversation/conversation-list.component.js.map +1 -1
- package/dist/lib/components/export/export-modal.component.d.ts.map +1 -1
- package/dist/lib/components/export/export-modal.component.js +3 -3
- package/dist/lib/components/export/export-modal.component.js.map +1 -1
- package/dist/lib/components/global-tasks/global-tasks-panel.component.js +2 -2
- package/dist/lib/components/global-tasks/global-tasks-panel.component.js.map +1 -1
- package/dist/lib/components/mention/mention-dropdown.component.js +2 -2
- package/dist/lib/components/mention/mention-editor.component.js +2 -2
- package/dist/lib/components/message/actionable-commands.component.js +2 -2
- package/dist/lib/components/message/conversation-message-rating.component.js +2 -2
- package/dist/lib/components/message/conversation-message-rating.component.js.map +1 -1
- package/dist/lib/components/message/message-input-box.component.js +2 -2
- package/dist/lib/components/message/message-input.component.js +2 -2
- package/dist/lib/components/message/message-item.component.d.ts +5 -4
- package/dist/lib/components/message/message-item.component.d.ts.map +1 -1
- package/dist/lib/components/message/message-item.component.js +33 -123
- package/dist/lib/components/message/message-item.component.js.map +1 -1
- package/dist/lib/components/message/message-list.component.js +2 -2
- package/dist/lib/components/message/suggested-responses.component.js +2 -2
- package/dist/lib/components/search/search-panel.component.js +2 -2
- package/dist/lib/components/sidebar/conversation-sidebar.component.js +2 -2
- package/dist/lib/components/sidebar/conversation-sidebar.component.js.map +1 -1
- package/dist/lib/components/task/tasks-full-view.component.js +2 -2
- package/dist/lib/components/task/tasks-full-view.component.js.map +1 -1
- package/dist/lib/components/tasks/task-widget.component.js +2 -2
- package/dist/lib/components/tasks/task-widget.component.js.map +1 -1
- package/dist/lib/components/tasks/tasks-dropdown.component.d.ts.map +1 -1
- package/dist/lib/components/tasks/tasks-dropdown.component.js +3 -3
- package/dist/lib/components/tasks/tasks-dropdown.component.js.map +1 -1
- package/dist/lib/components/thread/thread-panel.component.js +2 -2
- package/dist/lib/components/toast/toast.component.js +2 -2
- package/dist/lib/components/toast/toast.component.js.map +1 -1
- package/dist/lib/components/workspace/conversation-workspace.component.js +2 -2
- package/dist/lib/conversations.module.d.ts +61 -62
- package/dist/lib/conversations.module.d.ts.map +1 -1
- package/dist/lib/conversations.module.js +4 -8
- package/dist/lib/conversations.module.js.map +1 -1
- package/package.json +18 -17
- package/dist/lib/components/message/agent-response-form.component.d.ts +0 -90
- package/dist/lib/components/message/agent-response-form.component.d.ts.map +0 -1
- package/dist/lib/components/message/agent-response-form.component.js +0 -435
- package/dist/lib/components/message/agent-response-form.component.js.map +0 -1
- package/dist/lib/components/message/form-question.component.d.ts +0 -105
- package/dist/lib/components/message/form-question.component.d.ts.map +0 -1
- package/dist/lib/components/message/form-question.component.js +0 -638
- package/dist/lib/components/message/form-question.component.js.map +0 -1
|
@@ -1,435 +0,0 @@
|
|
|
1
|
-
import { Component, Input, Output, EventEmitter } from '@angular/core';
|
|
2
|
-
import { FormGroup, FormControl, Validators } from '@angular/forms';
|
|
3
|
-
import * as i0 from "@angular/core";
|
|
4
|
-
import * as i1 from "@angular/forms";
|
|
5
|
-
import * as i2 from "@progress/kendo-angular-buttons";
|
|
6
|
-
import * as i3 from "./form-question.component";
|
|
7
|
-
function AgentResponseFormComponent_Conditional_0_Conditional_1_For_2_Conditional_1_Template(rf, ctx) { if (rf & 1) {
|
|
8
|
-
i0.ɵɵelement(0, "i", 6);
|
|
9
|
-
} if (rf & 2) {
|
|
10
|
-
const option_r2 = i0.ɵɵnextContext().$implicit;
|
|
11
|
-
i0.ɵɵclassMap(i0.ɵɵinterpolate1("fa ", option_r2.icon));
|
|
12
|
-
} }
|
|
13
|
-
function AgentResponseFormComponent_Conditional_0_Conditional_1_For_2_Template(rf, ctx) { if (rf & 1) {
|
|
14
|
-
const _r1 = i0.ɵɵgetCurrentView();
|
|
15
|
-
i0.ɵɵelementStart(0, "button", 4);
|
|
16
|
-
i0.ɵɵlistener("click", function AgentResponseFormComponent_Conditional_0_Conditional_1_For_2_Template_button_click_0_listener() { const option_r2 = i0.ɵɵrestoreView(_r1).$implicit; const ctx_r2 = i0.ɵɵnextContext(3); return i0.ɵɵresetView(ctx_r2.onSimpleChoiceClick(option_r2.value)); });
|
|
17
|
-
i0.ɵɵconditionalCreate(1, AgentResponseFormComponent_Conditional_0_Conditional_1_For_2_Conditional_1_Template, 1, 3, "i", 5);
|
|
18
|
-
i0.ɵɵtext(2);
|
|
19
|
-
i0.ɵɵelementEnd();
|
|
20
|
-
} if (rf & 2) {
|
|
21
|
-
const option_r2 = ctx.$implicit;
|
|
22
|
-
const ctx_r2 = i0.ɵɵnextContext(3);
|
|
23
|
-
i0.ɵɵproperty("disabled", ctx_r2.disabled || ctx_r2.isSubmitting);
|
|
24
|
-
i0.ɵɵadvance();
|
|
25
|
-
i0.ɵɵconditional(ctx_r2.hasIcon(option_r2) ? 1 : -1);
|
|
26
|
-
i0.ɵɵadvance();
|
|
27
|
-
i0.ɵɵtextInterpolate1(" ", option_r2.label, " ");
|
|
28
|
-
} }
|
|
29
|
-
function AgentResponseFormComponent_Conditional_0_Conditional_1_Template(rf, ctx) { if (rf & 1) {
|
|
30
|
-
i0.ɵɵelementStart(0, "div", 1);
|
|
31
|
-
i0.ɵɵrepeaterCreate(1, AgentResponseFormComponent_Conditional_0_Conditional_1_For_2_Template, 3, 3, "button", 3, i0.ɵɵcomponentInstance().trackByValue, true);
|
|
32
|
-
i0.ɵɵelementEnd();
|
|
33
|
-
} if (rf & 2) {
|
|
34
|
-
const ctx_r2 = i0.ɵɵnextContext(2);
|
|
35
|
-
i0.ɵɵadvance();
|
|
36
|
-
i0.ɵɵrepeater(ctx_r2.getOptions(ctx_r2.responseForm.questions[0]));
|
|
37
|
-
} }
|
|
38
|
-
function AgentResponseFormComponent_Conditional_0_Conditional_2_Conditional_1_Template(rf, ctx) { if (rf & 1) {
|
|
39
|
-
i0.ɵɵelementStart(0, "h3", 8);
|
|
40
|
-
i0.ɵɵtext(1);
|
|
41
|
-
i0.ɵɵelementEnd();
|
|
42
|
-
} if (rf & 2) {
|
|
43
|
-
const ctx_r2 = i0.ɵɵnextContext(3);
|
|
44
|
-
i0.ɵɵadvance();
|
|
45
|
-
i0.ɵɵtextInterpolate(ctx_r2.responseForm.title);
|
|
46
|
-
} }
|
|
47
|
-
function AgentResponseFormComponent_Conditional_0_Conditional_2_Conditional_2_Template(rf, ctx) { if (rf & 1) {
|
|
48
|
-
i0.ɵɵelementStart(0, "p", 9);
|
|
49
|
-
i0.ɵɵtext(1);
|
|
50
|
-
i0.ɵɵelementEnd();
|
|
51
|
-
} if (rf & 2) {
|
|
52
|
-
const ctx_r2 = i0.ɵɵnextContext(3);
|
|
53
|
-
i0.ɵɵadvance();
|
|
54
|
-
i0.ɵɵtextInterpolate(ctx_r2.responseForm.description);
|
|
55
|
-
} }
|
|
56
|
-
function AgentResponseFormComponent_Conditional_0_Conditional_2_Conditional_3_For_2_Template(rf, ctx) { if (rf & 1) {
|
|
57
|
-
i0.ɵɵelement(0, "mj-form-question", 13);
|
|
58
|
-
} if (rf & 2) {
|
|
59
|
-
const question_r5 = ctx.$implicit;
|
|
60
|
-
const ctx_r2 = i0.ɵɵnextContext(4);
|
|
61
|
-
i0.ɵɵproperty("question", question_r5)("control", ctx_r2.getControl(question_r5.id))("formControlName", question_r5.id);
|
|
62
|
-
} }
|
|
63
|
-
function AgentResponseFormComponent_Conditional_0_Conditional_2_Conditional_3_Template(rf, ctx) { if (rf & 1) {
|
|
64
|
-
i0.ɵɵelementStart(0, "div", 10);
|
|
65
|
-
i0.ɵɵrepeaterCreate(1, AgentResponseFormComponent_Conditional_0_Conditional_2_Conditional_3_For_2_Template, 1, 3, "mj-form-question", 13, i0.ɵɵcomponentInstance().trackByQuestionId, true);
|
|
66
|
-
i0.ɵɵelementEnd();
|
|
67
|
-
} if (rf & 2) {
|
|
68
|
-
const ctx_r2 = i0.ɵɵnextContext(3);
|
|
69
|
-
i0.ɵɵadvance();
|
|
70
|
-
i0.ɵɵrepeater(ctx_r2.mainQuestions);
|
|
71
|
-
} }
|
|
72
|
-
function AgentResponseFormComponent_Conditional_0_Conditional_2_Conditional_5_For_1_Conditional_1_Conditional_1_Template(rf, ctx) { if (rf & 1) {
|
|
73
|
-
i0.ɵɵelement(0, "i", 6);
|
|
74
|
-
} if (rf & 2) {
|
|
75
|
-
const option_r7 = i0.ɵɵnextContext(2).$implicit;
|
|
76
|
-
i0.ɵɵclassMap(i0.ɵɵinterpolate1("fa ", option_r7.icon));
|
|
77
|
-
} }
|
|
78
|
-
function AgentResponseFormComponent_Conditional_0_Conditional_2_Conditional_5_For_1_Conditional_1_Template(rf, ctx) { if (rf & 1) {
|
|
79
|
-
i0.ɵɵelementStart(0, "span");
|
|
80
|
-
i0.ɵɵconditionalCreate(1, AgentResponseFormComponent_Conditional_0_Conditional_2_Conditional_5_For_1_Conditional_1_Conditional_1_Template, 1, 3, "i", 5);
|
|
81
|
-
i0.ɵɵtext(2);
|
|
82
|
-
i0.ɵɵelementEnd();
|
|
83
|
-
} if (rf & 2) {
|
|
84
|
-
const option_r7 = i0.ɵɵnextContext().$implicit;
|
|
85
|
-
const ctx_r2 = i0.ɵɵnextContext(4);
|
|
86
|
-
i0.ɵɵadvance();
|
|
87
|
-
i0.ɵɵconditional(ctx_r2.hasIcon(option_r7) ? 1 : -1);
|
|
88
|
-
i0.ɵɵadvance();
|
|
89
|
-
i0.ɵɵtextInterpolate1(" ", option_r7.label, " ");
|
|
90
|
-
} }
|
|
91
|
-
function AgentResponseFormComponent_Conditional_0_Conditional_2_Conditional_5_For_1_Conditional_2_Template(rf, ctx) { if (rf & 1) {
|
|
92
|
-
i0.ɵɵelementStart(0, "span");
|
|
93
|
-
i0.ɵɵelement(1, "span", 16);
|
|
94
|
-
i0.ɵɵelementEnd();
|
|
95
|
-
} }
|
|
96
|
-
function AgentResponseFormComponent_Conditional_0_Conditional_2_Conditional_5_For_1_Template(rf, ctx) { if (rf & 1) {
|
|
97
|
-
const _r6 = i0.ɵɵgetCurrentView();
|
|
98
|
-
i0.ɵɵelementStart(0, "button", 15);
|
|
99
|
-
i0.ɵɵlistener("click", function AgentResponseFormComponent_Conditional_0_Conditional_2_Conditional_5_For_1_Template_button_click_0_listener() { const option_r7 = i0.ɵɵrestoreView(_r6).$implicit; const ctx_r2 = i0.ɵɵnextContext(4); return i0.ɵɵresetView(ctx_r2.onFooterChoiceClick(option_r7.value)); });
|
|
100
|
-
i0.ɵɵconditionalCreate(1, AgentResponseFormComponent_Conditional_0_Conditional_2_Conditional_5_For_1_Conditional_1_Template, 3, 2, "span");
|
|
101
|
-
i0.ɵɵconditionalCreate(2, AgentResponseFormComponent_Conditional_0_Conditional_2_Conditional_5_For_1_Conditional_2_Template, 2, 0, "span");
|
|
102
|
-
i0.ɵɵelementEnd();
|
|
103
|
-
} if (rf & 2) {
|
|
104
|
-
const ctx_r2 = i0.ɵɵnextContext(4);
|
|
105
|
-
i0.ɵɵproperty("themeColor", "primary")("disabled", ctx_r2.disabled || ctx_r2.isSubmitting);
|
|
106
|
-
i0.ɵɵadvance();
|
|
107
|
-
i0.ɵɵconditional(!ctx_r2.isSubmitting ? 1 : -1);
|
|
108
|
-
i0.ɵɵadvance();
|
|
109
|
-
i0.ɵɵconditional(ctx_r2.isSubmitting ? 2 : -1);
|
|
110
|
-
} }
|
|
111
|
-
function AgentResponseFormComponent_Conditional_0_Conditional_2_Conditional_5_Template(rf, ctx) { if (rf & 1) {
|
|
112
|
-
i0.ɵɵrepeaterCreate(0, AgentResponseFormComponent_Conditional_0_Conditional_2_Conditional_5_For_1_Template, 3, 4, "button", 14, i0.ɵɵcomponentInstance().trackByValue, true);
|
|
113
|
-
} if (rf & 2) {
|
|
114
|
-
const ctx_r2 = i0.ɵɵnextContext(3);
|
|
115
|
-
i0.ɵɵrepeater(ctx_r2.getOptions(ctx_r2.footerChoiceQuestion));
|
|
116
|
-
} }
|
|
117
|
-
function AgentResponseFormComponent_Conditional_0_Conditional_2_Conditional_6_Conditional_1_Template(rf, ctx) { if (rf & 1) {
|
|
118
|
-
i0.ɵɵelementStart(0, "span");
|
|
119
|
-
i0.ɵɵelement(1, "i", 17);
|
|
120
|
-
i0.ɵɵtext(2);
|
|
121
|
-
i0.ɵɵelementEnd();
|
|
122
|
-
} if (rf & 2) {
|
|
123
|
-
const ctx_r2 = i0.ɵɵnextContext(4);
|
|
124
|
-
i0.ɵɵadvance(2);
|
|
125
|
-
i0.ɵɵtextInterpolate1(" ", ctx_r2.submitLabel, " ");
|
|
126
|
-
} }
|
|
127
|
-
function AgentResponseFormComponent_Conditional_0_Conditional_2_Conditional_6_Conditional_2_Template(rf, ctx) { if (rf & 1) {
|
|
128
|
-
i0.ɵɵelementStart(0, "span");
|
|
129
|
-
i0.ɵɵelement(1, "span", 16);
|
|
130
|
-
i0.ɵɵtext(2, " Submitting... ");
|
|
131
|
-
i0.ɵɵelementEnd();
|
|
132
|
-
} }
|
|
133
|
-
function AgentResponseFormComponent_Conditional_0_Conditional_2_Conditional_6_Template(rf, ctx) { if (rf & 1) {
|
|
134
|
-
i0.ɵɵelementStart(0, "button", 12);
|
|
135
|
-
i0.ɵɵconditionalCreate(1, AgentResponseFormComponent_Conditional_0_Conditional_2_Conditional_6_Conditional_1_Template, 3, 1, "span");
|
|
136
|
-
i0.ɵɵconditionalCreate(2, AgentResponseFormComponent_Conditional_0_Conditional_2_Conditional_6_Conditional_2_Template, 3, 0, "span");
|
|
137
|
-
i0.ɵɵelementEnd();
|
|
138
|
-
} if (rf & 2) {
|
|
139
|
-
const ctx_r2 = i0.ɵɵnextContext(3);
|
|
140
|
-
i0.ɵɵproperty("themeColor", "primary")("disabled", ctx_r2.disabled || ctx_r2.isSubmitting || ctx_r2.formGroup.invalid);
|
|
141
|
-
i0.ɵɵadvance();
|
|
142
|
-
i0.ɵɵconditional(!ctx_r2.isSubmitting ? 1 : -1);
|
|
143
|
-
i0.ɵɵadvance();
|
|
144
|
-
i0.ɵɵconditional(ctx_r2.isSubmitting ? 2 : -1);
|
|
145
|
-
} }
|
|
146
|
-
function AgentResponseFormComponent_Conditional_0_Conditional_2_Template(rf, ctx) { if (rf & 1) {
|
|
147
|
-
const _r4 = i0.ɵɵgetCurrentView();
|
|
148
|
-
i0.ɵɵelementStart(0, "form", 7);
|
|
149
|
-
i0.ɵɵlistener("ngSubmit", function AgentResponseFormComponent_Conditional_0_Conditional_2_Template_form_ngSubmit_0_listener() { i0.ɵɵrestoreView(_r4); const ctx_r2 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r2.onSubmit()); });
|
|
150
|
-
i0.ɵɵconditionalCreate(1, AgentResponseFormComponent_Conditional_0_Conditional_2_Conditional_1_Template, 2, 1, "h3", 8);
|
|
151
|
-
i0.ɵɵconditionalCreate(2, AgentResponseFormComponent_Conditional_0_Conditional_2_Conditional_2_Template, 2, 1, "p", 9);
|
|
152
|
-
i0.ɵɵconditionalCreate(3, AgentResponseFormComponent_Conditional_0_Conditional_2_Conditional_3_Template, 3, 0, "div", 10);
|
|
153
|
-
i0.ɵɵelementStart(4, "div", 11);
|
|
154
|
-
i0.ɵɵconditionalCreate(5, AgentResponseFormComponent_Conditional_0_Conditional_2_Conditional_5_Template, 2, 0);
|
|
155
|
-
i0.ɵɵconditionalCreate(6, AgentResponseFormComponent_Conditional_0_Conditional_2_Conditional_6_Template, 3, 4, "button", 12);
|
|
156
|
-
i0.ɵɵelementEnd()();
|
|
157
|
-
} if (rf & 2) {
|
|
158
|
-
const ctx_r2 = i0.ɵɵnextContext(2);
|
|
159
|
-
i0.ɵɵproperty("formGroup", ctx_r2.formGroup);
|
|
160
|
-
i0.ɵɵadvance();
|
|
161
|
-
i0.ɵɵconditional(ctx_r2.responseForm.title ? 1 : -1);
|
|
162
|
-
i0.ɵɵadvance();
|
|
163
|
-
i0.ɵɵconditional(ctx_r2.responseForm.description ? 2 : -1);
|
|
164
|
-
i0.ɵɵadvance();
|
|
165
|
-
i0.ɵɵconditional(ctx_r2.mainQuestions.length > 0 ? 3 : -1);
|
|
166
|
-
i0.ɵɵadvance(2);
|
|
167
|
-
i0.ɵɵconditional(ctx_r2.footerChoiceQuestion ? 5 : -1);
|
|
168
|
-
i0.ɵɵadvance();
|
|
169
|
-
i0.ɵɵconditional(ctx_r2.showSubmitButton ? 6 : -1);
|
|
170
|
-
} }
|
|
171
|
-
function AgentResponseFormComponent_Conditional_0_Template(rf, ctx) { if (rf & 1) {
|
|
172
|
-
i0.ɵɵelementStart(0, "div", 0);
|
|
173
|
-
i0.ɵɵconditionalCreate(1, AgentResponseFormComponent_Conditional_0_Conditional_1_Template, 3, 0, "div", 1);
|
|
174
|
-
i0.ɵɵconditionalCreate(2, AgentResponseFormComponent_Conditional_0_Conditional_2_Template, 7, 6, "form", 2);
|
|
175
|
-
i0.ɵɵelementEnd();
|
|
176
|
-
} if (rf & 2) {
|
|
177
|
-
const ctx_r2 = i0.ɵɵnextContext();
|
|
178
|
-
i0.ɵɵadvance();
|
|
179
|
-
i0.ɵɵconditional(ctx_r2.isSimpleChoice ? 1 : -1);
|
|
180
|
-
i0.ɵɵadvance();
|
|
181
|
-
i0.ɵɵconditional(!ctx_r2.isSimpleChoice ? 2 : -1);
|
|
182
|
-
} }
|
|
183
|
-
/**
|
|
184
|
-
* Component for displaying agent response forms with dynamic questions
|
|
185
|
-
* Handles both simple button choices and complex multi-question forms
|
|
186
|
-
*/
|
|
187
|
-
export class AgentResponseFormComponent {
|
|
188
|
-
cdr;
|
|
189
|
-
responseForm;
|
|
190
|
-
disabled = false;
|
|
191
|
-
isLastMessage = false;
|
|
192
|
-
isConversationOwner = false;
|
|
193
|
-
formSubmitted = new EventEmitter();
|
|
194
|
-
formGroup;
|
|
195
|
-
isSubmitting = false;
|
|
196
|
-
constructor(cdr) {
|
|
197
|
-
this.cdr = cdr;
|
|
198
|
-
}
|
|
199
|
-
ngOnInit() {
|
|
200
|
-
console.debug('AgentResponseForm ngOnInit:', {
|
|
201
|
-
hasResponseForm: !!this.responseForm,
|
|
202
|
-
responseForm: this.responseForm,
|
|
203
|
-
disabled: this.disabled,
|
|
204
|
-
isLastMessage: this.isLastMessage,
|
|
205
|
-
isConversationOwner: this.isConversationOwner,
|
|
206
|
-
isVisible: this.isVisible,
|
|
207
|
-
isSimpleChoice: this.isSimpleChoice
|
|
208
|
-
});
|
|
209
|
-
this.buildFormGroup();
|
|
210
|
-
}
|
|
211
|
-
/**
|
|
212
|
-
* Check if this is a simple choice (single question with buttongroup/radio, no title)
|
|
213
|
-
* Simple choices render as buttons only, complex forms render as full forms
|
|
214
|
-
*/
|
|
215
|
-
get isSimpleChoice() {
|
|
216
|
-
if (!this.responseForm)
|
|
217
|
-
return false;
|
|
218
|
-
return (this.responseForm.questions.length === 1 &&
|
|
219
|
-
!this.responseForm.title &&
|
|
220
|
-
this.isChoiceQuestion(this.responseForm.questions[0]));
|
|
221
|
-
}
|
|
222
|
-
/**
|
|
223
|
-
* Get the choice question that should be rendered in the footer (if any)
|
|
224
|
-
* Forms with a buttongroup/radio question have those buttons in the footer instead of Submit
|
|
225
|
-
*/
|
|
226
|
-
get footerChoiceQuestion() {
|
|
227
|
-
if (!this.responseForm || this.isSimpleChoice)
|
|
228
|
-
return null;
|
|
229
|
-
// Find the last buttongroup/radio question - it becomes the footer action
|
|
230
|
-
const choiceQuestions = this.responseForm.questions.filter(q => this.isChoiceQuestion(q));
|
|
231
|
-
return choiceQuestions.length > 0 ? choiceQuestions[choiceQuestions.length - 1] : null;
|
|
232
|
-
}
|
|
233
|
-
/**
|
|
234
|
-
* Get questions to render in the main form area (excludes footer choice question)
|
|
235
|
-
*/
|
|
236
|
-
get mainQuestions() {
|
|
237
|
-
if (!this.responseForm)
|
|
238
|
-
return [];
|
|
239
|
-
const footerChoice = this.footerChoiceQuestion;
|
|
240
|
-
if (!footerChoice)
|
|
241
|
-
return this.responseForm.questions;
|
|
242
|
-
return this.responseForm.questions.filter(q => q.id !== footerChoice.id);
|
|
243
|
-
}
|
|
244
|
-
/**
|
|
245
|
-
* Check if we should show the standard Submit button (no footer choice question)
|
|
246
|
-
*/
|
|
247
|
-
get showSubmitButton() {
|
|
248
|
-
return !this.footerChoiceQuestion;
|
|
249
|
-
}
|
|
250
|
-
/**
|
|
251
|
-
* Check if component should be visible
|
|
252
|
-
*/
|
|
253
|
-
get isVisible() {
|
|
254
|
-
return (this.isLastMessage &&
|
|
255
|
-
this.isConversationOwner &&
|
|
256
|
-
this.responseForm &&
|
|
257
|
-
this.responseForm.questions.length > 0);
|
|
258
|
-
}
|
|
259
|
-
/**
|
|
260
|
-
* Get submit button label
|
|
261
|
-
*/
|
|
262
|
-
get submitLabel() {
|
|
263
|
-
return this.responseForm.submitLabel || 'Submit';
|
|
264
|
-
}
|
|
265
|
-
/**
|
|
266
|
-
* Check if a question is a choice-based question
|
|
267
|
-
*/
|
|
268
|
-
isChoiceQuestion(question) {
|
|
269
|
-
const type = typeof question.type === 'string' ? question.type : question.type.type;
|
|
270
|
-
return ['buttongroup', 'radio'].includes(type);
|
|
271
|
-
}
|
|
272
|
-
/**
|
|
273
|
-
* Build the reactive form group from the response form definition
|
|
274
|
-
*/
|
|
275
|
-
buildFormGroup() {
|
|
276
|
-
const controls = {};
|
|
277
|
-
for (const question of this.responseForm.questions) {
|
|
278
|
-
const validators = [];
|
|
279
|
-
if (question.required) {
|
|
280
|
-
validators.push(Validators.required);
|
|
281
|
-
}
|
|
282
|
-
// Add email validator for email questions
|
|
283
|
-
const questionType = typeof question.type === 'string' ? question.type : question.type.type;
|
|
284
|
-
if (questionType === 'email') {
|
|
285
|
-
validators.push(Validators.email);
|
|
286
|
-
}
|
|
287
|
-
// Add min/max validators for number/currency questions
|
|
288
|
-
if (['number', 'currency'].includes(questionType) && typeof question.type === 'object') {
|
|
289
|
-
if ('min' in question.type && question.type.min != null) {
|
|
290
|
-
validators.push(Validators.min(question.type.min));
|
|
291
|
-
}
|
|
292
|
-
if ('max' in question.type && question.type.max != null) {
|
|
293
|
-
validators.push(Validators.max(question.type.max));
|
|
294
|
-
}
|
|
295
|
-
}
|
|
296
|
-
// Initialize value based on question type
|
|
297
|
-
let initialValue = question.defaultValue;
|
|
298
|
-
if (!initialValue) {
|
|
299
|
-
// For checkbox with multiple selection, initialize as empty array
|
|
300
|
-
if (questionType === 'checkbox' && typeof question.type === 'object' && 'multiple' in question.type && question.type.multiple) {
|
|
301
|
-
initialValue = [];
|
|
302
|
-
}
|
|
303
|
-
else {
|
|
304
|
-
initialValue = null;
|
|
305
|
-
}
|
|
306
|
-
}
|
|
307
|
-
controls[question.id] = new FormControl(initialValue, validators);
|
|
308
|
-
}
|
|
309
|
-
this.formGroup = new FormGroup(controls);
|
|
310
|
-
}
|
|
311
|
-
/**
|
|
312
|
-
* Get FormControl for a specific question
|
|
313
|
-
*/
|
|
314
|
-
getControl(questionId) {
|
|
315
|
-
return this.formGroup.get(questionId);
|
|
316
|
-
}
|
|
317
|
-
/**
|
|
318
|
-
* Handle simple choice button click (for single question forms)
|
|
319
|
-
*/
|
|
320
|
-
onSimpleChoiceClick(value) {
|
|
321
|
-
if (!this.disabled && !this.isSubmitting) {
|
|
322
|
-
const question = this.responseForm.questions[0];
|
|
323
|
-
this.isSubmitting = true;
|
|
324
|
-
this.formSubmitted.emit({ [question.id]: value });
|
|
325
|
-
// Reset submitting state after a short delay
|
|
326
|
-
setTimeout(() => {
|
|
327
|
-
this.isSubmitting = false;
|
|
328
|
-
this.cdr.detectChanges();
|
|
329
|
-
}, 1000);
|
|
330
|
-
}
|
|
331
|
-
}
|
|
332
|
-
/**
|
|
333
|
-
* Handle footer choice button click (for forms with choice buttons in footer)
|
|
334
|
-
* Submits the form with all field values plus the selected choice
|
|
335
|
-
*/
|
|
336
|
-
onFooterChoiceClick(value) {
|
|
337
|
-
if (!this.disabled && !this.isSubmitting && this.footerChoiceQuestion) {
|
|
338
|
-
// First validate any required fields in the main form
|
|
339
|
-
const mainControlKeys = this.mainQuestions.map(q => q.id);
|
|
340
|
-
let hasInvalidFields = false;
|
|
341
|
-
for (const key of mainControlKeys) {
|
|
342
|
-
const control = this.formGroup.get(key);
|
|
343
|
-
if (control?.invalid) {
|
|
344
|
-
control.markAsTouched();
|
|
345
|
-
hasInvalidFields = true;
|
|
346
|
-
}
|
|
347
|
-
}
|
|
348
|
-
if (hasInvalidFields) {
|
|
349
|
-
return;
|
|
350
|
-
}
|
|
351
|
-
this.isSubmitting = true;
|
|
352
|
-
// Gather all form values and add the choice value
|
|
353
|
-
const formData = { ...this.formGroup.value };
|
|
354
|
-
formData[this.footerChoiceQuestion.id] = value;
|
|
355
|
-
this.formSubmitted.emit(formData);
|
|
356
|
-
// Reset form and submitting state
|
|
357
|
-
Promise.resolve().then(() => {
|
|
358
|
-
this.formGroup.reset();
|
|
359
|
-
this.isSubmitting = false;
|
|
360
|
-
this.cdr.detectChanges();
|
|
361
|
-
});
|
|
362
|
-
}
|
|
363
|
-
}
|
|
364
|
-
/**
|
|
365
|
-
* Handle full form submission
|
|
366
|
-
*/
|
|
367
|
-
onSubmit() {
|
|
368
|
-
if (this.formGroup.invalid) {
|
|
369
|
-
// Mark all fields as touched to show validation errors
|
|
370
|
-
Object.keys(this.formGroup.controls).forEach(key => {
|
|
371
|
-
this.formGroup.controls[key].markAsTouched();
|
|
372
|
-
});
|
|
373
|
-
return;
|
|
374
|
-
}
|
|
375
|
-
if (!this.disabled && !this.isSubmitting) {
|
|
376
|
-
this.isSubmitting = true;
|
|
377
|
-
this.formSubmitted.emit(this.formGroup.value);
|
|
378
|
-
// Reset form and submitting state
|
|
379
|
-
Promise.resolve().then(() => {
|
|
380
|
-
this.formGroup.reset();
|
|
381
|
-
this.isSubmitting = false;
|
|
382
|
-
this.cdr.detectChanges();
|
|
383
|
-
});
|
|
384
|
-
}
|
|
385
|
-
}
|
|
386
|
-
/**
|
|
387
|
-
* Get options for a choice question (used in simple choice mode)
|
|
388
|
-
*/
|
|
389
|
-
getOptions(question) {
|
|
390
|
-
if (typeof question.type === 'object' && 'options' in question.type) {
|
|
391
|
-
return question.type.options;
|
|
392
|
-
}
|
|
393
|
-
return [];
|
|
394
|
-
}
|
|
395
|
-
/**
|
|
396
|
-
* Check if question has an icon
|
|
397
|
-
*/
|
|
398
|
-
hasIcon(option) {
|
|
399
|
-
return option && option.icon;
|
|
400
|
-
}
|
|
401
|
-
/**
|
|
402
|
-
* Track by function for questions list
|
|
403
|
-
*/
|
|
404
|
-
trackByQuestionId(index, question) {
|
|
405
|
-
return question.id;
|
|
406
|
-
}
|
|
407
|
-
/**
|
|
408
|
-
* Track by function for options list
|
|
409
|
-
*/
|
|
410
|
-
trackByValue(index, option) {
|
|
411
|
-
return option.value;
|
|
412
|
-
}
|
|
413
|
-
static ɵfac = function AgentResponseFormComponent_Factory(__ngFactoryType__) { return new (__ngFactoryType__ || AgentResponseFormComponent)(i0.ɵɵdirectiveInject(i0.ChangeDetectorRef)); };
|
|
414
|
-
static ɵcmp = /*@__PURE__*/ i0.ɵɵdefineComponent({ type: AgentResponseFormComponent, selectors: [["mj-agent-response-form"]], inputs: { responseForm: "responseForm", disabled: "disabled", isLastMessage: "isLastMessage", isConversationOwner: "isConversationOwner" }, outputs: { formSubmitted: "formSubmitted" }, standalone: false, decls: 1, vars: 1, consts: [[1, "agent-response-form"], [1, "simple-choice-buttons"], [1, "response-form", 3, "formGroup"], ["kendoButton", "", 1, "choice-button", 3, "disabled"], ["kendoButton", "", 1, "choice-button", 3, "click", "disabled"], ["aria-hidden", "true", 3, "class"], ["aria-hidden", "true"], [1, "response-form", 3, "ngSubmit", "formGroup"], [1, "form-title"], [1, "form-description"], [1, "form-questions"], [1, "form-actions"], ["kendoButton", "", "type", "submit", 1, "submit-button", 3, "themeColor", "disabled"], [3, "question", "control", "formControlName"], ["kendoButton", "", "type", "button", 1, "footer-choice-button", 3, "themeColor", "disabled"], ["kendoButton", "", "type", "button", 1, "footer-choice-button", 3, "click", "themeColor", "disabled"], [1, "k-icon", "k-i-loading"], ["aria-hidden", "true", 1, "fa", "fa-check"]], template: function AgentResponseFormComponent_Template(rf, ctx) { if (rf & 1) {
|
|
415
|
-
i0.ɵɵconditionalCreate(0, AgentResponseFormComponent_Conditional_0_Template, 3, 2, "div", 0);
|
|
416
|
-
} if (rf & 2) {
|
|
417
|
-
i0.ɵɵconditional(ctx.isVisible ? 0 : -1);
|
|
418
|
-
} }, dependencies: [i1.ɵNgNoValidate, i1.NgControlStatus, i1.NgControlStatusGroup, i1.FormGroupDirective, i1.FormControlName, i2.ButtonComponent, i3.FormQuestionComponent], styles: [".agent-response-form[_ngcontent-%COMP%] {\n margin-top: 16px;\n display: block;\n width: fit-content;\n max-width: 600px;\n}\n\n\n\n.simple-choice-buttons[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n gap: 8px;\n margin-top: 12px;\n}\n\n.choice-button[_ngcontent-%COMP%] {\n padding: 8px 16px;\n font-size: 14px;\n}\n\n.choice-button[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n margin-right: 6px;\n}\n\n\n\n.response-form[_ngcontent-%COMP%] {\n background: rgba(16, 185, 129, 0.03);\n border: 2px solid rgba(16, 185, 129, 0.3);\n border-radius: 12px;\n padding: 0;\n margin-top: 12px;\n box-shadow: 0 2px 8px rgba(16, 185, 129, 0.1);\n overflow: hidden;\n}\n\n.form-title[_ngcontent-%COMP%] {\n margin: 0;\n padding: 12px 16px;\n font-size: 14px;\n font-weight: 600;\n color: white;\n background: linear-gradient(135deg, #10b981 0%, #059669 100%);\n display: flex;\n align-items: center;\n gap: 8px;\n}\n\n.form-title[_ngcontent-%COMP%]::before {\n content: \"\\f044\";\n font-family: \"Font Awesome 6 Free\";\n font-weight: 900;\n font-size: 13px;\n opacity: 0.95;\n}\n\n.form-description[_ngcontent-%COMP%] {\n margin: 0;\n padding: 12px 16px;\n font-size: 13px;\n color: #059669;\n background: rgba(16, 185, 129, 0.08);\n border-bottom: 1px solid rgba(16, 185, 129, 0.15);\n font-style: italic;\n}\n\n.form-questions[_ngcontent-%COMP%] {\n padding: 16px;\n background: white;\n}\n\n.form-actions[_ngcontent-%COMP%] {\n display: flex;\n flex-wrap: wrap;\n gap: 8px;\n justify-content: flex-start;\n padding: 12px 16px;\n background: rgba(16, 185, 129, 0.05);\n border-top: 1px solid rgba(16, 185, 129, 0.15);\n}\n\n.submit-button[_ngcontent-%COMP%] {\n min-width: 120px;\n}\n\n\n\n.footer-choice-button[_ngcontent-%COMP%] {\n min-width: 120px;\n max-width: 100%;\n white-space: normal;\n text-align: left;\n line-height: 1.3;\n padding: 10px 16px;\n}\n\n.footer-choice-button[_ngcontent-%COMP%] i.fa[_ngcontent-%COMP%] {\n margin-right: 6px;\n flex-shrink: 0;\n}\n\n.footer-choice-button[_ngcontent-%COMP%] .k-icon[_ngcontent-%COMP%] {\n animation: _ngcontent-%COMP%_spin 1s linear infinite;\n}\n\n.submit-button[_ngcontent-%COMP%] i.fa[_ngcontent-%COMP%] {\n margin-right: 6px;\n}\n\n.submit-button[_ngcontent-%COMP%] .k-icon[_ngcontent-%COMP%] {\n margin-right: 6px;\n animation: _ngcontent-%COMP%_spin 1s linear infinite;\n}\n\n@keyframes _ngcontent-%COMP%_spin {\n 0% { transform: rotate(0deg); }\n 100% { transform: rotate(360deg); }\n}\n\n\n\n@media (max-width: 768px) {\n .agent-response-form[_ngcontent-%COMP%] {\n margin-top: 12px;\n }\n\n .response-form[_ngcontent-%COMP%] {\n border-radius: 10px;\n }\n\n .form-questions[_ngcontent-%COMP%] {\n padding: 12px;\n }\n\n .form-actions[_ngcontent-%COMP%] {\n padding: 10px 12px;\n }\n\n .simple-choice-buttons[_ngcontent-%COMP%] {\n gap: 8px;\n }\n\n .choice-button[_ngcontent-%COMP%] {\n padding: 10px 14px;\n font-size: 13px;\n }\n}\n\n@media (max-width: 480px) {\n .agent-response-form[_ngcontent-%COMP%] {\n margin-top: 10px;\n width: 100%;\n max-width: 100%;\n }\n\n .response-form[_ngcontent-%COMP%] {\n border-radius: 8px;\n border-width: 1.5px;\n }\n\n .form-title[_ngcontent-%COMP%] {\n font-size: 13px;\n padding: 10px 12px;\n }\n\n .form-description[_ngcontent-%COMP%] {\n font-size: 12px;\n padding: 10px 12px;\n }\n\n .form-questions[_ngcontent-%COMP%] {\n padding: 10px;\n }\n\n .form-actions[_ngcontent-%COMP%] {\n padding: 8px 10px;\n flex-direction: column;\n }\n\n .choice-button[_ngcontent-%COMP%] {\n width: 100%;\n min-height: 44px;\n padding: 12px 16px;\n font-size: 14px;\n }\n\n .footer-choice-button[_ngcontent-%COMP%] {\n width: 100%;\n min-height: 44px;\n font-size: 14px;\n }\n\n .submit-button[_ngcontent-%COMP%] {\n width: 100%;\n min-height: 44px;\n font-size: 13px;\n }\n}"] });
|
|
419
|
-
}
|
|
420
|
-
(() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(AgentResponseFormComponent, [{
|
|
421
|
-
type: Component,
|
|
422
|
-
args: [{ standalone: false, selector: 'mj-agent-response-form', template: "@if (isVisible) {\n <div class=\"agent-response-form\">\n <!-- Simple Choice Mode (single question, no title, buttongroup/radio) -->\n @if (isSimpleChoice) {\n <div class=\"simple-choice-buttons\">\n @for (option of getOptions(responseForm.questions[0]); track trackByValue($index, option)) {\n <button\n kendoButton\n [disabled]=\"disabled || isSubmitting\"\n (click)=\"onSimpleChoiceClick(option.value)\"\n class=\"choice-button\"\n >\n @if (hasIcon(option)) {\n <i class=\"fa {{ option.icon }}\" aria-hidden=\"true\"></i>\n }\n {{ option.label }}\n </button>\n }\n </div>\n }\n <!-- Full Form Mode (complex forms) -->\n @if (!isSimpleChoice) {\n <form [formGroup]=\"formGroup\" (ngSubmit)=\"onSubmit()\" class=\"response-form\">\n <!-- Form Title -->\n @if (responseForm.title) {\n <h3 class=\"form-title\">{{ responseForm.title }}</h3>\n }\n <!-- Form Description -->\n @if (responseForm.description) {\n <p class=\"form-description\">{{ responseForm.description }}</p>\n }\n <!-- Questions (excludes footer choice question) -->\n @if (mainQuestions.length > 0) {\n <div class=\"form-questions\">\n @for (question of mainQuestions; track trackByQuestionId($index, question)) {\n <mj-form-question\n [question]=\"question\"\n [control]=\"getControl(question.id)\"\n [formControlName]=\"question.id\"\n ></mj-form-question>\n }\n </div>\n }\n <!-- Footer Actions -->\n <div class=\"form-actions\">\n <!-- Footer Choice Buttons (replaces Submit when present) -->\n @if (footerChoiceQuestion) {\n @for (option of getOptions(footerChoiceQuestion); track trackByValue($index, option)) {\n <button\n kendoButton\n type=\"button\"\n [themeColor]=\"'primary'\"\n [disabled]=\"disabled || isSubmitting\"\n (click)=\"onFooterChoiceClick(option.value)\"\n class=\"footer-choice-button\"\n >\n @if (!isSubmitting) {\n <span>\n @if (hasIcon(option)) {\n <i class=\"fa {{ option.icon }}\" aria-hidden=\"true\"></i>\n }\n {{ option.label }}\n </span>\n }\n @if (isSubmitting) {\n <span>\n <span class=\"k-icon k-i-loading\"></span>\n </span>\n }\n </button>\n }\n }\n <!-- Standard Submit Button (when no footer choice) -->\n @if (showSubmitButton) {\n <button\n kendoButton\n type=\"submit\"\n [themeColor]=\"'primary'\"\n [disabled]=\"disabled || isSubmitting || formGroup.invalid\"\n class=\"submit-button\"\n >\n @if (!isSubmitting) {\n <span>\n <i class=\"fa fa-check\" aria-hidden=\"true\"></i>\n {{ submitLabel }}\n </span>\n }\n @if (isSubmitting) {\n <span>\n <span class=\"k-icon k-i-loading\"></span>\n Submitting...\n </span>\n }\n </button>\n }\n </div>\n </form>\n }\n </div>\n}\n", styles: [".agent-response-form {\n margin-top: 16px;\n display: block;\n width: fit-content;\n max-width: 600px;\n}\n\n/* Simple Choice Mode */\n.simple-choice-buttons {\n display: flex;\n flex-direction: column;\n gap: 8px;\n margin-top: 12px;\n}\n\n.choice-button {\n padding: 8px 16px;\n font-size: 14px;\n}\n\n.choice-button i {\n margin-right: 6px;\n}\n\n/* Full Form Mode - Styled to match response cards but clearly active */\n.response-form {\n background: rgba(16, 185, 129, 0.03);\n border: 2px solid rgba(16, 185, 129, 0.3);\n border-radius: 12px;\n padding: 0;\n margin-top: 12px;\n box-shadow: 0 2px 8px rgba(16, 185, 129, 0.1);\n overflow: hidden;\n}\n\n.form-title {\n margin: 0;\n padding: 12px 16px;\n font-size: 14px;\n font-weight: 600;\n color: white;\n background: linear-gradient(135deg, #10b981 0%, #059669 100%);\n display: flex;\n align-items: center;\n gap: 8px;\n}\n\n.form-title::before {\n content: \"\\f044\";\n font-family: \"Font Awesome 6 Free\";\n font-weight: 900;\n font-size: 13px;\n opacity: 0.95;\n}\n\n.form-description {\n margin: 0;\n padding: 12px 16px;\n font-size: 13px;\n color: #059669;\n background: rgba(16, 185, 129, 0.08);\n border-bottom: 1px solid rgba(16, 185, 129, 0.15);\n font-style: italic;\n}\n\n.form-questions {\n padding: 16px;\n background: white;\n}\n\n.form-actions {\n display: flex;\n flex-wrap: wrap;\n gap: 8px;\n justify-content: flex-start;\n padding: 12px 16px;\n background: rgba(16, 185, 129, 0.05);\n border-top: 1px solid rgba(16, 185, 129, 0.15);\n}\n\n.submit-button {\n min-width: 120px;\n}\n\n/* Footer choice buttons - horizontal on desktop with text wrapping */\n.footer-choice-button {\n min-width: 120px;\n max-width: 100%;\n white-space: normal;\n text-align: left;\n line-height: 1.3;\n padding: 10px 16px;\n}\n\n.footer-choice-button i.fa {\n margin-right: 6px;\n flex-shrink: 0;\n}\n\n.footer-choice-button .k-icon {\n animation: spin 1s linear infinite;\n}\n\n.submit-button i.fa {\n margin-right: 6px;\n}\n\n.submit-button .k-icon {\n margin-right: 6px;\n animation: spin 1s linear infinite;\n}\n\n@keyframes spin {\n 0% { transform: rotate(0deg); }\n 100% { transform: rotate(360deg); }\n}\n\n/* Responsive Design */\n@media (max-width: 768px) {\n .agent-response-form {\n margin-top: 12px;\n }\n\n .response-form {\n border-radius: 10px;\n }\n\n .form-questions {\n padding: 12px;\n }\n\n .form-actions {\n padding: 10px 12px;\n }\n\n .simple-choice-buttons {\n gap: 8px;\n }\n\n .choice-button {\n padding: 10px 14px;\n font-size: 13px;\n }\n}\n\n@media (max-width: 480px) {\n .agent-response-form {\n margin-top: 10px;\n width: 100%;\n max-width: 100%;\n }\n\n .response-form {\n border-radius: 8px;\n border-width: 1.5px;\n }\n\n .form-title {\n font-size: 13px;\n padding: 10px 12px;\n }\n\n .form-description {\n font-size: 12px;\n padding: 10px 12px;\n }\n\n .form-questions {\n padding: 10px;\n }\n\n .form-actions {\n padding: 8px 10px;\n flex-direction: column;\n }\n\n .choice-button {\n width: 100%;\n min-height: 44px;\n padding: 12px 16px;\n font-size: 14px;\n }\n\n .footer-choice-button {\n width: 100%;\n min-height: 44px;\n font-size: 14px;\n }\n\n .submit-button {\n width: 100%;\n min-height: 44px;\n font-size: 13px;\n }\n}\n"] }]
|
|
423
|
-
}], () => [{ type: i0.ChangeDetectorRef }], { responseForm: [{
|
|
424
|
-
type: Input
|
|
425
|
-
}], disabled: [{
|
|
426
|
-
type: Input
|
|
427
|
-
}], isLastMessage: [{
|
|
428
|
-
type: Input
|
|
429
|
-
}], isConversationOwner: [{
|
|
430
|
-
type: Input
|
|
431
|
-
}], formSubmitted: [{
|
|
432
|
-
type: Output
|
|
433
|
-
}] }); })();
|
|
434
|
-
(() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(AgentResponseFormComponent, { className: "AgentResponseFormComponent", filePath: "src/lib/components/message/agent-response-form.component.ts", lineNumber: 15 }); })();
|
|
435
|
-
//# sourceMappingURL=agent-response-form.component.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"agent-response-form.component.js","sourceRoot":"","sources":["../../../../src/lib/components/message/agent-response-form.component.ts","../../../../src/lib/components/message/agent-response-form.component.html"],"names":[],"mappings":"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","sourcesContent":["import { Component, Input, Output, EventEmitter, OnInit, ChangeDetectorRef } from '@angular/core';\nimport { FormGroup, FormControl, Validators } from '@angular/forms';\nimport { AgentResponseForm, FormQuestion } from '@memberjunction/ai-core-plus';\n\n/**\n * Component for displaying agent response forms with dynamic questions\n * Handles both simple button choices and complex multi-question forms\n */\n@Component({\n standalone: false,\n selector: 'mj-agent-response-form',\n templateUrl: './agent-response-form.component.html',\n styleUrls: ['./agent-response-form.component.css']\n})\nexport class AgentResponseFormComponent implements OnInit {\n @Input() responseForm!: AgentResponseForm;\n @Input() disabled: boolean = false;\n @Input() isLastMessage: boolean = false;\n @Input() isConversationOwner: boolean = false;\n\n @Output() formSubmitted = new EventEmitter<Record<string, any>>();\n\n public formGroup!: FormGroup;\n public isSubmitting: boolean = false;\n\n constructor(private cdr: ChangeDetectorRef) {}\n\n ngOnInit(): void {\n console.debug('AgentResponseForm ngOnInit:', {\n hasResponseForm: !!this.responseForm,\n responseForm: this.responseForm,\n disabled: this.disabled,\n isLastMessage: this.isLastMessage,\n isConversationOwner: this.isConversationOwner,\n isVisible: this.isVisible,\n isSimpleChoice: this.isSimpleChoice\n });\n this.buildFormGroup();\n }\n\n /**\n * Check if this is a simple choice (single question with buttongroup/radio, no title)\n * Simple choices render as buttons only, complex forms render as full forms\n */\n public get isSimpleChoice(): boolean {\n if (!this.responseForm) return false;\n\n return (\n this.responseForm.questions.length === 1 &&\n !this.responseForm.title &&\n this.isChoiceQuestion(this.responseForm.questions[0])\n );\n }\n\n /**\n * Get the choice question that should be rendered in the footer (if any)\n * Forms with a buttongroup/radio question have those buttons in the footer instead of Submit\n */\n public get footerChoiceQuestion(): FormQuestion | null {\n if (!this.responseForm || this.isSimpleChoice) return null;\n\n // Find the last buttongroup/radio question - it becomes the footer action\n const choiceQuestions = this.responseForm.questions.filter(q => this.isChoiceQuestion(q));\n return choiceQuestions.length > 0 ? choiceQuestions[choiceQuestions.length - 1] : null;\n }\n\n /**\n * Get questions to render in the main form area (excludes footer choice question)\n */\n public get mainQuestions(): FormQuestion[] {\n if (!this.responseForm) return [];\n\n const footerChoice = this.footerChoiceQuestion;\n if (!footerChoice) return this.responseForm.questions;\n\n return this.responseForm.questions.filter(q => q.id !== footerChoice.id);\n }\n\n /**\n * Check if we should show the standard Submit button (no footer choice question)\n */\n public get showSubmitButton(): boolean {\n return !this.footerChoiceQuestion;\n }\n\n /**\n * Check if component should be visible\n */\n public get isVisible(): boolean {\n return (\n this.isLastMessage &&\n this.isConversationOwner &&\n this.responseForm &&\n this.responseForm.questions.length > 0\n );\n }\n\n /**\n * Get submit button label\n */\n public get submitLabel(): string {\n return this.responseForm.submitLabel || 'Submit';\n }\n\n /**\n * Check if a question is a choice-based question\n */\n private isChoiceQuestion(question: FormQuestion): boolean {\n const type = typeof question.type === 'string' ? question.type : question.type.type;\n return ['buttongroup', 'radio'].includes(type);\n }\n\n /**\n * Build the reactive form group from the response form definition\n */\n private buildFormGroup(): void {\n const controls: Record<string, FormControl> = {};\n\n for (const question of this.responseForm.questions) {\n const validators = [];\n if (question.required) {\n validators.push(Validators.required);\n }\n\n // Add email validator for email questions\n const questionType = typeof question.type === 'string' ? question.type : question.type.type;\n if (questionType === 'email') {\n validators.push(Validators.email);\n }\n\n // Add min/max validators for number/currency questions\n if (['number', 'currency'].includes(questionType) && typeof question.type === 'object') {\n if ('min' in question.type && question.type.min != null) {\n validators.push(Validators.min(question.type.min as number));\n }\n if ('max' in question.type && question.type.max != null) {\n validators.push(Validators.max(question.type.max as number));\n }\n }\n\n // Initialize value based on question type\n let initialValue = question.defaultValue;\n if (!initialValue) {\n // For checkbox with multiple selection, initialize as empty array\n if (questionType === 'checkbox' && typeof question.type === 'object' && 'multiple' in question.type && question.type.multiple) {\n initialValue = [];\n } else {\n initialValue = null;\n }\n }\n\n controls[question.id] = new FormControl(initialValue, validators);\n }\n\n this.formGroup = new FormGroup(controls);\n }\n\n /**\n * Get FormControl for a specific question\n */\n public getControl(questionId: string): FormControl {\n return this.formGroup.get(questionId) as FormControl;\n }\n\n /**\n * Handle simple choice button click (for single question forms)\n */\n public onSimpleChoiceClick(value: any): void {\n if (!this.disabled && !this.isSubmitting) {\n const question = this.responseForm.questions[0];\n this.isSubmitting = true;\n this.formSubmitted.emit({ [question.id]: value });\n\n // Reset submitting state after a short delay\n setTimeout(() => {\n this.isSubmitting = false;\n this.cdr.detectChanges();\n }, 1000);\n }\n }\n\n /**\n * Handle footer choice button click (for forms with choice buttons in footer)\n * Submits the form with all field values plus the selected choice\n */\n public onFooterChoiceClick(value: any): void {\n if (!this.disabled && !this.isSubmitting && this.footerChoiceQuestion) {\n // First validate any required fields in the main form\n const mainControlKeys = this.mainQuestions.map(q => q.id);\n let hasInvalidFields = false;\n\n for (const key of mainControlKeys) {\n const control = this.formGroup.get(key);\n if (control?.invalid) {\n control.markAsTouched();\n hasInvalidFields = true;\n }\n }\n\n if (hasInvalidFields) {\n return;\n }\n\n this.isSubmitting = true;\n\n // Gather all form values and add the choice value\n const formData = { ...this.formGroup.value };\n formData[this.footerChoiceQuestion.id] = value;\n\n this.formSubmitted.emit(formData);\n\n // Reset form and submitting state\n Promise.resolve().then(() => {\n this.formGroup.reset();\n this.isSubmitting = false;\n this.cdr.detectChanges();\n });\n }\n }\n\n /**\n * Handle full form submission\n */\n public onSubmit(): void {\n if (this.formGroup.invalid) {\n // Mark all fields as touched to show validation errors\n Object.keys(this.formGroup.controls).forEach(key => {\n this.formGroup.controls[key].markAsTouched();\n });\n return;\n }\n\n if (!this.disabled && !this.isSubmitting) {\n this.isSubmitting = true;\n this.formSubmitted.emit(this.formGroup.value);\n\n // Reset form and submitting state\n Promise.resolve().then(() => {\n this.formGroup.reset();\n this.isSubmitting = false;\n this.cdr.detectChanges();\n });\n }\n }\n\n /**\n * Get options for a choice question (used in simple choice mode)\n */\n public getOptions(question: FormQuestion): any[] {\n if (typeof question.type === 'object' && 'options' in question.type) {\n return question.type.options;\n }\n return [];\n }\n\n /**\n * Check if question has an icon\n */\n public hasIcon(option: any): boolean {\n return option && option.icon;\n }\n\n /**\n * Track by function for questions list\n */\n public trackByQuestionId(index: number, question: FormQuestion): string {\n return question.id;\n }\n\n /**\n * Track by function for options list\n */\n public trackByValue(index: number, option: any): any {\n return option.value;\n }\n}\n","@if (isVisible) {\n <div class=\"agent-response-form\">\n <!-- Simple Choice Mode (single question, no title, buttongroup/radio) -->\n @if (isSimpleChoice) {\n <div class=\"simple-choice-buttons\">\n @for (option of getOptions(responseForm.questions[0]); track trackByValue($index, option)) {\n <button\n kendoButton\n [disabled]=\"disabled || isSubmitting\"\n (click)=\"onSimpleChoiceClick(option.value)\"\n class=\"choice-button\"\n >\n @if (hasIcon(option)) {\n <i class=\"fa {{ option.icon }}\" aria-hidden=\"true\"></i>\n }\n {{ option.label }}\n </button>\n }\n </div>\n }\n <!-- Full Form Mode (complex forms) -->\n @if (!isSimpleChoice) {\n <form [formGroup]=\"formGroup\" (ngSubmit)=\"onSubmit()\" class=\"response-form\">\n <!-- Form Title -->\n @if (responseForm.title) {\n <h3 class=\"form-title\">{{ responseForm.title }}</h3>\n }\n <!-- Form Description -->\n @if (responseForm.description) {\n <p class=\"form-description\">{{ responseForm.description }}</p>\n }\n <!-- Questions (excludes footer choice question) -->\n @if (mainQuestions.length > 0) {\n <div class=\"form-questions\">\n @for (question of mainQuestions; track trackByQuestionId($index, question)) {\n <mj-form-question\n [question]=\"question\"\n [control]=\"getControl(question.id)\"\n [formControlName]=\"question.id\"\n ></mj-form-question>\n }\n </div>\n }\n <!-- Footer Actions -->\n <div class=\"form-actions\">\n <!-- Footer Choice Buttons (replaces Submit when present) -->\n @if (footerChoiceQuestion) {\n @for (option of getOptions(footerChoiceQuestion); track trackByValue($index, option)) {\n <button\n kendoButton\n type=\"button\"\n [themeColor]=\"'primary'\"\n [disabled]=\"disabled || isSubmitting\"\n (click)=\"onFooterChoiceClick(option.value)\"\n class=\"footer-choice-button\"\n >\n @if (!isSubmitting) {\n <span>\n @if (hasIcon(option)) {\n <i class=\"fa {{ option.icon }}\" aria-hidden=\"true\"></i>\n }\n {{ option.label }}\n </span>\n }\n @if (isSubmitting) {\n <span>\n <span class=\"k-icon k-i-loading\"></span>\n </span>\n }\n </button>\n }\n }\n <!-- Standard Submit Button (when no footer choice) -->\n @if (showSubmitButton) {\n <button\n kendoButton\n type=\"submit\"\n [themeColor]=\"'primary'\"\n [disabled]=\"disabled || isSubmitting || formGroup.invalid\"\n class=\"submit-button\"\n >\n @if (!isSubmitting) {\n <span>\n <i class=\"fa fa-check\" aria-hidden=\"true\"></i>\n {{ submitLabel }}\n </span>\n }\n @if (isSubmitting) {\n <span>\n <span class=\"k-icon k-i-loading\"></span>\n Submitting...\n </span>\n }\n </button>\n }\n </div>\n </form>\n }\n </div>\n}\n"]}
|
|
@@ -1,105 +0,0 @@
|
|
|
1
|
-
import { OnInit } from '@angular/core';
|
|
2
|
-
import { ControlValueAccessor, FormControl } from '@angular/forms';
|
|
3
|
-
import { FormQuestion, FormOption } from '@memberjunction/ai-core-plus';
|
|
4
|
-
import * as i0 from "@angular/core";
|
|
5
|
-
/**
|
|
6
|
-
* Component for rendering individual form questions with various input types
|
|
7
|
-
* Implements ControlValueAccessor for seamless integration with Angular forms
|
|
8
|
-
*/
|
|
9
|
-
export declare class FormQuestionComponent implements ControlValueAccessor, OnInit {
|
|
10
|
-
question: FormQuestion;
|
|
11
|
-
control: FormControl;
|
|
12
|
-
value: any;
|
|
13
|
-
disabled: boolean;
|
|
14
|
-
private onChange;
|
|
15
|
-
private onTouched;
|
|
16
|
-
ngOnInit(): void;
|
|
17
|
-
/**
|
|
18
|
-
* Get the question type (handles both simple string and complex types)
|
|
19
|
-
*/
|
|
20
|
-
get questionType(): string;
|
|
21
|
-
/**
|
|
22
|
-
* Check if this is a choice-based question (buttongroup, radio, dropdown, checkbox)
|
|
23
|
-
*/
|
|
24
|
-
get isChoiceQuestion(): boolean;
|
|
25
|
-
/**
|
|
26
|
-
* Get options for choice questions
|
|
27
|
-
*/
|
|
28
|
-
get options(): FormOption[];
|
|
29
|
-
/**
|
|
30
|
-
* Check if multiple selections are allowed (for checkbox type)
|
|
31
|
-
*/
|
|
32
|
-
get allowMultiple(): boolean;
|
|
33
|
-
/**
|
|
34
|
-
* Get CSS class for field width based on widthHint or intelligent defaults
|
|
35
|
-
*/
|
|
36
|
-
get widthClass(): string;
|
|
37
|
-
/**
|
|
38
|
-
* Get placeholder text for text inputs
|
|
39
|
-
*/
|
|
40
|
-
get placeholder(): string | undefined;
|
|
41
|
-
/**
|
|
42
|
-
* Get min value for number/currency inputs
|
|
43
|
-
*/
|
|
44
|
-
get min(): number | undefined;
|
|
45
|
-
/**
|
|
46
|
-
* Get max value for number/currency inputs
|
|
47
|
-
*/
|
|
48
|
-
get max(): number | undefined;
|
|
49
|
-
/**
|
|
50
|
-
* Get step value for number/currency inputs
|
|
51
|
-
*/
|
|
52
|
-
get step(): number | undefined;
|
|
53
|
-
/**
|
|
54
|
-
* Get prefix for currency inputs
|
|
55
|
-
*/
|
|
56
|
-
get prefix(): string | undefined;
|
|
57
|
-
/**
|
|
58
|
-
* Get suffix for currency inputs
|
|
59
|
-
*/
|
|
60
|
-
get suffix(): string | undefined;
|
|
61
|
-
/**
|
|
62
|
-
* Handle value changes
|
|
63
|
-
*/
|
|
64
|
-
onValueChange(newValue: any): void;
|
|
65
|
-
/**
|
|
66
|
-
* Handle checkbox toggle for multiple selection
|
|
67
|
-
*/
|
|
68
|
-
toggleCheckbox(option: FormOption): void;
|
|
69
|
-
/**
|
|
70
|
-
* Check if a checkbox option is selected
|
|
71
|
-
*/
|
|
72
|
-
isChecked(option: FormOption): boolean;
|
|
73
|
-
writeValue(value: any): void;
|
|
74
|
-
registerOnChange(fn: any): void;
|
|
75
|
-
registerOnTouched(fn: any): void;
|
|
76
|
-
setDisabledState(isDisabled: boolean): void;
|
|
77
|
-
/**
|
|
78
|
-
* Debug handler for dropdown changes
|
|
79
|
-
*/
|
|
80
|
-
onDropdownChange(value: any): void;
|
|
81
|
-
/**
|
|
82
|
-
* Get slider configuration
|
|
83
|
-
*/
|
|
84
|
-
getSliderConfig(): {
|
|
85
|
-
min: number;
|
|
86
|
-
max: number;
|
|
87
|
-
step?: number;
|
|
88
|
-
suffix?: string;
|
|
89
|
-
};
|
|
90
|
-
/**
|
|
91
|
-
* Handle date range start date change
|
|
92
|
-
*/
|
|
93
|
-
onDateRangeStartChange(value: Date): void;
|
|
94
|
-
/**
|
|
95
|
-
* Handle date range end date change
|
|
96
|
-
*/
|
|
97
|
-
onDateRangeEndChange(value: Date): void;
|
|
98
|
-
/**
|
|
99
|
-
* Track by function for options list
|
|
100
|
-
*/
|
|
101
|
-
trackByValue(index: number, option: FormOption): any;
|
|
102
|
-
static ɵfac: i0.ɵɵFactoryDeclaration<FormQuestionComponent, never>;
|
|
103
|
-
static ɵcmp: i0.ɵɵComponentDeclaration<FormQuestionComponent, "mj-form-question", never, { "question": { "alias": "question"; "required": false; }; "control": { "alias": "control"; "required": false; }; }, {}, never, never, false, never>;
|
|
104
|
-
}
|
|
105
|
-
//# sourceMappingURL=form-question.component.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"form-question.component.d.ts","sourceRoot":"","sources":["../../../../src/lib/components/message/form-question.component.ts"],"names":[],"mappings":"AAAA,OAAO,EAAgC,MAAM,EAAE,MAAM,eAAe,CAAC;AACrE,OAAO,EAAE,oBAAoB,EAAqB,WAAW,EAAE,MAAM,gBAAgB,CAAC;AACtF,OAAO,EAAE,YAAY,EAAE,UAAU,EAAE,MAAM,8BAA8B,CAAC;;AAExE;;;GAGG;AACH,qBAaa,qBAAsB,YAAW,oBAAoB,EAAE,MAAM;IAC/D,QAAQ,EAAG,YAAY,CAAC;IACxB,OAAO,EAAG,WAAW,CAAC;IAExB,KAAK,EAAE,GAAG,CAAQ;IAClB,QAAQ,EAAE,OAAO,CAAS;IAEjC,OAAO,CAAC,QAAQ,CAAkC;IAClD,OAAO,CAAC,SAAS,CAAwB;IAEzC,QAAQ,IAAI,IAAI;IAahB;;OAEG;IACH,IAAW,YAAY,IAAI,MAAM,CAIhC;IAED;;OAEG;IACH,IAAW,gBAAgB,IAAI,OAAO,CAGrC;IAED;;OAEG;IACH,IAAW,OAAO,IAAI,UAAU,EAAE,CAKjC;IAED;;OAEG;IACH,IAAW,aAAa,IAAI,OAAO,CAGlC;IAED;;OAEG;IACH,IAAW,UAAU,IAAI,MAAM,CAoC9B;IAED;;OAEG;IACH,IAAW,WAAW,IAAI,MAAM,GAAG,SAAS,CAK3C;IAED;;OAEG;IACH,IAAW,GAAG,IAAI,MAAM,GAAG,SAAS,CAKnC;IAED;;OAEG;IACH,IAAW,GAAG,IAAI,MAAM,GAAG,SAAS,CAKnC;IAED;;OAEG;IACH,IAAW,IAAI,IAAI,MAAM,GAAG,SAAS,CAKpC;IAED;;OAEG;IACH,IAAW,MAAM,IAAI,MAAM,GAAG,SAAS,CAKtC;IAED;;OAEG;IACH,IAAW,MAAM,IAAI,MAAM,GAAG,SAAS,CAKtC;IAED;;OAEG;IACI,aAAa,CAAC,QAAQ,EAAE,GAAG,GAAG,IAAI;IAMzC;;OAEG;IACI,cAAc,CAAC,MAAM,EAAE,UAAU,GAAG,IAAI;IAsB/C;;OAEG;IACI,SAAS,CAAC,MAAM,EAAE,UAAU,GAAG,OAAO;IAS7C,UAAU,CAAC,KAAK,EAAE,GAAG,GAAG,IAAI;IAI5B,gBAAgB,CAAC,EAAE,EAAE,GAAG,GAAG,IAAI;IAI/B,iBAAiB,CAAC,EAAE,EAAE,GAAG,GAAG,IAAI;IAIhC,gBAAgB,CAAC,UAAU,EAAE,OAAO,GAAG,IAAI;IAI3C;;OAEG;IACI,gBAAgB,CAAC,KAAK,EAAE,GAAG,GAAG,IAAI;IASzC;;OAEG;IACI,eAAe,IAAI;QAAE,GAAG,EAAE,MAAM,CAAC;QAAC,GAAG,EAAE,MAAM,CAAC;QAAC,IAAI,CAAC,EAAE,MAAM,CAAC;QAAC,MAAM,CAAC,EAAE,MAAM,CAAA;KAAE;IAYtF;;OAEG;IACI,sBAAsB,CAAC,KAAK,EAAE,IAAI,GAAG,IAAI;IAKhD;;OAEG;IACI,oBAAoB,CAAC,KAAK,EAAE,IAAI,GAAG,IAAI;IAK9C;;OAEG;IACI,YAAY,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,UAAU,GAAG,GAAG;yCA3QhD,qBAAqB;2CAArB,qBAAqB;CA8QjC"}
|