diff options
Diffstat (limited to 'src/client/views/nodes/chatbot/chatboxcomponents')
| -rw-r--r-- | src/client/views/nodes/chatbot/chatboxcomponents/ChatBox.scss | 120 | ||||
| -rw-r--r-- | src/client/views/nodes/chatbot/chatboxcomponents/ChatBox.tsx | 80 |
2 files changed, 200 insertions, 0 deletions
diff --git a/src/client/views/nodes/chatbot/chatboxcomponents/ChatBox.scss b/src/client/views/nodes/chatbot/chatboxcomponents/ChatBox.scss index 31f7be4c4..8e00cbdb7 100644 --- a/src/client/views/nodes/chatbot/chatboxcomponents/ChatBox.scss +++ b/src/client/views/nodes/chatbot/chatboxcomponents/ChatBox.scss @@ -950,3 +950,123 @@ $font-size-xlarge: 18px; } } } + +/* Tool Reload Modal Styles */ +.tool-reload-modal-overlay { + position: fixed; + top: 0; + left: 0; + right: 0; + bottom: 0; + background-color: rgba(0, 0, 0, 0.5); + display: flex; + align-items: center; + justify-content: center; + z-index: 10000; + backdrop-filter: blur(4px); +} + +.tool-reload-modal { + background: white; + border-radius: 12px; + padding: 0; + min-width: 400px; + max-width: 500px; + box-shadow: + 0 20px 25px -5px rgba(0, 0, 0, 0.1), + 0 10px 10px -5px rgba(0, 0, 0, 0.04); + border: 1px solid #e2e8f0; + animation: modalSlideIn 0.3s ease-out; +} + +@keyframes modalSlideIn { + from { + opacity: 0; + transform: scale(0.95) translateY(-20px); + } + to { + opacity: 1; + transform: scale(1) translateY(0); + } +} + +.tool-reload-modal-header { + padding: 24px 24px 16px 24px; + border-bottom: 1px solid #e2e8f0; + + h3 { + margin: 0; + font-size: 18px; + font-weight: 600; + color: #1a202c; + display: flex; + align-items: center; + + &::before { + content: '🛠️'; + margin-right: 8px; + font-size: 20px; + } + } +} + +.tool-reload-modal-content { + padding: 20px 24px; + + p { + margin: 0 0 12px 0; + line-height: 1.5; + color: #4a5568; + + &:last-child { + margin-bottom: 0; + } + + strong { + color: #2d3748; + font-weight: 600; + } + } +} + +.tool-reload-modal-actions { + padding: 16px 24px 24px 24px; + display: flex; + gap: 12px; + justify-content: flex-end; + + button { + padding: 10px 20px; + border-radius: 6px; + font-weight: 500; + font-size: 14px; + cursor: pointer; + transition: all 0.2s ease; + border: none; + + &.primary { + background: #3182ce; + color: white; + + &:hover { + background: #2c5aa0; + transform: translateY(-1px); + } + + &:active { + transform: translateY(0); + } + } + + &.secondary { + background: #f7fafc; + color: #4a5568; + border: 1px solid #e2e8f0; + + &:hover { + background: #edf2f7; + border-color: #cbd5e0; + } + } + } +} diff --git a/src/client/views/nodes/chatbot/chatboxcomponents/ChatBox.tsx b/src/client/views/nodes/chatbot/chatboxcomponents/ChatBox.tsx index 470f94a8d..df6c5627c 100644 --- a/src/client/views/nodes/chatbot/chatboxcomponents/ChatBox.tsx +++ b/src/client/views/nodes/chatbot/chatboxcomponents/ChatBox.tsx @@ -79,6 +79,7 @@ export class ChatBox extends ViewBoxAnnotatableComponent<FieldViewProps>() { @observable private _citationPopup: { text: string; visible: boolean } = { text: '', visible: false }; @observable private _isFontSizeModalOpen: boolean = false; @observable private _fontSize: 'small' | 'normal' | 'large' | 'xlarge' = 'normal'; + @observable private _toolReloadModal: { visible: boolean; toolName: string } = { visible: false, toolName: '' }; // Private properties for managing OpenAI API, vector store, agent, and UI elements private openai!: OpenAI; // Using definite assignment assertion @@ -125,6 +126,9 @@ export class ChatBox extends ViewBoxAnnotatableComponent<FieldViewProps>() { // Create an agent with the vectorstore this.agent = new Agent(this.vectorstore, this.retrieveFormattedHistory.bind(this), this.retrieveCSVData.bind(this), this.createImageInDash.bind(this), this.createCSVInDash.bind(this), this.docManager); + // Set up the tool created callback + this.agent.setToolCreatedCallback(this.handleToolCreated); + // Add event listeners this.addScrollListener(); @@ -1159,6 +1163,56 @@ export class ChatBox extends ViewBoxAnnotatableComponent<FieldViewProps>() { this._inputValue = question; }; + /** + * Handles tool creation notification and shows the reload modal + * @param toolName The name of the tool that was created + */ + @action + handleToolCreated = (toolName: string) => { + this._toolReloadModal = { + visible: true, + toolName: toolName, + }; + }; + + /** + * Closes the tool reload modal + */ + @action + closeToolReloadModal = () => { + this._toolReloadModal = { + visible: false, + toolName: '', + }; + }; + + /** + * Handles the reload confirmation and triggers page reload + */ + @action + handleReloadConfirmation = async () => { + // Close the modal first + this.closeToolReloadModal(); + + try { + // Perform the deferred tool save operation + const saveSuccess = await this.agent.performDeferredToolSave(); + + if (saveSuccess) { + console.log('Tool saved successfully, proceeding with reload...'); + } else { + console.warn('Tool save failed, but proceeding with reload anyway...'); + } + } catch (error) { + console.error('Error during deferred tool save:', error); + } + + // Trigger page reload to rebuild webpack and load the new tool + setTimeout(() => { + window.location.reload(); + }, 100); + }; + _dictation: DictationButton | null = null; /** @@ -1434,6 +1488,32 @@ export class ChatBox extends ViewBoxAnnotatableComponent<FieldViewProps>() { <div className="citation-content">{this._citationPopup.text}</div> </div> )} + + {/* Tool Reload Modal */} + {this._toolReloadModal.visible && ( + <div className="tool-reload-modal-overlay"> + <div className="tool-reload-modal"> + <div className="tool-reload-modal-header"> + <h3>Tool Created Successfully!</h3> + </div> + <div className="tool-reload-modal-content"> + <p> + The tool <strong>{this._toolReloadModal.toolName}</strong> has been created and saved successfully. + </p> + <p>To make the tool available for future use, the page needs to be reloaded to rebuild the application bundle.</p> + <p>Click "Reload Page" to complete the tool installation.</p> + </div> + <div className="tool-reload-modal-actions"> + <button className="reload-button primary" onClick={this.handleReloadConfirmation}> + Reload Page + </button> + <button className="close-button secondary" onClick={this.closeToolReloadModal}> + Later + </button> + </div> + </div> + </div> + )} </div> ); } |
