@memberjunction/ng-chat 6.1.0-edge.4 → 6.1.0-edge.6
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.
|
@@ -124,7 +124,7 @@ function ChatComponent_Conditional_17_Template(rf, ctx) { if (rf & 1) {
|
|
|
124
124
|
i0.ɵɵelementStart(0, "div", 26);
|
|
125
125
|
i0.ɵɵlistener("click", function ChatComponent_Conditional_17_Template_div_click_0_listener() { i0.ɵɵrestoreView(_r8); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.showingClearAllDialog = false); });
|
|
126
126
|
i0.ɵɵelementStart(1, "div", 27);
|
|
127
|
-
i0.ɵɵlistener("click", function ChatComponent_Conditional_17_Template_div_click_1_listener($event) {
|
|
127
|
+
i0.ɵɵlistener("click", function ChatComponent_Conditional_17_Template_div_click_1_listener($event) { return $event.stopPropagation(); });
|
|
128
128
|
i0.ɵɵelementStart(2, "p", 28);
|
|
129
129
|
i0.ɵɵtext(3);
|
|
130
130
|
i0.ɵɵelementEnd();
|
|
@@ -336,7 +336,7 @@ export class ChatComponent {
|
|
|
336
336
|
i0.ɵɵelementStart(0, "div", 2);
|
|
337
337
|
i0.ɵɵconditionalCreate(1, ChatComponent_Conditional_1_Template, 12, 5, "div", 3);
|
|
338
338
|
i0.ɵɵelementStart(2, "div", 4, 0);
|
|
339
|
-
i0.ɵɵlistener("scroll", function ChatComponent_Template_div_scroll_2_listener() {
|
|
339
|
+
i0.ɵɵlistener("scroll", function ChatComponent_Template_div_scroll_2_listener() { return ctx.handleCheckScroll(); });
|
|
340
340
|
i0.ɵɵelementStart(4, "span");
|
|
341
341
|
i0.ɵɵtext(5);
|
|
342
342
|
i0.ɵɵelementEnd()();
|
|
@@ -344,15 +344,15 @@ export class ChatComponent {
|
|
|
344
344
|
i0.ɵɵconditionalCreate(7, ChatComponent_Conditional_7_Template, 6, 0, "div", 6);
|
|
345
345
|
i0.ɵɵelementStart(8, "div", 7)(9, "div", 8)(10, "textarea", 9, 1);
|
|
346
346
|
i0.ɵɵtwoWayListener("ngModelChange", function ChatComponent_Template_textarea_ngModelChange_10_listener($event) { i0.ɵɵrestoreView(_r1); i0.ɵɵtwoWayBindingSet(ctx.currentMessage, $event) || (ctx.currentMessage = $event); return i0.ɵɵresetView($event); });
|
|
347
|
-
i0.ɵɵlistener("input", function ChatComponent_Template_textarea_input_10_listener($event) {
|
|
347
|
+
i0.ɵɵlistener("input", function ChatComponent_Template_textarea_input_10_listener($event) { return ctx.handleInputChange($event); })("keyup.enter", function ChatComponent_Template_textarea_keyup_enter_10_listener() { return ctx.SendCurrentMessage(); });
|
|
348
348
|
i0.ɵɵtext(12, " ");
|
|
349
349
|
i0.ɵɵelementEnd()();
|
|
350
350
|
i0.ɵɵelementStart(13, "button", 10);
|
|
351
|
-
i0.ɵɵlistener("click", function ChatComponent_Template_button_click_13_listener() {
|
|
351
|
+
i0.ɵɵlistener("click", function ChatComponent_Template_button_click_13_listener() { return ctx.showingClearAllDialog = true; });
|
|
352
352
|
i0.ɵɵelement(14, "i", 11);
|
|
353
353
|
i0.ɵɵelementEnd();
|
|
354
354
|
i0.ɵɵelementStart(15, "button", 12);
|
|
355
|
-
i0.ɵɵlistener("click", function ChatComponent_Template_button_click_15_listener() {
|
|
355
|
+
i0.ɵɵlistener("click", function ChatComponent_Template_button_click_15_listener() { return ctx.SendCurrentMessage(); });
|
|
356
356
|
i0.ɵɵelement(16, "i", 13);
|
|
357
357
|
i0.ɵɵelementEnd()()();
|
|
358
358
|
i0.ɵɵconditionalCreate(17, ChatComponent_Conditional_17_Template, 9, 1, "div", 14);
|
|
@@ -374,7 +374,7 @@ export class ChatComponent {
|
|
|
374
374
|
i0.ɵɵproperty("disabled", !ctx.InternalAllowSend || ctx.currentMessage.length === 0 || ctx.ShowWaitingIndicator);
|
|
375
375
|
i0.ɵɵadvance(2);
|
|
376
376
|
i0.ɵɵconditional(ctx.showingClearAllDialog ? 17 : -1);
|
|
377
|
-
} }, dependencies: [i2.DefaultValueAccessor, i2.NgControlStatus, i2.NgModel], styles: [".loader[_ngcontent-%COMP%] {\n position: absolute;\n left: 0px;\n}\n\n.chat-wrapper[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n position: relative; \n\n}\n\n.chat-messages[_ngcontent-%COMP%] {\n overflow-y: auto; \n\n overflow-x: hidden; \n\n \n\n margin-bottom: 5px;\n\n margin-top: 2px; \n\n\n flex: 1;\n}\n\n\n\n.chat-messages[_ngcontent-%COMP%]::-webkit-scrollbar {\n width: 0;\n background: transparent; \n\n}\n\n\n\n.chat-messages[_ngcontent-%COMP%]:hover::-webkit-scrollbar {\n width: 12px; \n\n background-color: var(--mj-bg-surface-sunken); \n\n\n}\n\n\n\n.chat-messages[_ngcontent-%COMP%]:hover::-webkit-scrollbar-thumb {\n background-color: var(--mj-text-muted); \n\n opacity: 0.5; \n\n}\n\n\n\n.chat-messages[_ngcontent-%COMP%]:hover::-webkit-scrollbar-thumb {\n border-radius: 10px;\n}\n\n\n\n.chat-messages[_ngcontent-%COMP%]:hover::-webkit-scrollbar-thumb:hover {\n background: var(--mj-text-secondary); \n\n}\n\n\n.chat-messages[_ngcontent-%COMP%] {\n scrollbar-width: thin; \n\n scrollbar-color: var(--mj-text-muted) var(--mj-bg-surface-sunken); \n\n}\n \n\n\n\n.chat-input-area[_ngcontent-%COMP%] {\n background: var(--mj-bg-surface-card);\n display: flex;\n justify-content: center;\n align-items: center;\n padding-top: 12px;\n min-height: 35px;\n margin-bottom: 15px;\n}\n.chat-input-area[_ngcontent-%COMP%] > button[_ngcontent-%COMP%] {\n vertical-align: top;\n width: 30px;\n height: 30px;\n margin-top: 3px;\n border-radius: 12px;\n}\n.chat-input-area[_ngcontent-%COMP%] > button[_ngcontent-%COMP%]:first-of-type {\n margin-left: -40px;\n}\n.chat-input-area[_ngcontent-%COMP%] > button[_ngcontent-%COMP%]:last-child {\n margin-left: -65px;\n}\n\n.text-area-wrapper[_ngcontent-%COMP%] {\n padding: 3px;\n border: solid 1px color-mix(in srgb, var(--mj-text-primary) 8%, transparent);\n border-radius: 15px;\n\n margin-top: 4px;\n margin-right: -1px;\n min-height: 42px;\n max-height: 100%; \n\n\n overflow: hidden; \n align-items: center;\n\n \n\n max-width: 710px; \n width: 75%; \n\n padding-right: 90px; \n\n} \n.text-area-wrapper[_ngcontent-%COMP%] > textarea[_ngcontent-%COMP%] {\n border: 0;\n outline: 0;\n resize: none;\n\n min-height: 20px; \n\n\n width: 100%;\n overflow-y: hidden; \n\n\n font-family: S\u00F6hne, ui-sans-serif, system-ui, -apple-system, \"Segoe UI\", Roboto, Ubuntu, Cantarell, \"Noto Sans\", sans-serif, \"Helvetica Neue\", Arial, \"Apple Color Emoji\", \"Segoe UI Emoji\", \"Segoe UI Symbol\", \"Noto Color Emoji\";\n font-size: 1rem;\n\n margin-left: 7px;\n margin-top: 7px;\n margin-bottom: 5px;\n}\n\n.text-area-wrapper[_ngcontent-%COMP%] > textarea[_ngcontent-%COMP%]:disabled {\n background-color: var(--mj-bg-surface-card);\n}\n\n\n .chat-message-wrap {\n display: flex;\n align-items: flex-start; \n\n margin-bottom: 10px;\n margin-right: 10px;\n}\n\n .chat-message-image {\n margin-top: 12px;\n font-size: 24px; \n\n margin-right: 10px; \n\n width: 50px;\n flex-shrink: 0; \n \n}\n\n\n\n .chat-message {\n padding-left: 7px;\n padding-right: 7px;\n margin-bottom: 10px;\n border-radius: 5px;\n background-color: var(--mj-bg-surface-sunken);\n box-shadow: var(--mj-shadow-sm);\n word-wrap: break-word;\n}\n\n .chat-message-ai {\n background-color: color-mix(in srgb, var(--mj-brand-primary) 5%, var(--mj-bg-surface));\n}\n\n.scroll-to-bottom[_ngcontent-%COMP%] {\n position: absolute; \n\n left: 50%; \n\n transform: translateX(-50%); \n\n bottom: 100px; \n\n z-index: 1000; \n\n border-radius: 50%;\n width: 35px;\n height: 35px;\n cursor: pointer;\n display: flex;\n align-items: center;\n justify-content: center;\n font-size: 22px;\n background-color: var(--mj-bg-surface-sunken);\n box-shadow: var(--mj-shadow-md); \n\n cursor: pointer;\n}\n\n\n\n\n\n.welcome-wrapper[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n justify-content: center;\n align-items: center;\n height: 100%;\n width: 100%;\n overflow: hidden;\n}\n\n.welcome-message[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n text-align: center;\n overflow: hidden;\n height: 100%;\n}\n\n\n.welcome-message[_ngcontent-%COMP%] img[_ngcontent-%COMP%] {\n width: 120px;\n height: 50px;\n margin-bottom: 20px; \n\n}\n\n.welcome-header-text[_ngcontent-%COMP%] {\n font-size: larger;\n font-weight: bold;\n}\n\n\n\n.welcome-suggested-questions[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n justify-content: center;\n align-content: center;\n}\n.welcome-suggested-questions-col[_ngcontent-%COMP%] {\n display: flex;\n}\n\n\n\n.welcome-question[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column; \n\n align-items: left;;\n width: 300px; \n justify-content: space-between;\n margin: 5px; \n\n border: solid 1px color-mix(in srgb, var(--mj-text-primary) 8%, transparent);\n border-radius: 15px;\n padding: 10px;\n cursor: pointer;\n}\n\n.welcome-question[_ngcontent-%COMP%]:hover {\n background-color: color-mix(in srgb, var(--mj-text-primary) 5%, transparent);\n}\n\n\n.welcome-question-header[_ngcontent-%COMP%] {\n font-size: 12pt;\n font-weight: bold;\n display: block; \n\n}\n\n\n\n.welcome-question[_ngcontent-%COMP%] span[_ngcontent-%COMP%]:not(.welcome-question-header) {\n font-weight: normal;\n font-size: 10pt;\n}\n\n\n\n\n.chat-action-btn[_ngcontent-%COMP%] {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n width: 30px;\n height: 30px;\n border: 1px solid var(--mj-border-default);\n border-radius: 50%;\n background: var(--mj-bg-surface);\n color: var(--mj-text-secondary);\n font-size: 13px;\n cursor: pointer;\n transition: all 0.15s ease;\n padding: 0;\n}\n\n.chat-action-btn[_ngcontent-%COMP%]:hover:not(:disabled) {\n background: var(--mj-bg-surface-hover);\n color: var(--mj-text-primary);\n border-color: var(--mj-border-strong);\n}\n\n.chat-action-btn[_ngcontent-%COMP%]:disabled {\n opacity: 0.4;\n cursor: not-allowed;\n}\n\n.chat-send-btn[_ngcontent-%COMP%] {\n background: var(--mj-brand-primary);\n border-color: var(--mj-brand-primary);\n color: var(--mj-text-inverse);\n}\n\n.chat-send-btn[_ngcontent-%COMP%]:hover:not(:disabled) {\n background: var(--mj-brand-primary-hover);\n border-color: var(--mj-brand-primary-hover);\n color: var(--mj-text-inverse);\n}\n\n\n\n\n.chat-dialog-overlay[_ngcontent-%COMP%] {\n position: fixed;\n inset: 0;\n background: var(--mj-bg-overlay);\n display: flex;\n align-items: center;\n justify-content: center;\n z-index: 10000;\n}\n\n.chat-dialog[_ngcontent-%COMP%] {\n background: var(--mj-bg-surface);\n border: 1px solid var(--mj-border-default);\n border-radius: 10px;\n padding: 24px;\n min-width: 280px;\n max-width: 400px;\n box-shadow: 0 8px 32px color-mix(in srgb, var(--mj-text-primary) 15%, transparent);\n}\n\n.chat-dialog-message[_ngcontent-%COMP%] {\n margin: 0 0 20px 0;\n font-size: 14px;\n color: var(--mj-text-primary);\n line-height: 1.5;\n}\n\n.chat-dialog-actions[_ngcontent-%COMP%] {\n display: flex;\n gap: 8px;\n}\n\n.chat-dialog-btn[_ngcontent-%COMP%] {\n padding: 8px 20px;\n border: 1px solid var(--mj-border-default);\n border-radius: 6px;\n background: var(--mj-bg-surface);\n color: var(--mj-text-secondary);\n font-size: 13px;\n font-weight: 500;\n cursor: pointer;\n transition: all 0.15s ease;\n}\n\n.chat-dialog-btn[_ngcontent-%COMP%]:hover {\n background: var(--mj-bg-surface-hover);\n}\n\n.chat-dialog-btn-primary[_ngcontent-%COMP%] {\n background: var(--mj-brand-primary);\n border-color: var(--mj-brand-primary);\n color: var(--mj-text-inverse);\n}\n\n.chat-dialog-btn-primary[_ngcontent-%COMP%]:hover {\n background: var(--mj-brand-primary-hover);\n}\n\n\n\n\n\n\n\n\n.typing-indicator[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 4px;\n padding: 8px 16px;\n margin: 4px 0;\n}\n\n.typing-dot[_ngcontent-%COMP%] {\n width: 6px;\n height: 6px;\n border-radius: 50%;\n background: var(--mj-brand-primary);\n animation: _ngcontent-%COMP%_typingBounce 1.4s infinite ease-in-out both;\n}\n\n.typing-dot[_ngcontent-%COMP%]:nth-child(1) { animation-delay: 0s; }\n.typing-dot[_ngcontent-%COMP%]:nth-child(2) { animation-delay: 0.16s; }\n.typing-dot[_ngcontent-%COMP%]:nth-child(3) { animation-delay: 0.32s; }\n\n@keyframes _ngcontent-%COMP%_typingBounce {\n 0%, 80%, 100% {\n transform: scale(0.6);\n opacity: 0.4;\n }\n 40% {\n transform: scale(1);\n opacity: 1;\n }\n}\n\n.typing-text[_ngcontent-%COMP%] {\n font-size: 0.78rem;\n color: var(--mj-text-muted);\n margin-left: 4px;\n}\n\n\n\n .chat-message pre {\n background: var(--mj-bg-surface-sunken);\n border: 1px solid var(--mj-border-subtle);\n border-radius: 8px;\n padding: 12px 16px;\n overflow-x: auto;\n margin: 8px 0;\n font-size: 0.85rem;\n line-height: 1.5;\n}\n\n .chat-message code {\n font-family: 'SF Mono', 'Fira Code', 'Fira Mono', 'Roboto Mono', monospace;\n font-size: 0.85em;\n}\n\n .chat-message p code {\n background: var(--mj-bg-surface-sunken);\n padding: 0.15em 0.4em;\n border-radius: 4px;\n font-size: 0.85em;\n}\n\n\n\n .chat-message-wrap {\n animation: _ngcontent-%COMP%_messageSlideIn 0.3s ease-out;\n}\n\n@keyframes _ngcontent-%COMP%_messageSlideIn {\n from {\n opacity: 0;\n transform: translateY(8px);\n }\n to {\n opacity: 1;\n transform: translateY(0);\n }\n}\n\n\n\n .chat-tool-execution {\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 8px 12px;\n background: color-mix(in srgb, var(--mj-brand-primary) 8%, var(--mj-bg-surface));\n border: 1px solid color-mix(in srgb, var(--mj-brand-primary) 20%, var(--mj-bg-surface));\n border-radius: 8px;\n margin: 4px 0;\n font-size: 0.82rem;\n color: var(--mj-text-secondary);\n}\n\n .chat-tool-execution i {\n color: var(--mj-brand-primary);\n}\n\n\n\n@media (max-width: 640px) {\n .chat-input-area[_ngcontent-%COMP%] {\n padding: 8px;\n margin-bottom: 8px;\n }\n\n .text-area-wrapper[_ngcontent-%COMP%] {\n width: 100%;\n max-width: none;\n padding-right: 70px;\n }\n\n .welcome-suggested-questions-col[_ngcontent-%COMP%] {\n flex-direction: column;\n }\n\n .welcome-question[_ngcontent-%COMP%] {\n width: 100%;\n }\n\n .chat-message-image {\n width: 32px;\n font-size: 18px;\n margin-right: 8px;\n }\n}"] });
|
|
377
|
+
} }, dependencies: [i2.DefaultValueAccessor, i2.NgControlStatus, i2.NgModel], styles: [".loader[_ngcontent-%COMP%] {\n position: absolute;\n left: 0px;\n}\n\n.chat-wrapper[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n position: relative; \n}\n\n.chat-messages[_ngcontent-%COMP%] {\n overflow-y: auto; \n overflow-x: hidden; \n \n margin-bottom: 5px;\n\n margin-top: 2px; \n\n flex: 1;\n}\n\n\n.chat-messages[_ngcontent-%COMP%]::-webkit-scrollbar {\n width: 0;\n background: transparent; \n}\n\n\n.chat-messages[_ngcontent-%COMP%]:hover::-webkit-scrollbar {\n width: 12px; \n background-color: var(--mj-bg-surface-sunken); \n\n}\n\n\n.chat-messages[_ngcontent-%COMP%]:hover::-webkit-scrollbar-thumb {\n background-color: var(--mj-text-muted); \n opacity: 0.5; \n}\n\n\n.chat-messages[_ngcontent-%COMP%]:hover::-webkit-scrollbar-thumb {\n border-radius: 10px;\n}\n\n\n.chat-messages[_ngcontent-%COMP%]:hover::-webkit-scrollbar-thumb:hover {\n background: var(--mj-text-secondary); \n}\n\n.chat-messages[_ngcontent-%COMP%] {\n scrollbar-width: thin; \n scrollbar-color: var(--mj-text-muted) var(--mj-bg-surface-sunken); \n}\n \n\n\n\n.chat-input-area[_ngcontent-%COMP%] {\n background: var(--mj-bg-surface-card);\n display: flex;\n justify-content: center;\n align-items: center;\n padding-top: 12px;\n min-height: 35px;\n margin-bottom: 15px;\n}\n.chat-input-area[_ngcontent-%COMP%] > button[_ngcontent-%COMP%] {\n vertical-align: top;\n width: 30px;\n height: 30px;\n margin-top: 3px;\n border-radius: 12px;\n}\n.chat-input-area[_ngcontent-%COMP%] > button[_ngcontent-%COMP%]:first-of-type {\n margin-left: -40px;\n}\n.chat-input-area[_ngcontent-%COMP%] > button[_ngcontent-%COMP%]:last-child {\n margin-left: -65px;\n}\n\n.text-area-wrapper[_ngcontent-%COMP%] {\n padding: 3px;\n border: solid 1px color-mix(in srgb, var(--mj-text-primary) 8%, transparent);\n border-radius: 15px;\n\n margin-top: 4px;\n margin-right: -1px;\n min-height: 42px;\n max-height: 100%; \n\n overflow: hidden; \n align-items: center;\n\n \n max-width: 710px; \n width: 75%; \n padding-right: 90px; \n} \n.text-area-wrapper[_ngcontent-%COMP%] > textarea[_ngcontent-%COMP%] {\n border: 0;\n outline: 0;\n resize: none;\n\n min-height: 20px; \n\n width: 100%;\n overflow-y: hidden; \n\n font-family: S\u00F6hne, ui-sans-serif, system-ui, -apple-system, \"Segoe UI\", Roboto, Ubuntu, Cantarell, \"Noto Sans\", sans-serif, \"Helvetica Neue\", Arial, \"Apple Color Emoji\", \"Segoe UI Emoji\", \"Segoe UI Symbol\", \"Noto Color Emoji\";\n font-size: 1rem;\n\n margin-left: 7px;\n margin-top: 7px;\n margin-bottom: 5px;\n}\n\n.text-area-wrapper[_ngcontent-%COMP%] > textarea[_ngcontent-%COMP%]:disabled {\n background-color: var(--mj-bg-surface-card);\n}\n\n\n .chat-message-wrap {\n display: flex;\n align-items: flex-start; \n margin-bottom: 10px;\n margin-right: 10px;\n}\n\n .chat-message-image {\n margin-top: 12px;\n font-size: 24px; \n margin-right: 10px; \n width: 50px;\n flex-shrink: 0; \n}\n\n\n .chat-message {\n padding-left: 7px;\n padding-right: 7px;\n margin-bottom: 10px;\n border-radius: 5px;\n background-color: var(--mj-bg-surface-sunken);\n box-shadow: var(--mj-shadow-sm);\n word-wrap: break-word;\n}\n\n .chat-message-ai {\n background-color: color-mix(in srgb, var(--mj-brand-primary) 5%, var(--mj-bg-surface));\n}\n\n.scroll-to-bottom[_ngcontent-%COMP%] {\n position: absolute; \n left: 50%; \n transform: translateX(-50%); \n bottom: 100px; \n z-index: 1000; \n border-radius: 50%;\n width: 35px;\n height: 35px;\n cursor: pointer;\n display: flex;\n align-items: center;\n justify-content: center;\n font-size: 22px;\n background-color: var(--mj-bg-surface-sunken);\n box-shadow: var(--mj-shadow-md); \n cursor: pointer;\n}\n\n\n\n\n.welcome-wrapper[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n justify-content: center;\n align-items: center;\n height: 100%;\n width: 100%;\n overflow: hidden;\n}\n\n.welcome-message[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n text-align: center;\n overflow: hidden;\n height: 100%;\n}\n\n\n.welcome-message[_ngcontent-%COMP%] img[_ngcontent-%COMP%] {\n width: 120px;\n height: 50px;\n margin-bottom: 20px; \n}\n\n.welcome-header-text[_ngcontent-%COMP%] {\n font-size: larger;\n font-weight: bold;\n}\n\n\n.welcome-suggested-questions[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n justify-content: center;\n align-content: center;\n}\n.welcome-suggested-questions-col[_ngcontent-%COMP%] {\n display: flex;\n}\n\n\n.welcome-question[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column; \n align-items: left;;\n width: 300px; \n justify-content: space-between;\n margin: 5px; \n border: solid 1px color-mix(in srgb, var(--mj-text-primary) 8%, transparent);\n border-radius: 15px;\n padding: 10px;\n cursor: pointer;\n}\n\n.welcome-question[_ngcontent-%COMP%]:hover {\n background-color: color-mix(in srgb, var(--mj-text-primary) 5%, transparent);\n}\n\n\n.welcome-question-header[_ngcontent-%COMP%] {\n font-size: 12pt;\n font-weight: bold;\n display: block; \n}\n\n\n.welcome-question[_ngcontent-%COMP%] span[_ngcontent-%COMP%]:not(.welcome-question-header) {\n font-weight: normal;\n font-size: 10pt;\n}\n\n\n\n.chat-action-btn[_ngcontent-%COMP%] {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n width: 30px;\n height: 30px;\n border: 1px solid var(--mj-border-default);\n border-radius: 50%;\n background: var(--mj-bg-surface);\n color: var(--mj-text-secondary);\n font-size: 13px;\n cursor: pointer;\n transition: all 0.15s ease;\n padding: 0;\n}\n\n.chat-action-btn[_ngcontent-%COMP%]:hover:not(:disabled) {\n background: var(--mj-bg-surface-hover);\n color: var(--mj-text-primary);\n border-color: var(--mj-border-strong);\n}\n\n.chat-action-btn[_ngcontent-%COMP%]:disabled {\n opacity: 0.4;\n cursor: not-allowed;\n}\n\n.chat-send-btn[_ngcontent-%COMP%] {\n background: var(--mj-brand-primary);\n border-color: var(--mj-brand-primary);\n color: var(--mj-text-inverse);\n}\n\n.chat-send-btn[_ngcontent-%COMP%]:hover:not(:disabled) {\n background: var(--mj-brand-primary-hover);\n border-color: var(--mj-brand-primary-hover);\n color: var(--mj-text-inverse);\n}\n\n\n\n.chat-dialog-overlay[_ngcontent-%COMP%] {\n position: fixed;\n inset: 0;\n background: var(--mj-bg-overlay);\n display: flex;\n align-items: center;\n justify-content: center;\n z-index: 10000;\n}\n\n.chat-dialog[_ngcontent-%COMP%] {\n background: var(--mj-bg-surface);\n border: 1px solid var(--mj-border-default);\n border-radius: 10px;\n padding: 24px;\n min-width: 280px;\n max-width: 400px;\n box-shadow: 0 8px 32px color-mix(in srgb, var(--mj-text-primary) 15%, transparent);\n}\n\n.chat-dialog-message[_ngcontent-%COMP%] {\n margin: 0 0 20px 0;\n font-size: 14px;\n color: var(--mj-text-primary);\n line-height: 1.5;\n}\n\n.chat-dialog-actions[_ngcontent-%COMP%] {\n display: flex;\n gap: 8px;\n}\n\n.chat-dialog-btn[_ngcontent-%COMP%] {\n padding: 8px 20px;\n border: 1px solid var(--mj-border-default);\n border-radius: 6px;\n background: var(--mj-bg-surface);\n color: var(--mj-text-secondary);\n font-size: 13px;\n font-weight: 500;\n cursor: pointer;\n transition: all 0.15s ease;\n}\n\n.chat-dialog-btn[_ngcontent-%COMP%]:hover {\n background: var(--mj-bg-surface-hover);\n}\n\n.chat-dialog-btn-primary[_ngcontent-%COMP%] {\n background: var(--mj-brand-primary);\n border-color: var(--mj-brand-primary);\n color: var(--mj-text-inverse);\n}\n\n.chat-dialog-btn-primary[_ngcontent-%COMP%]:hover {\n background: var(--mj-brand-primary-hover);\n}\n\n\n\n\n\n\n.typing-indicator[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 4px;\n padding: 8px 16px;\n margin: 4px 0;\n}\n\n.typing-dot[_ngcontent-%COMP%] {\n width: 6px;\n height: 6px;\n border-radius: 50%;\n background: var(--mj-brand-primary);\n animation: _ngcontent-%COMP%_typingBounce 1.4s infinite ease-in-out both;\n}\n\n.typing-dot[_ngcontent-%COMP%]:nth-child(1) { animation-delay: 0s; }\n.typing-dot[_ngcontent-%COMP%]:nth-child(2) { animation-delay: 0.16s; }\n.typing-dot[_ngcontent-%COMP%]:nth-child(3) { animation-delay: 0.32s; }\n\n@keyframes _ngcontent-%COMP%_typingBounce {\n 0%, 80%, 100% {\n transform: scale(0.6);\n opacity: 0.4;\n }\n 40% {\n transform: scale(1);\n opacity: 1;\n }\n}\n\n.typing-text[_ngcontent-%COMP%] {\n font-size: 0.78rem;\n color: var(--mj-text-muted);\n margin-left: 4px;\n}\n\n\n .chat-message pre {\n background: var(--mj-bg-surface-sunken);\n border: 1px solid var(--mj-border-subtle);\n border-radius: 8px;\n padding: 12px 16px;\n overflow-x: auto;\n margin: 8px 0;\n font-size: 0.85rem;\n line-height: 1.5;\n}\n\n .chat-message code {\n font-family: 'SF Mono', 'Fira Code', 'Fira Mono', 'Roboto Mono', monospace;\n font-size: 0.85em;\n}\n\n .chat-message p code {\n background: var(--mj-bg-surface-sunken);\n padding: 0.15em 0.4em;\n border-radius: 4px;\n font-size: 0.85em;\n}\n\n\n .chat-message-wrap {\n animation: _ngcontent-%COMP%_messageSlideIn 0.3s ease-out;\n}\n\n@keyframes _ngcontent-%COMP%_messageSlideIn {\n from {\n opacity: 0;\n transform: translateY(8px);\n }\n to {\n opacity: 1;\n transform: translateY(0);\n }\n}\n\n\n .chat-tool-execution {\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 8px 12px;\n background: color-mix(in srgb, var(--mj-brand-primary) 8%, var(--mj-bg-surface));\n border: 1px solid color-mix(in srgb, var(--mj-brand-primary) 20%, var(--mj-bg-surface));\n border-radius: 8px;\n margin: 4px 0;\n font-size: 0.82rem;\n color: var(--mj-text-secondary);\n}\n\n .chat-tool-execution i {\n color: var(--mj-brand-primary);\n}\n\n\n@media (max-width: 640px) {\n .chat-input-area[_ngcontent-%COMP%] {\n padding: 8px;\n margin-bottom: 8px;\n }\n\n .text-area-wrapper[_ngcontent-%COMP%] {\n width: 100%;\n max-width: none;\n padding-right: 70px;\n }\n\n .welcome-suggested-questions-col[_ngcontent-%COMP%] {\n flex-direction: column;\n }\n\n .welcome-question[_ngcontent-%COMP%] {\n width: 100%;\n }\n\n .chat-message-image {\n width: 32px;\n font-size: 18px;\n margin-right: 8px;\n }\n}"] });
|
|
378
378
|
}
|
|
379
379
|
(() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(ChatComponent, [{
|
|
380
380
|
type: Component,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"chat.component.js","sourceRoot":"","sources":["../../../src/lib/chat/chat.component.ts","../../../src/lib/chat/chat.component.html"],"names":[],"mappings":"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","sourcesContent":["import { AfterViewInit, ChangeDetectorRef, Component, ElementRef, EventEmitter, Input, Output, ViewChild } from '@angular/core';\nimport { MarkdownService } from '@memberjunction/ng-markdown';\nimport { LogError } from '@memberjunction/core'\n\n\nexport class ChatWelcomeQuestion {\n public topLine: string=\"\";\n public bottomLine: string=\"\";\n public prompt: string=\"\";\n}\nexport class ChatMessage {\n public message!: string;\n public senderName!: string;\n public senderType: 'user' | 'ai' = 'user';\n public id?: string | number | null;\n /** Optional: indicates a tool execution is in progress */\n public toolName?: string;\n /** Optional: indicates a thinking/processing state */\n public isThinking?: boolean;\n /** Timestamp when the message was created */\n public timestamp: Date = new Date();\n\n constructor(message: string, senderName: string, senderType: 'user' | 'ai', id: string | number | null = null) {\n this.message = message;\n this.senderName = senderName;\n this.senderType = senderType;\n this.id = id;\n this.timestamp = new Date();\n }\n}\n\n@Component({\n standalone: false,\n selector: 'mj-chat',\n templateUrl: './chat.component.html',\n styleUrl: './chat.component.css'\n})\nexport class ChatComponent implements AfterViewInit {\n @Input() InitialMessage: string = '';\n @Input() Messages: ChatMessage[] = [];\n /**\n * Optional, provide this to show an image for the AI. If not provided, a default robot icon will be shown.\n */\n @Input() AIImageURL: string = '';\n @Input() AILargeImageURL: string = '';\n\n /**\n * Optional, provide up to 4 welcome questions with example prompts. \n * These will be shown to the user when the chat is first opened and there are no messages.\n */\n @Input() WelcomeQuestions: ChatWelcomeQuestion[] = [];\n\n /**\n * Optional, provide a prompt for the user when they click the clear all messages button.\n */\n @Input() ClearAllMessagesPrompt: string = 'Are you sure you want to clear all messages?';\n\n /**\n * Set this to enable/disable sending of a message. Whenever the input is empty, this field will be\n * ignored and the send button will be disabled.\n */\n @Input() AllowSend: boolean = true;\n public InternalAllowSend: boolean = true;\n /**\n * The placeholder text for the input field\n */\n @Input() public Placeholder: string = 'Type a message...';\n\n private _ShowWaitingIndicator: boolean = false;\n @Input() public get ShowWaitingIndicator(): boolean {\n return this._ShowWaitingIndicator;\n }\n public set ShowWaitingIndicator(value: boolean) {\n this._ShowWaitingIndicator = value;\n this.cd?.detectChanges(); // Manually trigger change detection\n if (!value) {\n this.FocusTextArea();\n }\n }\n\n ngAfterViewInit(): void {\n this.FocusTextArea();\n }\n\n @Output() MessageAdded = new EventEmitter<ChatMessage>();\n @Output() ClearChatRequested = new EventEmitter<void>();\n\n @ViewChild('messagesContainer', { static: true }) private messagesContainer!: ElementRef;\n @ViewChild('theInput') theInput: ElementRef | undefined;\n\n public currentMessage: string = '';\n public showingClearAllDialog: boolean = false;\n constructor(private markdownService: MarkdownService, private cd: ChangeDetectorRef) {}\n\n public SendCurrentMessage(): void {\n if (this.currentMessage.trim() !== '') {\n this.SendMessage(this.currentMessage, 'User', 'user', null);\n this.currentMessage = ''; // Clear the input field\n }\n }\n\n public handleInputChange(event: any) {\n const val = this.theInput?.nativeElement.value;\n this.InternalAllowSend = this.AllowSend && (val ? val.length > 0 : false);\n this.resizeTextInput();\n }\n\n protected resizeTextInput() {\n try {\n const textarea = this.theInput?.nativeElement;\n if (textarea) {\n textarea.style.height = 'auto'; // Reset height to recalculate\n textarea.style.height = `${textarea.scrollHeight}px`; // Set to scrollHeight \n }\n }\n catch (e) {\n LogError(e);\n }\n }\n\n\n public SendMessage(message: string, senderName: string, senderType: 'user' | 'ai', id: any, fireEvent: boolean = true): void {\n const newMessage = new ChatMessage(message, senderName, senderType, id);\n this.AppendMessage(newMessage, fireEvent); \n }\n\n public SendUserMessage(message: string) {\n this.SendMessage(message, 'User', 'user', null);\n }\n\n public HandleClearChat() {\n this.ClearChatRequested.emit();\n }\n\n public ClearAllMessages() {\n this.Messages = [];\n this.messagesContainer.nativeElement.innerHTML = `<span>${this.InitialMessage}</span>`;\n\n this.ScrollMessagesToBottom();\n\n this.cd.detectChanges(); // Manually trigger change detection\n\n this.FocusTextArea();\n this.showingClearAllDialog = false;\n }\n\n protected FocusTextArea() {\n setTimeout(() => this.theInput?.nativeElement.focus(), 0); // use a timeout to ensure that angular has updated the DOM\n }\n\n protected async AppendMessage(message: ChatMessage, fireEvent: boolean = true) {\n const messageWrapElement = document.createElement('div');\n messageWrapElement.className = \"chat-message-wrap\";\n const imageElement = document.createElement('span');\n if (message.senderType === 'ai') {\n if (this.AIImageURL) {\n const img = document.createElement('img');\n img.src = this.AIImageURL;\n img.style.maxWidth = '24px';\n imageElement.appendChild(img);\n }\n else\n imageElement.classList.add('fa-solid', 'fa-robot');\n }\n else {\n imageElement.classList.add('fa-solid', 'fa-user');\n }\n imageElement.classList.add(\"chat-message-image\");\n\n messageWrapElement.appendChild(imageElement);\n const messageElement = document.createElement('div');\n messageElement.innerHTML = await this.markdownService.parse(message.message);\n messageElement.className = \"chat-message\"; \n if (message.senderType === 'ai') {\n messageElement.classList.add('chat-message-ai');\n }\n messageWrapElement.appendChild(messageElement);\n\n this.Messages.push(message);\n if (this.Messages.length === 1) {\n // clear out the default message\n this.messagesContainer.nativeElement.innerHTML = '';\n }\n this.messagesContainer.nativeElement.appendChild(messageWrapElement); \n if (fireEvent)\n this.MessageAdded.emit(message); \n\n this.ScrollMessagesToBottom(false);\n\n this.cd.detectChanges(); // Manually trigger change detection\n }\n\n protected ScrollMessagesToBottom(animate: boolean = true): void {\n try {\n if (animate) {\n const element = this.messagesContainer.nativeElement;\n element.scrollTo({\n top: element.scrollHeight,\n behavior: 'smooth' // This enables the smooth scrolling\n }); \n }\n else {\n this.messagesContainer.nativeElement.scrollTop = this.messagesContainer.nativeElement.scrollHeight;\n }\n } catch(err) {}\n }\n\n\n public ShowScrollToBottomButton: boolean = false;\n\n handleCheckScroll(): void {\n const element = this.messagesContainer.nativeElement;\n if (element.scrollHeight - element.scrollTop > element.clientHeight) {\n this.ShowScrollToBottomButton = true;\n } else {\n this.ShowScrollToBottomButton = false;\n }\n }\n}\n","<div class=\"chat-wrapper\">\n @if(Messages.length === 0 && !ShowWaitingIndicator) {\n <div class=\"welcome-wrapper\">\n <div class='welcome-message'>\n @if(AILargeImageURL) {\n <img [src]=\"AILargeImageURL\"/>\n }\n <div class=\"welcome-header-text\">What can I help with today?</div>\n </div>\n <div class='welcome-suggested-questions'>\n <div class=\"welcome-suggested-questions-col\">\n @if (WelcomeQuestions.length > 0) {\n <div class=\"welcome-question\" (click)=\"SendUserMessage(WelcomeQuestions[0].prompt)\">\n <span class=\"welcome-question-header\">{{WelcomeQuestions[0].topLine}}</span>\n <span>{{WelcomeQuestions[0].bottomLine}}</span>\n </div>\n }\n @if (WelcomeQuestions.length > 1) {\n <div class=\"welcome-question\" (click)=\"SendUserMessage(WelcomeQuestions[1].prompt)\">\n <span class=\"welcome-question-header\">{{WelcomeQuestions[1].topLine}}</span>\n <span>{{WelcomeQuestions[1].bottomLine}}</span>\n </div> \n }\n </div>\n <div class=\"welcome-suggested-questions-col\">\n @if (WelcomeQuestions.length > 2) {\n <div class=\"welcome-question\" (click)=\"SendUserMessage(WelcomeQuestions[2].prompt)\">\n <span class=\"welcome-question-header\">{{WelcomeQuestions[2].topLine}}</span>\n <span>{{WelcomeQuestions[2].bottomLine}}</span>\n </div> \n }\n @if (WelcomeQuestions.length > 3) {\n <div class=\"welcome-question\" (click)=\"SendUserMessage(WelcomeQuestions[3].prompt)\">\n <span class=\"welcome-question-header\">{{WelcomeQuestions[3].topLine}}</span>\n <span>{{WelcomeQuestions[3].bottomLine}}</span>\n </div> \n }\n </div>\n </div>\n </div> \n }\n\n <div class=\"chat-messages\" \n #messagesContainer \n (scroll)=\"handleCheckScroll()\">\n <!-- messages go here -->\n <span>{{InitialMessage}}</span>\n </div>\n @if (ShowScrollToBottomButton) {\n <span class=\"scroll-to-bottom fas fa-arrow-down\" (click)=\"ScrollMessagesToBottom()\"></span>\n }\n\n @if (ShowWaitingIndicator) {\n <div class=\"typing-indicator\">\n <div class=\"typing-dot\"></div>\n <div class=\"typing-dot\"></div>\n <div class=\"typing-dot\"></div>\n <span class=\"typing-text\">Thinking...</span>\n </div>\n }\n\n <div class = \"chat-input-area\">\n <div class=\"text-area-wrapper\">\n <textarea #theInput \n [(ngModel)]=\"currentMessage\" \n [disabled]=\"ShowWaitingIndicator\" \n [placeholder]=\"Placeholder\" \n (input)=\"handleInputChange($event)\"\n (keyup.enter)=\"SendCurrentMessage()\" >\n </textarea>\n </div>\n <button class=\"chat-action-btn\"\n [disabled]=\"Messages.length === 0 || ShowWaitingIndicator\"\n (click)=\"showingClearAllDialog = true\"\n title=\"Clear Chat\">\n <i class=\"fa-solid fa-trash-can\"></i>\n </button>\n <button class=\"chat-action-btn chat-send-btn\"\n [disabled]=\"!InternalAllowSend || currentMessage.length === 0 || ShowWaitingIndicator\"\n (click)=\"SendCurrentMessage()\"\n title=\"Send Message\">\n <i class=\"fa-solid fa-arrow-up\"></i>\n </button>\n </div>\n</div>\n@if (showingClearAllDialog) {\n <div class=\"chat-dialog-overlay\" (click)=\"showingClearAllDialog = false\">\n <div class=\"chat-dialog\" (click)=\"$event.stopPropagation()\">\n <p class=\"chat-dialog-message\">{{ClearAllMessagesPrompt}}</p>\n <div class=\"chat-dialog-actions\">\n <button class=\"chat-dialog-btn chat-dialog-btn-primary\" (click)=\"HandleClearChat()\">Yes</button>\n <button class=\"chat-dialog-btn\" (click)=\"showingClearAllDialog = false\">No</button>\n </div>\n </div>\n </div>\n}\n"]}
|
|
1
|
+
{"version":3,"file":"chat.component.js","sourceRoot":"","sources":["../../../src/lib/chat/chat.component.ts","../../../src/lib/chat/chat.component.html"],"names":[],"mappings":"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","sourcesContent":["import { AfterViewInit, ChangeDetectorRef, Component, ElementRef, EventEmitter, Input, Output, ViewChild } from '@angular/core';\nimport { MarkdownService } from '@memberjunction/ng-markdown';\nimport { LogError } from '@memberjunction/core'\n\n\nexport class ChatWelcomeQuestion {\n public topLine: string=\"\";\n public bottomLine: string=\"\";\n public prompt: string=\"\";\n}\nexport class ChatMessage {\n public message!: string;\n public senderName!: string;\n public senderType: 'user' | 'ai' = 'user';\n public id?: string | number | null;\n /** Optional: indicates a tool execution is in progress */\n public toolName?: string;\n /** Optional: indicates a thinking/processing state */\n public isThinking?: boolean;\n /** Timestamp when the message was created */\n public timestamp: Date = new Date();\n\n constructor(message: string, senderName: string, senderType: 'user' | 'ai', id: string | number | null = null) {\n this.message = message;\n this.senderName = senderName;\n this.senderType = senderType;\n this.id = id;\n this.timestamp = new Date();\n }\n}\n\n@Component({\n standalone: false,\n selector: 'mj-chat',\n templateUrl: './chat.component.html',\n styleUrl: './chat.component.css'\n})\nexport class ChatComponent implements AfterViewInit {\n @Input() InitialMessage: string = '';\n @Input() Messages: ChatMessage[] = [];\n /**\n * Optional, provide this to show an image for the AI. If not provided, a default robot icon will be shown.\n */\n @Input() AIImageURL: string = '';\n @Input() AILargeImageURL: string = '';\n\n /**\n * Optional, provide up to 4 welcome questions with example prompts. \n * These will be shown to the user when the chat is first opened and there are no messages.\n */\n @Input() WelcomeQuestions: ChatWelcomeQuestion[] = [];\n\n /**\n * Optional, provide a prompt for the user when they click the clear all messages button.\n */\n @Input() ClearAllMessagesPrompt: string = 'Are you sure you want to clear all messages?';\n\n /**\n * Set this to enable/disable sending of a message. Whenever the input is empty, this field will be\n * ignored and the send button will be disabled.\n */\n @Input() AllowSend: boolean = true;\n public InternalAllowSend: boolean = true;\n /**\n * The placeholder text for the input field\n */\n @Input() public Placeholder: string = 'Type a message...';\n\n private _ShowWaitingIndicator: boolean = false;\n @Input() public get ShowWaitingIndicator(): boolean {\n return this._ShowWaitingIndicator;\n }\n public set ShowWaitingIndicator(value: boolean) {\n this._ShowWaitingIndicator = value;\n this.cd?.detectChanges(); // Manually trigger change detection\n if (!value) {\n this.FocusTextArea();\n }\n }\n\n ngAfterViewInit(): void {\n this.FocusTextArea();\n }\n\n @Output() MessageAdded = new EventEmitter<ChatMessage>();\n @Output() ClearChatRequested = new EventEmitter<void>();\n\n @ViewChild('messagesContainer', { static: true }) private messagesContainer!: ElementRef;\n @ViewChild('theInput') theInput: ElementRef | undefined;\n\n public currentMessage: string = '';\n public showingClearAllDialog: boolean = false;\n constructor(private markdownService: MarkdownService, private cd: ChangeDetectorRef) {}\n\n public SendCurrentMessage(): void {\n if (this.currentMessage.trim() !== '') {\n this.SendMessage(this.currentMessage, 'User', 'user', null);\n this.currentMessage = ''; // Clear the input field\n }\n }\n\n public handleInputChange(event: any) {\n const val = this.theInput?.nativeElement.value;\n this.InternalAllowSend = this.AllowSend && (val ? val.length > 0 : false);\n this.resizeTextInput();\n }\n\n protected resizeTextInput() {\n try {\n const textarea = this.theInput?.nativeElement;\n if (textarea) {\n textarea.style.height = 'auto'; // Reset height to recalculate\n textarea.style.height = `${textarea.scrollHeight}px`; // Set to scrollHeight \n }\n }\n catch (e) {\n LogError(e);\n }\n }\n\n\n public SendMessage(message: string, senderName: string, senderType: 'user' | 'ai', id: any, fireEvent: boolean = true): void {\n const newMessage = new ChatMessage(message, senderName, senderType, id);\n this.AppendMessage(newMessage, fireEvent); \n }\n\n public SendUserMessage(message: string) {\n this.SendMessage(message, 'User', 'user', null);\n }\n\n public HandleClearChat() {\n this.ClearChatRequested.emit();\n }\n\n public ClearAllMessages() {\n this.Messages = [];\n this.messagesContainer.nativeElement.innerHTML = `<span>${this.InitialMessage}</span>`;\n\n this.ScrollMessagesToBottom();\n\n this.cd.detectChanges(); // Manually trigger change detection\n\n this.FocusTextArea();\n this.showingClearAllDialog = false;\n }\n\n protected FocusTextArea() {\n setTimeout(() => this.theInput?.nativeElement.focus(), 0); // use a timeout to ensure that angular has updated the DOM\n }\n\n protected async AppendMessage(message: ChatMessage, fireEvent: boolean = true) {\n const messageWrapElement = document.createElement('div');\n messageWrapElement.className = \"chat-message-wrap\";\n const imageElement = document.createElement('span');\n if (message.senderType === 'ai') {\n if (this.AIImageURL) {\n const img = document.createElement('img');\n img.src = this.AIImageURL;\n img.style.maxWidth = '24px';\n imageElement.appendChild(img);\n }\n else\n imageElement.classList.add('fa-solid', 'fa-robot');\n }\n else {\n imageElement.classList.add('fa-solid', 'fa-user');\n }\n imageElement.classList.add(\"chat-message-image\");\n\n messageWrapElement.appendChild(imageElement);\n const messageElement = document.createElement('div');\n messageElement.innerHTML = await this.markdownService.parse(message.message);\n messageElement.className = \"chat-message\"; \n if (message.senderType === 'ai') {\n messageElement.classList.add('chat-message-ai');\n }\n messageWrapElement.appendChild(messageElement);\n\n this.Messages.push(message);\n if (this.Messages.length === 1) {\n // clear out the default message\n this.messagesContainer.nativeElement.innerHTML = '';\n }\n this.messagesContainer.nativeElement.appendChild(messageWrapElement); \n if (fireEvent)\n this.MessageAdded.emit(message); \n\n this.ScrollMessagesToBottom(false);\n\n this.cd.detectChanges(); // Manually trigger change detection\n }\n\n protected ScrollMessagesToBottom(animate: boolean = true): void {\n try {\n if (animate) {\n const element = this.messagesContainer.nativeElement;\n element.scrollTo({\n top: element.scrollHeight,\n behavior: 'smooth' // This enables the smooth scrolling\n }); \n }\n else {\n this.messagesContainer.nativeElement.scrollTop = this.messagesContainer.nativeElement.scrollHeight;\n }\n } catch(err) {}\n }\n\n\n public ShowScrollToBottomButton: boolean = false;\n\n handleCheckScroll(): void {\n const element = this.messagesContainer.nativeElement;\n if (element.scrollHeight - element.scrollTop > element.clientHeight) {\n this.ShowScrollToBottomButton = true;\n } else {\n this.ShowScrollToBottomButton = false;\n }\n }\n}\n","<div class=\"chat-wrapper\">\n @if(Messages.length === 0 && !ShowWaitingIndicator) {\n <div class=\"welcome-wrapper\">\n <div class='welcome-message'>\n @if(AILargeImageURL) {\n <img [src]=\"AILargeImageURL\"/>\n }\n <div class=\"welcome-header-text\">What can I help with today?</div>\n </div>\n <div class='welcome-suggested-questions'>\n <div class=\"welcome-suggested-questions-col\">\n @if (WelcomeQuestions.length > 0) {\n <div class=\"welcome-question\" (click)=\"SendUserMessage(WelcomeQuestions[0].prompt)\">\n <span class=\"welcome-question-header\">{{WelcomeQuestions[0].topLine}}</span>\n <span>{{WelcomeQuestions[0].bottomLine}}</span>\n </div>\n }\n @if (WelcomeQuestions.length > 1) {\n <div class=\"welcome-question\" (click)=\"SendUserMessage(WelcomeQuestions[1].prompt)\">\n <span class=\"welcome-question-header\">{{WelcomeQuestions[1].topLine}}</span>\n <span>{{WelcomeQuestions[1].bottomLine}}</span>\n </div> \n }\n </div>\n <div class=\"welcome-suggested-questions-col\">\n @if (WelcomeQuestions.length > 2) {\n <div class=\"welcome-question\" (click)=\"SendUserMessage(WelcomeQuestions[2].prompt)\">\n <span class=\"welcome-question-header\">{{WelcomeQuestions[2].topLine}}</span>\n <span>{{WelcomeQuestions[2].bottomLine}}</span>\n </div> \n }\n @if (WelcomeQuestions.length > 3) {\n <div class=\"welcome-question\" (click)=\"SendUserMessage(WelcomeQuestions[3].prompt)\">\n <span class=\"welcome-question-header\">{{WelcomeQuestions[3].topLine}}</span>\n <span>{{WelcomeQuestions[3].bottomLine}}</span>\n </div> \n }\n </div>\n </div>\n </div> \n }\n\n <div class=\"chat-messages\" \n #messagesContainer \n (scroll)=\"handleCheckScroll()\">\n <!-- messages go here -->\n <span>{{InitialMessage}}</span>\n </div>\n @if (ShowScrollToBottomButton) {\n <span class=\"scroll-to-bottom fas fa-arrow-down\" (click)=\"ScrollMessagesToBottom()\"></span>\n }\n\n @if (ShowWaitingIndicator) {\n <div class=\"typing-indicator\">\n <div class=\"typing-dot\"></div>\n <div class=\"typing-dot\"></div>\n <div class=\"typing-dot\"></div>\n <span class=\"typing-text\">Thinking...</span>\n </div>\n }\n\n <div class = \"chat-input-area\">\n <div class=\"text-area-wrapper\">\n <textarea #theInput \n [(ngModel)]=\"currentMessage\" \n [disabled]=\"ShowWaitingIndicator\" \n [placeholder]=\"Placeholder\" \n (input)=\"handleInputChange($event)\"\n (keyup.enter)=\"SendCurrentMessage()\" >\n </textarea>\n </div>\n <button class=\"chat-action-btn\"\n [disabled]=\"Messages.length === 0 || ShowWaitingIndicator\"\n (click)=\"showingClearAllDialog = true\"\n title=\"Clear Chat\">\n <i class=\"fa-solid fa-trash-can\"></i>\n </button>\n <button class=\"chat-action-btn chat-send-btn\"\n [disabled]=\"!InternalAllowSend || currentMessage.length === 0 || ShowWaitingIndicator\"\n (click)=\"SendCurrentMessage()\"\n title=\"Send Message\">\n <i class=\"fa-solid fa-arrow-up\"></i>\n </button>\n </div>\n</div>\n@if (showingClearAllDialog) {\n <div class=\"chat-dialog-overlay\" (click)=\"showingClearAllDialog = false\">\n <div class=\"chat-dialog\" (click)=\"$event.stopPropagation()\">\n <p class=\"chat-dialog-message\">{{ClearAllMessagesPrompt}}</p>\n <div class=\"chat-dialog-actions\">\n <button class=\"chat-dialog-btn chat-dialog-btn-primary\" (click)=\"HandleClearChat()\">Yes</button>\n <button class=\"chat-dialog-btn\" (click)=\"showingClearAllDialog = false\">No</button>\n </div>\n </div>\n </div>\n}\n"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@memberjunction/ng-chat",
|
|
3
|
-
"version": "6.1.0-edge.
|
|
3
|
+
"version": "6.1.0-edge.6",
|
|
4
4
|
"description": "MemberJunction: Reusable Chat Component - can be used for AI or peer to peer chat applications.",
|
|
5
5
|
"main": "./dist/public-api.js",
|
|
6
6
|
"typings": "./dist/public-api.d.ts",
|
|
@@ -11,23 +11,23 @@
|
|
|
11
11
|
"author": "",
|
|
12
12
|
"license": "BUSL-1.1",
|
|
13
13
|
"devDependencies": {
|
|
14
|
-
"@angular/compiler": "21.
|
|
15
|
-
"@angular/compiler-cli": "21.
|
|
14
|
+
"@angular/compiler": "21.2.22",
|
|
15
|
+
"@angular/compiler-cli": "21.2.22",
|
|
16
16
|
"vitest": "^4.0.18",
|
|
17
|
-
"@memberjunction/ng-test-utils": "6.1.0-edge.
|
|
17
|
+
"@memberjunction/ng-test-utils": "6.1.0-edge.6"
|
|
18
18
|
},
|
|
19
19
|
"peerDependencies": {
|
|
20
|
-
"@angular/common": "^21.
|
|
21
|
-
"@angular/core": "^21.
|
|
22
|
-
"@angular/forms": "^21.
|
|
20
|
+
"@angular/common": "^21.2.22",
|
|
21
|
+
"@angular/core": "^21.2.22",
|
|
22
|
+
"@angular/forms": "^21.2.22"
|
|
23
23
|
},
|
|
24
24
|
"dependencies": {
|
|
25
|
-
"@memberjunction/core": "6.1.0-edge.
|
|
26
|
-
"@memberjunction/ng-container-directives": "6.1.0-edge.
|
|
27
|
-
"@memberjunction/ng-shared-generic": "6.1.0-edge.
|
|
28
|
-
"@memberjunction/ng-ui-components": "6.1.0-edge.
|
|
25
|
+
"@memberjunction/core": "6.1.0-edge.6",
|
|
26
|
+
"@memberjunction/ng-container-directives": "6.1.0-edge.6",
|
|
27
|
+
"@memberjunction/ng-shared-generic": "6.1.0-edge.6",
|
|
28
|
+
"@memberjunction/ng-ui-components": "6.1.0-edge.6",
|
|
29
29
|
"tslib": "^2.8.1",
|
|
30
|
-
"@memberjunction/ng-markdown": "6.1.0-edge.
|
|
30
|
+
"@memberjunction/ng-markdown": "6.1.0-edge.6"
|
|
31
31
|
},
|
|
32
32
|
"sideEffects": false,
|
|
33
33
|
"repository": {
|