style(portal): improve team roster state views

This commit is contained in:
rcourtman
2026-03-27 23:10:52 +00:00
parent 219d3b37a0
commit 3793cc161b
5 changed files with 59 additions and 15 deletions
+1 -1
View File
@@ -1,5 +1,5 @@
{
"source_hash": "7a0f2e57cde80096b6b3e6f00199572003416ff27bb9288a1228175a2e70bf63",
"source_hash": "5c0116abefe33e38423a53786fa29fe46555d46fa8bc8dcea9ca2063cb1a7cc2",
"build_inputs": [
"package.json",
"tsconfig.json",
+21 -7
View File
@@ -1276,6 +1276,12 @@ header .logout-btn:hover,
.team-roster {
align-self: start;
}
.team-roster.state-only {
border: none;
background: transparent;
box-shadow: none;
padding: 0;
}
.team-operations-panel {
display: flex;
flex-direction: column;
@@ -1313,6 +1319,12 @@ header .logout-btn:hover,
background: #fff;
overflow: hidden;
}
.team-roster-list.state-only {
border: none;
border-radius: 0;
background: transparent;
overflow: visible;
}
.team-roster-head {
display: grid;
grid-template-columns: minmax(0, 1fr) auto;
@@ -1401,12 +1413,13 @@ header .logout-btn:hover,
flex-direction: column;
align-items: flex-start;
justify-content: center;
gap: 6px;
min-height: 148px;
padding: 18px;
border: 1px dashed var(--line-strong);
border-radius: 10px;
background: var(--panel-muted);
gap: 8px;
min-height: 196px;
padding: 22px;
border: 1px solid var(--line);
border-radius: 12px;
background: #f8fbfd;
box-shadow: inset 0 0 0 1px rgba(11, 106, 114, 0.04);
}
.team-list-message-title {
font-size: 16px;
@@ -1420,8 +1433,9 @@ header .logout-btn:hover,
color: var(--ink-soft);
}
.team-list-message.error {
border-color: rgba(166, 27, 27, 0.2);
border-color: rgba(166, 27, 27, 0.18);
background: var(--danger-soft);
box-shadow: inset 4px 0 0 rgba(166, 27, 27, 0.26);
}
.team-list-message.error .team-list-message-title,
.team-list-message.error .team-list-message-copy {
+7
View File
@@ -144,6 +144,7 @@
}
function setContainerMessage(container, title, msg, isError) {
container.textContent = "";
container.classList.add("state-only");
var message = document.createElement("div");
message.className = "team-list-message" + (isError ? " error" : "");
var heading = document.createElement("strong");
@@ -268,6 +269,7 @@
var section = getElement("team-section-" + accountID);
var roster = getElement("team-list-" + accountID);
if (!section || !roster) return;
var rosterPanel = roster.closest(".team-roster");
var actorRole = section.getAttribute("data-actor-role") || "";
var isOwner = actorRole === "owner";
section.classList.toggle("visible", entry.teamVisible);
@@ -276,18 +278,23 @@
return;
}
if (entry.teamQuery.status === "loading") {
if (rosterPanel) rosterPanel.classList.add("state-only");
setContainerMessage(roster, "Loading roster", "Checking who currently has access to this account.", false);
return;
}
if (entry.teamQuery.status === "error") {
if (rosterPanel) rosterPanel.classList.add("state-only");
setContainerMessage(roster, "Roster needs attention", entry.teamQuery.error, true);
return;
}
if (!entry.teamQuery.data.length) {
if (rosterPanel) rosterPanel.classList.add("state-only");
setContainerMessage(roster, "No operators yet", "Invite someone new when this hosted account needs shared access.", false);
return;
}
roster.textContent = "";
roster.classList.remove("state-only");
if (rosterPanel) rosterPanel.classList.remove("state-only");
ensureRosterHead(roster);
for (var i = 0; i < entry.teamQuery.data.length; i += 1) {
var member = entry.teamQuery.data[i];
@@ -169,6 +169,7 @@ export function renderWorkspaceManagement(account: PortalAccountSummary, entry:
function setContainerMessage(container: HTMLElement, title: string, msg: string, isError: boolean): void {
container.textContent = '';
container.classList.add('state-only');
var message = document.createElement('div');
message.className = 'team-list-message' + (isError ? ' error' : '');
var heading = document.createElement('strong');
@@ -322,6 +323,7 @@ export function renderTeamSection(accountID: string, entry: PortalAccountUIEntry
var section = getElement<HTMLElement>('team-section-' + accountID);
var roster = getElement<HTMLElement>('team-list-' + accountID);
if (!section || !roster) return;
var rosterPanel = roster.closest('.team-roster') as HTMLElement | null;
var actorRole = section.getAttribute('data-actor-role') || '';
var isOwner = actorRole === 'owner';
@@ -332,19 +334,24 @@ export function renderTeamSection(accountID: string, entry: PortalAccountUIEntry
return;
}
if (entry.teamQuery.status === 'loading') {
if (rosterPanel) rosterPanel.classList.add('state-only');
setContainerMessage(roster, 'Loading roster', 'Checking who currently has access to this account.', false);
return;
}
if (entry.teamQuery.status === 'error') {
if (rosterPanel) rosterPanel.classList.add('state-only');
setContainerMessage(roster, 'Roster needs attention', entry.teamQuery.error, true);
return;
}
if (!entry.teamQuery.data.length) {
if (rosterPanel) rosterPanel.classList.add('state-only');
setContainerMessage(roster, 'No operators yet', 'Invite someone new when this hosted account needs shared access.', false);
return;
}
roster.textContent = '';
roster.classList.remove('state-only');
if (rosterPanel) rosterPanel.classList.remove('state-only');
ensureRosterHead(roster);
for (var i = 0; i < entry.teamQuery.data.length; i += 1) {
var member = entry.teamQuery.data[i];
@@ -1440,6 +1440,13 @@ header .logout-btn:hover,
align-self: start;
}
.team-roster.state-only {
border: none;
background: transparent;
box-shadow: none;
padding: 0;
}
.team-operations-panel {
display: flex;
flex-direction: column;
@@ -1484,6 +1491,13 @@ header .logout-btn:hover,
overflow: hidden;
}
.team-roster-list.state-only {
border: none;
border-radius: 0;
background: transparent;
overflow: visible;
}
.team-roster-head {
display: grid;
grid-template-columns: minmax(0, 1fr) auto;
@@ -1583,12 +1597,13 @@ header .logout-btn:hover,
flex-direction: column;
align-items: flex-start;
justify-content: center;
gap: 6px;
min-height: 148px;
padding: 18px;
border: 1px dashed var(--line-strong);
border-radius: 10px;
background: var(--panel-muted);
gap: 8px;
min-height: 196px;
padding: 22px;
border: 1px solid var(--line);
border-radius: 12px;
background: #f8fbfd;
box-shadow: inset 0 0 0 1px rgba(11, 106, 114, 0.04);
}
.team-list-message-title {
@@ -1605,8 +1620,9 @@ header .logout-btn:hover,
}
.team-list-message.error {
border-color: rgba(166, 27, 27, 0.2);
border-color: rgba(166, 27, 27, 0.18);
background: var(--danger-soft);
box-shadow: inset 4px 0 0 rgba(166, 27, 27, 0.26);
}
.team-list-message.error .team-list-message-title,