fix(web): settings say whose they are, roles and grants explain themselves, webhooks say where they live (TASK-2255 C59/C60/C109) (#2030)

C59: the user menu and the sidebar both said "Settings" and went to
different pages. The workspace page is now "Workspace settings", the
user menu says "Account settings", and each page names and links the
other. Theme says it is saved in this browser only.

C60: the invite form explains Owner, Editor and Viewer in one line
each, and the share dialog says a share is not a membership.

C109: plans sell a webhook quota and the web UI has no webhook screen;
the Apps tab now says webhooks are managed with `pad webhook` or the
API.

C110 (MCP audit names) is a server-side join and lands separately.

Claude-Session: https://claude.ai/code/session_01FAVXA5mJ5BNhKmv95jxQkQ
This commit is contained in:
xarmian
2026-10-10 17:34:24 -04:00
committed by GitHub
parent f3b753e3a8
commit 0015f49c1e
4 changed files with 54 additions and 3 deletions
+10
View File
@@ -266,6 +266,10 @@
<!-- Add people section -->
<div class="add-section">
<span class="section-label">Add people</span>
<!-- TASK-2255 (C60): a grant is not a membership. -->
<p class="grant-note">
Shares only this {type}: they can open it without joining the workspace. To give someone the whole workspace, invite them from Workspace settings.
</p>
<div class="add-row">
<input aria-label="Email address"
class="email-input"
@@ -501,6 +505,12 @@
overflow-y: auto;
}
.grant-note {
font-size: 0.8em;
color: var(--text-secondary);
margin: 2px 0 var(--space-2);
}
.section-label {
display: block;
font-size: 0.75em;
+2 -1
View File
@@ -539,8 +539,9 @@
<a href="/console" class="menu-link" role="menuitem" onclick={closeUserMenu}>
Workspaces
</a>
<!-- TASK-2255 (C59): not the workspace's ⚙ Settings. -->
<a href="/console/settings" class="menu-link" role="menuitem" onclick={closeUserMenu}>
Settings
Account settings
</a>
<!-- Hidden in the mobile apps: no purchase path there (PLAN-3291 DR-3). -->
{#if authStore.commerceAllowed}
@@ -955,8 +955,15 @@
{#if loading}
<div class="loading">Loading settings...</div>
{:else}
<!-- TASK-2255 (C59): two controls both said "Settings" and went to
different places. This page is the workspace's; the account's own
settings are linked from here, and link back. -->
<header class="settings-header">
<h1>Settings</h1>
<h1>Workspace settings</h1>
<p class="section-note">
For this workspace and everyone in it. Your own profile, password and sign-in are in
<a href="/console/settings">Account settings</a>.
</p>
</header>
<!-- Partial-import banner (TASK-896). -->
@@ -1046,6 +1053,7 @@
</section>
<section class="section">
<h2>Theme</h2>
<p class="section-note">Saved in this browser only, for every workspace.</p>
<div class="card">
<div class="theme-row">
<span>Appearance</span>
@@ -1290,6 +1298,13 @@
{inviting ? 'Inviting...' : 'Invite'}
</Button>
</div>
<!-- TASK-2255 (C60): the roles were never explained, and a wrong
guess is an access-control mistake. -->
<ul class="role-legend">
<li><strong>Owner</strong>: everything, including members, settings and deleting the workspace.</li>
<li><strong>Editor</strong>: creates and edits items.</li>
<li><strong>Viewer</strong>: reads only.</li>
</ul>
{#if inviteResult}
<p class="invite-result" class:invite-success={inviteResult.type === 'success'} class:invite-error={inviteResult.type === 'error'}>
{inviteResult.message}
@@ -1388,6 +1403,15 @@
<AppsTab {wsSlug} />
{/key}
</section>
<!-- TASK-2255 (C109): plans sell a webhook quota, and the web UI has no
webhook screen; say where they are managed. -->
<section class="section">
<h2>Webhooks</h2>
<p class="section-note">
Webhooks are managed from the command line (<code>pad webhook list</code>,
<code>create</code>, <code>delete</code>, <code>test</code>) or the REST API, not from this page.
</p>
</section>
{:else if activeTab === 'danger'}
<section class="section">
<div class="danger-banner">
@@ -1440,6 +1464,11 @@
ring is the browser's, shown only for keyboard focus. */
.settings-tabpanel:focus:not(:focus-visible) { outline: none; }
.settings-header h1 { font-size: 1.6em; }
.section-note { font-size: 0.85em; color: var(--text-secondary); margin: var(--space-1) 0 var(--space-2); }
/* A link inside running text must not rely on colour alone (axe link-in-text-block). */
.section-note a { text-decoration: underline; }
.role-legend { list-style: none; padding: 0; margin: var(--space-2) 0 0; font-size: 0.82em; color: var(--text-secondary); }
.role-legend li + li { margin-top: 2px; }
/* ── Tab bar ──── */
/* C82 (TASK-2245): the five owner tabs are 562px intrinsic while the bar's
box is viewport minus the page's 48px of padding, so below ~610px the row
+12 -1
View File
@@ -624,7 +624,12 @@
</svelte:head>
<div class="settings-page">
<h1 class="page-title">Account Settings</h1>
<h1 class="page-title">Account settings</h1>
<!-- TASK-2255 (C59): the workspace's own settings are a different page. -->
<p class="page-note">
Your profile, password and sign-in, in every workspace. A workspace's name, members and
collections are in its own Workspace settings (⚙ in that workspace's sidebar).
</p>
{#if loading}
<div class="loading">Loading...</div>
@@ -1197,6 +1202,12 @@
max-width: 600px;
}
.page-note {
font-size: 0.88em;
color: var(--text-secondary);
margin: 0 0 var(--space-4);
}
.page-title {
font-size: 1.4rem;
font-weight: 700;