Rename ShellUser.menu to profileLinks, so menu keeps one meaning in the shell
This commit was merged in pull request #220.
This commit is contained in:
@@ -608,7 +608,7 @@ interface RequestContext {
|
||||
}
|
||||
```
|
||||
|
||||
**`ctx.chrome`** — `{ brand, csrfToken, nav, signInHref, theme, user }` (`user.menu` holds the profile-dropdown links). Hand each field to the
|
||||
**`ctx.chrome`** — `{ brand, csrfToken, nav, signInHref, theme, user }` (`user.profileLinks` holds the profile-dropdown links). Hand each field to the
|
||||
matching `partials/shell` local and a `view` result renders the **native app shell**, exactly as
|
||||
`examples/plugins/scheduling/views/overview.ejs` does; a field you omit falls back to its shell
|
||||
default rather than erroring. `chrome.nav` is the whole global menu — every installed plugin's
|
||||
|
||||
@@ -103,7 +103,7 @@ const entries = (opts: { permissions?: string[]; signedIn?: boolean }): { href:
|
||||
plugins: [account],
|
||||
translatorFor: () => (key) => (key === "account.settings" ? "Inställningar" : key),
|
||||
...(opts.signedIn === false ? {} : { user: { email: "ada@x.io", id: "u1", permissions: opts.permissions ?? [] } }),
|
||||
}).user.menu!;
|
||||
}).user.profileLinks!;
|
||||
|
||||
test("profile menu entries are gated like nav nodes, translated by their plugin and carry the locale", () => {
|
||||
assert.deepEqual(entries({}), [
|
||||
|
||||
+3
-3
@@ -22,11 +22,11 @@ export interface ProfileLink {
|
||||
// What a plugin's `profileMenu` declares: a link plus the one gate that decides who sees it.
|
||||
export interface ProfileMenuEntry extends ProfileLink, Gate {}
|
||||
|
||||
// `menu` rides on the user, which every view already hands to the shell, so no view needs a new local.
|
||||
// `profileLinks` rides on the user, which every view already hands to the shell, so no view needs a new local.
|
||||
export interface ShellUser {
|
||||
email: string;
|
||||
initials: string;
|
||||
menu?: ProfileLink[]; // gate-filtered, translated, locale-carried. The host always sets it; a hand-built fixture may omit it
|
||||
profileLinks?: ProfileLink[]; // gate-filtered, translated, locale-carried. The host always sets it; a hand-built fixture may omit it
|
||||
name: string;
|
||||
}
|
||||
|
||||
@@ -79,7 +79,7 @@ export function buildPluginChrome(opts: ChromeOptions): PageChrome {
|
||||
nav: carryLocaleInto(nav, carryLocale),
|
||||
signInHref: carryLocale(returnTo),
|
||||
...(theme != null ? { theme } : {}),
|
||||
user: { ...shellUser(opts.user, t), menu: profileLinks(opts, t, carryLocale) },
|
||||
user: { ...shellUser(opts.user, t), profileLinks: profileLinks(opts, t, carryLocale) },
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@@ -137,7 +137,7 @@ test("profile menu entries render as links above Sign out, with their icon", asy
|
||||
csrfToken: "tok.sig",
|
||||
user: {
|
||||
email: "ada@acme.io", initials: "AD", name: "ada",
|
||||
menu: [{ href: "/account/settings", icon: "i-user", label: "My <settings>" }, { href: "/account/help", label: "Help" }],
|
||||
profileLinks: [{ href: "/account/settings", icon: "i-user", label: "My <settings>" }, { href: "/account/help", label: "Help" }],
|
||||
},
|
||||
});
|
||||
const panel = html.slice(html.indexOf('id="profile-menu"'), html.indexOf("</aside>"));
|
||||
|
||||
@@ -71,7 +71,7 @@
|
||||
</button>
|
||||
<div id="profile-menu" class="menu-pop left up" popover style="min-width:220px">
|
||||
<div class="menu-head"><%= t("shell.signedInAs", { name: user.name }) %></div>
|
||||
<% (user.menu || []).forEach((link) => { %>
|
||||
<% (user.profileLinks || []).forEach((link) => { %>
|
||||
<a class="menu-item" href="<%= link.href %>"><% if (link.icon) { %><svg class="ico"><use href="#<%= link.icon %>" /></svg><% } %><%= link.label %></a>
|
||||
<% }) %>
|
||||
<%# Sign out is a state change → a POST form (not a GET link), CSRF-guarded by app.ts %>
|
||||
|
||||
Reference in New Issue
Block a user