closed shadowRoot and changed pages, components, layout to extend base class

This commit is contained in:
Fran Jurmanović
2021-06-02 13:19:32 +02:00
parent f01c328716
commit 91032927fd
25 changed files with 206 additions and 109 deletions

View File

@@ -0,0 +1,43 @@
import { html, render } from "@github/jtml";
import { AppMainElement } from "components/";
import { closest } from "core/utils";
class BaseComponentElement extends HTMLElement {
@closest appMain: AppMainElement;
bindEvents = () => {
const _elems = this.querySelectorAll("[data-action]");
_elems?.forEach((el) => {
for (const action of (el.getAttribute("data-action") || "")
.trim()
.split(/\s+/)) {
const eventSep = action.lastIndexOf(":");
const methodSep = action.lastIndexOf("#");
const tag = action.slice(eventSep + 1, methodSep);
const type = action.slice(0, eventSep);
const method = action.slice(methodSep + 1);
if (tag.toUpperCase() === this.tagName) {
el.addEventListener(type, this?.[method]);
} else {
this.childNodes.forEach((child: HTMLElement) => {
if (child.tagName == tag.toUpperCase()) {
el.addEventListener(type, child?.[method]);
}
});
}
}
});
};
render = () => {
return html``;
};
update = () => {
render(this.render(), this);
this.bindEvents();
};
}
export default BaseComponentElement;

View File

@@ -0,0 +1 @@
export { default as BaseComponentElement } from "./BaseComponentElement/BaseComponentElement";

View File

@@ -0,0 +1,3 @@
export * from "./layouts";
export * from "./components";
export * from "./pages";

View File

@@ -1,7 +1,11 @@
import { target } from "@github/catalyst"; import { target } from "@github/catalyst";
import { html, render } from "@github/jtml";
import { AppMainElement } from "components/";
import { closest } from "core/utils";
class BaseLayoutElement extends HTMLElement { class BaseLayoutElement extends HTMLElement {
@target appSlot: HTMLElement; @target appSlot: HTMLElement;
@closest appMain: AppMainElement;
public isLayout: boolean = true; public isLayout: boolean = true;
public _appSlot: string; public _appSlot: string;
constructor() { constructor() {
@@ -24,6 +28,35 @@ class BaseLayoutElement extends HTMLElement {
this._appSlot = _appSlot; this._appSlot = _appSlot;
this.appSlot.innerHTML = _appSlot; this.appSlot.innerHTML = _appSlot;
}; };
bindEvents = () => {
const _elems = this.querySelectorAll("[data-action]");
_elems?.forEach((el) => {
for (const action of (el.getAttribute("data-action") || "")
.trim()
.split(/\s+/)) {
const eventSep = action.lastIndexOf(":");
const methodSep = action.lastIndexOf("#");
const tag = action.slice(eventSep + 1, methodSep);
const type = action.slice(0, eventSep);
const method = action.slice(methodSep + 1);
if (tag.toUpperCase() === this.tagName) {
this.addEventListener(type, this[method]);
}
}
});
};
render = () => {
return html``;
};
update = () => {
render(this.render(), this);
this.bindEvents();
};
} }
export default BaseLayoutElement; export default BaseLayoutElement;

View File

@@ -0,0 +1,37 @@
import { html, render } from "@github/jtml";
import { AppMainElement } from "components/";
import { closest } from "core/utils";
class BasePageElement extends HTMLElement {
@closest appMain: AppMainElement;
bindEvents = () => {
const _elems = this.querySelectorAll("[data-action]");
_elems?.forEach((el) => {
for (const action of (el.getAttribute("data-action") || "")
.trim()
.split(/\s+/)) {
const eventSep = action.lastIndexOf(":");
const methodSep = action.lastIndexOf("#");
const tag = action.slice(eventSep + 1, methodSep);
const type = action.slice(0, eventSep);
const method = action.slice(methodSep + 1);
if (tag.toUpperCase() === this.tagName) {
this.addEventListener(type, this[method]);
}
}
});
};
render = () => {
return html``;
};
update = () => {
render(this.render(), this);
this.bindEvents();
};
}
export default BasePageElement;

View File

@@ -0,0 +1 @@
export { default as BasePageElement } from "./BasePageElement/BasePageElement";

View File

@@ -1,13 +1,19 @@
import { attr, targets, controller, target } from "@github/catalyst"; import {
attr,
targets,
controller,
target,
listenForBind,
} from "@github/catalyst";
import { closest, index, update, isTrue } from "core/utils"; import { closest, index, update, isTrue } from "core/utils";
import { html, render, until } from "@github/jtml"; import { html, render, until } from "@github/jtml";
import { PingService } from "services/"; import { PingService } from "services/";
import { AppMainElement } from "components/app-main/AppMainElement"; import { AppMainElement } from "components/app-main/AppMainElement";
import { RouterService } from "core/services"; import { RouterService } from "core/services";
import { BaseComponentElement } from "common/";
@controller @controller
class AppLinkElement extends HTMLElement { class AppLinkElement extends BaseComponentElement {
@closest appMain: AppMainElement;
@attr to: string; @attr to: string;
@attr goBack: string; @attr goBack: string;
@attr title: string; @attr title: string;
@@ -67,8 +73,4 @@ class AppLinkElement extends HTMLElement {
>${this.title}</a >${this.title}</a
>`}`; >`}`;
}; };
update = () => {
render(this.render(), this);
};
} }

