From d7cf778feea6fbc53133073da43f027d604bb987 Mon Sep 17 00:00:00 2001 From: Bernhard Windisch Date: Wed, 1 Jul 2026 11:01:22 +0200 Subject: [PATCH] fix(admin): keep the Regenerate-Secret button reachable in the client modal MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The OAuth-client modal's left "General" column is an independent scroll region (`.col-identity`, a flex column). Two layout bugs hid the Regenerate-Secret button — its last child — at a real (100%) zoom: 1. `.two-col` is a CSS grid with no explicit rows track, so the single implicit row was `auto` and sized to the taller (right) column's content, overgrowing the modal body. The left column then never scrolled and its bottom slid under the sticky footer. Fixed with `grid-template-rows: minmax(0, 1fr)` so each column scrolls within the modal height. 2. As a flex column, an overflowing `.col-identity` shrinks its most shrinkable child to fit. The button (`overflow:hidden` → 0 min-height) was that child, so it collapsed to `height:0` and vanished — only reappearing when zoomed out far enough to stop the overflow. Fixed by pinning the column's children to `flex-shrink: 0` so the column scrolls instead of crushing them. Verified live: the button now renders at full height, is reachable by scrolling the column, and sits above the footer. Co-Authored-By: Claude Opus 4.8 (1M context) --- .../src/views/admin/oauth/ClientDetails.vue | 20 +++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/src/frontend-vue/src/views/admin/oauth/ClientDetails.vue b/src/frontend-vue/src/views/admin/oauth/ClientDetails.vue index 77eb4564..2133a008 100644 --- a/src/frontend-vue/src/views/admin/oauth/ClientDetails.vue +++ b/src/frontend-vue/src/views/admin/oauth/ClientDetails.vue @@ -732,6 +732,13 @@ async function copySecret() { flex: 1; display: grid; grid-template-columns: 24rem 1fr; + /* Bind the single implicit row to the flex-allocated height. Without an + explicit rows track the row is `auto` and sizes to the taller column's + content, so it can overgrow the modal body — then `.col-identity`'s + overflow never engages and its last element (the Regenerate-Secret + button) is pushed under the sticky footer, unreachable by scroll. + `minmax(0, 1fr)` clamps the row so each column scrolls independently. */ + grid-template-rows: minmax(0, 1fr); gap: 1.25rem; min-height: 0; min-width: 0; @@ -741,10 +748,23 @@ async function copySecret() { flex-direction: column; gap: 0.6rem; padding-right: 1.25rem; + /* Bottom breathing room so the last control (Regenerate Secret) clears the + scroll-area edge instead of sitting flush against it. */ + padding-bottom: 0.5rem; border-right: 1px solid var(--coar-border-neutral-secondary, #e5e7eb); overflow-y: auto; min-height: 0; } + +/* This is a scroll container: its children must keep their natural height and + let the column scroll — never be flex-shrunk to fit. Without this the last + item (the Regenerate-Secret button, whose overflow:hidden gives it a 0 + min-height) is the most shrinkable child, so an overflowing column crushes + it to height:0 and it vanishes (it only reappeared when zoomed out far + enough that the content stopped overflowing). */ +.col-identity > * { + flex-shrink: 0; +} .col-heading { margin: 0 0 0.25rem 0; font-size: 0.78rem;