Move service application and database settings into an embedded modal with a footer, subtitle helper, and Docker restart-count control. Accept max_restart_count on the service applications API, cap compose YAML collection aliases, and tighten status, backup, and database sidebar layouts.
S3-compatible and legacy buckets may include uppercase letters. Relax the bucket name pattern, validation messages, and tests so those names are accepted while still rejecting invalid characters and formats.
Normalize schemes when comparing routing identities and include per-service
Compose domains in conflict checks. Show the conflicting service name and
align the service domains heading layout.
Add indexing, redirect, and hostname regeneration controls to domain editors. Queue DNS checks only for scheme or hostname changes and show progress consistently across application, service, and preview domains.
Add restartLimitReached to the notification event toggle list so admins can disable restart-limit email notifications. Cover the toggle with an authorization test.
Pull image-based Docker Compose services with --ignore-buildable before stopping the current deployment so image-only services are ready first. Fail the deploy if pull fails, and run the pull on the runtime server when a build server is used.
Extract a shared view-toggle utility so list/grid switchers use the same 32px control height instead of mixed h-8/h-9 styles. Point section-heading View all links at the shared button class so they match other actions.
Honor an explicit sidebarCollapsed preference instead of always auto-collapsing with a second nav. Show the primary domain on the application access card, use a persisted GitLab name in the page title after delete, and shrink the compose view switcher.
Remove the enable/disable toggle from the server UI, logs page, and
Sentinel API so is_sentinel_enabled is derived and read-only. Enable
existing regular servers via migration, start Sentinel after validate-
and-install, and drop the daily ServerManagerJob restart.
Replace the collapsible mobile configuration menu with an always-visible
responsive grid, stack the mobile heading, and swap the domain editor
unsaved bar for a sticky Save footer with a scrollable form body.
Centralize scp-style Git URL parsing so user@host:path (including custom
usernames and embedded ports) is accepted and converted to HTTPS for
public clones, API create, webhooks, validation, and commit/branch links.
Use resolveStoredTeam() instead of teams()->first() when picking the
next active team after a team deletion or when an admin switches into
a user's account, so a valid stored preference wins over an arbitrary
first team. DeleteTeam now returns null when the deletion leaves the
owner with multiple teams, deferring to the selection screen instead
of guessing. refreshSession also stops persisting current_team_id
while impersonating, so viewing another user's account no longer
overwrites their real last-active team.
Make clearStoredTeamIfMatches perform an atomic conditional UPDATE
so a concurrent team switch isn't clobbered, and call it for the
deleting owner in DeleteTeam so their stored team id doesn't point
at a deleted team. refreshSession now falls back to
resolveStoredTeam() instead of an arbitrary first team. Add a
return type to SelectTeam::render() and tests covering owner
deletion and concurrent-selection preservation.
Reset the user's persisted current_team_id when they are removed from
a team, when their team is deleted, or when refreshSession finds no
team left, so a dangling reference is never restored on next login.
Add current_team_id to users so the last active team is restored on
login instead of always defaulting to the personal team. When a user
belongs to multiple teams and has no valid stored choice, redirect
them to a new team.select screen (SelectTeam Livewire component) to
pick one, rather than silently choosing the first team. Update
Fortify and OAuth login flows to use the new resolveStoredTeam()
logic.
The metrics-disabled empty state already titles itself "Metrics are disabled", so the extra status badge was redundant. Cover the Sentinel-enabled branch so that badge does not return.
Move the settings-section body class onto each domain group so apps
render as stacked cards instead of a single bordered list. Update the
ServiceDomains view assertions to match.
Standard buttons now capitalize each word in their labels. Movement and
depth-shadow changes use an 80ms duration while color transitions stay
at 120ms.
Neutral buttons in dark mode now use a white 8% depth edge so it matches
the regular border. Highlighted buttons keep the accent-mixed edge.
Document the behavior and assert the dark-mode selector in CSS tests.
Standard .button controls now use a compact 2px bottom edge, lift 1px on
hover, and press down with the depth removed. Highlighted buttons mix the
accent with black for a matching edge, and focus-visible keeps the accent
ring. Other button-like controls still use the lighter scale press.
Scroll active application settings sections with buttons instead of Livewire navigation, persist sidebar collapse even with auto-collapse, drop the unused modal id, and right-align destination status.
Replace inline modal-shadow styles on toasts, popups, and warning
banners with a shared `surface-popover` utility that uses the lighter
dropdown shadow instead of the heavier modal shadow. Apply the same
`shadow-dropdown` swap to the deployments indicator pill and the
server/deployment log floating menus. Remove now-unused console
header and error-contact-link rules from app.css, and add a test
asserting these surfaces consistently use the dropdown shadow.
Auto-collapse the main sidebar on pages that have a settings rail (follows
the page when enabled; expanded elsewhere), with an animated slide and a
profile-menu toggle (localStorage) to disable it.
Rework the settings rail to position:fixed like the main sidebar: full
height (3rem -> viewport bottom), left tracks the sidebar's collapsing
width via --sidebar-w, content pinned to grid column 2. Fixes the sticky
scroll crop and top/bottom gaps.
Turn the floating card settings rail into a flat, full-height rail welded
to the main sidebar (3rem -> bottom), surface bled across main's gutter.
Unify the application config grid to the canonical 210px/gap-8 (was the
lone 236px/gap-4 outlier). Affects all shared settings rails.
Introduce theme-controls and theme-controls/picker Blade components
housing the theme/page-width/custom-color logic previously duplicated
in top-user-menu and profile/appearance, and fix custom theme surface
colors to use oklch mixes instead of raw white/black/hex for correct
contrast.
Give the connected terminal (System theme) the same construction as the
target-picker card: an attached elevated header band holding the target and
theme selectors, a hairline frame, and a body panel whose ring forms the
divider and rounds into the header at the corners. The rounded-corner notch
now shows the elevated (header) surface while the terminal keeps a base fill.
Colorful console themes are unchanged.
- Settings rail (application-settings-navigation) is now white in light mode
instead of a gray fill; separation comes from the hairline ring + soft lift.
- Mobile slide-over: replace the heavy shadow-modal with a soft left-casting
shadow (scrim handles content dimming, shadcn-style) + rounded-l corners.
- Unify scattered shadow-lg usages onto the shadow-dropdown / shadow-modal
tokens across dropdowns, tooltips, popups and slide-over.
- Light-mode semantic text + tertiary/nav contrast tuning for WCAG AA.
- status-summary: support right-aligned dropdown; use it on the app heading.
Add shared easing curves and press/focus transitions for buttons, inputs,
and form controls in app.css. Refine dropdown, modal, tooltip, and
slide-over enter/leave transitions to use consistent easing and durations,
and remove the focus-visible box-shadow ring on inputs/selects in favor of
border-color transitions.
- Add reusable <x-section-heading> (title, muted subtitle, optional action)
with a compact contained "View all" button; migrate dashboard Projects/
Servers/Deployments and shared-variables environment headers to it.
- Dashboard: hide the empty active-deployments node so it no longer adds a
gap above the first section; align section actions with the title row.
- Mobile: use the panel-left sidebar-toggle icon (matching desktop) as the
drawer trigger instead of a hamburger.