View File

@@ -2,14 +2,14 @@ import { controller, target } from "@github/catalyst";
import { closest } from "core/utils"; import { closest } from "core/utils";
import { AppService, HttpClient, RouterService } from "core/services"; import { AppService, HttpClient, RouterService } from "core/services";
import { AuthStore } from "core/store"; import { AuthStore } from "core/store";
import { BaseComponentElement } from "common/";
@controller @controller
class AppMainElement extends HTMLElement { class AppMainElement extends BaseComponentElement {
public routerService: RouterService; public routerService: RouterService;
public authStore: AuthStore; public authStore: AuthStore;
private httpClient: HttpClient; private httpClient: HttpClient;
public appService: AppService; public appService: AppService;
@closest appMain;
@target appModal; @target appModal;
@target mainRoot; @target mainRoot;
@@ -28,28 +28,31 @@ class AppMainElement extends HTMLElement {
path: "/", path: "/",
component: "home-page", component: "home-page",
layout: "menu-layout", layout: "menu-layout",
middleware: this.isAuth,
}, },
{ {
path: "/home", path: "/home",
component: "home-page", component: "home-page",
layout: "menu-layout", layout: "menu-layout",
middleware: this.middleAuth, middleware: this.isAuth,
}, },
{ {
path: "/history", path: "/history",
component: "history-page", component: "history-page",
layout: "menu-layout", layout: "menu-layout",
middleware: this.middleAuth, middleware: this.isAuth,
}, },
{ {
path: "/register", path: "/register",
component: "register-page", component: "register-page",
layout: "menu-layout", layout: "menu-layout",
middleware: this.isAuth,
}, },
{ {
path: "/login", path: "/login",
component: "login-page", component: "login-page",
layout: "menu-layout", layout: "menu-layout",
middleware: this.isAuth,
}, },
{ {
path: "/unauthorized", path: "/unauthorized",
@@ -130,9 +133,9 @@ class AppMainElement extends HTMLElement {
if (this.appModal) this.removeChild(this.appModal); if (this.appModal) this.removeChild(this.appModal);
}; };
get isAuth(): boolean { isAuth = (): boolean => {
return this.authStore && this.authStore.token; return this.authStore && this.authStore.token;
} };
} }
export type { AppMainElement }; export type { AppMainElement };

View File

