style(portal): tighten account console sections

This commit is contained in:
rcourtman
2026-03-27 17:32:00 +00:00
parent cf307f3906
commit b00152199c
4 changed files with 3 additions and 10 deletions
+1 -1
View File
@@ -1,5 +1,5 @@
{
"source_hash": "74ac8f2899e8cddd8834f1a02166bdcc9971a26141ccb23c0213d2948a619e79",
"source_hash": "c17b1452a1c3fa53f55c51b5219dddbd5ee5faec28d79f4743271b3a3be0e4f1",
"build_inputs": [
"package.json",
"tsconfig.json",
+1 -1
View File
@@ -1783,7 +1783,7 @@
var hostedContent = accounts.map(function(account) {
return '<section class="account-surface"><div class="account-surface-header"><div class="account-heading"><div class="account-eyebrow">' + escapeHTML(accountKindLabel(account)) + "</div><h2>" + escapeHTML(account.name) + '</h2><div class="account-summary">' + escapeHTML(accountKindLabel(account) + " \xB7 " + titleCase(account.role) + " \xB7 " + workspaceCountLabel((account.workspaces || []).length)) + '</div></div><div class="account-badges"><span class="badge badge-' + escapeHTML(account.kind) + '">' + escapeHTML(account.kind_label) + "</span>" + roleBadgeHTML(account.role) + '</div></div><div class="account-surface-body">' + renderAccountOverviewSection(account) + renderAccountWorkspaceSection(account, context.accountAPIBasePath) + renderAccountTeamSection(account) + "</div></section>";
}).join("");
return '<div class="portal-shell" data-shell-section="' + activeSection + '">' + renderOverviewBand(accounts) + '<div class="portal-shell-layout">' + renderShellNavigation(accounts, context.bootstrap.support_email || "", activeSection) + '<div class="portal-shell-main"><section class="portal-content-panel portal-content-panel-overview"><div class="portal-top-section-header"><div class="account-panel-kicker">' + (hosted ? "Hosted operations" : "Hosted access") + "</div><h2>" + (hosted ? "Hosted operations" : "No hosted workspaces are attached yet") + "</h2><p>" + (hosted ? "Use this area for workspace access, fleet operations, hosted billing, and team management." : "This account does not currently have hosted workspace access. If that is unexpected, contact support while using the commercial tools below.") + '</p></div><div id="accounts-root">' + hostedContent + '</div></section><section class="portal-content-panel portal-content-panel-services service-section" id="account-services-section"><div class="service-header"><div><div class="account-panel-kicker">Account services</div><h2>' + serviceHeading + '</h2></div><div class="service-note">' + serviceNote + '</div></div><div class="service-shell"><div class="service-shell-main"><div class="service-action-list">' + renderServiceActionRow("open-manage-service", "Billing", "Manage subscriptions", "Open Stripe billing access for existing self-hosted subscriptions without leaving the Pulse Account shell.", "manage-service-panel", "manage-inline-email") + renderServiceActionRow("open-retrieve-service", "Licenses", "Retrieve licenses", "Recover the latest active self-hosted license and invoice link for a commercial email address.", "retrieve-service-panel", "retrieve-inline-email") + renderServiceActionRow("open-refund-service", "Refunds", "Refund requests", "Request an immediate self-serve refund for eligible self-hosted purchases with explicit revocation confirmation.", "refund-service-panel", "refund-inline-email") + renderServiceActionRow("open-data-service", "Privacy", "Data and privacy", "Request commercial data export or deletion without leaving the account shell.", "data-service-panel", "data-export-email") + '</div><div class="service-panel" id="manage-service-panel"><div id="manage-service-root"></div></div><div class="service-panel" id="retrieve-service-panel"><div id="retrieve-service-root"></div></div><div class="service-panel" id="refund-service-panel"><div id="refund-service-root"></div></div><div class="service-panel" id="data-service-panel"><h3>Data and privacy</h3><p>Request export or deletion of the commercial data tied to an email address. Payment data held directly by Stripe still requires support handling.</p><div class="subsection"><div id="data-export-root"></div></div><div class="subsection"><div id="data-delete-root"></div></div><div class="helper-text">Payment-card data stays with Stripe. For Stripe deletion support, contact <a href="mailto:' + escapeAttr(context.bootstrap.support_email || "") + '">' + escapeHTML(context.bootstrap.support_email || "") + '</a>.</div></div></div><aside class="service-shell-sidebar"><div class="service-brief-card"><div class="account-panel-kicker">Scope</div><h3>Commercial account actions</h3><p>Use this area for self-hosted billing, license recovery, refunds, and privacy requests. Hosted workspace operations stay in the Workspaces and Team sections.</p></div><div class="service-brief-card"><div class="account-panel-kicker">Support</div><h3>Need help with a commercial request?</h3><p>Use support if billing, refund, privacy, or license actions do not behave as expected for this account.</p><a class="portal-support-link" href="mailto:' + escapeAttr(context.bootstrap.support_email || "") + '">' + escapeHTML(context.bootstrap.support_email || "") + '</a></div></aside></div></section><section class="portal-content-panel portal-content-panel-support">' + renderSupportSection(context) + "</section></div></div></div>";
return '<div class="portal-shell" data-shell-section="' + activeSection + '">' + renderOverviewBand(accounts) + '<div class="portal-shell-layout">' + renderShellNavigation(accounts, context.bootstrap.support_email || "", activeSection) + '<div class="portal-shell-main"><section class="portal-content-panel portal-content-panel-overview"><div id="accounts-root">' + hostedContent + '</div></section><section class="portal-content-panel portal-content-panel-services service-section" id="account-services-section"><div class="service-header"><div><div class="account-panel-kicker">Account services</div><h2>' + serviceHeading + '</h2></div><div class="service-note">' + serviceNote + '</div></div><div class="service-shell"><div class="service-shell-main"><div class="service-action-list">' + renderServiceActionRow("open-manage-service", "Billing", "Manage subscriptions", "Open Stripe billing access for existing self-hosted subscriptions without leaving the Pulse Account shell.", "manage-service-panel", "manage-inline-email") + renderServiceActionRow("open-retrieve-service", "Licenses", "Retrieve licenses", "Recover the latest active self-hosted license and invoice link for a commercial email address.", "retrieve-service-panel", "retrieve-inline-email") + renderServiceActionRow("open-refund-service", "Refunds", "Refund requests", "Request an immediate self-serve refund for eligible self-hosted purchases with explicit revocation confirmation.", "refund-service-panel", "refund-inline-email") + renderServiceActionRow("open-data-service", "Privacy", "Data and privacy", "Request commercial data export or deletion without leaving the account shell.", "data-service-panel", "data-export-email") + '</div><div class="service-panel" id="manage-service-panel"><div id="manage-service-root"></div></div><div class="service-panel" id="retrieve-service-panel"><div id="retrieve-service-root"></div></div><div class="service-panel" id="refund-service-panel"><div id="refund-service-root"></div></div><div class="service-panel" id="data-service-panel"><h3>Data and privacy</h3><p>Request export or deletion of the commercial data tied to an email address. Payment data held directly by Stripe still requires support handling.</p><div class="subsection"><div id="data-export-root"></div></div><div class="subsection"><div id="data-delete-root"></div></div><div class="helper-text">Payment-card data stays with Stripe. For Stripe deletion support, contact <a href="mailto:' + escapeAttr(context.bootstrap.support_email || "") + '">' + escapeHTML(context.bootstrap.support_email || "") + '</a>.</div></div></div><aside class="service-shell-sidebar"><div class="service-brief-card"><div class="account-panel-kicker">Scope</div><h3>Commercial account actions</h3><p>Use this area for self-hosted billing, license recovery, refunds, and privacy requests. Hosted workspace operations stay in the Workspaces and Team sections.</p></div><div class="service-brief-card"><div class="account-panel-kicker">Support</div><h3>Need help with a commercial request?</h3><p>Use support if billing, refund, privacy, or license actions do not behave as expected for this account.</p><a class="portal-support-link" href="mailto:' + escapeAttr(context.bootstrap.support_email || "") + '">' + escapeHTML(context.bootstrap.support_email || "") + '</a></div></aside></div></section><section class="portal-content-panel portal-content-panel-support">' + renderSupportSection(context) + "</section></div></div></div>";
}
function renderSignedOutPortalHTML(context) {
var statusHTML = "";
@@ -184,7 +184,7 @@ describe('shell view', function() {
expect(html).toContain('<h1>Self-hosted Pulse Account</h1>');
expect(html).toContain('No hosted workspace access is attached to this account yet.');
expect(html).toContain('This account does not currently have hosted workspace access.');
expect(html).toContain('Use this area for self-hosted billing, license recovery, refunds, and privacy requests.');
expect(html).toContain('Account services');
expect(html).not.toContain('Self-hosted licenses and billing');
});
@@ -669,13 +669,6 @@ export function renderAuthenticatedPortalHTML(context: ShellViewContext): string
renderShellNavigation(accounts, context.bootstrap.support_email || '', activeSection) +
'<div class="portal-shell-main">' +
'<section class="portal-content-panel portal-content-panel-overview">' +
'<div class="portal-top-section-header">' +
'<div class="account-panel-kicker">' + (hosted ? 'Hosted operations' : 'Hosted access') + '</div>' +
'<h2>' + (hosted ? 'Hosted operations' : 'No hosted workspaces are attached yet') + '</h2>' +
'<p>' + (hosted
? 'Use this area for workspace access, fleet operations, hosted billing, and team management.'
: 'This account does not currently have hosted workspace access. If that is unexpected, contact support while using the commercial tools below.') + '</p>' +
'</div>' +
'<div id="accounts-root">' + hostedContent + '</div>' +
'</section>' +
'<section class="portal-content-panel portal-content-panel-services service-section" id="account-services-section">' +