diff --git a/.gitignore b/.gitignore index 5f5d89b4..e564b443 100644 --- a/.gitignore +++ b/.gitignore @@ -103,6 +103,9 @@ celerybeat-schedule .spyderproject .spyproject +# vscode project settings +.vscode + # Rope project settings .ropeproject diff --git a/packages/jupyter-chat/src/components/attachments.tsx b/packages/jupyter-chat/src/components/attachments.tsx index 817ee943..2c3b51c1 100644 --- a/packages/jupyter-chat/src/components/attachments.tsx +++ b/packages/jupyter-chat/src/components/attachments.tsx @@ -5,12 +5,12 @@ import CloseIcon from '@mui/icons-material/Close'; import { Box, Button, Tooltip } from '@mui/material'; -import React, { useContext } from 'react'; +import React from 'react'; import { PathExt } from '@jupyterlab/coreutils'; import { UUID } from '@lumino/coreutils'; +import { useChatContext } from '../context'; import { IAttachment } from '../types'; -import { AttachmentOpenerContext } from '../context'; const ATTACHMENT_CLASS = 'jp-chat-attachment'; const ATTACHMENT_CLICKABLE_CLASS = 'jp-chat-attachment-clickable'; @@ -87,7 +87,7 @@ export type AttachmentProps = AttachmentsProps & { */ export function AttachmentPreview(props: AttachmentProps): JSX.Element { const remove_tooltip = 'Remove attachment'; - const attachmentOpenerRegistry = useContext(AttachmentOpenerContext); + const { attachmentOpenerRegistry } = useChatContext(); const isClickable = !!attachmentOpenerRegistry?.get(props.attachment.type); return ( diff --git a/packages/jupyter-chat/src/components/chat.tsx b/packages/jupyter-chat/src/components/chat.tsx index cda29956..f95cf656 100644 --- a/packages/jupyter-chat/src/components/chat.tsx +++ b/packages/jupyter-chat/src/components/chat.tsx @@ -18,7 +18,7 @@ import { } from './input'; import { JlThemeProvider } from './jl-theme-provider'; import { ChatMessages } from './messages'; -import { AttachmentOpenerContext } from '../context'; +import { ChatReactContext } from '../context'; import { IChatModel } from '../model'; import { IAttachmentOpenerRegistry, @@ -27,7 +27,7 @@ import { } from '../registers'; import { ChatArea } from '../types'; -export function ChatBody(props: Chat.IChatBodyProps): JSX.Element { +export function ChatBody(props: Chat.IChatProps): JSX.Element { const { model } = props; let { inputToolbarRegistry } = props; if (!inputToolbarRegistry) { @@ -36,17 +36,14 @@ export function ChatBody(props: Chat.IChatBodyProps): JSX.Element { // const horizontalPadding = props.area === 'main' ? 8 : 4; const horizontalPadding = 4; + const contextValue: Chat.IChatProps = { + ...props, + inputToolbarRegistry + }; + return ( - - + + - + ); } export function Chat(props: Chat.IOptions): JSX.Element { - const [view, setView] = useState(props.chatView || Chat.View.chat); + const [view, setView] = useState(Chat.View.chat); return ( (model.value); const inputRef = useRef(); - const chatCommands = useChatCommands(model, props.chatCommandRegistry); + const chatCommands = useChatCommands(model, chatCommandRegistry); const [sendWithShiftEnter, setSendWithShiftEnter] = useState( model.config.sendWithShiftEnter ?? false @@ -99,22 +99,22 @@ export function ChatInput(props: ChatInput.IProps): JSX.Element { */ useEffect(() => { const updateToolbar = () => { - setToolbarElements(toolbarRegistry.getItems()); + setToolbarElements(inputToolbarRegistry?.getItems() || []); }; - toolbarRegistry.itemsChanged.connect(updateToolbar); + inputToolbarRegistry?.itemsChanged.connect(updateToolbar); updateToolbar(); return () => { - toolbarRegistry.itemsChanged.disconnect(updateToolbar); + inputToolbarRegistry?.itemsChanged.disconnect(updateToolbar); }; - }, [toolbarRegistry]); + }, [inputToolbarRegistry]); /** * Handle the changes in the writers list. */ useEffect(() => { - if (!props.chatModel) { + if (!chatModel) { return; } @@ -124,15 +124,15 @@ export function ChatInput(props: ChatInput.IProps): JSX.Element { }; // Set initial writers state - const initialWriters = props.chatModel.writers; + const initialWriters = chatModel.writers; setWriters(initialWriters); - props.chatModel.writersChanged?.connect(updateWriters); + chatModel.writersChanged?.connect(updateWriters); return () => { - props.chatModel?.writersChanged?.disconnect(updateWriters); + chatModel?.writersChanged?.disconnect(updateWriters); }; - }, [props.chatModel]); + }, [chatModel]); const inputExists = !!input.trim(); @@ -196,14 +196,14 @@ export function ChatInput(props: ChatInput.IProps): JSX.Element { (!sendWithShiftEnter && !event.shiftKey) ) { // Run all command providers - await props.chatCommandRegistry?.onSubmit(model); + await chatCommandRegistry?.onSubmit(model); model.send(model.value); event.stopPropagation(); event.preventDefault(); } } - const horizontalPadding = props.area === 'sidebar' ? 1.5 : 2; + const horizontalPadding = area === 'sidebar' ? 1.5 : 2; return ( ))} @@ -357,10 +357,6 @@ export namespace ChatInput { * The input model. */ model: IInputModel; - /** - * The toolbar registry. - */ - toolbarRegistry: IInputToolbarRegistry; /** * The function to be called to cancel editing. */ @@ -369,18 +365,6 @@ export namespace ChatInput { * Custom mui/material styles. */ sx?: SxProps; - /** - * Chat command registry. - */ - chatCommandRegistry?: IChatCommandRegistry; - /** - * The area where the chat is displayed. - */ - area?: ChatArea; - /** - * The chat model. - */ - chatModel?: IChatModel; /** * Whether the input is in edit mode (editing an existing message). * Defaults to false (new message mode). diff --git a/packages/jupyter-chat/src/components/messages/footer.tsx b/packages/jupyter-chat/src/components/messages/footer.tsx index 036ccbbc..0f7d6cf9 100644 --- a/packages/jupyter-chat/src/components/messages/footer.tsx +++ b/packages/jupyter-chat/src/components/messages/footer.tsx @@ -6,19 +6,17 @@ import { Box } from '@mui/material'; import React from 'react'; -import { - IMessageFooterRegistry, - MessageFooterSectionProps -} from '../../registers'; +import { useChatContext } from '../../context'; +import { IChatMessage } from '../../types'; /** * The chat footer component properties. */ -export interface IMessageFootersProps extends MessageFooterSectionProps { +export interface IMessageFootersProps { /** - * The chat footer registry. + * The chat model. */ - registry: IMessageFooterRegistry; + message: IChatMessage; } /** @@ -27,9 +25,13 @@ export interface IMessageFootersProps extends MessageFooterSectionProps { */ export function MessageFooterComponent( props: IMessageFootersProps -): JSX.Element { - const { message, model, registry } = props; - const footer = registry.getFooter(); +): JSX.Element | null { + const { message } = props; + const { model, messageFooterRegistry } = useChatContext(); + if (!messageFooterRegistry) { + return null; + } + const footer = messageFooterRegistry.getFooter(); return ( diff --git a/packages/jupyter-chat/src/components/messages/message-renderer.tsx b/packages/jupyter-chat/src/components/messages/message-renderer.tsx index c028001b..3514b636 100644 --- a/packages/jupyter-chat/src/components/messages/message-renderer.tsx +++ b/packages/jupyter-chat/src/components/messages/message-renderer.tsx @@ -3,15 +3,14 @@ * Distributed under the terms of the Modified BSD License. */ -import { IRenderMimeRegistry } from '@jupyterlab/rendermime'; import { PromiseDelegate } from '@lumino/coreutils'; import React, { useState, useEffect } from 'react'; import { createPortal } from 'react-dom'; -import { CodeToolbar, CodeToolbarProps } from '../code-blocks/code-toolbar'; import { MessageToolbar } from './toolbar'; +import { CodeToolbar, CodeToolbarProps } from '../code-blocks/code-toolbar'; +import { useChatContext } from '../../context'; import { MarkdownRenderer, MD_RENDERED_CLASS } from '../../markdown-renderer'; -import { IChatModel } from '../../model'; /** * The type of the props for the MessageRenderer component. @@ -21,14 +20,6 @@ type MessageRendererProps = { * The string to render. */ markdownStr: string; - /** - * The rendermime registry. - */ - rmRegistry: IRenderMimeRegistry; - /** - * The model of the chat. - */ - model: IChatModel; /** * The promise to resolve when the message is rendered. */ @@ -51,7 +42,8 @@ type MessageRendererProps = { * The message renderer base component. */ function MessageRendererBase(props: MessageRendererProps): JSX.Element { - const { markdownStr, rmRegistry } = props; + const { markdownStr } = props; + const { model, rmRegistry } = useChatContext(); const appendContent = props.appendContent || false; const [renderedContent, setRenderedContent] = useState( null @@ -81,7 +73,7 @@ function MessageRendererBase(props: MessageRendererProps): JSX.Element { ); newCodeToolbarDefns.push([ codeToolbarRoot, - { model: props.model, content: preBlock.textContent || '' } + { model: model, content: preBlock.textContent || '' } ]); }); diff --git a/packages/jupyter-chat/src/components/messages/message.tsx b/packages/jupyter-chat/src/components/messages/message.tsx index ad4c3470..5be3d20b 100644 --- a/packages/jupyter-chat/src/components/messages/message.tsx +++ b/packages/jupyter-chat/src/components/messages/message.tsx @@ -7,9 +7,9 @@ import { PromiseDelegate } from '@lumino/coreutils'; import React, { forwardRef, useEffect, useState } from 'react'; import { MessageRenderer } from './message-renderer'; -import { BaseMessageProps } from './messages'; import { AttachmentPreviewList } from '../attachments'; import { ChatInput } from '../input'; +import { useChatContext } from '../../context'; import { IInputModel, InputModel } from '../../input-model'; import { IChatMessage } from '../../types'; import { replaceSpanToMention } from '../../utils'; @@ -17,7 +17,7 @@ import { replaceSpanToMention } from '../../utils'; /** * The message component props. */ -type ChatMessageProps = BaseMessageProps & { +type ChatMessageProps = { /** * The message to display. */ @@ -37,7 +37,8 @@ type ChatMessageProps = BaseMessageProps & { */ export const ChatMessage = forwardRef( (props, ref): JSX.Element => { - const { message, model, rmRegistry } = props; + const { message } = props; + const { model } = useChatContext(); const [edit, setEdit] = useState(false); const [deleted, setDeleted] = useState(false); const [canEdit, setCanEdit] = useState(false); @@ -132,15 +133,11 @@ export const ChatMessage = forwardRef( cancelEdition()} model={model.getEditionModel(message.id)!} - chatCommandRegistry={props.chatCommandRegistry} - toolbarRegistry={props.inputToolbarRegistry} edit={true} /> ) : ( deleteMessage(message.id) : undefined} rendered={props.renderedPromise} diff --git a/packages/jupyter-chat/src/components/messages/messages.tsx b/packages/jupyter-chat/src/components/messages/messages.tsx index ef182f4e..6da6639f 100644 --- a/packages/jupyter-chat/src/components/messages/messages.tsx +++ b/packages/jupyter-chat/src/components/messages/messages.tsx @@ -3,7 +3,6 @@ * Distributed under the terms of the Modified BSD License. */ -import { IRenderMimeRegistry } from '@jupyterlab/rendermime'; import { PromiseDelegate } from '@lumino/coreutils'; import { Box } from '@mui/material'; import clsx from 'clsx'; @@ -14,55 +13,21 @@ import { ChatMessageHeader } from './header'; import { ChatMessage } from './message'; import { Navigation } from './navigation'; import { WelcomeMessage } from './welcome'; -import { IInputToolbarRegistry } from '../input'; import { ScrollContainer } from '../scroll-container'; -import { IChatCommandRegistry, IMessageFooterRegistry } from '../../registers'; -import { IChatModel } from '../../model'; -import { ChatArea, IChatMessage } from '../../types'; +import { useChatContext } from '../../context'; +import { IChatMessage } from '../../types'; export const MESSAGE_CLASS = 'jp-chat-message'; const MESSAGES_BOX_CLASS = 'jp-chat-messages-container'; const MESSAGE_STACKED_CLASS = 'jp-chat-message-stacked'; -/** - * The base components props. - */ -export type BaseMessageProps = { - /** - * The mime renderer registry. - */ - rmRegistry: IRenderMimeRegistry; - /** - * The chat model. - */ - model: IChatModel; - /** - * The chat commands registry. - */ - chatCommandRegistry?: IChatCommandRegistry; - /** - * The input toolbar registry. - */ - inputToolbarRegistry: IInputToolbarRegistry; - /** - * The footer registry. - */ - messageFooterRegistry?: IMessageFooterRegistry; - /** - * The welcome message. - */ - welcomeMessage?: string; - /** - * The area where the chat is displayed. - */ - area?: ChatArea; -}; - /** * The messages list component. */ -export function ChatMessages(props: BaseMessageProps): JSX.Element { - const { model } = props; +export function ChatMessages(): JSX.Element { + const { area, messageFooterRegistry, model, welcomeMessage } = + useChatContext(); + const [messages, setMessages] = useState(model.messages); const refMsgBox = useRef(null); const [allRendered, setAllRendered] = useState(false); @@ -137,7 +102,7 @@ export function ChatMessages(props: BaseMessageProps): JSX.Element { } }); - props.model.messagesInViewport = inViewport; + model.messagesInViewport = inViewport; // Ensure that all messages are rendered before updating unread messages, otherwise // it can lead to wrong assumption , because more message are in the viewport @@ -165,16 +130,11 @@ export function ChatMessages(props: BaseMessageProps): JSX.Element { }; }, [messages, allRendered]); - const horizontalPadding = props.area === 'main' ? 8 : 4; + const horizontalPadding = area === 'main' ? 8 : 4; return ( <> - {props.welcomeMessage && ( - - )} + {welcomeMessage && } (listRef.current[i] = el)} /> - {props.messageFooterRegistry && ( - + {messageFooterRegistry && ( + )} ); })} - + ); } diff --git a/packages/jupyter-chat/src/components/messages/navigation.tsx b/packages/jupyter-chat/src/components/messages/navigation.tsx index b31bae07..cf502432 100644 --- a/packages/jupyter-chat/src/components/messages/navigation.tsx +++ b/packages/jupyter-chat/src/components/messages/navigation.tsx @@ -11,7 +11,7 @@ import { } from '@jupyterlab/ui-components'; import React, { useEffect, useState } from 'react'; -import { BaseMessageProps } from './messages'; +import { useChatContext } from '../../context'; import { IChatModel } from '../../model'; const NAVIGATION_BUTTON_CLASS = 'jp-chat-navigation'; @@ -22,7 +22,7 @@ const NAVIGATION_BOTTOM_CLASS = 'jp-chat-navigation-bottom'; /** * The navigation component props. */ -type NavigationProps = BaseMessageProps & { +type NavigationProps = { /** * The reference to the messages container. */ @@ -37,7 +37,7 @@ type NavigationProps = BaseMessageProps & { * The navigation component, to navigate to unread messages. */ export function Navigation(props: NavigationProps): JSX.Element { - const { model } = props; + const { model } = useChatContext(); const [lastInViewport, setLastInViewport] = useState(true); const [unreadBefore, setUnreadBefore] = useState(null); const [unreadAfter, setUnreadAfter] = useState(null); diff --git a/packages/jupyter-chat/src/components/messages/welcome.tsx b/packages/jupyter-chat/src/components/messages/welcome.tsx index 7ad82bfe..e3f7cdfc 100644 --- a/packages/jupyter-chat/src/components/messages/welcome.tsx +++ b/packages/jupyter-chat/src/components/messages/welcome.tsx @@ -6,17 +6,28 @@ import { classes } from '@jupyterlab/ui-components'; import React, { useEffect, useRef } from 'react'; +import { useChatContext } from '../../context'; import { MarkdownRenderer, MD_RENDERED_CLASS } from '../../markdown-renderer'; const WELCOME_MESSAGE_CLASS = 'jp-chat-welcome-message'; +/** + * The component props. + */ +export interface IWelcomeMessageProps { + /** + * The content of the welcome message (markdown). + */ + content: string; +} + /** * The welcome message component. * This message is displayed on top of the chat messages, and is rendered using a * markdown renderer. */ -export function WelcomeMessage(props: MarkdownRenderer.IOptions): JSX.Element { - const { rmRegistry } = props; +export function WelcomeMessage(props: IWelcomeMessageProps): JSX.Element { + const { rmRegistry } = useChatContext(); const content = props.content + '\n----\n'; // ref that tracks the content container to store the rendermime node in diff --git a/packages/jupyter-chat/src/context.ts b/packages/jupyter-chat/src/context.ts index 75f4166f..94009a46 100644 --- a/packages/jupyter-chat/src/context.ts +++ b/packages/jupyter-chat/src/context.ts @@ -2,9 +2,19 @@ * Copyright (c) Jupyter Development Team. * Distributed under the terms of the Modified BSD License. */ -import { createContext } from 'react'; -import { IAttachmentOpenerRegistry } from './registers'; -export const AttachmentOpenerContext = createContext< - IAttachmentOpenerRegistry | undefined ->(undefined); +import { createContext, useContext } from 'react'; + +import { Chat } from './components'; + +export const ChatReactContext = createContext( + undefined +); + +export function useChatContext(): Chat.IChatProps { + const context = useContext(ChatReactContext); + if (!context) { + throw new Error('The chat context is missing in the chat'); + } + return context; +} diff --git a/packages/jupyter-chat/src/widgets/multichat-panel.tsx b/packages/jupyter-chat/src/widgets/multichat-panel.tsx index 515e4306..16d9a565 100644 --- a/packages/jupyter-chat/src/widgets/multichat-panel.tsx +++ b/packages/jupyter-chat/src/widgets/multichat-panel.tsx @@ -8,8 +8,7 @@ * Originally adapted from jupyterlab-chat's ChatPanel */ -import { InputDialog, IThemeManager } from '@jupyterlab/apputils'; -import { IRenderMimeRegistry } from '@jupyterlab/rendermime'; +import { InputDialog } from '@jupyterlab/apputils'; import { addIcon, closeIcon, @@ -34,11 +33,6 @@ import { } from '../components'; import { chatIcon, readIcon } from '../icons'; import { IChatModel } from '../model'; -import { - IAttachmentOpenerRegistry, - IChatCommandRegistry, - IMessageFooterRegistry -} from '../registers'; const SIDEPANEL_CLASS = 'jp-chat-sidepanel'; const ADD_BUTTON_CLASS = 'jp-chat-add'; @@ -58,13 +52,8 @@ export class MultiChatPanel extends SidePanel { this.addClass(SIDEPANEL_CLASS); - this._rmRegistry = options.rmRegistry; - this._themeManager = options.themeManager; - this._chatCommandRegistry = options.chatCommandRegistry; - this._attachmentOpenerRegistry = options.attachmentOpenerRegistry; + this._chatOptions = options; this._inputToolbarFactory = options.inputToolbarFactory; - this._messageFooterRegistry = options.messageFooterRegistry; - this._welcomeMessage = options.welcomeMessage; this._getChatNames = options.getChatNames; this._createModel = options.createModel; @@ -149,13 +138,8 @@ export class MultiChatPanel extends SidePanel { // Create a new widget. const widget = new ChatWidget({ model, - rmRegistry: this._rmRegistry, - themeManager: this._themeManager, - chatCommandRegistry: this._chatCommandRegistry, - attachmentOpenerRegistry: this._attachmentOpenerRegistry, + ...this._chatOptions, inputToolbarRegistry, - messageFooterRegistry: this._messageFooterRegistry, - welcomeMessage: this._welcomeMessage, area: 'sidebar' }); @@ -267,13 +251,8 @@ export class MultiChatPanel extends SidePanel { this ); private _sectionAdded = new Signal(this); - private _rmRegistry: IRenderMimeRegistry; - private _themeManager?: IThemeManager | null; - private _chatCommandRegistry?: IChatCommandRegistry; - private _attachmentOpenerRegistry?: IAttachmentOpenerRegistry; + private _chatOptions: Omit; private _inputToolbarFactory?: IInputToolbarRegistryFactory; - private _messageFooterRegistry?: IMessageFooterRegistry; - private _welcomeMessage?: string; private _updateChatListDebouncer: Debouncer; private _createModel?: ( diff --git a/packages/jupyterlab-chat/src/factory.ts b/packages/jupyterlab-chat/src/factory.ts index 22d250f9..9ade93f4 100644 --- a/packages/jupyterlab-chat/src/factory.ts +++ b/packages/jupyterlab-chat/src/factory.ts @@ -3,23 +3,9 @@ * Distributed under the terms of the Modified BSD License. */ -import { - ChatArea, - ChatWidget, - IActiveCellManager, - IAttachmentOpenerRegistry, - IChatCommandRegistry, - IInputToolbarRegistry, - IMessageFooterRegistry, - ISelectionWatcher, - IInputToolbarRegistryFactory -} from '@jupyter/chat'; -import { IThemeManager } from '@jupyterlab/apputils'; -import { IDocumentManager } from '@jupyterlab/docmanager'; +import { Chat, ChatWidget, IInputToolbarRegistryFactory } from '@jupyter/chat'; import { ABCWidgetFactory, DocumentRegistry } from '@jupyterlab/docregistry'; -import { IRenderMimeRegistry } from '@jupyterlab/rendermime'; -import { Contents, User } from '@jupyterlab/services'; -import { CommandRegistry } from '@lumino/commands'; +import { Contents } from '@jupyterlab/services'; import { ISignal, Signal } from '@lumino/signaling'; import { LabChatModel } from './model'; @@ -78,13 +64,8 @@ export class ChatWidgetFactory extends ABCWidgetFactory< */ constructor(options: ChatWidgetFactory.IOptions) { super(options); - this._themeManager = options.themeManager; - this._rmRegistry = options.rmRegistry; - this._chatCommandRegistry = options.chatCommandRegistry; - this._attachmentOpenerRegistry = options.attachmentOpenerRegistry; + this._chatOptions = options; this._inputToolbarFactory = options.inputToolbarFactory; - this._messageFooterRegistry = options.messageFooterRegistry; - this._welcomeMessage = options.welcomeMessage; } /** @@ -94,12 +75,7 @@ export class ChatWidgetFactory extends ABCWidgetFactory< * @returns The widget */ protected createNewWidget(context: ChatWidgetFactory.IContext): LabChatPanel { - context.rmRegistry = this._rmRegistry; - context.themeManager = this._themeManager; - context.chatCommandRegistry = this._chatCommandRegistry; - context.attachmentOpenerRegistry = this._attachmentOpenerRegistry; - context.messageFooterRegistry = this._messageFooterRegistry; - context.welcomeMessage = this._welcomeMessage; + Object.assign(context, this._chatOptions); context.area = 'main'; if (this._inputToolbarFactory) { context.inputToolbarRegistry = this._inputToolbarFactory.create(); @@ -118,39 +94,22 @@ export class ChatWidgetFactory extends ABCWidgetFactory< get contentProviderId(): string { return 'rtc'; } + // Must override both getter and setter from ABCFactory for type compatibility. set contentProviderId(_value: string | undefined) {} - private _themeManager: IThemeManager | null; - private _rmRegistry: IRenderMimeRegistry; - private _chatCommandRegistry?: IChatCommandRegistry; - private _attachmentOpenerRegistry?: IAttachmentOpenerRegistry; + private _chatOptions: Omit; private _inputToolbarFactory?: IInputToolbarRegistryFactory; - private _messageFooterRegistry?: IMessageFooterRegistry; - private _welcomeMessage?: string; } export namespace ChatWidgetFactory { - export interface IContext extends DocumentRegistry.IContext { - themeManager: IThemeManager | null; - rmRegistry: IRenderMimeRegistry; - documentManager?: IDocumentManager; - chatCommandRegistry?: IChatCommandRegistry; - attachmentOpenerRegistry?: IAttachmentOpenerRegistry; - inputToolbarRegistry?: IInputToolbarRegistry; - messageFooterRegistry?: IMessageFooterRegistry; - welcomeMessage?: string; - area?: ChatArea; - } + export interface IContext + extends DocumentRegistry.IContext, + Omit {} export interface IOptions - extends DocumentRegistry.IWidgetFactoryOptions { - themeManager: IThemeManager | null; - rmRegistry: IRenderMimeRegistry; - chatCommandRegistry?: IChatCommandRegistry; - attachmentOpenerRegistry?: IAttachmentOpenerRegistry; - inputToolbarFactory?: IInputToolbarRegistryFactory; - messageFooterRegistry?: IMessageFooterRegistry; - welcomeMessage?: string; + extends DocumentRegistry.IWidgetFactoryOptions, + Omit { + inputToolbarFactory: IInputToolbarRegistryFactory; } } @@ -158,12 +117,7 @@ export class LabChatModelFactory implements DocumentRegistry.IModelFactory { constructor(options: LabChatModel.IOptions) { - this._user = options.user; - this._widgetConfig = options.widgetConfig; - this._commands = options.commands; - this._activeCellManager = options.activeCellManager ?? null; - this._selectionWatcher = options.selectionWatcher ?? null; - this._documentManager = options.documentManager ?? null; + this._modelOptions = options; } collaborative = true; @@ -224,28 +178,16 @@ export class LabChatModelFactory /** * Create a new instance of LabChatModel. * - * @param languagePreference Language - * @param modelDB Model database * @returns The model */ createNew(options: DocumentRegistry.IModelOptions): LabChatModel { return new LabChatModel({ ...options, - user: this._user, - widgetConfig: this._widgetConfig, - commands: this._commands, - activeCellManager: this._activeCellManager, - selectionWatcher: this._selectionWatcher, - documentManager: this._documentManager + ...this._modelOptions }); } private _disposed = false; - private _user: User.IIdentity | null; - private _widgetConfig: IWidgetConfig; - private _commands?: CommandRegistry; - private _activeCellManager: IActiveCellManager | null; - private _selectionWatcher: ISelectionWatcher | null; - private _documentManager: IDocumentManager | null; + private _modelOptions: Omit; }