Wrap the top bar's buttons onto a second row when narrow (closes #272)
Check / check (pull_request) Skipped
Check / check (pull_request) Skipped
The top bar's two sides were held apart only by justify-between, with no gap and no wrapping, so at 390 px "by @sneak" ended where the New App button began. The bar's row now wraps and has a gap: in a window too narrow for one row, New App and Logout move to a second row; on wider windows the bar looks as before. Model: opus-5-5
This commit is contained in:
@@ -20,6 +20,10 @@ regress.
|
|||||||
|
|
||||||
# Completed Steps
|
# Completed Steps
|
||||||
|
|
||||||
|
- 2026-10-02: In a window too narrow for the top bar, such as 390 px, the New
|
||||||
|
App and Logout buttons move to a second row instead of running into "by
|
||||||
|
@sneak"; the bar keeps a gap between its two sides at every width (#272).
|
||||||
|
|
||||||
- 2026-10-02: App names may contain dots, such as `sneak.berlin`: lowercase
|
- 2026-10-02: App names may contain dots, such as `sneak.berlin`: lowercase
|
||||||
letters and numbers joined by single dots or by hyphens, 2 to 63 characters.
|
letters and numbers joined by single dots or by hyphens, 2 to 63 characters.
|
||||||
Docker accepts every such name in the image name `upaas-<name>`; a dot needs a
|
Docker accepts every such name in the image name `upaas-<name>`; a dot needs a
|
||||||
|
|||||||
@@ -52,3 +52,26 @@ func TestDashboardTableFitsCard(t *testing.T) {
|
|||||||
assert.Contains(t, cellTag, "whitespace-normal")
|
assert.Contains(t, cellTag, "whitespace-normal")
|
||||||
assert.Contains(t, cellTag, "break-all")
|
assert.Contains(t, cellTag, "break-all")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TestTopBarWrapsWhenNarrow checks that the top bar keeps a gap between the
|
||||||
|
// µPaaS title and the New App and Logout buttons, and puts the buttons on a
|
||||||
|
// second row in a window too narrow for one, instead of letting them meet.
|
||||||
|
func TestTopBarWrapsWhenNarrow(t *testing.T) {
|
||||||
|
t.Parallel()
|
||||||
|
|
||||||
|
testCtx := setupTestHandlers(t)
|
||||||
|
|
||||||
|
request := httptest.NewRequestWithContext(t.Context(), http.MethodGet, "/", nil)
|
||||||
|
recorder := httptest.NewRecorder()
|
||||||
|
|
||||||
|
testCtx.handlers.HandleDashboard().ServeHTTP(recorder, request)
|
||||||
|
|
||||||
|
require.Equal(t, http.StatusOK, recorder.Code)
|
||||||
|
|
||||||
|
_, afterNav, found := strings.Cut(recorder.Body.String(), `<nav class="app-bar">`)
|
||||||
|
require.True(t, found, "dashboard has no top bar")
|
||||||
|
|
||||||
|
rowTag, _, _ := strings.Cut(strings.TrimSpace(afterNav), ">")
|
||||||
|
assert.Contains(t, rowTag, "flex-wrap")
|
||||||
|
assert.Contains(t, rowTag, "gap-")
|
||||||
|
}
|
||||||
|
|||||||
+1
-1
@@ -26,7 +26,7 @@
|
|||||||
|
|
||||||
{{define "nav"}}
|
{{define "nav"}}
|
||||||
<nav class="app-bar">
|
<nav class="app-bar">
|
||||||
<div class="max-w-6xl mx-auto flex justify-between items-center">
|
<div class="max-w-6xl mx-auto flex flex-wrap justify-between items-center gap-3">
|
||||||
<div class="flex items-center gap-3">
|
<div class="flex items-center gap-3">
|
||||||
<a href="/" class="text-xl font-medium text-gray-900 hover:text-primary-600 transition-colors">µPaaS</a>
|
<a href="/" class="text-xl font-medium text-gray-900 hover:text-primary-600 transition-colors">µPaaS</a>
|
||||||
<span class="text-sm text-gray-500">by <a href="https://sneak.berlin" class="text-primary-600 hover:text-primary-800">@sneak</a></span>
|
<span class="text-sm text-gray-500">by <a href="https://sneak.berlin" class="text-primary-600 hover:text-primary-800">@sneak</a></span>
|
||||||
|
|||||||
Reference in New Issue
Block a user