feat: show locked beamline banners to non-staff

Beamline setup, ABR meas. pos. and Beam configuration banners stay
visible for non-staff instead of vanishing, but are locked stand-ins:
clicking one pops the staff-only notice (same pattern as the
Auxiliary-puck tab) telling the user to log in as staff or contact
their local contact.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
2026-08-13 15:05:42 +02:00
co-authored by Claude Fable 5
parent 656b441593
commit 1bce76e6fc
+39 -1
View File
@@ -362,6 +362,10 @@ class MainWindow(QMainWindow):
beamline_layout = QVBoxLayout(beamline_page)
beamline_layout.setContentsMargins(0, 0, 0, 0)
self.samcam = SamcamPanel(beamline_page)
# Non-staff keep the staff-only banners visible (locked stand-ins, a
# click explains the gate) so the Beamline tab reads the same for
# every role instead of looking amputated.
self._locked_beamline_banners: list[TitleLabel] = []
if self._decoded_token.staff:
self.monochromator_panel = MonochromatorPanel(beamline_page)
self.abr_tweak = AbrTweakWidget(beamline_page)
@@ -372,6 +376,20 @@ class MainWindow(QMainWindow):
beamline_layout.addWidget(self.monochromator_panel)
beamline_layout.addWidget(self.abr_tweak)
beamline_layout.addWidget(self.beam_config)
else:
for title in ("Beamline setup", "ABR meas. pos.", "Beam configuration"):
# Holder with default layout margins so the banner aligns with
# the real panels' banners (same trick as BeamConfigPanel).
holder = QWidget(beamline_page)
holder_layout = QVBoxLayout(holder)
holder_layout.setSpacing(0)
banner = TitleLabel(title, holder)
banner.setCursor(Qt.CursorShape.PointingHandCursor)
banner.setToolTip("Only accessible for beamline scientists")
banner.installEventFilter(self)
holder_layout.addWidget(banner)
beamline_layout.addWidget(holder)
self._locked_beamline_banners.append(banner)
# Samcam last: the beam panels are the ones tweaked most.
beamline_layout.addWidget(self.samcam)
beamline_layout.addStretch()
@@ -403,7 +421,13 @@ class MainWindow(QMainWindow):
# Dewar-tabs look: first banner flush under the tab bar (no top
# margin) and the tab row starting at the banners' left edge. The
# Experiment side needs two levels: the frame AND its first panel.
beamline_first = self.monochromator_panel if self._decoded_token.staff else self.samcam
beamline_first = (
self.monochromator_panel
if self._decoded_token.staff
# Non-staff: the first locked banner's holder is the column's
# first widget now, not samcam.
else self._locked_beamline_banners[0].parentWidget()
)
for first in (beamline_first, self.data_collection, self.data_collection.file_path_panel):
first_layout = first.layout()
assert first_layout is not None # panels build their layouts in __init__
@@ -1391,6 +1415,15 @@ class MainWindow(QMainWindow):
"The Auxiliary puck (reference tools) view is available to staff accounts only.",
)
def _show_beamline_staff_only_popup(self) -> None:
QMessageBox.information(
self,
"Staff only",
"Beamline configuration is available to staff accounts only.\n"
"Log in with a staff account or contact your local contact "
"to configure the beamline.",
)
@Slot()
def _raise_reference_tools(self) -> None:
if not self._decoded_token.staff:
@@ -3182,6 +3215,11 @@ class MainWindow(QMainWindow):
):
self._show_reference_tools_staff_only_popup()
return True
# Non-staff click on a locked Beamline banner: same treatment as the
# Auxiliary-puck tab — explain the gate instead of eating the click.
if event.type() == QEvent.Type.MouseButtonPress and obj in self._locked_beamline_banners:
self._show_beamline_staff_only_popup()
return True
return super().eventFilter(obj, event)
def _start_remote_close_countdown(