feat: App bar enhancements (#1996)

- Always shows current org name
- Moves org dropdown next to logo
- Reduces logo size when logged in at smaller screen sizes
This commit is contained in:
sua yoo 2024-08-06 17:54:05 -07:00 committed by GitHub
parent 96e48b001b
commit ba1e2ab602
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 159 additions and 115 deletions

File diff suppressed because one or more lines are too long

Before

Width:  |  Height:  |  Size: 5.9 KiB

After

Width:  |  Height:  |  Size: 8.3 KiB

View File

@ -283,90 +283,113 @@ export class App extends LiteElement {
const isSuperAdmin = this.appState.userInfo?.isSuperAdmin; const isSuperAdmin = this.appState.userInfo?.isSuperAdmin;
let homeHref = "/"; let homeHref = "/";
if (!isSuperAdmin && this.appState.orgSlug) { if (!isSuperAdmin && this.appState.orgSlug) {
homeHref = `/orgs/${this.appState.orgSlug}`; homeHref = this.orgBasePath;
} }
const showFullLogo =
this.viewState.route === "login" || !this.authService.authState;
return html` return html`
<div class="border-b bg-neutral-50"> <div class="border-b bg-neutral-50">
<nav <nav
class="mx-auto box-border flex h-12 items-center justify-between px-3 xl:pl-6" class="mx-auto box-border flex h-12 items-center justify-between px-3 xl:pl-6"
> >
<a <div class="flex items-center">
class="items-between flex gap-2" <a
aria-label="home" class="items-between flex gap-2"
href=${homeHref} aria-label="home"
@click=${(e: MouseEvent) => { href=${homeHref}
if (isSuperAdmin) { @click=${(e: MouseEvent) => {
this.clearSelectedOrg(); if (isSuperAdmin) {
} this.clearSelectedOrg();
this.navLink(e); }
}} this.navLink(e);
> }}
<img class="h-6" alt="Browsertrix logo" src=${brandLockupColor} /> >
<div
class="${showFullLogo
? "w-[10.5rem]"
: "w-6 md:w-[10.5rem]"} h-6 bg-cover bg-no-repeat"
style="background-image: url(${brandLockupColor})"
role="img"
title="Browsertrix logo"
></div>
</a>
${when(
this.authService.authState,
() => html`
${isSuperAdmin
? html`
<div
role="separator"
class="mx-2.5 h-6 w-0 border-l"
></div>
<a
class="flex items-center gap-2 font-medium text-primary-700 transition-colors hover:text-primary"
href="/"
@click=${(e: MouseEvent) => {
this.clearSelectedOrg();
this.navLink(e);
}}
>
<sl-icon
class="text-lg"
name="house-gear-fill"
></sl-icon>
${msg("Admin")}</a
>
`
: nothing}
<div role="separator" class="mx-2.5 h-7 w-0 border-l"></div>
${this.renderOrgs()}
`,
)}
</div>
<div class="grid auto-cols-max grid-flow-col items-center gap-5">
${isSuperAdmin ${isSuperAdmin
? html`<btrix-tag>${msg("Admin")}</btrix-tag>` ? html`
: nothing}
</a>
${isSuperAdmin
? html`
<div
class="grid grid-flow-col items-center gap-3 text-xs md:gap-5 md:text-sm"
>
<a <a
class="font-medium text-neutral-500 hover:text-neutral-400" class="font-medium text-neutral-500 hover:text-primary"
href="/"
@click=${(e: MouseEvent) => {
this.clearSelectedOrg();
this.navLink(e);
}}
>${msg("Dashboard")}</a
>
<a
class="font-medium text-neutral-500 hover:text-neutral-400"
href="/crawls" href="/crawls"
@click=${this.navLink} @click=${this.navLink}
>${msg("Running Crawls")}</a >${msg("Running Crawls")}</a
> >
<div class="hidden md:block">${this.renderFindCrawl()}</div> <div class="hidden md:block">${this.renderFindCrawl()}</div>
</div> `
` : ""}
: ""}
<div class="grid auto-cols-max grid-flow-col items-center gap-3">
${this.authService.authState ${this.authService.authState
? html` ${this.renderOrgs()} ? html`<sl-dropdown placement="bottom-end" distance="4">
<sl-dropdown placement="bottom-end"> <button slot="trigger">
<sl-icon-button <sl-avatar
slot="trigger"
name="person-circle"
label=${msg("Open user menu")} label=${msg("Open user menu")}
style="font-size: 1.5rem;" shape="rounded"
></sl-icon-button> class="[--size:1.75rem]"
></sl-avatar>
<sl-menu class="w-60 min-w-min max-w-full"> </button>
<div class="px-7 py-2">${this.renderMenuUserInfo()}</div> <sl-menu class="w-60 min-w-min max-w-full">
<sl-divider></sl-divider> <div class="px-7 py-2">${this.renderMenuUserInfo()}</div>
<sl-menu-item <sl-divider></sl-divider>
@click=${() => this.navigate(ROUTES.accountSettings)} <sl-menu-item
> @click=${() => this.navigate(ROUTES.accountSettings)}
<sl-icon slot="prefix" name="gear"></sl-icon> >
${msg("Account Settings")} <sl-icon slot="prefix" name="gear"></sl-icon>
</sl-menu-item> ${msg("Account Settings")}
${this.appState.userInfo?.isSuperAdmin </sl-menu-item>
? html` <sl-menu-item ${this.appState.userInfo?.isSuperAdmin
@click=${() => this.navigate(ROUTES.usersInvite)} ? html` <sl-menu-item
> @click=${() => this.navigate(ROUTES.usersInvite)}
<sl-icon slot="prefix" name="person-plus"></sl-icon> >
${msg("Invite Users")} <sl-icon slot="prefix" name="person-plus"></sl-icon>
</sl-menu-item>` ${msg("Invite Users")}
: ""} </sl-menu-item>`
<sl-divider></sl-divider> : ""}
<sl-menu-item @click="${this.onLogOut}"> <sl-divider></sl-divider>
<sl-icon slot="prefix" name="door-open"></sl-icon> <sl-menu-item @click="${this.onLogOut}">
${msg("Log Out")} <sl-icon slot="prefix" name="door-open"></sl-icon>
</sl-menu-item> ${msg("Log Out")}
</sl-menu> </sl-menu-item>
</sl-dropdown>` </sl-menu>
</sl-dropdown>`
: html` : html`
<a href="/log-in"> ${msg("Log In")} </a> <a href="/log-in"> ${msg("Log In")} </a>
${this.appState.settings?.registrationEnabled ${this.appState.settings?.registrationEnabled
@ -388,7 +411,7 @@ export class App extends LiteElement {
private renderOrgs() { private renderOrgs() {
const orgs = this.appState.userInfo?.orgs; const orgs = this.appState.userInfo?.orgs;
if (!orgs || orgs.length < 2 || !this.appState.userInfo) return; if (!orgs) return;
const selectedOption = this.appState.orgSlug const selectedOption = this.appState.orgSlug
? orgs.find(({ slug }) => slug === this.appState.orgSlug) ? orgs.find(({ slug }) => slug === this.appState.orgSlug)
@ -405,47 +428,61 @@ export class App extends LiteElement {
const orgNameLength = 50; const orgNameLength = 50;
return html` return html`
<sl-dropdown placement="bottom-end"> <a
<sl-button slot="trigger" variant="text" size="small" caret class="font-medium text-neutral-600"
>${selectedOption.name.slice(0, orgNameLength)}</sl-button href=${this.orgBasePath}
> @click=${this.navLink}
<sl-menu >
@sl-select=${(e: CustomEvent<{ item: { value: string } }>) => { ${selectedOption.name.slice(0, orgNameLength)}
const { value } = e.detail.item; </a>
if (value) { ${when(
this.navigate(`/orgs/${value}`); orgs.length > 1,
} else { () => html`
if (this.appState.userInfo) { <sl-dropdown placement="bottom-end">
this.clearSelectedOrg(); <sl-icon-button
} slot="trigger"
this.navigate(`/`); name="chevron-expand"
} label=${msg("Expand org list")}
}} ></sl-icon-button>
> <sl-menu
${when( @sl-select=${(e: CustomEvent<{ item: { value: string } }>) => {
this.appState.userInfo.isSuperAdmin, const { value } = e.detail.item;
() => html` if (value) {
<sl-menu-item this.navigate(`/orgs/${value}`);
type="checkbox" } else {
value="" if (this.appState.userInfo) {
?checked=${!selectedOption.slug} this.clearSelectedOrg();
>${msg("All Organizations")}</sl-menu-item }
> this.navigate(`/`);
<sl-divider></sl-divider> }
`, }}
)} >
${orgs.map( ${when(
(org) => html` this.appState.userInfo?.isSuperAdmin,
<sl-menu-item () => html`
type="checkbox" <sl-menu-item
value=${org.slug} type="checkbox"
?checked=${org.slug === selectedOption.slug} value=""
>${org.name.slice(0, orgNameLength)}</sl-menu-item ?checked=${!selectedOption.slug}
> >${msg("All Organizations")}</sl-menu-item
`, >
)} <sl-divider></sl-divider>
</sl-menu> `,
</sl-dropdown> )}
${orgs.map(
(org) => html`
<sl-menu-item
type="checkbox"
value=${org.slug}
?checked=${org.slug === selectedOption.slug}
>${org.name.slice(0, orgNameLength)}</sl-menu-item
>
`,
)}
</sl-menu>
</sl-dropdown>
`,
)}
`; `;
} }
@ -454,9 +491,7 @@ export class App extends LiteElement {
if (this.appState.userInfo.isSuperAdmin) { if (this.appState.userInfo.isSuperAdmin) {
return html` return html`
<div class="mb-2"> <div class="mb-2">
<sl-tag class="uppercase" variant="primary" size="small" <btrix-tag>${msg("Admin")}</btrix-tag>
>${msg("admin")}</sl-tag
>
</div> </div>
<div class="font-medium text-neutral-700"> <div class="font-medium text-neutral-700">
${this.appState.userInfo.name} ${this.appState.userInfo.name}
@ -729,7 +764,7 @@ export class App extends LiteElement {
> >
<button <button
slot="trigger" slot="trigger"
class="font-medium text-primary hover:text-indigo-400" class="font-medium text-primary-700 hover:text-primary"
> >
${msg("Jump to Crawl")} ${msg("Jump to Crawl")}
</button> </button>

View File

@ -7,6 +7,7 @@ import { registerIconLibrary } from "@shoelace-style/shoelace/dist/utilities/ico
import "@shoelace-style/shoelace/dist/themes/light.css"; import "@shoelace-style/shoelace/dist/themes/light.css";
import "@shoelace-style/shoelace/dist/components/alert/alert"; import "@shoelace-style/shoelace/dist/components/alert/alert";
import "@shoelace-style/shoelace/dist/components/avatar/avatar";
import "@shoelace-style/shoelace/dist/components/button/button"; import "@shoelace-style/shoelace/dist/components/button/button";
import "@shoelace-style/shoelace/dist/components/icon/icon"; import "@shoelace-style/shoelace/dist/components/icon/icon";
import "@shoelace-style/shoelace/dist/components/input/input"; import "@shoelace-style/shoelace/dist/components/input/input";

View File

@ -102,6 +102,14 @@
} }
@layer components { @layer components {
sl-avatar::part(base) {
transition: var(--sl-transition-x-fast) background-color;
}
sl-avatar:hover::part(base) {
background-color: var(--sl-color-primary-500);
}
/* Add more spacing between label, input and help text */ /* Add more spacing between label, input and help text */
.form-label, .form-label,
btrix-tag-input::part(form-control-label), btrix-tag-input::part(form-control-label),