feat: disable Beamline tab when active pgroup is outside token pgroups
CI / lint (push) Skipped
CI / test (3.11) (push) Skipped
CI / test (3.12) (push) Skipped
CI / test (3.13) (push) Skipped
CI / test-with-beamline-plugins (pxi_bec) (push) Skipped
CI / test-with-beamline-plugins (pxii_bec) (push) Skipped
CI / test-with-beamline-plugins (pxiii_bec) (push) Skipped
CI / lint (push) Skipped
CI / test (3.11) (push) Skipped
CI / test (3.12) (push) Skipped
CI / test (3.13) (push) Skipped
CI / test-with-beamline-plugins (pxi_bec) (push) Skipped
CI / test-with-beamline-plugins (pxii_bec) (push) Skipped
CI / test-with-beamline-plugins (pxiii_bec) (push) Skipped
Switching to a visitor pgroup means running a user experiment: grey out the Beamline tab (tooltip: beamline scientists only), bring the Experiment tab forward with Dataset path and Exp. Config. opened. Gate applies on transitions only so manual tab choices survive the 1 Hz status ticks. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
@@ -596,6 +596,9 @@ class MainWindow(QMainWindow):
|
||||
# Tracks beamline-state TRANSITIONS for the default sample-tab switch
|
||||
# (see _apply_default_sample_tab).
|
||||
self._last_beamline_state: BeamlineStateEnum | None = None
|
||||
# None = not yet evaluated, so the first status tick always applies
|
||||
# the gate (the GUI may start while a visitor pgroup is active).
|
||||
self._beamline_tab_gated: bool | None = None
|
||||
|
||||
# Wrapper for the left inset: QTabWidget ignores its own contents
|
||||
# margins for the tab bar, so the padding lives one level up. Aligns
|
||||
@@ -2578,10 +2581,33 @@ class MainWindow(QMainWindow):
|
||||
else:
|
||||
self.sample_lists_tabs.setCurrentIndex(0)
|
||||
|
||||
def _apply_pgroup_gate(self, pgroup: str | None) -> None:
|
||||
# Switching to a pgroup outside the token's own (admin) pgroups means
|
||||
# running a visitor's experiment: the Beamline tab is then off-limits,
|
||||
# and the Experiment tab comes up with Dataset path + Exp. Config.
|
||||
# open. Applied only on gate TRANSITIONS so a manual tab choice
|
||||
# survives the 1 Hz status ticks.
|
||||
gated = pgroup is not None and pgroup not in (self._decoded_token.pgroups or [])
|
||||
if gated == self._beamline_tab_gated:
|
||||
return
|
||||
self._beamline_tab_gated = gated
|
||||
self.left_column_tabs.setTabEnabled(0, not gated)
|
||||
self.left_column_tabs.setTabToolTip(
|
||||
0, "Only accessible for beamline scientists" if gated else ""
|
||||
)
|
||||
if gated:
|
||||
self.left_column_tabs.setCurrentIndex(1)
|
||||
# persist=False: programmatic open must not overwrite the user's
|
||||
# saved per-panel collapse choice (same rule as the session gate).
|
||||
for banner in self.data_collection.findChildren(TitleLabel):
|
||||
if banner.text() in ("Dataset path", "Experiment configuration"):
|
||||
banner.set_collapsed(False, persist=False)
|
||||
|
||||
@Slot(DAQStatusModel)
|
||||
def update_daq_status(self, s: DAQStatusModel):
|
||||
self._latest_daq_status = s
|
||||
self._apply_session_gate(getattr(getattr(s, "session", None), "session", None))
|
||||
self._apply_pgroup_gate(getattr(getattr(s, "session", None), "current_pgroup", None))
|
||||
|
||||
# Default tab only on state TRANSITIONS — a manual tab choice
|
||||
# survives while the state stays put.
|
||||
|
||||
Reference in New Issue
Block a user