From cacd40011ebb22c0462bb5610fe63c8692a92b67 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fred=20Lef=C3=A9v=C3=A8re-Laoide?= <90181748+FredLL-Avaiga@users.noreply.github.com> Date: Fri, 20 Dec 2024 15:38:08 +0100 Subject: [PATCH] #2152 on submission change called twice with same status (#2353) (#2355) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * #2152 on submission change called twice with same status (#2353) #2305 normalize components height resolves #2152 #2305 * unused import * fix test * fix tests --------- Co-authored-by: Fred Lefévère-Laoide --- .../public/stylekit/controls/button.css | 4 + .../stylekit/controls/file_download.css | 3 + .../stylekit/controls/file_selector.css | 3 + .../public/stylekit/controls/selector.css | 2 +- .../public/stylekit/controls/slider.css | 1 + .../public/stylekit/controls/status.css | 1 + .../public/stylekit/controls/toggle.css | 3 + taipy/gui_core/_context.py | 100 +++++++++--------- tests/gui_core/test_context_is_readable.py | 6 +- 9 files changed, 65 insertions(+), 58 deletions(-) diff --git a/frontend/taipy-gui/public/stylekit/controls/button.css b/frontend/taipy-gui/public/stylekit/controls/button.css index 9bf4d9a171..f2b1e56a6e 100644 --- a/frontend/taipy-gui/public/stylekit/controls/button.css +++ b/frontend/taipy-gui/public/stylekit/controls/button.css @@ -21,6 +21,10 @@ MODIFIER CLASSES **************************************************/ +.taipy-button { + margin: 4px 0; +} + /* fullwidth : */ .taipy-button.fullwidth { display: flex; diff --git a/frontend/taipy-gui/public/stylekit/controls/file_download.css b/frontend/taipy-gui/public/stylekit/controls/file_download.css index 54085e4b4c..903818c918 100644 --- a/frontend/taipy-gui/public/stylekit/controls/file_download.css +++ b/frontend/taipy-gui/public/stylekit/controls/file_download.css @@ -20,6 +20,9 @@ /************************************************* MODIFIER CLASSES **************************************************/ +.taipy-file-download>button { + margin: 4px 0; +} /* fullwidth : */ .taipy-file-download.fullwidth button { diff --git a/frontend/taipy-gui/public/stylekit/controls/file_selector.css b/frontend/taipy-gui/public/stylekit/controls/file_selector.css index 08515985d8..d99757cdb8 100644 --- a/frontend/taipy-gui/public/stylekit/controls/file_selector.css +++ b/frontend/taipy-gui/public/stylekit/controls/file_selector.css @@ -20,6 +20,9 @@ /************************************************* MODIFIER CLASSES **************************************************/ +.taipy-file-selector .MuiButtonBase-root { + margin: 4px 0; +} /* fullwidth : */ .taipy-file-selector.fullwidth [role='button'] { diff --git a/frontend/taipy-gui/public/stylekit/controls/selector.css b/frontend/taipy-gui/public/stylekit/controls/selector.css index 0e56ecdc7d..cdb929aca4 100644 --- a/frontend/taipy-gui/public/stylekit/controls/selector.css +++ b/frontend/taipy-gui/public/stylekit/controls/selector.css @@ -22,7 +22,7 @@ **************************************************/ .taipy-selector { - margin: 0; + margin: 4px 0; } diff --git a/frontend/taipy-gui/public/stylekit/controls/slider.css b/frontend/taipy-gui/public/stylekit/controls/slider.css index 4bba39e40a..e978642689 100644 --- a/frontend/taipy-gui/public/stylekit/controls/slider.css +++ b/frontend/taipy-gui/public/stylekit/controls/slider.css @@ -26,4 +26,5 @@ max-width: 100%; min-height: 48px; align-items: center; + margin: 4px 0; } diff --git a/frontend/taipy-gui/public/stylekit/controls/status.css b/frontend/taipy-gui/public/stylekit/controls/status.css index c0e1d73381..3643303e77 100644 --- a/frontend/taipy-gui/public/stylekit/controls/status.css +++ b/frontend/taipy-gui/public/stylekit/controls/status.css @@ -25,4 +25,5 @@ display: inline-flex; min-height: 48px; padding-top: 0.5em; + margin: 4px 0; } diff --git a/frontend/taipy-gui/public/stylekit/controls/toggle.css b/frontend/taipy-gui/public/stylekit/controls/toggle.css index 7ff2b1afe9..2a75e9ee5e 100644 --- a/frontend/taipy-gui/public/stylekit/controls/toggle.css +++ b/frontend/taipy-gui/public/stylekit/controls/toggle.css @@ -36,6 +36,9 @@ /************************************************* MODIFIER CLASSES **************************************************/ +.taipy-toggle { + margin: 4px 0; +} /* relative : Reset the theme toggle position to fit page flow */ .taipy-toggle.relative { diff --git a/taipy/gui_core/_context.py b/taipy/gui_core/_context.py index 82f8b7bdad..59ba3dddad 100644 --- a/taipy/gui_core/_context.py +++ b/taipy/gui_core/_context.py @@ -33,7 +33,6 @@ Sequence, SequenceId, Submission, - SubmissionId, can_create, cancel_job, create_scenario, @@ -166,67 +165,64 @@ def submission_status_callback(self, submission_id: t.Optional[str] = None, even if not submission_id: return submission = None - new_status = None + new_status: t.Optional[SubmissionStatus] = None payload: t.Optional[t.Dict[str, t.Any]] = None client_id: t.Optional[str] = None + submission_name: t.Optional[str] = None try: - last_client_status = self.client_submission.get(submission_id) - if not last_client_status: + submission = t.cast(Submission, core_get(submission_id)) + if not submission or not submission.entity_id: return + new_status = submission.submission_status - client_id = last_client_status.client_id - - with self.gui._get_authorization(client_id): - if not is_readable(t.cast(SubmissionId, submission_id)): - return - submission = t.cast(Submission, core_get(submission_id)) - if not submission or not submission.entity_id: + with self.submissions_lock: + last_client_status = self.client_submission.get(submission_id) + if not last_client_status: return payload = {} - new_status = t.cast(SubmissionStatus, submission.submission_status) - - if client_id: - running_tasks = {} - # with self.gui._get_authorization(client_id): - for job in submission.jobs: - job = job if isinstance(job, Job) else t.cast(Job, core_get(job)) - running_tasks[job.task.id] = ( - SubmissionStatus.RUNNING.value - if job.is_running() - else SubmissionStatus.PENDING.value - if job.is_pending() - else None - ) - payload.update(tasks=running_tasks) - - if last_client_status.submission_status is not new_status: - # callback - submission_name = submission.properties.get("on_submission") - if submission_name: - self.gui.invoke_callback( - client_id, - submission_name, - [ - core_get(submission.id), - { - "submission_status": new_status.name, - "submittable_entity": core_get(submission.entity_id), - **(event.metadata if event else {}), - }, - ], - submission.properties.get("module_context"), + if last_client_status.submission_status is not new_status: + # callback + submission_name = submission.properties.get("on_submission") + + if new_status in ( + SubmissionStatus.COMPLETED, + SubmissionStatus.FAILED, + SubmissionStatus.CANCELED, + ): + self.client_submission.pop(submission_id, None) + else: + last_client_status.submission_status = new_status + + if client_id:= submission.properties.get("client_id"): + with self.gui._get_authorization(client_id): + if payload is not None: + running_tasks = {} + for job in submission.jobs: + job = job if isinstance(job, Job) else t.cast(Job, core_get(job)) + running_tasks[job.task.id] = ( + SubmissionStatus.RUNNING.value + if job.is_running() + else SubmissionStatus.PENDING.value + if job.is_pending() + else None ) + payload.update(tasks=running_tasks) - if new_status in ( - SubmissionStatus.COMPLETED, - SubmissionStatus.FAILED, - SubmissionStatus.CANCELED, - ): - with self.submissions_lock: - self.client_submission.pop(submission_id, None) - else: - last_client_status.submission_status = new_status + if submission_name: + self.gui.invoke_callback( + client_id, + submission_name, + [ + core_get(submission.id), + { + "submission_status": new_status.name if new_status else "None", + "submittable_entity": core_get(submission.entity_id), + **(event.metadata if event else {}), + }, + ], + submission.properties.get("module_context"), + ) except Exception as e: _warn(f"Submission ({submission_id}) is not available", e) diff --git a/tests/gui_core/test_context_is_readable.py b/tests/gui_core/test_context_is_readable.py index d321f31fb6..a2a4101bc9 100644 --- a/tests/gui_core/test_context_is_readable.py +++ b/tests/gui_core/test_context_is_readable.py @@ -215,10 +215,6 @@ def test_submission_status_callback(self): assert found is True mockget.reset_mock() - with patch("taipy.gui_core._context.is_readable", side_effect=mock_is_readable_false): - gui_core_context.submission_status_callback(a_submission.id) - mockget.assert_not_called() - def test_data_node_adapter(self): with patch("taipy.gui_core._context.core_get", side_effect=mock_core_get): gui_core_context = _GuiCoreContext(Mock()) @@ -386,7 +382,7 @@ def test_get_scenarios_for_owner(self): mockget.reset_mock() with patch("taipy.gui_core._context.is_readable", side_effect=mock_is_readable_false): - gui_core_context.submission_status_callback(a_scenario.id) + gui_core_context.get_scenarios_for_owner(a_scenario.id) mockget.assert_not_called() def test_update_data(self):