mirror of
https://github.com/openobserve/openobserve.git
synced 2026-11-04 08:09:27 +00:00
# Design System Unification — one visual language, enforced end-to-end
Establishes **one source of truth for every visual decision**, wires the
whole app to it, and **locks it in with CI** so it can't drift back.
### Foundations
- **Design-token system ("one knob per decision").** Every colour, text
size, spacing, corner radius, and shadow is a named token defined in
exactly one place — change the token, every screen updates. Collapsed
hundreds of near-duplicate definitions and removed "fake" duplicates
that pretended to be different but weren't.
- **Shared component library (O2).** Buttons, tables, dialogs, drawers,
form fields, badges, etc. already know the correct colours, spacing, and
dark-mode behaviour; new screens compose them instead of hand-styling.
Added new primitives on this branch (`OContent`, `KpiCard`) and
standardized existing ones.
- **One page structure everywhere** (`PageLayout` / `AppPageHeader` /
`AppPage` / `OContent`) — titles, breadcrumbs, spacing, and content
edges line up identically across every screen.
- **One table implementation** — all tabular data uses the same table
(sorting, density, sticky headers, empty states).
- **Styling consolidated onto Tailwind; old systems removed** —
hand-written CSS driven to the practical minimum, the legacy **Quasar**
framework fully removed, surviving stylesheets required to justify
themselves.
- **Two-tier corner radius** — a tight **4px** for controls and a soft
**12px** for surfaces (dialogs, cards, the app shell), plus a
full-circle option — replacing five radius names that all secretly meant
the same thing.
### Detailed improvements across screens
**Page structure & alignment** — unified page shell rolled across ~40+
screens (IAM, Settings, Alerts, Dashboards, Functions, Pipelines, RUM,
Metrics, Synthetics, Billing, editors, lists); one header height; one
page-edge grid driving headers, tables, rails, and tabs; unified
side-rail widths; inset rail selection/hover pills; every tab strip on
the grid line; tightened title/subtitle spacing.
**Tables (cross-screen)** — action columns consistently centered (incl.
Organizations); unified row-number column with no "#" truncation;
non-standard tables restyled to match; loading skeletons made
geometrically identical to the loaded table; symmetric edge inset; IAM
first-column grid alignment fixed.
**Traces** — flame graph + span-detail correlation panel fixes;
correlated logs/metrics placeholder fit; sticky headers; removed a
double scrollbar + a 1px sliver; aligned table fonts/badges; polished
the service detail drawer; stream-selector + correlation alignment;
aligned loading spinners; floating overlay arrows for the
disabled-services strip.
**Logs** — field-list controls aligned (focus ring no longer clipped);
detail-drawer spacing + metrics-tab overflow fixed; Run Query toolbar
tidied; listing sizing + stray border fixed.
**Metrics** — search added to the "Type" facet rail and aligned with the
other rails; proper empty states for the explorer and facet rail.
**Dashboards** — removed inconsistent card shadows; tightened
borders/resizers/field-list spacing; aligned View Dashboard chrome to
the grid; chart colours via the token helper.
**Home** — redesigned the Usage tab; added reusable KPI stat cards so
summary strips stop drifting.
**Dark mode** — new theme-switch animation; fixed a 1px content shift on
toggle and a white flash on load; fixed AI-chat text and assorted
light/dark mismatches; completed the token-driven dark migration.
**Empty states, controls & small polish** — restored 3 broken
empty-state animations; adopted the standard empty state; added the
sliding indicator to the toggle control; fixed the Quality-page inset +
drawer badge; refreshed Search History / Schedulers; fixed the
alert-history drawer scrollbar + timeline hover; removed a stray
menu-bar border.
### Dead code & cruft removal
- **Deleted the entire legacy `utilities.css`** global stylesheet (well
over a thousand lines) — evacuated in waves, roughly half of it dead
once traced.
- **Removed Quasar entirely**, including dead `.q-*` styles and ~25
phantom `--q-*` variables that were silently breaking bits of the UI.
- Stripped hundreds of **dead CSS classes and tokens that compiled to
nothing** — e.g. 46 uses of a colour class with no backing token, a
no-op shadow class on 51 elements, dead layout/utility classes, a
leftover `card-container` block, a dead table-actions token, and a
mis-registered gradient that rendered nothing.
- Cut **unused keyframe animations (19 → 3)** and removed **unused
components** + a stray build artifact.
- Net effect: a much smaller, leaner styling surface — less to maintain,
fewer dead ends to copy.
## Safety & verification
Large but low-risk: this is overwhelmingly a **styling and structure**
change, not product behaviour or data. Guarded by the
design-token/consistency/type checks above plus the existing test suite,
and reviewed screen-by-screen.
---------
Co-authored-by: Kirtan Thakkar <kirtan@kiara.tech>
Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
Co-authored-by: ktx-mihir <mihir.patel@kiara.tech>
62 lines
2.8 KiB
Bash
62 lines
2.8 KiB
Bash
#!/usr/bin/env bash
|
|
# Copyright 2026 OpenObserve Inc.
|
|
# Regenerates the quantitative numbers in web/SPACING_AUDIT.md.
|
|
# Usage: bash web/scripts/spacing-audit.sh (requires ripgrep + python3)
|
|
# Writes per-category lists to /tmp/spacing_audit_*.txt
|
|
set -euo pipefail
|
|
cd "$(dirname "$0")/../src"
|
|
|
|
# ripgrep: use the real binary, or fall back to the one bundled with Claude Code
|
|
if ! command -v rg >/dev/null 2>&1; then
|
|
_cc="${CLAUDE_CODE_EXECPATH:-$HOME/.local/bin/claude}"
|
|
if [[ -x "$_cc" ]]; then
|
|
rg() { ( exec -a rg "$_cc" "$@" ); }
|
|
else
|
|
echo "ripgrep (rg) is required: brew install ripgrep" >&2; exit 1
|
|
fi
|
|
fi
|
|
|
|
OUT=/tmp
|
|
EXCL=(-g '!*.spec.*' -g '!test/**' -g '!__mocks__/**' -g '!assets/dashboard/echarts.min.js')
|
|
PROPS='(?:p|px|py|pt|pr|pb|pl|m|mx|my|mt|mr|mb|ml|gap|gap-x|gap-y|space-x|space-y)'
|
|
|
|
echo "== 1. Tailwind spacing utility histogram =="
|
|
rg -o --no-filename -g '*.vue' "${EXCL[@]}" "\\b${PROPS}-(?:\\d+(?:\\.\\d+)?|\\[[^\\]]+\\])" \
|
|
| sort | uniq -c | sort -rn > "$OUT/spacing_audit_utilities.txt"
|
|
awk '{s+=$1} END {print "total:", s, "distinct:", NR}' "$OUT/spacing_audit_utilities.txt"
|
|
|
|
echo "== 2. Scale-step histogram (props aggregated) =="
|
|
awk '{n=$1; cls=$2; sub(/^[a-z-]+-/,"",cls); steps[cls]+=n} END {for (s in steps) print steps[s], s}' \
|
|
"$OUT/spacing_audit_utilities.txt" | grep -v ' \[' | sort -rn | tee "$OUT/spacing_audit_steps.txt"
|
|
|
|
echo "== 3. Arbitrary values: convertible vs off-grid =="
|
|
grep ' \S*\[' "$OUT/spacing_audit_utilities.txt" > "$OUT/spacing_audit_arbitrary.txt" || true
|
|
python3 - "$OUT/spacing_audit_arbitrary.txt" <<'EOF'
|
|
import re, sys
|
|
conv=off=pxv=other=0; offs=[]
|
|
for line in open(sys.argv[1]):
|
|
n, cls = int(line.split()[0]), line.split()[1]
|
|
m = re.search(r'\[([0-9.]+)rem\]', cls)
|
|
if m:
|
|
suffix = float(m.group(1)) / 0.25
|
|
if abs(suffix*4 - round(suffix*4)) < 1e-9: conv += n
|
|
else: off += n; offs.append((n, cls))
|
|
elif re.search(r'\[[0-9.]+px\]', cls): pxv += n
|
|
else: other += n
|
|
print("convertible-to-class:", conv, "| off-grid:", off, "| px:", pxv, "| other:", other)
|
|
for n, c in sorted(offs, reverse=True): print(f" {n:4d} {c}")
|
|
EOF
|
|
|
|
echo "== 4. CSS padding/margin declarations =="
|
|
rg -o --no-filename -g '*.vue' -g '*.css' -g '*.scss' "${EXCL[@]}" -g '!lib/styles/tokens/**' \
|
|
'(?:padding|margin)(?:-(?:top|right|bottom|left))?\s*:\s*[^;}"]+' \
|
|
| sed 's/\s\+/ /g' | sort | uniq -c | sort -rn > "$OUT/spacing_audit_css.txt"
|
|
awk '{s+=$1} END {print "total:", s, "distinct:", NR}' "$OUT/spacing_audit_css.txt"
|
|
|
|
echo "== 5. Spacing token adoption =="
|
|
printf 'var(--spacing-*) outside token files: '
|
|
rg --no-filename -g '!lib/styles/tokens/**' -g '!*.spec.*' 'var\(--spacing-' | wc -l | tr -d ' '
|
|
|
|
echo "== 6. Top files by arbitrary spacing =="
|
|
rg -c -g '*.vue' "${EXCL[@]}" "\\b${PROPS}-\\[[^\\]]+\\]" | sort -t: -k2 -rn | head -15
|