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:
parent
92fdcfd986
commit
9a7033875b
@ -54,12 +54,6 @@ describe("browsertrix-app", () => {
|
|||||||
expect(el).lightDom.descendants("btrix-home");
|
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
|
// TODO move tests to AuthService
|
||||||
it("sets auth state from session storage", async () => {
|
it("sets auth state from session storage", async () => {
|
||||||
stub(AuthService.prototype, "startFreshnessCheck").callsFake(() => {});
|
stub(AuthService.prototype, "startFreshnessCheck").callsFake(() => {});
|
||||||
@ -86,7 +80,7 @@ describe("browsertrix-app", () => {
|
|||||||
Promise.resolve(mockAPIUser),
|
Promise.resolve(mockAPIUser),
|
||||||
);
|
);
|
||||||
stub(AuthService.prototype, "startFreshnessCheck").callsFake(() => {});
|
stub(AuthService.prototype, "startFreshnessCheck").callsFake(() => {});
|
||||||
stub(AuthService, "initSessionStorage").callsFake(() =>
|
stub(AuthService, "initSessionStorage").callsFake(async () =>
|
||||||
Promise.resolve({
|
Promise.resolve({
|
||||||
headers: { Authorization: "_fake_headers_" },
|
headers: { Authorization: "_fake_headers_" },
|
||||||
tokenExpiresAt: 0,
|
tokenExpiresAt: 0,
|
||||||
@ -105,7 +99,7 @@ describe("browsertrix-app", () => {
|
|||||||
Promise.resolve(mockAPIUser),
|
Promise.resolve(mockAPIUser),
|
||||||
);
|
);
|
||||||
stub(AuthService.prototype, "startFreshnessCheck").callsFake(() => {});
|
stub(AuthService.prototype, "startFreshnessCheck").callsFake(() => {});
|
||||||
stub(AuthService, "initSessionStorage").callsFake(() =>
|
stub(AuthService, "initSessionStorage").callsFake(async () =>
|
||||||
Promise.resolve({
|
Promise.resolve({
|
||||||
headers: { Authorization: "_fake_headers_" },
|
headers: { Authorization: "_fake_headers_" },
|
||||||
tokenExpiresAt: 0,
|
tokenExpiresAt: 0,
|
||||||
@ -134,7 +128,7 @@ describe("browsertrix-app", () => {
|
|||||||
}),
|
}),
|
||||||
);
|
);
|
||||||
stub(AuthService.prototype, "startFreshnessCheck").callsFake(() => {});
|
stub(AuthService.prototype, "startFreshnessCheck").callsFake(() => {});
|
||||||
stub(AuthService, "initSessionStorage").callsFake(() =>
|
stub(AuthService, "initSessionStorage").callsFake(async () =>
|
||||||
Promise.resolve({
|
Promise.resolve({
|
||||||
headers: { Authorization: "_fake_headers_" },
|
headers: { Authorization: "_fake_headers_" },
|
||||||
tokenExpiresAt: 0,
|
tokenExpiresAt: 0,
|
||||||
|
@ -82,6 +82,9 @@ export class App extends LiteElement {
|
|||||||
this.syncViewState();
|
this.syncViewState();
|
||||||
if (authState) {
|
if (authState) {
|
||||||
this.authService.saveLogin(authState);
|
this.authService.saveLogin(authState);
|
||||||
|
}
|
||||||
|
this.syncViewState();
|
||||||
|
if (authState) {
|
||||||
void this.updateUserInfo();
|
void this.updateUserInfo();
|
||||||
}
|
}
|
||||||
super.connectedCallback();
|
super.connectedCallback();
|
||||||
@ -124,7 +127,7 @@ export class App extends LiteElement {
|
|||||||
(pathname === "/log-in" || pathname === "/reset-password")
|
(pathname === "/log-in" || pathname === "/reset-password")
|
||||||
) {
|
) {
|
||||||
// Redirect to logged in home page
|
// 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);
|
window.history.replaceState(this.viewState, "", this.viewState.pathname);
|
||||||
} else {
|
} else {
|
||||||
this.viewState = this.router.match(
|
this.viewState = this.router.match(
|
||||||
@ -225,7 +228,7 @@ export class App extends LiteElement {
|
|||||||
|
|
||||||
if (newViewPath === "/log-in" && this.authService.authState) {
|
if (newViewPath === "/log-in" && this.authService.authState) {
|
||||||
// Redirect to logged in home page
|
// Redirect to logged in home page
|
||||||
this.viewState = this.router.match(ROUTES.home);
|
this.viewState = this.router.match(this.orgBasePath);
|
||||||
} else {
|
} else {
|
||||||
this.viewState = this.router.match(newViewPath);
|
this.viewState = this.router.match(newViewPath);
|
||||||
}
|
}
|
||||||
@ -815,7 +818,7 @@ export class App extends LiteElement {
|
|||||||
});
|
});
|
||||||
|
|
||||||
if (!detail.api) {
|
if (!detail.api) {
|
||||||
this.navigate(detail.redirectUrl || ROUTES.home);
|
this.navigate(detail.redirectUrl || this.orgBasePath);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (detail.firstLogin) {
|
if (detail.firstLogin) {
|
||||||
@ -833,11 +836,13 @@ export class App extends LiteElement {
|
|||||||
this.navigate(ROUTES.login, {
|
this.navigate(ROUTES.login, {
|
||||||
redirectUrl,
|
redirectUrl,
|
||||||
});
|
});
|
||||||
this.notify({
|
if (redirectUrl && redirectUrl !== "/") {
|
||||||
message: msg("Please log in to continue."),
|
this.notify({
|
||||||
variant: "warning",
|
message: msg("Please log in to continue."),
|
||||||
icon: "exclamation-triangle",
|
variant: "warning",
|
||||||
});
|
icon: "exclamation-triangle",
|
||||||
|
});
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
onNavigateTo = (event: CustomEvent<NavigateEventDetail>) => {
|
onNavigateTo = (event: CustomEvent<NavigateEventDetail>) => {
|
||||||
|
@ -4,6 +4,7 @@ import { serialize } from "@shoelace-style/shoelace/dist/utilities/form.js";
|
|||||||
import { type PropertyValues } from "lit";
|
import { type PropertyValues } from "lit";
|
||||||
import { customElement, state } from "lit/decorators.js";
|
import { customElement, state } from "lit/decorators.js";
|
||||||
|
|
||||||
|
import needLogin from "@/decorators/needLogin";
|
||||||
import type { InviteSuccessDetail } from "@/features/accounts/invite-form";
|
import type { InviteSuccessDetail } from "@/features/accounts/invite-form";
|
||||||
import type { APIUser } from "@/index";
|
import type { APIUser } from "@/index";
|
||||||
import type { APIPaginatedList } from "@/types/api";
|
import type { APIPaginatedList } from "@/types/api";
|
||||||
@ -26,6 +27,7 @@ import { formatAPIUser } from "@/utils/user";
|
|||||||
*/
|
*/
|
||||||
@localized()
|
@localized()
|
||||||
@customElement("btrix-home")
|
@customElement("btrix-home")
|
||||||
|
@needLogin
|
||||||
export class Home extends LiteElement {
|
export class Home extends LiteElement {
|
||||||
@state()
|
@state()
|
||||||
private orgList?: OrgData[];
|
private orgList?: OrgData[];
|
||||||
@ -52,6 +54,7 @@ export class Home extends LiteElement {
|
|||||||
private readonly validateOrgNameMax = maxLengthValidator(40);
|
private readonly validateOrgNameMax = maxLengthValidator(40);
|
||||||
|
|
||||||
connectedCallback() {
|
connectedCallback() {
|
||||||
|
console.log("saldfhjkass");
|
||||||
if (this.authState) {
|
if (this.authState) {
|
||||||
if (this.slug) {
|
if (this.slug) {
|
||||||
this.navTo(`/orgs/${this.slug}`);
|
this.navTo(`/orgs/${this.slug}`);
|
@ -1,5 +1,4 @@
|
|||||||
import "./home";
|
import(/* webpackChunkName: "admin" */ "./admin");
|
||||||
|
|
||||||
import(/* webpackChunkName: "sign-up" */ "./sign-up");
|
import(/* webpackChunkName: "sign-up" */ "./sign-up");
|
||||||
import(/* webpackChunkName: "log-in" */ "./log-in");
|
import(/* webpackChunkName: "log-in" */ "./log-in");
|
||||||
import(/* webpackChunkName: "org" */ "./org");
|
import(/* webpackChunkName: "org" */ "./org");
|
||||||
|
@ -8,7 +8,6 @@ import { renderInviteMessage } from "./ui/inviteMessage";
|
|||||||
import { BtrixElement } from "@/classes/BtrixElement";
|
import { BtrixElement } from "@/classes/BtrixElement";
|
||||||
import type { APIUser } from "@/index";
|
import type { APIUser } from "@/index";
|
||||||
import type { OrgUpdatedDetail } from "@/pages/invite/ui/org-form";
|
import type { OrgUpdatedDetail } from "@/pages/invite/ui/org-form";
|
||||||
import { ROUTES } from "@/routes";
|
|
||||||
import type { UserOrg, UserOrgInviteInfo } from "@/types/user";
|
import type { UserOrg, UserOrgInviteInfo } from "@/types/user";
|
||||||
import { isApiError } from "@/utils/api";
|
import { isApiError } from "@/utils/api";
|
||||||
import { AppStateService } from "@/utils/state";
|
import { AppStateService } from "@/utils/state";
|
||||||
@ -149,7 +148,7 @@ export class AcceptInvite extends BtrixElement {
|
|||||||
? nothing
|
? nothing
|
||||||
: html`
|
: html`
|
||||||
<a
|
<a
|
||||||
href=${ROUTES.home}
|
href=${this.navigate.orgBasePath}
|
||||||
@click=${this.navigate.link}
|
@click=${this.navigate.link}
|
||||||
class="mt-3 inline-block underline hover:no-underline"
|
class="mt-3 inline-block underline hover:no-underline"
|
||||||
>
|
>
|
||||||
|
@ -6,7 +6,6 @@ import { renderInviteMessage } from "./ui/inviteMessage";
|
|||||||
|
|
||||||
import type { SignUpSuccessDetail } from "@/features/accounts/sign-up-form";
|
import type { SignUpSuccessDetail } from "@/features/accounts/sign-up-form";
|
||||||
import type { OrgUpdatedDetail } from "@/pages/invite/ui/org-form";
|
import type { OrgUpdatedDetail } from "@/pages/invite/ui/org-form";
|
||||||
import { ROUTES } from "@/routes";
|
|
||||||
import type { UserOrg, UserOrgInviteInfo } from "@/types/user";
|
import type { UserOrg, UserOrgInviteInfo } from "@/types/user";
|
||||||
import AuthService, { type LoggedInEventDetail } from "@/utils/AuthService";
|
import AuthService, { type LoggedInEventDetail } from "@/utils/AuthService";
|
||||||
import LiteElement, { html } from "@/utils/LiteElement";
|
import LiteElement, { html } from "@/utils/LiteElement";
|
||||||
@ -97,7 +96,7 @@ export class Join extends LiteElement {
|
|||||||
html`<btrix-alert variant="danger">
|
html`<btrix-alert variant="danger">
|
||||||
<div>${err instanceof Error ? err.message : err}</div>
|
<div>${err instanceof Error ? err.message : err}</div>
|
||||||
<a
|
<a
|
||||||
href=${ROUTES.home}
|
href=${this.orgBasePath}
|
||||||
@click=${this.navLink}
|
@click=${this.navLink}
|
||||||
class="mt-3 inline-block underline hover:no-underline"
|
class="mt-3 inline-block underline hover:no-underline"
|
||||||
>
|
>
|
||||||
@ -174,7 +173,7 @@ export class Join extends LiteElement {
|
|||||||
if (inviteInfo?.orgSlug) {
|
if (inviteInfo?.orgSlug) {
|
||||||
this.navTo(`/orgs/${inviteInfo.orgSlug}`);
|
this.navTo(`/orgs/${inviteInfo.orgSlug}`);
|
||||||
} else {
|
} else {
|
||||||
this.navTo(ROUTES.home);
|
this.navTo(this.orgBasePath);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -4,7 +4,6 @@ import { assign, createMachine, interpret } from "@xstate/fsm";
|
|||||||
import { type PropertyValues } from "lit";
|
import { type PropertyValues } from "lit";
|
||||||
import { customElement, property, state } from "lit/decorators.js";
|
import { customElement, property, state } from "lit/decorators.js";
|
||||||
|
|
||||||
import { ROUTES } from "@/routes";
|
|
||||||
import { isApiError } from "@/utils/api";
|
import { isApiError } from "@/utils/api";
|
||||||
import type { ViewState } from "@/utils/APIRouter";
|
import type { ViewState } from "@/utils/APIRouter";
|
||||||
import AuthService from "@/utils/AuthService";
|
import AuthService from "@/utils/AuthService";
|
||||||
@ -145,7 +144,7 @@ export class LogInPage extends LiteElement {
|
|||||||
viewState!: ViewState;
|
viewState!: ViewState;
|
||||||
|
|
||||||
@property({ type: String })
|
@property({ type: String })
|
||||||
redirectUrl: string = ROUTES.home;
|
redirectUrl?: string;
|
||||||
|
|
||||||
private readonly formStateService = interpret(machine);
|
private readonly formStateService = interpret(machine);
|
||||||
|
|
||||||
|
@ -5,7 +5,7 @@ type Routes = { [key: string]: UrlPattern };
|
|||||||
type Paths = { [key: string]: string };
|
type Paths = { [key: string]: string };
|
||||||
|
|
||||||
export type ViewState = {
|
export type ViewState = {
|
||||||
// route name, e.g. "home"
|
// route name, e.g. "admin"
|
||||||
route: string | null;
|
route: string | null;
|
||||||
// path name
|
// path name
|
||||||
// e.g. "/dashboard"
|
// e.g. "/dashboard"
|
||||||
|
@ -347,7 +347,7 @@ export default class AuthService {
|
|||||||
this.logout();
|
this.logout();
|
||||||
const { pathname, search, hash } = window.location;
|
const { pathname, search, hash } = window.location;
|
||||||
const redirectUrl =
|
const redirectUrl =
|
||||||
pathname !== ROUTES.login && pathname !== ROUTES.home
|
pathname !== ROUTES.login && pathname !== "/"
|
||||||
? `${pathname}${search}${hash}`
|
? `${pathname}${search}${hash}`
|
||||||
: "";
|
: "";
|
||||||
window.dispatchEvent(AuthService.createNeedLoginEvent({ redirectUrl }));
|
window.dispatchEvent(AuthService.createNeedLoginEvent({ redirectUrl }));
|
||||||
|
Loading…
Reference in New Issue
Block a user