From e1ab0e51d66c8bf724ce86fe2fa7a99a5e730133 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fran=20Jurmanovi=C4=87?= Date: Mon, 31 May 2021 12:00:07 +0200 Subject: [PATCH] fixed architecture to dispatch events when routes and token changes --- .../BaseLayoutElement/BaseLayoutElement.ts | 5 ++- src/components/app-link/AppLinkElement.ts | 14 +++--- src/components/app-main/AppMainElement.ts | 11 ++++- .../services/router-service/RouterService.ts | 3 +- src/core/store/AuthStore.ts | 9 ++++ src/layouts/menu-layout/MenuLayoutElement.ts | 43 ++++++++++++++----- src/pages/home-page/HomePageElement.ts | 24 ++++++++--- src/pages/index.ts | 1 + src/pages/login-page/LoginPageElement.ts | 32 +++++++++++++- src/pages/logout-page/LogoutPageElement.ts | 18 ++++++++ 10 files changed, 131 insertions(+), 29 deletions(-) create mode 100644 src/pages/logout-page/LogoutPageElement.ts diff --git a/src/common/layouts/BaseLayoutElement/BaseLayoutElement.ts b/src/common/layouts/BaseLayoutElement/BaseLayoutElement.ts index 2144a1d..a64c1db 100644 --- a/src/common/layouts/BaseLayoutElement/BaseLayoutElement.ts +++ b/src/common/layouts/BaseLayoutElement/BaseLayoutElement.ts @@ -3,6 +3,7 @@ import { target } from "@github/catalyst"; class BaseLayoutElement extends HTMLElement { @target slotted: HTMLElement; public isLayout: boolean = true; + public _slotted: string; constructor() { super(); } @@ -19,7 +20,9 @@ class BaseLayoutElement extends HTMLElement { }; setElement = (newTag: string) => { - this.slotted.innerHTML = `<${newTag}>`; + const _slotted = `<${newTag}>`; + this._slotted = _slotted; + this.slotted.innerHTML = _slotted; }; } diff --git a/src/components/app-link/AppLinkElement.ts b/src/components/app-link/AppLinkElement.ts index 8c3b134..8f88deb 100644 --- a/src/components/app-link/AppLinkElement.ts +++ b/src/components/app-link/AppLinkElement.ts @@ -21,13 +21,15 @@ class AppLinkElement extends HTMLElement { this.routerService = this.appMain?.routerService; this.update(); if (isTrue(this.goBack)) { - window.addEventListener("routechanged", () => { - this.update(); - }); + window.addEventListener("routechanged", this.update); } } - public disconnectedCallback(): void {} + public disconnectedCallback(): void { + if (isTrue(this.goBack)) { + window.removeEventListener("routechanged", this.update); + } + } goTo = () => { if (!isTrue(this.goBack) && this.to) { @@ -55,7 +57,7 @@ class AppLinkElement extends HTMLElement { >`}`; } - update() { + update = () => { render(this.render(), this); - } + }; } diff --git a/src/components/app-main/AppMainElement.ts b/src/components/app-main/AppMainElement.ts index 84f9d40..4a470da 100644 --- a/src/components/app-main/AppMainElement.ts +++ b/src/components/app-main/AppMainElement.ts @@ -27,11 +27,12 @@ class AppMainElement extends HTMLElement { path: "/", component: "home-page", layout: "menu-layout", - middleware: this.middleAuth, }, { path: "/home", component: "home-page", + layout: "menu-layout", + middleware: this.middleAuth, }, { path: "/register", @@ -46,10 +47,16 @@ class AppMainElement extends HTMLElement { { path: "/unauthorized", component: "login-page", + layout: "menu-layout", }, { - path: "token-expired", + path: "/token-expired", component: "login-page", + layout: "menu-layout", + }, + { + path: "/logout", + component: "logout-page", }, ]); this.routerService.init(); diff --git a/src/core/services/router-service/RouterService.ts b/src/core/services/router-service/RouterService.ts index 98503ca..324da51 100644 --- a/src/core/services/router-service/RouterService.ts +++ b/src/core/services/router-service/RouterService.ts @@ -43,7 +43,6 @@ class RouterService { update() { if (!this._routes) return; - window.dispatchEvent(this.domEvents.routechanged); const path = window.location.pathname; const _mainRoot = this.mainRoot; const route = this.routerState; @@ -98,12 +97,12 @@ class RouterService { _mainRoot.appendChild(_newElement); } } - return; } else { const newRoute = this.findByPath(); this.historyStack.push(newRoute); this.update(); } + window.dispatchEvent(this.domEvents.routechanged); } goTo(path: string) { diff --git a/src/core/store/AuthStore.ts b/src/core/store/AuthStore.ts index 5a6ed18..7622e02 100644 --- a/src/core/store/AuthStore.ts +++ b/src/core/store/AuthStore.ts @@ -5,6 +5,9 @@ class AuthStore { private _token; private _userDetails; private authService: AuthService; + private domEvents: any = { + tokenchange: new Event("tokenchange"), + }; constructor(private appService: AppService) { this.token = localStorage.getItem("token"); this.authService = new AuthService(this.appService); @@ -19,6 +22,7 @@ class AuthStore { set token(token) { this._token = token; localStorage.setItem("token", token); + window.dispatchEvent(this.domEvents.tokenchange); } get user() { @@ -52,6 +56,11 @@ class AuthStore { throw err; } }; + + userLogout = () => { + this.token = null; + localStorage.removeItem("token"); + }; } export default AuthStore; diff --git a/src/layouts/menu-layout/MenuLayoutElement.ts b/src/layouts/menu-layout/MenuLayoutElement.ts index 4fdccd4..34e7c7a 100644 --- a/src/layouts/menu-layout/MenuLayoutElement.ts +++ b/src/layouts/menu-layout/MenuLayoutElement.ts @@ -1,30 +1,51 @@ -import { attr, targets, controller, target } from "@github/catalyst"; -import { closest, index, update, isTrue } from "core/utils"; -import { html, render, until } from "@github/jtml"; -import { PingService } from "services/"; +import { controller } from "@github/catalyst"; +import { closest } from "core/utils"; +import { html, render } from "@github/jtml"; import { BaseLayoutElement } from "common/layouts"; +import { AppMainElement } from "components/"; @controller class MenuLayoutElement extends BaseLayoutElement { - @closest appMain; + @closest appMain: AppMainElement; constructor() { super(); } - @update - connectedCallback() {} + connectedCallback() { + this.update(); + window.addEventListener("tokenchange", this.updateAuth); + } + + disconnectedCallback(): void { + window.removeEventListener("tokenchange", this.updateAuth); + } + + get isAuth() { + const _hasToken = this.appMain?.isAuth; + const _hasData = this.appMain?.authStore?.user; + return _hasData && _hasToken; + } + + updateAuth = () => { + this.update(); + }; render() { return html` -
+ ${this.isAuth && + html`
-
+
`}
`; } - update() { + update = () => { render(this.render(), this); - } + const _slotted = this._slotted; + if (_slotted && this.slotted) { + this.slotted.innerHTML = _slotted; + } + }; } diff --git a/src/pages/home-page/HomePageElement.ts b/src/pages/home-page/HomePageElement.ts index c0e9543..5520eff 100644 --- a/src/pages/home-page/HomePageElement.ts +++ b/src/pages/home-page/HomePageElement.ts @@ -11,10 +11,16 @@ class HomePageElement extends HTMLElement { constructor() { super(); } - @update + connectedCallback() { this.pingService = new PingService(this.appMain?.appService); if (this.appMain.isAuth) this.getPong(); + this.update(); + window.addEventListener("tokenchange", this.update); + } + + disconnectedCallback(): void { + window.removeEventListener("tokenchange", this.update); } getPong = async () => { @@ -31,13 +37,21 @@ class HomePageElement extends HTMLElement { render() { return html` - | | - + ${this.appMain.isAuth + ? html` + |` + : html``} `; } - update() { + update = () => { render(this.render(), this); - } + }; } diff --git a/src/pages/index.ts b/src/pages/index.ts index 0496d6d..a15baa5 100644 --- a/src/pages/index.ts +++ b/src/pages/index.ts @@ -1,3 +1,4 @@ +export * from "./logout-page/LogoutPageElement"; export * from "./home-page/HomePageElement"; export * from "./register-page/RegisterPageElement"; export * from "./login-page/LoginPageElement"; diff --git a/src/pages/login-page/LoginPageElement.ts b/src/pages/login-page/LoginPageElement.ts index f1c375f..a76869a 100644 --- a/src/pages/login-page/LoginPageElement.ts +++ b/src/pages/login-page/LoginPageElement.ts @@ -3,18 +3,37 @@ import { closest, index, update, isTrue } from "core/utils"; import { html, render, until } from "@github/jtml"; import { AuthService, PingService } from "services/"; import { AppMainElement, InputFieldElement } from "components/"; +import { RouterService } from "core/services"; @controller class LoginPageElement extends HTMLElement { @targets inputs: Array; @closest appMain: AppMainElement; authService: AuthService; + routerService: RouterService; constructor() { super(); } @update connectedCallback() { this.authService = new AuthService(this.appMain.appService); + this.routerService = this.appMain.routerService; + } + + get emailInput() { + for (const i in this.inputs) { + if (this.inputs[i]?.name == "email") { + return this.inputs[i]; + } + } + } + + get passwordInput() { + for (const i in this.inputs) { + if (this.inputs[i]?.name == "password") { + return this.inputs[i]; + } + } } get values(): Object { @@ -36,9 +55,18 @@ class LoginPageElement extends HTMLElement { ); if (response?.token) { - this.appMain.routerService.goTo("/"); + console.log(this.appMain); + this.routerService.goTo("/"); } - } catch (err) {} + } catch (err) { + if (err?.errorCode == 400103) { + this.emailInput.error = err?.message; + this.emailInput.update(); + } else if (err?.errorCode == 400104) { + this.passwordInput.error = err?.message; + this.passwordInput.update(); + } + } }; validate(): boolean { diff --git a/src/pages/logout-page/LogoutPageElement.ts b/src/pages/logout-page/LogoutPageElement.ts new file mode 100644 index 0000000..0517fb8 --- /dev/null +++ b/src/pages/logout-page/LogoutPageElement.ts @@ -0,0 +1,18 @@ +import { controller } from "@github/catalyst"; +import { closest, update } from "core/utils"; +import { AuthService } from "services/"; +import { AppMainElement } from "components/"; + +@controller +class LogoutPageElement extends HTMLElement { + @closest appMain: AppMainElement; + authService: AuthService; + constructor() { + super(); + } + connectedCallback() { + this.authService = new AuthService(this.appMain.appService); + this.appMain?.authStore?.userLogout(); + this.appMain?.routerService.goTo("/login"); + } +}