chore: Refactor home component (#2000)

Resolves https://github.com/webrecorder/browsertrix/issues/1972

---------

Co-authored-by: Emma Segal-Grossman <hi@emma.cafe>
This commit is contained in:
sua yoo 2024-08-15 14:16:14 -07:00 committed by GitHub
parent 92fdcfd986
commit 9a7033875b
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
9 changed files with 26 additions and 28 deletions

View File

@ -54,12 +54,6 @@ describe("browsertrix-app", () => {
expect(el).lightDom.descendants("btrix-home");
});
it("renders when `AuthService.initSessionStorage` rejects", async () => {
stub(AuthService, "initSessionStorage").returns(Promise.reject());
const el = await fixture("<browsertrix-app></browsertrix-app>");
expect(el).lightDom.descendants("btrix-log-in");
});
// TODO move tests to AuthService
it("sets auth state from session storage", async () => {
stub(AuthService.prototype, "startFreshnessCheck").callsFake(() => {});
@ -86,7 +80,7 @@ describe("browsertrix-app", () => {
Promise.resolve(mockAPIUser),
);
stub(AuthService.prototype, "startFreshnessCheck").callsFake(() => {});
stub(AuthService, "initSessionStorage").callsFake(() =>
stub(AuthService, "initSessionStorage").callsFake(async () =>
Promise.resolve({
headers: { Authorization: "_fake_headers_" },
tokenExpiresAt: 0,
@ -105,7 +99,7 @@ describe("browsertrix-app", () => {
Promise.resolve(mockAPIUser),
);
stub(AuthService.prototype, "startFreshnessCheck").callsFake(() => {});
stub(AuthService, "initSessionStorage").callsFake(() =>
stub(AuthService, "initSessionStorage").callsFake(async () =>
Promise.resolve({
headers: { Authorization: "_fake_headers_" },
tokenExpiresAt: 0,
@ -134,7 +128,7 @@ describe("browsertrix-app", () => {
}),
);
stub(AuthService.prototype, "startFreshnessCheck").callsFake(() => {});
stub(AuthService, "initSessionStorage").callsFake(() =>
stub(AuthService, "initSessionStorage").callsFake(async () =>
Promise.resolve({
headers: { Authorization: "_fake_headers_" },
tokenExpiresAt: 0,

View File

@ -82,6 +82,9 @@ export class App extends LiteElement {
this.syncViewState();
if (authState) {
this.authService.saveLogin(authState);
}
this.syncViewState();
if (authState) {
void this.updateUserInfo();
}
super.connectedCallback();
@ -124,7 +127,7 @@ export class App extends LiteElement {
(pathname === "/log-in" || pathname === "/reset-password")
) {
// Redirect to logged in home page
this.viewState = this.router.match(ROUTES.home);
this.viewState = this.router.match(this.orgBasePath);
window.history.replaceState(this.viewState, "", this.viewState.pathname);
} else {
this.viewState = this.router.match(
@ -225,7 +228,7 @@ export class App extends LiteElement {
if (newViewPath === "/log-in" && this.authService.authState) {
// Redirect to logged in home page
this.viewState = this.router.match(ROUTES.home);
this.viewState = this.router.match(this.orgBasePath);
} else {
this.viewState = this.router.match(newViewPath);
}
@ -815,7 +818,7 @@ export class App extends LiteElement {
});
if (!detail.api) {
this.navigate(detail.redirectUrl || ROUTES.home);
this.navigate(detail.redirectUrl || this.orgBasePath);
}
if (detail.firstLogin) {
@ -833,11 +836,13 @@ export class App extends LiteElement {
this.navigate(ROUTES.login, {
redirectUrl,
});
this.notify({
message: msg("Please log in to continue."),
variant: "warning",
icon: "exclamation-triangle",
});
if (redirectUrl && redirectUrl !== "/") {
this.notify({
message: msg("Please log in to continue."),
variant: "warning",
icon: "exclamation-triangle",
});
}
};
onNavigateTo = (event: CustomEvent<NavigateEventDetail>) => {

View File

@ -4,6 +4,7 @@ import { serialize } from "@shoelace-style/shoelace/dist/utilities/form.js";
import { type PropertyValues } from "lit";
import { customElement, state } from "lit/decorators.js";
import needLogin from "@/decorators/needLogin";
import type { InviteSuccessDetail } from "@/features/accounts/invite-form";
import type { APIUser } from "@/index";
import type { APIPaginatedList } from "@/types/api";
@ -26,6 +27,7 @@ import { formatAPIUser } from "@/utils/user";
*/
@localized()
@customElement("btrix-home")
@needLogin
export class Home extends LiteElement {
@state()
private orgList?: OrgData[];
@ -52,6 +54,7 @@ export class Home extends LiteElement {
private readonly validateOrgNameMax = maxLengthValidator(40);
connectedCallback() {
console.log("saldfhjkass");
if (this.authState) {
if (this.slug) {
this.navTo(`/orgs/${this.slug}`);

View File

@ -1,5 +1,4 @@
import "./home";
import(/* webpackChunkName: "admin" */ "./admin");
import(/* webpackChunkName: "sign-up" */ "./sign-up");
import(/* webpackChunkName: "log-in" */ "./log-in");
import(/* webpackChunkName: "org" */ "./org");

View File

@ -8,7 +8,6 @@ import { renderInviteMessage } from "./ui/inviteMessage";
import { BtrixElement } from "@/classes/BtrixElement";
import type { APIUser } from "@/index";
import type { OrgUpdatedDetail } from "@/pages/invite/ui/org-form";
import { ROUTES } from "@/routes";
import type { UserOrg, UserOrgInviteInfo } from "@/types/user";
import { isApiError } from "@/utils/api";
import { AppStateService } from "@/utils/state";
@ -149,7 +148,7 @@ export class AcceptInvite extends BtrixElement {
? nothing
: html`
<a
href=${ROUTES.home}
href=${this.navigate.orgBasePath}
@click=${this.navigate.link}
class="mt-3 inline-block underline hover:no-underline"
>

View File

@ -6,7 +6,6 @@ import { renderInviteMessage } from "./ui/inviteMessage";
import type { SignUpSuccessDetail } from "@/features/accounts/sign-up-form";
import type { OrgUpdatedDetail } from "@/pages/invite/ui/org-form";
import { ROUTES } from "@/routes";
import type { UserOrg, UserOrgInviteInfo } from "@/types/user";
import AuthService, { type LoggedInEventDetail } from "@/utils/AuthService";
import LiteElement, { html } from "@/utils/LiteElement";
@ -97,7 +96,7 @@ export class Join extends LiteElement {
html`<btrix-alert variant="danger">
<div>${err instanceof Error ? err.message : err}</div>
<a
href=${ROUTES.home}
href=${this.orgBasePath}
@click=${this.navLink}
class="mt-3 inline-block underline hover:no-underline"
>
@ -174,7 +173,7 @@ export class Join extends LiteElement {
if (inviteInfo?.orgSlug) {
this.navTo(`/orgs/${inviteInfo.orgSlug}`);
} else {
this.navTo(ROUTES.home);
this.navTo(this.orgBasePath);
}
}
}

View File

@ -4,7 +4,6 @@ import { assign, createMachine, interpret } from "@xstate/fsm";
import { type PropertyValues } from "lit";
import { customElement, property, state } from "lit/decorators.js";
import { ROUTES } from "@/routes";
import { isApiError } from "@/utils/api";
import type { ViewState } from "@/utils/APIRouter";
import AuthService from "@/utils/AuthService";
@ -145,7 +144,7 @@ export class LogInPage extends LiteElement {
viewState!: ViewState;
@property({ type: String })
redirectUrl: string = ROUTES.home;
redirectUrl?: string;
private readonly formStateService = interpret(machine);

View File

@ -5,7 +5,7 @@ type Routes = { [key: string]: UrlPattern };
type Paths = { [key: string]: string };
export type ViewState = {
// route name, e.g. "home"
// route name, e.g. "admin"
route: string | null;
// path name
// e.g. "/dashboard"

View File

@ -347,7 +347,7 @@ export default class AuthService {
this.logout();
const { pathname, search, hash } = window.location;
const redirectUrl =
pathname !== ROUTES.login && pathname !== ROUTES.home
pathname !== ROUTES.login && pathname !== "/"
? `${pathname}${search}${hash}`
: "";
window.dispatchEvent(AuthService.createNeedLoginEvent({ redirectUrl }));