diff --git a/frontend/taipy-gui/src/components/Taipy/Chat.spec.tsx b/frontend/taipy-gui/src/components/Taipy/Chat.spec.tsx index cfc88195c..324d08efb 100644 --- a/frontend/taipy-gui/src/components/Taipy/Chat.spec.tsx +++ b/frontend/taipy-gui/src/components/Taipy/Chat.spec.tsx @@ -212,7 +212,7 @@ describe("Chat Component", () => { }); jest.restoreAllMocks(); }); - it("Not upload image over a file size limit", async () => { + it("does not upload image over a file size limit", async () => { const dispatch = jest.fn(); const state: TaipyState = INITIAL_STATE; const { getByText, getByAltText } = render( diff --git a/frontend/taipy-gui/src/components/Taipy/Chat.tsx b/frontend/taipy-gui/src/components/Taipy/Chat.tsx index 7eb5ea070..94ea8a2f4 100644 --- a/frontend/taipy-gui/src/components/Taipy/Chat.tsx +++ b/frontend/taipy-gui/src/components/Taipy/Chat.tsx @@ -22,6 +22,7 @@ import React, { ReactNode, lazy, ChangeEvent, + UIEvent, } from "react"; import { SxProps, Theme, darken, lighten } from "@mui/material/styles"; import Avatar from "@mui/material/Avatar"; @@ -250,6 +251,7 @@ const Chat = (props: ChatProps) => { const [imagePreview, setImagePreview] = useState(null); const [objectURLs, setObjectURLs] = useState([]); const fileInputRef = useRef(null); + const userScrolled = useRef(false); const className = useClassNames(props.libClassName, props.dynamicClassName, props.className); const active = useDynamicProperty(props.active, props.defaultActive, true); @@ -424,7 +426,7 @@ const Chat = (props: ChatProps) => { ); const showBottom = useCallback(() => { - anchorDivRef.current?.scrollIntoView(); + anchorDivRef.current?.scrollIntoView && anchorDivRef.current?.scrollIntoView(); setShowMessage(false); }, []); @@ -450,8 +452,9 @@ const Chat = (props: ChatProps) => { } } page.current.key = getChatKey(0, pageSize); + !userScrolled.current && showBottom(); } - }, [refresh, pageSize, props.messages]); + }, [refresh, pageSize, props.messages, showBottom]); useEffect(() => { if (showMessage && !isAnchorDivVisible) { @@ -490,10 +493,14 @@ const Chat = (props: ChatProps) => { [loadMoreItems] ); + const handleOnScroll = useCallback((evt: UIEvent) => { + userScrolled.current = (evt.target as HTMLDivElement).scrollHeight - (evt.target as HTMLDivElement).offsetHeight - (evt.target as HTMLDivElement).scrollTop > 1; + }, []); + return ( - + {rows.length && !rows[0] ? ( diff --git a/taipy/gui_core/_context.py b/taipy/gui_core/_context.py index 8928d589a..82f8b7bda 100644 --- a/taipy/gui_core/_context.py +++ b/taipy/gui_core/_context.py @@ -639,11 +639,10 @@ def submit_entity(self, state: State, id: str, payload: t.Dict[str, str]): client_id=self.gui._get_client_id(), module_context=self.gui._get_locals_context(), ) - client_status = _ClientStatus(self.gui._get_client_id(), submission_entity.submission_status) + client_status = _ClientStatus(self.gui._get_client_id(), None) with self.submissions_lock: self.client_submission[submission_entity.id] = client_status if Config.core.mode == "development": - client_status.submission_status = SubmissionStatus.SUBMITTED self.submission_status_callback(submission_entity.id) _GuiCoreContext.__assign_var(state, error_var, "") except Exception as e: @@ -715,7 +714,6 @@ def _get_sort_params(params: t.Optional[t.List[t.Any]] = None, parent: t.Optiona args.append(None) return args - def get_sorted_datanode_list( self, entities: t.Union[ diff --git a/taipy/gui_core/_utils.py b/taipy/gui_core/_utils.py index bdb7656b7..27fe9f09f 100644 --- a/taipy/gui_core/_utils.py +++ b/taipy/gui_core/_utils.py @@ -17,4 +17,4 @@ @dataclass class _ClientStatus: client_id: t.Optional[str] - submission_status: SubmissionStatus + submission_status: t.Optional[SubmissionStatus] diff --git a/tests/gui_core/test_context_is_readable.py b/tests/gui_core/test_context_is_readable.py index e495a238c..d321f31fb 100644 --- a/tests/gui_core/test_context_is_readable.py +++ b/tests/gui_core/test_context_is_readable.py @@ -25,7 +25,7 @@ from taipy.core.job._job_manager_factory import _JobManagerFactory from taipy.core.scenario._scenario_manager_factory import _ScenarioManagerFactory from taipy.core.submission._submission_manager_factory import _SubmissionManagerFactory -from taipy.core.submission.submission import Submission, SubmissionStatus +from taipy.core.submission.submission import Submission from taipy.core.task._task_manager_factory import _TaskManagerFactory from taipy.gui import Gui, State from taipy.gui_core._context import _GuiCoreContext @@ -204,7 +204,7 @@ def test_submission_status_callback(self): mockGui._get_authorization = lambda s: contextlib.nullcontext() gui_core_context = _GuiCoreContext(mockGui) - gui_core_context.client_submission[a_submission.id] = _ClientStatus("client_id", SubmissionStatus.UNDEFINED) + gui_core_context.client_submission[a_submission.id] = _ClientStatus("client_id", None) gui_core_context.submission_status_callback(a_submission.id) mockget.assert_called() found = False