Skip to content

Commit c9f9897

Browse files
committed
Show profile name and metastore separately in topbar, fix modal close buttons
Topbar now shows CLI profile name (instead of workspace name) when connected via profile mode, with metastore name displayed separately next to the host URL. Extracted get_metastore_name() from get_workspace_name() to avoid duplication. Fixed modal close buttons invisible in dark mode by replacing filter-based approach with pure CSS white X pseudo-elements. Co-authored-by: Isaac
1 parent bfee234 commit c9f9897

3 files changed

Lines changed: 97 additions & 19 deletions

File tree

app.py

Lines changed: 22 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,7 @@
5050
get_cli_profiles,
5151
get_current_user_info,
5252
get_host,
53+
get_metastore_name,
5354
get_workspace_name,
5455
make_api_call,
5556
resolve_account_connection,
@@ -1212,7 +1213,10 @@ def _theme_card(tid: str, t: dict) -> html.Div:
12121213
_MODE_BADGE,
12131214
html.Div([
12141215
html.Span(id="workspace-name-display", className="workspace-name"),
1215-
html.Span(id="host-display", className="host-display"),
1216+
html.Div([
1217+
html.Span(id="host-display", className="host-display"),
1218+
html.Span(id="metastore-display", className="metastore-display"),
1219+
], className="workspace-info-row"),
12161220
], className="workspace-info ms-3"),
12171221
html.Button(
12181222
html.I(className="bi bi-gear-fill"),
@@ -1487,18 +1491,20 @@ def rebuild_sidebar_for_scope(scope):
14871491
Output("user-display", "children"),
14881492
Output("host-display", "children"),
14891493
Output("workspace-name-display", "children"),
1494+
Output("metastore-display", "children"),
14901495
Input("url", "pathname"),
14911496
Input("conn-config", "data"),
14921497
)
14931498
def init_on_load(_, conn_config):
1494-
"""Callback 1: Populate topbar user chip, host label, and workspace name."""
1499+
"""Callback 1: Populate topbar user chip, host label, workspace name, and metastore."""
14951500
host, token = _resolve_conn(conn_config)
14961501
host_label = html.Span(
14971502
(host or "").replace("https://", ""),
14981503
className="text-muted",
14991504
) if host else html.Span("(not connected)", className="text-warning")
15001505

15011506
ws_name = None
1507+
ms_name = None
15021508
if token and host:
15031509
info = get_current_user_info(token, host)
15041510
name = info.get("display_name") or info.get("user_name") or "Unknown"
@@ -1507,7 +1513,13 @@ def init_on_load(_, conn_config):
15071513
name,
15081514
html.I(className="bi bi-chevron-down ms-1 small"),
15091515
], className="user-chip")
1510-
ws_name = get_workspace_name(token, host)
1516+
# Use CLI profile name when in profile mode, otherwise workspace name
1517+
conn_mode = (conn_config or {}).get("mode")
1518+
if conn_mode == "profile":
1519+
ws_name = (conn_config or {}).get("profile") or DATABRICKS_PROFILE
1520+
else:
1521+
ws_name = get_workspace_name(token, host)
1522+
ms_name = get_metastore_name(token, host)
15111523
else:
15121524
user_el = html.Span([
15131525
html.I(className="bi bi-person-circle me-1"),
@@ -1516,11 +1528,16 @@ def init_on_load(_, conn_config):
15161528
], className="user-chip text-warning")
15171529

15181530
ws_name_el = html.Span(
1519-
[html.I(className="bi bi-building me-1"), ws_name],
1531+
[html.I(className="bi bi-tag me-1"), ws_name],
15201532
className="workspace-name-text"
15211533
) if ws_name else None
15221534

1523-
return user_el, host_label, ws_name_el
1535+
ms_name_el = html.Span(
1536+
[html.I(className="bi bi-layers me-1"), ms_name],
1537+
className="metastore-name-text"
1538+
) if ms_name else None
1539+
1540+
return user_el, host_label, ws_name_el, ms_name_el
15241541

15251542

15261543
# 1b. Toggle deploy modal

assets/style.css

