feat(portal): sharpen workspace fleet layout

This commit is contained in:
rcourtman
2026-03-27 16:07:08 +00:00
parent f489116da5
commit 7bc9bb414d
5 changed files with 119 additions and 48 deletions
+1 -1
View File
@@ -1,5 +1,5 @@
{
"source_hash": "3ee5dcea0783b4085b4a7feb3fd0dcee628b4280042752af29256a685db8a466",
"source_hash": "c60aecd13aa823a23de54658d2f067e93ce5d5d05b80cee353495dccbb3c07d2",
"build_inputs": [
"package.json",
"tsconfig.json",
+48 -18
View File
@@ -400,7 +400,7 @@ header .logout-btn:hover,
.account-overview-card,
.account-stat-card,
.account-operations-panel,
.workspace-card,
.workspace-row,
.workspace-management-panel,
.team-management-panel,
.add-workspace-form,
@@ -511,29 +511,29 @@ header .logout-btn:hover,
padding: 6px 4px 0;
}
.workspace-list {
display: flex;
flex-direction: column;
gap: 12px;
}
.workspace-row {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
gap: 14px;
}
.workspace-card {
display: flex;
flex-direction: column;
justify-content: space-between;
gap: 18px;
grid-template-columns: minmax(0, 1fr) auto;
gap: 16px;
align-items: center;
padding: 18px;
min-height: 250px;
}
.workspace-card-main {
.workspace-row-main {
display: grid;
grid-template-columns: minmax(0, 1.4fr) minmax(220px, 0.85fr);
gap: 18px;
align-items: center;
}
.workspace-row-title {
display: flex;
flex-direction: column;
gap: 12px;
gap: 10px;
}
.workspace-card-topline {
display: flex;
flex-direction: column;
gap: 12px;
}
.workspace-title-group {
.workspace-row-heading {
display: flex;
flex-direction: column;
gap: 8px;
@@ -568,6 +568,28 @@ header .logout-btn:hover,
line-height: 1.65;
color: var(--ink-soft);
}
.workspace-row-status-grid {
display: grid;
grid-template-columns: repeat(2, minmax(0, 1fr));
gap: 10px;
}
.workspace-row-status-cell {
display: flex;
flex-direction: column;
gap: 8px;
min-height: 84px;
padding: 14px;
border: 1px solid var(--line);
border-radius: var(--radius-md);
background: var(--panel-muted);
}
.workspace-row-status-label {
font-size: 11px;
font-weight: 800;
letter-spacing: 0.12em;
text-transform: uppercase;
color: var(--ink-muted);
}
.workspace-state-label {
font-size: 13px;
font-weight: 700;
@@ -932,6 +954,10 @@ header .logout-btn:hover,
.service-grid {
grid-template-columns: 1fr;
}
.workspace-row,
.workspace-row-main {
grid-template-columns: 1fr;
}
}
@media (max-width: 720px) {
header {
@@ -960,9 +986,13 @@ header .logout-btn:hover,
flex-direction: column;
align-items: flex-start;
}
.workspace-actions,
.workspace-actions form,
.workspace-actions .btn-primary,
.workspace-actions .btn-secondary {
width: 100%;
}
.workspace-row-status-grid {
grid-template-columns: 1fr;
}
}
+2 -2
View File
@@ -1607,7 +1607,7 @@
var state = String(workspace.state || "");
var createdLabel = formatWorkspaceDate(workspace.created_at);
var metaParts = [
'<span class="workspace-meta-item">' + escapeHTML(titleCase(state || "unknown")) + "</span>"
'<span class="workspace-meta-item">' + escapeHTML(workspace.id) + "</span>"
];
if (createdLabel) {
metaParts.push('<span class="workspace-meta-item">Created ' + escapeHTML(createdLabel) + "</span>");
@@ -1625,7 +1625,7 @@
if (account.can_manage && (state === "active" || state === "suspended" || state === "failed")) {
manageAction = '<button type="button" class="btn-secondary btn-workspace-manage" data-action="select-workspace" data-account-id="' + escapeAttr(account.id) + '" data-workspace-id="' + escapeAttr(workspace.id) + '">Manage</button>';
}
return '<article class="workspace-card"><div class="workspace-card-main"><div class="workspace-card-topline"><div class="workspace-title-group"><h4 class="workspace-name">' + escapeHTML(workspace.display_name) + '</h4><div class="workspace-meta">' + metaParts.join("") + '</div></div><div class="workspace-badges">' + healthBadgeHTML(workspace) + '<span class="badge badge-' + escapeHTML(state || "unknown") + '">' + escapeHTML(titleCase(state || "Unknown")) + '</span></div></div><p class="workspace-summary">' + escapeHTML(workspaceStatusCopy(workspace)) + '</p></div><div class="workspace-actions">' + openAction + manageAction + "</div></article>";
return '<article class="workspace-row"><div class="workspace-row-main"><div class="workspace-row-title"><div class="workspace-row-heading"><h4 class="workspace-name">' + escapeHTML(workspace.display_name) + '</h4><div class="workspace-meta">' + metaParts.join("") + '</div></div><p class="workspace-summary">' + escapeHTML(workspaceStatusCopy(workspace)) + '</p></div><div class="workspace-row-status-grid"><div class="workspace-row-status-cell"><span class="workspace-row-status-label">Health</span>' + healthBadgeHTML(workspace) + '</div><div class="workspace-row-status-cell"><span class="workspace-row-status-label">Lifecycle</span><span class="badge badge-' + escapeHTML(state || "unknown") + '">' + escapeHTML(titleCase(state || "Unknown")) + '</span></div></div></div><div class="workspace-actions">' + openAction + manageAction + "</div></article>";
}
function renderAccountSection(account, accountAPIBasePath) {
var workspaces = Array.isArray(account.workspaces) ? account.workspaces : [];
@@ -165,7 +165,7 @@ function renderWorkspaceCard(account: PortalAccountSummary, workspace: PortalWor
var state = String(workspace.state || '');
var createdLabel = formatWorkspaceDate(workspace.created_at);
var metaParts = [
'<span class="workspace-meta-item">' + escapeHTML(titleCase(state || 'unknown')) + '</span>',
'<span class="workspace-meta-item">' + escapeHTML(workspace.id) + '</span>',
];
if (createdLabel) {
metaParts.push('<span class="workspace-meta-item">Created ' + escapeHTML(createdLabel) + '</span>');
@@ -197,19 +197,25 @@ function renderWorkspaceCard(account: PortalAccountSummary, workspace: PortalWor
}
return (
'<article class="workspace-card">' +
'<div class="workspace-card-main">' +
'<div class="workspace-card-topline">' +
'<div class="workspace-title-group">' +
'<article class="workspace-row">' +
'<div class="workspace-row-main">' +
'<div class="workspace-row-title">' +
'<div class="workspace-row-heading">' +
'<h4 class="workspace-name">' + escapeHTML(workspace.display_name) + '</h4>' +
'<div class="workspace-meta">' + metaParts.join('') + '</div>' +
'</div>' +
'<div class="workspace-badges">' +
'<p class="workspace-summary">' + escapeHTML(workspaceStatusCopy(workspace)) + '</p>' +
'</div>' +
'<div class="workspace-row-status-grid">' +
'<div class="workspace-row-status-cell">' +
'<span class="workspace-row-status-label">Health</span>' +
healthBadgeHTML(workspace) +
'</div>' +
'<div class="workspace-row-status-cell">' +
'<span class="workspace-row-status-label">Lifecycle</span>' +
'<span class="badge badge-' + escapeHTML(state || 'unknown') + '">' + escapeHTML(titleCase(state || 'Unknown')) + '</span>' +
'</div>' +
'</div>' +
'<p class="workspace-summary">' + escapeHTML(workspaceStatusCopy(workspace)) + '</p>' +
'</div>' +
'<div class="workspace-actions">' +
openAction +
+55 -20
View File
@@ -433,7 +433,7 @@ header .logout-btn:hover,
.account-overview-card,
.account-stat-card,
.account-operations-panel,
.workspace-card,
.workspace-row,
.workspace-management-panel,
.team-management-panel,
.add-workspace-form,
@@ -553,33 +553,33 @@ header .logout-btn:hover,
}
.workspace-list {
display: flex;
flex-direction: column;
gap: 12px;
}
.workspace-row {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
gap: 14px;
}
.workspace-card {
display: flex;
flex-direction: column;
justify-content: space-between;
gap: 18px;
grid-template-columns: minmax(0, 1fr) auto;
gap: 16px;
align-items: center;
padding: 18px;
min-height: 250px;
}
.workspace-card-main {
.workspace-row-main {
display: grid;
grid-template-columns: minmax(0, 1.4fr) minmax(220px, 0.85fr);
gap: 18px;
align-items: center;
}
.workspace-row-title {
display: flex;
flex-direction: column;
gap: 12px;
gap: 10px;
}
.workspace-card-topline {
display: flex;
flex-direction: column;
gap: 12px;
}
.workspace-title-group {
.workspace-row-heading {
display: flex;
flex-direction: column;
gap: 8px;
@@ -619,6 +619,31 @@ header .logout-btn:hover,
color: var(--ink-soft);
}
.workspace-row-status-grid {
display: grid;
grid-template-columns: repeat(2, minmax(0, 1fr));
gap: 10px;
}
.workspace-row-status-cell {
display: flex;
flex-direction: column;
gap: 8px;
min-height: 84px;
padding: 14px;
border: 1px solid var(--line);
border-radius: var(--radius-md);
background: var(--panel-muted);
}
.workspace-row-status-label {
font-size: 11px;
font-weight: 800;
letter-spacing: 0.12em;
text-transform: uppercase;
color: var(--ink-muted);
}
.workspace-state-label {
font-size: 13px;
font-weight: 700;
@@ -1045,6 +1070,11 @@ header .logout-btn:hover,
.service-grid {
grid-template-columns: 1fr;
}
.workspace-row,
.workspace-row-main {
grid-template-columns: 1fr;
}
}
@media (max-width: 720px) {
@@ -1079,9 +1109,14 @@ header .logout-btn:hover,
align-items: flex-start;
}
.workspace-actions,
.workspace-actions form,
.workspace-actions .btn-primary,
.workspace-actions .btn-secondary {
width: 100%;
}
.workspace-row-status-grid {
grid-template-columns: 1fr;
}
}