Feature/history panel - #339
Open
ThomasMalletCodra wants to merge 78 commits into
Open
Conversation
Assisted-by: Claude Opus 4.7
Migrated from history panel legacy branch
…get and HTML rendering
…el and related components
…ages and replay actions
(cherry picked from commit 6807861)
…s and add new history panel entries
Split the history feature into dedicated modules, refresh the GUI wiring and widgets, and update the related tests and translations.
# Conflicts: # datalab/locale/fr/LC_MESSAGES/datalab.po # doc/locale/fr/LC_MESSAGES/release_notes/release_1.03.po # doc/release_notes/release_1.03.md
Follow-up to a review noting that ruff/pylint had not been run on the History panel refactor after it was split into submodules. Cross-module access to underscore-prefixed members triggered W0212, plus a batch of other lint warnings that were addressed without disabling any checks.
Creation actions (new signal/image) were recorded in the history but, unlike process actions, could not be edited, recomputed or reverted. Editing a creation left downstream steps inconsistent. This makes creations first-class history actions: their parameters can be re-edited, the result is recomputed in place (keeping the UUID and downstream references), and the chain cascades correctly. * [NEW] : Allow editing creation (new_object) parameters via dialog and recompute in place, preserving the output UUID so downstream actions stay linked * [NEW] : Resolve target panel for UI creation actions so they replay and cascade like compute actions * [CHG] : add_ui_entry now returns the created HistoryAction, enabling creation output_uuids to be registered for downstream resolution * [CHG] : Restore/undo without saving now covers creation actions for both single action and full session * [FIX] : Snapshot creation parameters on edit for proper export/import and revert
…ompute Edit-mode replay opened parameter dialogs per selected action, each editing its own downstream chain. Overlapping chains caused repeated prompts and inconsistent state. Recompute also stopped at the edited action instead of cascading to the full downstream. * [FIX] : Process selected actions once via edit_mode_replay_actions, with deduplication, session-order sorting and a re-entrance guard, instead of calling edit_mode_replay per action * [FIX] : Replay only the selected actions; on param change, recompute in place then cascade fully downstream from the most upstream edited action * [CHG] : Cancel restores parameter snapshots for already-edited actions
Temporarily set aside two features not part of the current scope, without removing their implementation, and allow parameter editing when replaying a whole session in edit mode. * [CHG] : Hide the "Generate macro" action from the toolbar and context menu while keeping its implementation for a later re-enable * [CHG] : Hide the "Restore parameters" action from the toolbar and context menu while keeping the restore logic intact * [CHG] : Clicking a session in edit mode now replays it with parameter dialogs instead of a view-only replay, so session parameters stay editable
First two lots of the History-panel "workflow" refactor. Sessions remain the persistence unit and top-level tree items; processing chains are a derived, read-only view grouping actions by UUID parenthood. * [NEW] : Add pure, non-mutating read-model (chainmodel.py) with ProcessingChain dataclass, action_input_uuids, build_session_chains and build_processing_chains; deterministic grouping rooted at creation or external-root actions, dropping no action * [CHG] : Render the history tree in 3 levels (Session -> Chain -> Action) with new item-kind roles and _build_session_children; update populate_tree, add_action_to_tree, update_compatibility_states, get_selected_actions and get_selected_actions_or_sessions * [CHG] : Make select_action_in_tree and current_session depth-agnostic by walking to the top-level ancestor for the 3-level tree * [CHG] : Target the last action leaf of the session for post-delete auto-selection * [NEW] : Add test_history_chain_model_grouping and make the _get_tree_item_for helper depth-agnostic No persistence-format change. All history tests pass (21 passed), ruff clean.
This delivers two lots of the History-panel workflow refactor, both scoped to DataLab with no change to the persistence format. Deleting an intermediate history action previously truncated the whole session, discarding every downstream step. It now splices the action out of its processing chain and preserves the work that followed. When the deleted action had downstream steps, its now-orphaned output object is deep-copied into a new "Chain copy" group as a parentless creation root, and every downstream action consuming that output is rewired onto the copy, so the derived chain view renders those steps as a new independent chain. The persistent "Edit mode" toggle was error-prone as a long-lived session state. It is now hidden from the toolbar and context menu (code and API kept) in favor of two explicit launch modes, making replay intent clear at the moment the user triggers it. * [CHG] : Deleting an intermediate action now splits its processing chain instead of truncating the session; downstream steps are preserved on a deep-copied autonomous output and rendered as a new independent chain * [NEW] : Opt-in confirmation (skipped when unattended) to also remove the orphaned output object(s) from the workspace after a chain split * [CHG] : Hide the persistent "Edit mode" toggle from the toolbar and context menu, replaced by explicit "Replay" (silent) and "Step-by-step" launch modes; double-click behavior unchanged * [NEW] : "Step-by-step" replay action driving parameter dialogs and committing edits immediately, with no persistent edit session (replay_step_by_step) * [NEW] : French translations for the 6 new UI strings; resolved 2 fuzzy entries, including a stale "Processing chain — %d step(s)" that broke .mo compilation New tests: test_history_delete_splits_chain, test_history_step_by_step_launch. Full history suite: 23 passed, ruff clean.
The object-properties "Analysis parameters" section was read-only, so a user who wanted to re-run a 1-to-0 analysis (2D peak detection, FWHM, segments) with different settings had to restart the whole operation from scratch. This lot adds an editable "Analysis" tab that mirrors the existing editable Processing tab, letting the user adjust the stored parameters and re-run the analysis in place without polluting the history chain. * [NEW] : Add editable "Analysis" scroll tab to ObjectProp via setup_analysis_tab() and apply_analysis_parameters(); parameters are read from the object's ANALYSIS_PARAMETERS_OPTION metadata through extract_analysis_parameters (guards against None, non-1-to-0 and list params) * [NEW] : Re-run through processor.recompute_1_to_0() under the history replaying() guard so no synthetic history entry is created and the chain is left untouched * [NEW] : Add find_analysis_action() in history/chain.py (delegated from history/panel.py) to locate the matching 1-to-0 compute action by input UUID and function name, scanning most-recent-first for consistency with find_action_for_output * [CHG] : Extend update_properties_from with dynamic teardown/rebuild of the analysis tab; force_tab == "analysis" now prefers the editable tab and falls back to the unchanged read-only HTML view * [CHG] : On re-run, keep the located action consistent by refreshing snapshot_kwargs() and kwargs["param"] and updating the tree (no cascade, analysis is a leaf) * [CHG] : Force create_rois to False before recompute to avoid re-creating non-deletable ROIs when editing parameters Validation: new test_analysis_parameters_edit_image (peak-image threshold edit, recompute effect + ROI guard) plus analysis-recompute, result-deletion and full history suites all pass; ruff clean on all changed files; fr translations 100% translated and compiling.
- Introduce derived processing-chain view in the History panel - Split chains on delete and add step-by-step replay - Add editable analysis parameters tab for in-place re-run - Narrow history panel scope for the current deliverable
update_compatibility_states iterated every action item and resolved its uuid via get_action_from_uuid, which raises when the action is no longer in the model. During reconnect_chain_after_removal the recompute cascade emits SIG_OBJECT_MODIFIED (firing refresh_compatibility_items) before the final repopulate, so the tree transiently references a just-removed action and the Qt slot crashed with 'Action not found'. Build a uuid->action map once and skip unresolved items instead of raising; harden get_selected_actions[_or_ sessions] the same way. Add a regression test.
History duplication used to clone whole sessions and remap them at the session level, which left duplicated entries still pointing at the original objects' UUIDs. The feature is reworked around processing chains: selecting a session duplicates all its chains, selecting an action duplicates the single chain that contains it. Every cloned object receives a fresh UUID and all action references are remapped to the clones, so the result is an independent, editable and replayable session. Operation-rooted chains consume an object created outside the chain, so they cannot be replayed on their own. A synthetic "Initial state" creation head is prepended per distinct source object to materialize a clone snapshot, making such chains self-contained. * [CHG] : Resolve selection to processing chains via build_session_chains instead of normalising actions to their parent session * [FIX] : Assign a fresh UUID to every cloned object and remap all action references, fixing duplicated entries still referencing original UUIDs * [NEW] : Handle Cas A (creation-rooted chain) by duplicating the root new_object action as-is so it stays replayable * [NEW] : Handle Cas B (operation-rooted chain) by prepending a synthetic KIND_UI new_object head (empty kwargs/state, output_uuids=[clone]) recognised as a chain root by build_session_chains * [TEST] : Update test_history_duplication (scenarios 1-3) and add test_history_duplication_cas_a_creation_root and test_history_duplication_cas_b_synthetic_head (26 passed) * [NEW] : Add French translation "Initial state" -> "Etat initial"
A history session now represents exactly one linear processing chain. The previous read-model split a session into several chains at each creation action, which detached downstream processing when duplicating a session. Session boundaries are already decided at recording time (the "start a new history session?" prompt shown on object creation), so no per-creation splitting is performed at display time anymore. * [CHG] : build_session_chains() now returns a single ProcessingChain per session (root = first action, all actions kept in order) * [FIX] : copy_with_uuid_remap() resolves an effective panel string from the action target so new_object output UUIDs are remapped on duplication * [CHG] : Remove dead HistoryAction.regenerate_uuid no-op
Clean-up pass on the history panel: remove symbols that had no caller left in production nor in the test suite. This reduces the maintenance surface without changing any behaviour. * [CHG] : Remove unused add_to_history decorator and its _resolve_self_target helper (never applied anywhere), drop the add_to_history re-export * [CHG] : Remove unused add_entry entry-point and its panel delegation * [CHG] : Remove dead chain helper collect_downstream_uuids * [CHG] : Remove unused HistoryTree.get_selected_actions * [CHG] : Remove dead replay helpers edit_mode_replay (singular), view_only_session_replay and show_readonly_param_dialog * [CHG] : Remove ~14 dead HistoryPanel delegation methods that duplicated live module-level functions with no caller
The "Generate macro" action of the history panel was permanently hidden (setVisible(False), "out of current scope"). Remove it entirely together with its unreachable implementation to reduce the maintenance surface. * [CHG] : Remove the generate_macro_action and its HistoryPanel.generate_macro delegation from the history panel * [CHG] : Remove the historytools_ops.generate_macro implementation * [CHG] : Remove HistoryAction.to_macro_code (only consumed by generate_macro)
The "Restore parameters" toolbar/context action was permanently hidden (setVisible(False), "out of current scope"). Remove the dead UI entry point and its unused panel delegation. The underlying replay_restore_actions() branch is kept as it is still exercised elsewhere. * [CHG] : Remove the _restore_selection_action and all its references in create_menu_actions and update_actions_state * [CHG] : Remove the dead HistoryPanel.restore_action_params delegation
The "Edit mode" toggle action was permanently hidden (setVisible(False), superseded by the Replay / Step-by-step launch modes). Remove the dead UI entry point and its _edit_action attribute. The edit-mode mechanism itself is kept intact as it is still used by the recompute pipeline (is_edit_mode), the step-by-step replay and the test suite. * [CHG] : Remove the edit_action button, its _edit_action attribute and the now-useless action re-sync branch in toggle_edit_mode
Reflect the removal of the disabled "Generate macro", "Restore parameters" and "Edit mode" toolbar actions, and document the "New session" and "Step-by-step" actions that were missing. * [CHG] : Update historypanel.rst toolbar list to match the actual actions * [CHG] : Drop obsolete UI translation entries (Generate macro, Restore parameters, Edit mode and related strings) * [CHG] : Update the French documentation catalog for the history panel
Rename module-level functions, methods and the cross-module panel attributes so they no longer use the single leading-underscore "private" formalism, in line with the project coding conventions. This clears the protected-access (W0212) warnings raised on cross-module usage without introducing any lint suppression. Property backing fields and purely-internal attributes stay private. * [CHG] : Rename private history helper functions to public names * [CHG] : Rename private HistoryAction, WorkspaceState, HistoryPanel and HistoryTree methods to public names * [CHG] : Expose the cross-module panel flags (edit_replay_in_progress, suppress_session_prompt, session_input_pending) as public attributes
Metadata deletion, separate-view creation, and startup side effects could leave object models and remote-control operations inconsistent or make GUI tests depend on shared state. Preserve stable identities, decouple separate views from the main plot cache, and make test-only history tracking and unattended startup behavior explicit. * [FIX] : Preserve object UUIDs when deleting metadata so ObjectModel and RPC set_object operations remain coherent * [FIX] : Build separate-view items without requiring or mutating the main plot cache * [CHG] : Disable HistoryPanel tracking by default in test application contexts and explicitly enable it for history-dependent tests * [FIX] : Skip the guided tour during unattended startup while preserving the interactive preference and behavior * [FIX] : Add focused regression coverage for metadata identity, remote object updates, separate views, history isolation, and unattended startup
…ability
The History panel had accumulated overlapping responsibilities and broad tests,
making replay workflows harder to maintain and unrelated GUI tests sensitive to
persistent History state. Split the feature into cohesive services, simplified
object lifecycle flows, and replaced oversized coverage with focused behavioral
contracts across supported Python versions.
* [CHG] : Separate History runtime, UI, navigation, facade, and reconnection
responsibilities into cohesive components
* [NEW] : Extract replay UUID mapping and object creation services for reuse
across duplication, recompute, deletion, and HDF5 import workflows
* [FIX] : Keep runtime output indexes consistent and preserve plugin
provenance when replaying or reconnecting objects
* [CHG] : Replace overlapping History tests with 12 compact behavioral
contracts and a dedicated visual smoke test
* [FIX] : Disable History tracking by default in unrelated GUI tests and
prevent unattended runs from persisting dock or current-tab state
Consolidate the History panel implementation around explicit runtime, navigation,
replay, and persistence responsibilities. This integration also preserves object
identity across metadata and remote-control workflows while isolating GUI tests
from interactive application state.
* [CHG] : Split History runtime, UI, navigation, facade, and reconnection
responsibilities into cohesive components
* [NEW] : Add reusable replay UUID mapping and object creation services
* [FIX] : Preserve object UUIDs across metadata deletion, remote updates,
separate views, replay, duplication, and HDF5 persistence
* [FIX] : Keep action/output indexes and plugin provenance consistent during
deletion, recomputation, reconnection, duplication, and import
* [CHG] : Replace overlapping History tests with focused model, workflow,
navigation, persistence, and visual contracts
* [FIX] : Isolate unattended GUI tests from History tracking, guided-tour
startup, dock visibility, and persistent current-tab state
# Conflicts: # datalab/gui/panel/base.py # datalab/gui/processor/base.py # datalab/tests/features/common/auto_analysis_recompute_unit_test.py # doc/locale/fr/LC_MESSAGES/release_notes/release_1.03.po
Post-merge auditing exposed cases where plugin provenance could be lost during History operations, partial recomputation failures could leave outputs in an inconsistent state, and multi-action edits could replay dependent work more than once. History execution now preserves feature identity, reports failures explicitly, and applies dependent updates in a deterministic, transactional way. * [FIX] : Preserve plugin origins when replaying actions, remapping metadata, recomputing transformations, and refreshing analyses * [FIX] : Stop dependent cascades after failed actions and keep affected actions stale while allowing independent branches to continue * [FIX] : Validate multi-output recomputation before updating objects and roll back all outputs when an update cannot be completed * [FIX] : Isolate multi-object analysis persistence failures, continue with remaining objects, and distinguish empty results from failed execution * [CHG] : Deduplicate and globally order multi-action edits, restore action state on cancellation, and cascade analyses after upstream changes * [NEW] : Add regression coverage for plugin provenance, transactional recomputation, cascade failures, and multi-action History edits * [CHG] : Synchronize French translations for recomputation failure messages
# Conflicts: # datalab/gui/newobject.py # datalab/gui/processor/base.py # datalab/gui/processor/signal.py # datalab/tests/features/common/interactive_processing_test.py # datalab/tests/features/signal/fitdialog_unit_test.py # datalab/widgets/fitdialog.py
dappham-CODRA
force-pushed
the
feature/history-panel
branch
from
July 30, 2026 10:59
30ce255 to
0d2a98a
Compare
Editing a complete History session could bypass the global in-place recompute planner, while multi-output or legacy actions could lose downstream dependencies after runtime mappings were pruned. All edit selections now use one deduplicated plan with consistent output UUID resolution. * [FIX] : Expand selected sessions into actions and process overlapping selections once through the global edit planner * [FIX] : Resolve dependency closure and failed-branch blocking from durable, runtime, then legacy output UUIDs * [CHG] : Cover Qt tree selection, pruned multi-output mappings, and legacy failed branches on Python 3.9 and 3.14
Edited image creation needs a pure non-GUI regression contract to ensure cascade recomputation preserves existing workspace objects while propagating regenerated data to downstream processing. * [CHG] : Verify the exact edited Gauss2D parameters reach production image creation * [CHG] : Verify source identity, UUID and metadata are preserved in place * [CHG] : Verify downstream 1-to-1 processing consumes regenerated data and updates its existing output in place
History sessions exposed redundant hierarchy and could route actions through the current panel instead of their actual data owner, causing unnecessary prompts and incorrect signal or image session assignment. * [CHG] : Name default sessions "Processing" and display actions directly beneath their session * [FIX] : Skip first-use prompts and create type-specific sessions for new or loaded signals and images * [FIX] : Preserve effective data ownership during recording, loading, navigation, replay, and legacy action handling * [FIX] : Keep image histogram actions in the image session when producing signal outputs * [CHG] : Add pure non-GUI unit coverage for session naming, routing, prompting, legacy compatibility, and histogram ownership
History session creation relied on a fixed prompt flow, preventing callers from consistently choosing whether new inputs start or continue a populated session. Add persisted ask/yes/no policies and a typed decision path, ahead of separate plugin runtime integration. * [NEW] : Add persisted policies for regular inputs, plugin-created inputs, and plugin multi-load operations * [NEW] : Expose history session policies in the processing settings * [CHG] : Propagate typed policies and session-creation results through the history facade * [NEW] : Cover explicit policies, invalid values, and settings round trips with focused tests
Plugin-created objects did not consistently honor the configured session policy, and multi-object loads could prompt repeatedly or consume their decision before an object was accepted. Resolve persisted policies at the insertion boundary and carry one lazy, panel-specific decision across each plugin batch. * [FIX] : Apply live general and plugin ask/yes/no settings while preserving explicit per-call choices * [NEW] : Add a validated multi-load scope that decides on the first accepted object and leaves empty or cancelled batches untouched * [FIX] : Decide before insertion, suppress duplicate prompts, report memory refusals, and debounce signal and image panels independently * [CHG] : Batch Test Data plugin loads using the matching data panel * [NEW] : Cover plugin policy behavior and add French settings translations
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
No description provided.