@@ -1,15 +1,15 @@
import { controller, target } from "@github/catalyst"; import { controller, target } from "@github/catalyst";
import { html, render, TemplateResult } from "@github/jtml"; import { html, render, TemplateResult } from "@github/jtml";
import { BaseComponentElement } from "common/";
import { AppMainElement } from "components/app-main/AppMainElement"; import { AppMainElement } from "components/app-main/AppMainElement";
import { closest, update } from "core/utils"; import { closest, update } from "core/utils";
import { WalletService } from "services/"; import { WalletService } from "services/";
@controller @controller
class AppMenuElement extends HTMLElement { class AppMenuElement extends BaseComponentElement {
private walletService: WalletService; private walletService: WalletService;
private walletData: Array<any>; private walletData: Array<any>;
private totalWallets: number; private totalWallets: number;
@closest appMain: AppMainElement;
constructor() { constructor() {
super(); super();
} }
@@ -51,13 +51,8 @@ class AppMenuElement extends HTMLElement {
} }
}; };
update = () => {
render(this.render(), this);
};
get isAuth(): boolean { get isAuth(): boolean {
if (this.appMain?.isAuth) { if (this.appMain?.isAuth) {
console.log(true);
return true; return true;
} }
return false; return false;

View File

@@ -1,11 +1,11 @@
import { controller, target } from "@github/catalyst"; import { controller, target } from "@github/catalyst";
import { BaseComponentElement } from "common/";
import { AppMainElement } from "components/app-main/AppMainElement"; import { AppMainElement } from "components/app-main/AppMainElement";
import { closest } from "core/utils"; import { closest } from "core/utils";
@controller @controller
class AppModalElement extends HTMLElement { class AppModalElement extends BaseComponentElement {
@target modalElement: HTMLElement; @target modalElement: HTMLElement;
@closest appMain: AppMainElement;
constructor() { constructor() {
super(); super();
} }

View File

@@ -1,11 +1,11 @@
import { attr, controller, target } from "@github/catalyst"; import { attr, controller, target } from "@github/catalyst";
import { html, render } from "@github/jtml"; import { html, render } from "@github/jtml";
import { BaseComponentElement } from "common/";
import { AppMainElement } from "components/app-main/AppMainElement"; import { AppMainElement } from "components/app-main/AppMainElement";
import { closest, isTrue } from "core/utils"; import { closest, isTrue } from "core/utils";
@controller @controller
class AppPaginationElement extends HTMLElement { class AppPaginationElement extends BaseComponentElement {
@closest appMain: AppMainElement;
public items: Array<any>; public items: Array<any>;
@attr page: number; @attr page: number;
@attr rpp: number; @attr rpp: number;
@@ -39,6 +39,7 @@ class AppPaginationElement extends HTMLElement {
}; };
executeFetch = async (options?) => { executeFetch = async (options?) => {
console.log(this.page);
if (!options) { if (!options) {
options = { options = {
rpp: this.rpp || 5, rpp: this.rpp || 5,
@@ -52,6 +53,7 @@ class AppPaginationElement extends HTMLElement {
this.totalItems = response?.totalRecords; this.totalItems = response?.totalRecords;
this.page = response?.page; this.page = response?.page;
this.rpp = response?.rpp; this.rpp = response?.rpp;
console.log(this.page);
} catch (err) { } catch (err) {
console.error(err); console.error(err);
} }
@@ -67,6 +69,7 @@ class AppPaginationElement extends HTMLElement {
pageNext = () => { pageNext = () => {
const { rpp, totalItems, page } = this; const { rpp, totalItems, page } = this;
console.log(this.page);
const pageRange = Math.ceil(totalItems / rpp); const pageRange = Math.ceil(totalItems / rpp);
if (page < pageRange) { if (page < pageRange) {
this.page++; this.page++;
@@ -84,7 +87,9 @@ class AppPaginationElement extends HTMLElement {
const renderItems = () => { const renderItems = () => {
if (items?.length > 0) { if (items?.length > 0) {
return html`${items?.map((item) => renderItem(item))}`; return html`<span>
${items?.map((item) => renderItem(item))}
</span>`;
} }
return html``; return html``;
}; };
@@ -92,6 +97,7 @@ class AppPaginationElement extends HTMLElement {
const renderPagination = () => { const renderPagination = () => {
if (totalItems > items?.length) { if (totalItems > items?.length) {
const pageRange = Math.ceil(totalItems / rpp); const pageRange = Math.ceil(totalItems / rpp);
console.log(pageRange);
return html` return html`
<div> <div>
<button <button
@@ -115,16 +121,7 @@ class AppPaginationElement extends HTMLElement {
} }
}; };
return html`<div> return html`<div>${renderItems()} ${renderPagination()}</div>`;
<table>
${renderItems()}
</table>
${renderPagination()}
</div>`;
};
update = () => {
render(this.render(), this);
}; };
} }

View File

@@ -1,11 +1,11 @@
import { controller, target } from "@github/catalyst"; import { controller, target } from "@github/catalyst";
import { BaseComponentElement } from "common/";
import { AppMainElement } from "components/app-main/AppMainElement"; import { AppMainElement } from "components/app-main/AppMainElement";
import { closest } from "core/utils"; import { closest } from "core/utils";
@controller @controller
class AppRootElement extends HTMLElement { class AppRootElement extends BaseComponentElement {
@target rootElement: HTMLElement; @target rootElement: HTMLElement;
@closest appMain: AppMainElement;
constructor() { constructor() {
super(); super();
} }

View File

@@ -1,19 +1,24 @@
import { controller } from "@github/catalyst"; import { controller } from "@github/catalyst";
import style from "styles/main.scss"; import style from "styles/main.scss";
(function () {
const _shadow = new WeakMap();
@controller @controller
class AppShadowElement extends HTMLElement { class AppShadowElement extends HTMLElement {
constructor() { constructor() {
super(); super();
_shadow.set(this, this.attachShadow({ mode: "closed" }));
} }
connectedCallback() { connectedCallback() {
this.attachShadow({ mode: "open" }); const _root = _shadow.get(this);
const _appMain = document.createElement("app-main"); const _appMain = document.createElement("app-main");
const _style = document.createElement("style"); const _style = document.createElement("style");
_style.innerHTML = style; _style.innerHTML = style;
this.shadowRoot.appendChild(_style); _root.appendChild(_style);
this.shadowRoot.appendChild(_appMain); _root.appendChild(_appMain);
} }
} }
})();

View File

@@ -1,11 +1,11 @@
import { controller, target } from "@github/catalyst"; import { controller, target } from "@github/catalyst";
import { BaseComponentElement } from "common/";
import { AppMainElement } from "components/app-main/AppMainElement"; import { AppMainElement } from "components/app-main/AppMainElement";
import { closest } from "core/utils"; import { closest } from "core/utils";
@controller @controller
class AppSlotElement extends HTMLElement { class AppSlotElement extends BaseComponentElement {
@target slotElement: HTMLElement; @target slotElement: HTMLElement;
@closest appMain: AppMainElement;
constructor() { constructor() {
super(); super();
} }

View File

@@ -7,10 +7,10 @@ import { RouterService } from "core/services";
import randomId from "core/utils/random-id"; import randomId from "core/utils/random-id";
import validator from "validator"; import validator from "validator";
import { validatorErrors } from "core/constants"; import { validatorErrors } from "core/constants";
import { BaseComponentElement } from "common/";
@controller @controller
class InputFieldElement extends HTMLElement { class InputFieldElement extends BaseComponentElement {
@closest appMain: AppMainElement;
@attr name: string; @attr name: string;
@attr type: string; @attr type: string;
@attr label: string; @attr label: string;
@@ -79,10 +79,6 @@ class InputFieldElement extends HTMLElement {
${this.error && html`<span>${this.error}</span>`} ${this.error && html`<span>${this.error}</span>`}
</div>`; </div>`;
}; };
update = () => {
render(this.render(), this);
};
} }
export type { InputFieldElement }; export type { InputFieldElement };

View File

@@ -4,10 +4,10 @@ import { html, render, until } from "@github/jtml";
import { PingService } from "services/"; import { PingService } from "services/";
import { AppMainElement } from "components/app-main/AppMainElement"; import { AppMainElement } from "components/app-main/AppMainElement";
import { RouterService } from "core/services"; import { RouterService } from "core/services";
import { BaseComponentElement } from "common/";
@controller @controller
class MenuItemElement extends HTMLElement { class MenuItemElement extends BaseComponentElement {
@closest appMain: AppMainElement;
@attr path: string; @attr path: string;
@attr title: string; @attr title: string;
@target itemEl: HTMLElement; @target itemEl: HTMLElement;
@@ -45,8 +45,4 @@ class MenuItemElement extends HTMLElement {
</div> </div>
`; `;
}; };
update = () => {
render(this.render(), this);
};
} }

View File

@@ -47,9 +47,6 @@ class RouterService {
const _mainRoot = this.mainRoot; const _mainRoot = this.mainRoot;
const route = this.routerState; const route = this.routerState;
if (path == route?.path || route?.path == "/not-found") { if (path == route?.path || route?.path == "/not-found") {
if (route.middleware && typeof route.middleware == "function") {
if (route.middleware()) return;
}
let changed: boolean = false; let changed: boolean = false;
if (_mainRoot?.childNodes.length > 0) { if (_mainRoot?.childNodes.length > 0) {
_mainRoot?.childNodes?.forEach?.((child: BaseLayoutElement) => { _mainRoot?.childNodes?.forEach?.((child: BaseLayoutElement) => {

View File

@@ -1,3 +1,3 @@
import "layouts"; import "layouts";
import "pages";
import "components"; import "components";
import "pages";

View File

@@ -15,16 +15,20 @@ class MenuLayoutElement extends BaseLayoutElement {
connectedCallback() { connectedCallback() {
this.update(); this.update();
window.addEventListener("tokenchange", this.updateAuth); window.addEventListener("tokenchange", this.updateAuth);
window.addEventListener("routechanged", this.updateAuth);
} }
disconnectedCallback(): void { disconnectedCallback(): void {
window.removeEventListener("tokenchange", this.updateAuth); window.removeEventListener("tokenchange", this.updateAuth);
window.removeEventListener("routechanged", this.updateAuth);
} }
get isAuth() { get isAuth() {
const _hasToken = this.appMain?.isAuth; const _is = this.appMain?.routerService?.routerState?.middleware;
const _hasData = this.appMain?.authStore?.user; if (typeof _is == "function") {
return _hasToken; return _is();
}
return !!_is;
} }
updateAuth = () => { updateAuth = () => {
@@ -32,13 +36,10 @@ class MenuLayoutElement extends BaseLayoutElement {
}; };
render = () => { render = () => {
const _isAuth = this.isAuth;
return html` return html`
<app-menu></app-menu> ${_isAuth ? html`<app-menu></app-menu>` : html``}
<app-slot data-target="menu-layout.appSlot"></app-slot> <app-slot data-target="menu-layout.appSlot"></app-slot>
`; `;
}; };
update = () => {
render(this.render(), this);
};
} }

View File

@@ -3,11 +3,11 @@ import { closest, index, update, isTrue } from "core/utils";
import { html, render, until } from "@github/jtml"; import { html, render, until } from "@github/jtml";
import { TransactionsService } from "services/"; import { TransactionsService } from "services/";
import { AppMainElement, AppPaginationElement } from "components/"; import { AppMainElement, AppPaginationElement } from "components/";
import { BasePageElement } from "common/";
@controller @controller
class HistoryPageElement extends HTMLElement { class HistoryPageElement extends BasePageElement {
private transactionsService: TransactionsService; private transactionsService: TransactionsService;
@closest appMain: AppMainElement;
@target pagination: AppPaginationElement; @target pagination: AppPaginationElement;
constructor() { constructor() {
super(); super();
@@ -42,8 +42,4 @@ class HistoryPageElement extends HTMLElement {
></app-pagination> ></app-pagination>
`; `;
}; };
update = () => {
render(this.render(), this);
};
} }

View File

@@ -3,11 +3,11 @@ import { closest, index, update, isTrue } from "core/utils";
import { html, render, until } from "@github/jtml"; import { html, render, until } from "@github/jtml";
import { PingService } from "services/"; import { PingService } from "services/";
import { AppMainElement } from "components/"; import { AppMainElement } from "components/";
import { BasePageElement } from "common/";
@controller @controller
class HomePageElement extends HTMLElement { class HomePageElement extends BasePageElement {
private pingService: PingService; private pingService: PingService;
@closest appMain: AppMainElement;
constructor() { constructor() {
super(); super();
} }
@@ -48,8 +48,4 @@ class HomePageElement extends HTMLElement {
<button data-action="click:home-page#openModal">Test</button> <button data-action="click:home-page#openModal">Test</button>
`; `;
}; };
update = () => {
render(this.render(), this);
};
} }

View File

@@ -1,14 +1,20 @@
import { attr, targets, controller, target } from "@github/catalyst"; import {
attr,
targets,
controller,
target,
listenForBind,
} from "@github/catalyst";
import { closest, index, update, isTrue } from "core/utils"; import { closest, index, update, isTrue } from "core/utils";
import { html, render, until } from "@github/jtml"; import { html, render, until } from "@github/jtml";
import { AuthService, PingService } from "services/"; import { AuthService, PingService } from "services/";
import { AppMainElement, InputFieldElement } from "components/"; import { AppMainElement, InputFieldElement } from "components/";
import { RouterService } from "core/services"; import { RouterService } from "core/services";
import { BasePageElement } from "common/";
@controller @controller
class LoginPageElement extends HTMLElement { class LoginPageElement extends BasePageElement {
@targets inputs: Array<InputFieldElement>; @targets inputs: Array<InputFieldElement>;
@closest appMain: AppMainElement;
authService: AuthService; authService: AuthService;
routerService: RouterService; routerService: RouterService;
errorMessage: string; errorMessage: string;
@@ -48,6 +54,7 @@ class LoginPageElement extends HTMLElement {
onSubmit = async () => { onSubmit = async () => {
try { try {
console.log("test");
if (!this.validate()) { if (!this.validate()) {
return; return;
} }
@@ -113,8 +120,4 @@ class LoginPageElement extends HTMLElement {
</div> </div>
`; `;
}; };
update() {
render(this.render(), this);
}
} }

View File

@@ -2,10 +2,10 @@ import { controller } from "@github/catalyst";
import { closest, update } from "core/utils"; import { closest, update } from "core/utils";
import { AuthService } from "services/"; import { AuthService } from "services/";
import { AppMainElement } from "components/"; import { AppMainElement } from "components/";
import { BasePageElement } from "common/";
@controller @controller
class LogoutPageElement extends HTMLElement { class LogoutPageElement extends BasePageElement {
@closest appMain: AppMainElement;
authService: AuthService; authService: AuthService;
constructor() { constructor() {
super(); super();

View File

@@ -2,10 +2,10 @@ import { controller } from "@github/catalyst";
import { closest, update } from "core/utils"; import { closest, update } from "core/utils";
import { html, render } from "@github/jtml"; import { html, render } from "@github/jtml";
import { AppMainElement } from "components/"; import { AppMainElement } from "components/";
import { BasePageElement } from "common/";
@controller @controller
class NotFoundElement extends HTMLElement { class NotFoundElement extends BasePageElement {
@closest appMain: AppMainElement;
constructor() { constructor() {
super(); super();
} }
@@ -19,8 +19,4 @@ class NotFoundElement extends HTMLElement {
<div><app-link data-to="/" data-title="Homepage"></app-link></div> <div><app-link data-to="/" data-title="Homepage"></app-link></div>
`; `;
}; };
update = () => {
render(this.render(), this);
};
} }

View File

@@ -3,11 +3,11 @@ import { closest, index, update, isTrue } from "core/utils";
import { html, render, until } from "@github/jtml"; import { html, render, until } from "@github/jtml";
import { AuthService, PingService } from "services/"; import { AuthService, PingService } from "services/";
import { AppMainElement, InputFieldElement } from "components/"; import { AppMainElement, InputFieldElement } from "components/";
import { BasePageElement } from "common/";
@controller @controller
class RegisterPageElement extends HTMLElement { class RegisterPageElement extends BasePageElement {
@targets inputs: Array<InputFieldElement>; @targets inputs: Array<InputFieldElement>;
@closest appMain: AppMainElement;
authService: AuthService; authService: AuthService;
constructor() { constructor() {
super(); super();
@@ -84,8 +84,4 @@ class RegisterPageElement extends HTMLElement {
</form> </form>
`; `;
}; };
update = () => {
render(this.render(), this);
};
} }