feat(portal): make management surfaces explicit

This commit is contained in:
rcourtman
2026-03-27 15:48:14 +00:00
parent 3d52d6b008
commit c8e4a7a680
6 changed files with 143 additions and 17 deletions
+1 -1
View File
@@ -1,5 +1,5 @@
{
"source_hash": "3e262c9fe2687c5e0d4ff9d11cd6f313d2f7b1e9fdb2a3f6be274246cd491d25",
"source_hash": "3b31c205a79f7c867444f852e0c63518ac751ef055d7c7679830912af99327cf",
"build_inputs": [
"package.json",
"tsconfig.json",
+42 -8
View File
@@ -247,7 +247,7 @@ header .logout-btn:hover,
}
.portal-frame {
display: grid;
grid-template-columns: minmax(250px, 290px) minmax(0, 1fr);
grid-template-columns: minmax(220px, 250px) minmax(0, 1fr);
gap: 22px;
align-items: start;
}
@@ -397,14 +397,15 @@ header .logout-btn:hover,
}
.account-surface-body {
display: grid;
grid-template-columns: minmax(260px, 320px) minmax(0, 1fr);
gap: 24px;
grid-template-columns: 1fr;
gap: 18px;
margin-top: 22px;
}
.account-overview-rail {
display: flex;
flex-direction: column;
display: grid;
grid-template-columns: minmax(280px, 0.95fr) minmax(0, 1.15fr);
gap: 14px;
align-items: start;
}
.account-overview-card,
.account-stat-card,
@@ -464,6 +465,13 @@ header .logout-btn:hover,
grid-template-columns: repeat(2, minmax(0, 1fr));
gap: 12px;
}
.account-overview-card {
grid-column: 1;
}
.account-status-grid {
grid-column: 2;
grid-row: 1 / span 2;
}
.account-stat-card {
min-height: 108px;
}
@@ -503,6 +511,10 @@ header .logout-btn:hover,
180deg,
var(--panel),
var(--panel-strong));
grid-column: 1;
}
.add-workspace-form {
grid-column: 1 / -1;
}
.account-main-stage {
display: flex;
@@ -577,7 +589,7 @@ header .logout-btn:hover,
}
.account-management-grid {
display: grid;
grid-template-columns: repeat(2, minmax(0, 1fr));
grid-template-columns: 1fr;
gap: 14px;
}
.workspace-management-panel,
@@ -588,6 +600,19 @@ header .logout-btn:hover,
.team-section.visible .team-management-panel {
box-shadow: var(--shadow-md);
}
.workspace-management-panel {
background:
linear-gradient(
180deg,
rgba(255, 253, 248, 0.98),
rgba(245, 238, 226, 0.98));
}
.workspace-management-content {
display: grid;
grid-template-columns: minmax(0, 1fr) auto;
gap: 16px;
align-items: end;
}
.workspace-management-header,
.team-management-header {
display: flex;
@@ -666,7 +691,7 @@ header .logout-btn:hover,
}
.team-management-grid {
display: grid;
grid-template-columns: minmax(0, 1.45fr) minmax(280px, 1fr);
grid-template-columns: minmax(0, 1.6fr) minmax(320px, 0.95fr);
gap: 14px;
}
.team-panel-heading {
@@ -893,7 +918,6 @@ header .logout-btn:hover,
}
@media (max-width: 1180px) {
.portal-frame,
.account-surface-body,
.account-management-grid,
.team-management-grid {
grid-template-columns: 1fr;
@@ -905,6 +929,16 @@ header .logout-btn:hover,
display: grid;
grid-template-columns: repeat(3, minmax(0, 1fr));
}
.account-overview-rail {
grid-template-columns: 1fr;
}
.account-status-grid {
grid-column: auto;
grid-row: auto;
}
.workspace-management-content {
grid-template-columns: 1fr;
}
}
@media (max-width: 920px) {
.portal-hero {
+12
View File
@@ -662,6 +662,10 @@
deps.store.updateAccountState(function(accountState) {
var entry = ensurePortalAccountUIEntry(accountState, accountID);
entry.addWorkspaceOpen = !entry.addWorkspaceOpen;
if (entry.addWorkspaceOpen) {
entry.teamVisible = false;
entry.selectedWorkspaceID = "";
}
shouldFocus = entry.addWorkspaceOpen;
});
if (shouldFocus) {
@@ -672,6 +676,10 @@
deps.store.updateAccountState(function(accountState) {
var entry = ensurePortalAccountUIEntry(accountState, accountID);
entry.selectedWorkspaceID = entry.selectedWorkspaceID === workspaceID ? "" : workspaceID;
if (entry.selectedWorkspaceID) {
entry.teamVisible = false;
entry.addWorkspaceOpen = false;
}
});
};
var clearWorkspaceSelection = function(accountID) {
@@ -768,6 +776,10 @@
deps.store.updateAccountState(function(accountState) {
var entry = ensurePortalAccountUIEntry(accountState, accountID);
entry.teamVisible = !entry.teamVisible;
if (entry.teamVisible) {
entry.selectedWorkspaceID = "";
entry.addWorkspaceOpen = false;
}
nextVisible = entry.teamVisible;
});
if (nextVisible) {
@@ -143,8 +143,23 @@ describe('account runtime', function() {
'</div>' +
'</div>';
deps.store.updateAccountState(function(accountState) {
var entry = accountState.byAccountID.acct_1 || (accountState.byAccountID.acct_1 = {
addWorkspaceOpen: true,
createWorkspace: { pending: false, error: '' },
selectedWorkspaceID: '',
manageWorkspace: { pending: false, error: '' },
teamVisible: true,
teamQuery: { status: 'idle', error: '', data: [] },
});
entry.addWorkspaceOpen = true;
entry.teamVisible = true;
}, { notify: false });
runtime.selectWorkspace('acct_1', 'ws_2');
expect(deps.store.getAccountState().byAccountID.acct_1.selectedWorkspaceID).toBe('ws_2');
expect(deps.store.getAccountState().byAccountID.acct_1.teamVisible).toBe(false);
expect(deps.store.getAccountState().byAccountID.acct_1.addWorkspaceOpen).toBe(false);
expect(document.getElementById('workspace-management-title-acct_1')?.textContent).toContain('Alpha Workspace');
expect(document.getElementById('workspace-management-action-acct_1')?.textContent).toContain('Suspend workspace');
@@ -182,10 +197,25 @@ describe('account runtime', function() {
'<select id="invite-role-acct_1"><option value="admin">Admin</option></select>' +
'</div>';
deps.store.updateAccountState(function(accountState) {
var entry = accountState.byAccountID.acct_1 || (accountState.byAccountID.acct_1 = {
addWorkspaceOpen: true,
createWorkspace: { pending: false, error: '' },
selectedWorkspaceID: 'ws_1',
manageWorkspace: { pending: false, error: '' },
teamVisible: false,
teamQuery: { status: 'idle', error: '', data: [] },
});
entry.addWorkspaceOpen = true;
entry.selectedWorkspaceID = 'ws_1';
}, { notify: false });
runtime.toggleTeam('acct_1');
await flushAsync();
expect(deps.store.getAccountState().byAccountID.acct_1.teamVisible).toBe(true);
expect(deps.store.getAccountState().byAccountID.acct_1.selectedWorkspaceID).toBe('');
expect(deps.store.getAccountState().byAccountID.acct_1.addWorkspaceOpen).toBe(false);
expect(deps.store.getAccountState().byAccountID.acct_1.teamQuery.status).toBe('ready');
expect(deps.store.getAccountState().byAccountID.acct_1.teamQuery.data).toHaveLength(1);
expect(document.getElementById('team-stats-acct_1')?.textContent).toContain('Members');
@@ -86,6 +86,10 @@ export function installAccountRuntime(deps: AccountRuntimeDeps): AccountRuntime
deps.store.updateAccountState(function(accountState) {
var entry = ensurePortalAccountUIEntry(accountState, accountID);
entry.addWorkspaceOpen = !entry.addWorkspaceOpen;
if (entry.addWorkspaceOpen) {
entry.teamVisible = false;
entry.selectedWorkspaceID = '';
}
shouldFocus = entry.addWorkspaceOpen;
});
if (shouldFocus) {
@@ -97,6 +101,10 @@ export function installAccountRuntime(deps: AccountRuntimeDeps): AccountRuntime
deps.store.updateAccountState(function(accountState) {
var entry = ensurePortalAccountUIEntry(accountState, accountID);
entry.selectedWorkspaceID = entry.selectedWorkspaceID === workspaceID ? '' : workspaceID;
if (entry.selectedWorkspaceID) {
entry.teamVisible = false;
entry.addWorkspaceOpen = false;
}
});
};
@@ -198,6 +206,10 @@ export function installAccountRuntime(deps: AccountRuntimeDeps): AccountRuntime
deps.store.updateAccountState(function(accountState) {
var entry = ensurePortalAccountUIEntry(accountState, accountID);
entry.teamVisible = !entry.teamVisible;
if (entry.teamVisible) {
entry.selectedWorkspaceID = '';
entry.addWorkspaceOpen = false;
}
nextVisible = entry.teamVisible;
});
if (nextVisible) {
@@ -249,7 +249,7 @@ header .logout-btn:hover,
.portal-frame {
display: grid;
grid-template-columns: minmax(250px, 290px) minmax(0, 1fr);
grid-template-columns: minmax(220px, 250px) minmax(0, 1fr);
gap: 22px;
align-items: start;
}
@@ -420,15 +420,16 @@ header .logout-btn:hover,
.account-surface-body {
display: grid;
grid-template-columns: minmax(260px, 320px) minmax(0, 1fr);
gap: 24px;
grid-template-columns: 1fr;
gap: 18px;
margin-top: 22px;
}
.account-overview-rail {
display: flex;
flex-direction: column;
display: grid;
grid-template-columns: minmax(280px, 0.95fr) minmax(0, 1.15fr);
gap: 14px;
align-items: start;
}
.account-overview-card,
@@ -494,6 +495,15 @@ header .logout-btn:hover,
gap: 12px;
}
.account-overview-card {
grid-column: 1;
}
.account-status-grid {
grid-column: 2;
grid-row: 1 / span 2;
}
.account-stat-card {
min-height: 108px;
}
@@ -527,6 +537,11 @@ header .logout-btn:hover,
flex-direction: column;
gap: 16px;
background: linear-gradient(180deg, var(--panel), var(--panel-strong));
grid-column: 1;
}
.add-workspace-form {
grid-column: 1 / -1;
}
.account-main-stage {
@@ -614,7 +629,7 @@ header .logout-btn:hover,
.account-management-grid {
display: grid;
grid-template-columns: repeat(2, minmax(0, 1fr));
grid-template-columns: 1fr;
gap: 14px;
}
@@ -628,6 +643,17 @@ header .logout-btn:hover,
box-shadow: var(--shadow-md);
}
.workspace-management-panel {
background: linear-gradient(180deg, rgba(255, 253, 248, 0.98), rgba(245, 238, 226, 0.98));
}
.workspace-management-content {
display: grid;
grid-template-columns: minmax(0, 1fr) auto;
gap: 16px;
align-items: end;
}
.workspace-management-header,
.team-management-header {
display: flex;
@@ -717,7 +743,7 @@ header .logout-btn:hover,
.team-management-grid {
display: grid;
grid-template-columns: minmax(0, 1.45fr) minmax(280px, 1fr);
grid-template-columns: minmax(0, 1.6fr) minmax(320px, 0.95fr);
gap: 14px;
}
@@ -981,7 +1007,6 @@ header .logout-btn:hover,
@media (max-width: 1180px) {
.portal-frame,
.account-surface-body,
.account-management-grid,
.team-management-grid {
grid-template-columns: 1fr;
@@ -995,6 +1020,19 @@ header .logout-btn:hover,
display: grid;
grid-template-columns: repeat(3, minmax(0, 1fr));
}
.account-overview-rail {
grid-template-columns: 1fr;
}
.account-status-grid {
grid-column: auto;
grid-row: auto;
}
.workspace-management-content {
grid-template-columns: 1fr;
}
}
@media (max-width: 920px) {