Lines changed: 53 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -955,7 +955,32 @@ body {
955955
.deploy-modal .modal-header {
956956
border-bottom: 1px solid rgba(255,255,255,0.06);
957957
}
958-
.deploy-modal .btn-close { filter: invert(1) grayscale(1) brightness(0.7); }
958+
.deploy-modal .btn-close,
959+
.settings-modal .btn-close {
960+
background: transparent !important;
961+
opacity: 0.7 !important;
962+
padding: 0 !important;
963+
width: 28px;
964+
height: 28px;
965+
position: relative;
966+
}
967+
.deploy-modal .btn-close::before,
968+
.deploy-modal .btn-close::after,
969+
.settings-modal .btn-close::before,
970+
.settings-modal .btn-close::after {
971+
content: "";
972+
position: absolute;
973+
top: 50%; left: 50%;
974+
width: 18px; height: 2px;
975+
background: #f8fafc;
976+
border-radius: 1px;
977+
}
978+
.deploy-modal .btn-close::before,
979+
.settings-modal .btn-close::before { transform: translate(-50%,-50%) rotate(45deg); }
980+
.deploy-modal .btn-close::after,
981+
.settings-modal .btn-close::after { transform: translate(-50%,-50%) rotate(-45deg); }
982+
.deploy-modal .btn-close:hover,
983+
.settings-modal .btn-close:hover { opacity: 1 !important; }
959984
.deploy-section-title {
960985
color: var(--accent-primary, #7f4bc4);
961986
margin-top: 0.5rem;
@@ -996,7 +1021,7 @@ body {
9961021
}
9971022

9981023
.workspace-name-text {
999-
font-size: 13px;
1024+
font-size: 14px;
10001025
font-weight: 600;
10011026
color: var(--text-hi);
10021027
white-space: nowrap;
@@ -1007,16 +1032,41 @@ body {
10071032
align-items: center;
10081033
}
10091034

1035+
.workspace-info-row {
1036+
display: flex;
1037+
align-items: center;
1038+
gap: 8px;
1039+
min-width: 0;
1040+
}
1041+
10101042
.host-display {
10111043
font-family: var(--font-mono);
1012-
font-size: 10px;
1044+
font-size: 11.5px;
10131045
color: var(--text-3);
10141046
max-width: 280px;
10151047
overflow: hidden;
10161048
text-overflow: ellipsis;
10171049
white-space: nowrap;
10181050
}
10191051

1052+
.metastore-display { display: flex; align-items: center; min-width: 0; }
1053+
.metastore-name-text {
1054+
font-size: 11.5px;
1055+
color: var(--text-3);
1056+
white-space: nowrap;
1057+
overflow: hidden;
1058+
text-overflow: ellipsis;
1059+
max-width: 200px;
1060+
display: flex;
1061+
align-items: center;
1062+
gap: 2px;
1063+
}
1064+
.metastore-name-text::before {
1065+
content: "|";
1066+
margin-right: 6px;
1067+
color: var(--border);
1068+
}
1069+
10201070
.user-chip {
10211071
font-size: 12px;
10221072
color: var(--text-2);
@@ -1296,7 +1346,6 @@ body {
12961346
.settings-modal .modal-header {
12971347
border-bottom: 1px solid rgba(255,255,255,0.06);
12981348
}
1299-
.settings-modal .btn-close { filter: invert(1) grayscale(1) brightness(0.7); }
13001349

13011350
.settings-group {
13021351
margin-bottom: 20px;

auth.py

Lines changed: 22 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -282,11 +282,12 @@ def get_workspace_name(token: str, host: str) -> Optional[str]:
282282
283283
1. ``GET /api/2.0/workspace-conf?keys=workspaceName`` -- admin-set
284284
workspace display name.
285-
2. ``GET /api/2.1/unity-catalog/metastore_summary`` -- metastore
286-
name (often mirrors the workspace name).
287-
3. Parse the hostname (e.g. ``adb-123.azuredatabricks.net`` →
285+
2. Parse the hostname (e.g. ``adb-123.azuredatabricks.net`` →
288286
``adb-123``).
289287
288+
Note: the metastore name fallback was removed because
289+
:func:`get_metastore_name` is now displayed separately.
290+
290291
Args:
291292
token: Bearer token for the workspace.
292293
host: Full workspace URL including scheme.
@@ -303,18 +304,29 @@ def get_workspace_name(token: str, host: str) -> Optional[str]:
303304
if name:
304305
return name
305306

306-
# 2 — Unity Catalog metastore summary
307+
# 2 — parse hostname: "adb-123.azuredatabricks.net" → "adb-123"
308+
# custom domains: "myco.databricks.com" → "myco"
309+
import re as _re
310+
m = _re.match(r"https?://([^./]+)", host)
311+
return m.group(1) if m else None
312+
313+
314+
def get_metastore_name(token: str, host: str) -> Optional[str]:
315+
"""Return the name of the Unity Catalog metastore attached to this workspace.
316+
317+
Args:
318+
token: Bearer token for the workspace.
319+
host: Full workspace URL including scheme.
320+
321+
Returns:
322+
The metastore display name, or ``None`` if not available.
323+
"""
307324
r = make_api_call("GET", "/api/2.1/unity-catalog/metastore_summary", token, host)
308325
if r["success"]:
309326
name = (r["data"] or {}).get("name", "")
310327
if name:
311328
return name
312-
313-
# 3 — parse hostname: "adb-123.azuredatabricks.net" → "adb-123"
314-
# custom domains: "myco.databricks.com" → "myco"
315-
import re as _re
316-
m = _re.match(r"https?://([^./]+)", host)
317-
return m.group(1) if m else None
329+
return None
318330

319331

320332
# ── User Info ─────────────────────────────────────────────────────────────────

0 commit comments

Comments
 (0)