${msg("Password")}
diff --git a/frontend/src/index.test.ts b/frontend/src/index.test.ts
index a3ba9a8e..a0f0d67d 100644
--- a/frontend/src/index.test.ts
+++ b/frontend/src/index.test.ts
@@ -103,7 +103,7 @@ describe("browsertrix-app", () => {
email: "test-user@example.com",
name: "Test User",
isVerified: false,
- isAdmin: false,
+ isSuperAdmin: false,
orgs: [
{
id: "test_org_id",
diff --git a/frontend/src/index.ts b/frontend/src/index.ts
index bd7cfcc4..67f517d0 100644
--- a/frontend/src/index.ts
+++ b/frontend/src/index.ts
@@ -1,4 +1,4 @@
-import { localized, msg } from "@lit/localize";
+import { localized, msg, str } from "@lit/localize";
import type { SlDialog } from "@shoelace-style/shoelace";
import { nothing, render, type TemplateResult } from "lit";
import { customElement, property, query, state } from "lit/decorators.js";
@@ -149,7 +149,7 @@ export class App extends LiteElement {
if (
orgs.length &&
- !this.appState.userInfo!.isAdmin &&
+ !this.appState.userInfo!.isSuperAdmin &&
!this.appState.orgSlug
) {
const firstOrg = orgs[0].slug;
@@ -232,7 +232,7 @@ export class App extends LiteElement {
render() {
return html`
- ${this.renderNavBar()}
+ ${this.renderNavBar()} ${this.renderAlertBanner()}
${this.renderPage()}
${this.renderFooter()}
@@ -247,10 +247,41 @@ export class App extends LiteElement {
`;
}
+ private renderAlertBanner() {
+ if (this.appState.userInfo?.orgs && !this.appState.userInfo.orgs.length) {
+ return this.renderNoOrgsBanner();
+ }
+ }
+
+ private renderNoOrgsBanner() {
+ return html`
+
+
+
+
+
+ ${msg("Your account isn't quite set up yet")}
+
+ ${msg(
+ "You must belong to at least one org in order to access Browsertrix features.",
+ )}
+ ${this.appState.settings?.salesEmail
+ ? msg(
+ str`If you haven't received an invitation to an org, please contact us at ${this.appState.settings.salesEmail}.`,
+ )
+ : msg(
+ str`If you haven't received an invitation to an org, please contact your Browsertrix administrator.`,
+ )}
+
+
+
+ `;
+ }
+
private renderNavBar() {
- const isAdmin = this.appState.userInfo?.isAdmin;
+ const isSuperAdmin = this.appState.userInfo?.isSuperAdmin;
let homeHref = "/";
- if (!isAdmin && this.appState.orgSlug) {
+ if (!isSuperAdmin && this.appState.orgSlug) {
homeHref = `/orgs/${this.appState.orgSlug}`;
}
@@ -263,7 +294,7 @@ export class App extends LiteElement {
aria-label="home"
href=${homeHref}
@click=${(e: MouseEvent) => {
- if (isAdmin) {
+ if (isSuperAdmin) {
this.clearSelectedOrg();
}
this.navLink(e);
@@ -271,7 +302,7 @@ export class App extends LiteElement {
>

- ${isAdmin
+ ${isSuperAdmin
? html`
${msg("Account Settings")}
- ${this.appState.userInfo?.isAdmin
+ ${this.appState.userInfo?.isSuperAdmin
? html` this.navigate(ROUTES.usersInvite)}
>
@@ -387,7 +418,7 @@ export class App extends LiteElement {
}}
>
${when(
- this.appState.userInfo.isAdmin,
+ this.appState.userInfo.isSuperAdmin,
() => html`
) {
if (changedProperties.has("slug") && this.slug) {
this.navTo(`/orgs/${this.slug}`);
- } else if (changedProperties.has("authState") && this.authState) {
- void this.fetchOrgs();
+ } else if (changedProperties.has("userInfo") && this.userInfo) {
+ if (this.userInfo.isSuperAdmin) {
+ void this.fetchOrgs();
+ } else {
+ this.navTo(`/account/settings`);
+ }
}
}
@@ -71,7 +75,7 @@ export class Home extends LiteElement {
const orgListUpdated = changedProperties.has("orgList") && this.orgList;
const userInfoUpdated = changedProperties.has("userInfo") && this.userInfo;
if (orgListUpdated || userInfoUpdated) {
- if (this.userInfo?.isAdmin && this.orgList && !this.orgList.length) {
+ if (this.userInfo?.isSuperAdmin && this.orgList && !this.orgList.length) {
this.isAddingOrg = true;
}
}
@@ -89,7 +93,7 @@ export class Home extends LiteElement {
let title: string | undefined;
let content: TemplateResult<1> | undefined;
- if (this.userInfo.isAdmin) {
+ if (this.userInfo.isSuperAdmin) {
title = msg("Welcome");
content = this.renderAdminOrgs();
} else {
diff --git a/frontend/src/pages/org/index.ts b/frontend/src/pages/org/index.ts
index 78fecd81..c39753df 100644
--- a/frontend/src/pages/org/index.ts
+++ b/frontend/src/pages/org/index.ts
@@ -197,16 +197,7 @@ export class Org extends LiteElement {
if (org) {
this.navTo(`/orgs/${org.slug}`);
} else {
- // Handle edge case where user does not belong
- // to any orgs but is attempting to log in
- // TODO check if hosted instance and show support email if so
- this.notify({
- message: msg(
- "You must belong to at least one org in order to log in. Please contact your Browsertrix admin to resolve the issue.",
- ),
- variant: "danger",
- icon: "exclamation-octagon",
- });
+ this.navTo(`/account/settings`);
}
return;
@@ -376,7 +367,7 @@ export class Org extends LiteElement {
path: "browser-profiles",
}),
)}
- ${when(this.isAdmin || this.userInfo?.isAdmin, () =>
+ ${when(this.isAdmin || this.userInfo?.isSuperAdmin, () =>
this.renderNavTab({
tabName: "settings",
label: msg("Org Settings"),
diff --git a/frontend/src/types/user.ts b/frontend/src/types/user.ts
index 544338fe..69b734b0 100644
--- a/frontend/src/types/user.ts
+++ b/frontend/src/types/user.ts
@@ -30,6 +30,6 @@ export type CurrentUser = {
email: string;
name: string;
isVerified: boolean;
- isAdmin: boolean;
+ isSuperAdmin: boolean;
orgs: UserOrg[];
};
diff --git a/frontend/src/utils/form.ts b/frontend/src/utils/form.ts
index 56788c16..6df6e62f 100644
--- a/frontend/src/utils/form.ts
+++ b/frontend/src/utils/form.ts
@@ -54,7 +54,9 @@ export function maxLengthValidator(maxLength: number): MaxLengthValidator {
el.setCustomValidity(
isInvalid
- ? msg(str`Please shorten this text to ${maxLength} or fewer characters.`)
+ ? msg(
+ str`Please shorten this text to ${maxLength} or fewer characters.`,
+ )
: "",
);
diff --git a/frontend/src/utils/user.ts b/frontend/src/utils/user.ts
index 930764ab..1d238d66 100644
--- a/frontend/src/utils/user.ts
+++ b/frontend/src/utils/user.ts
@@ -7,7 +7,7 @@ export function formatAPIUser(userData: APIUser): CurrentUser {
email: userData.email,
name: userData.name,
isVerified: userData.is_verified,
- isAdmin: userData.is_superuser,
+ isSuperAdmin: userData.is_superuser,
orgs: userData.orgs,
};
}