Merge branch 'feature/WW-26-architecture'

This commit is contained in:
Fran Jurmanović
2021-06-05 13:14:02 +02:00
14 changed files with 151 additions and 13 deletions

8
declaration.d.ts vendored
View File

@@ -1 +1,9 @@
declare module "*.scss"; declare module "*.scss";
declare var __CONFIG__: SettingType;
type SettingType = {
apiUrl: string;
apiVersion: string;
ssl: string;
appName: string;
};

View File

@@ -1,5 +1,10 @@
import { html, render, TemplateResult } from "@github/jtml"; import { html, render, TemplateResult } from "@github/jtml";
import { AppMainElement, AppModalElement, AppRootElement } from "components/"; import {
AppLoaderElement,
AppMainElement,
AppModalElement,
AppRootElement,
} from "components/";
import { AppService, RouterService } from "core/services"; import { AppService, RouterService } from "core/services";
import { AuthStore } from "core/store"; import { AuthStore } from "core/store";
import { closest } from "core/utils"; import { closest } from "core/utils";
@@ -33,6 +38,9 @@ class BaseElement extends HTMLElement {
public get mainRoot(): AppRootElement { public get mainRoot(): AppRootElement {
return this.appMain?.mainRoot; return this.appMain?.mainRoot;
} }
public get appLoader(): AppLoaderElement {
return this.appMain?.appLoader;
}
public get isAuth(): boolean { public get isAuth(): boolean {
return this.appMain?.isAuth(); return this.appMain?.isAuth();

View File

@@ -0,0 +1,63 @@
import { controller, target } from "@github/catalyst";
import { html } from "@github/jtml";
import { BaseComponentElement } from "common/";
@controller
class AppLoaderElement extends BaseComponentElement {
private finished: boolean = true;
private _loading: number = 0;
constructor() {
super();
}
public start = () => {
this.finished = false;
this._loading++;
this.update();
};
public stop = () => {
if (this._loading > 0) {
this._loading--;
}
console.log(this._loading);
if (this._loading == 0) {
this.finishInitiate();
}
this.update();
};
public get loading() {
return this._loading > 0;
}
private finishInitiate = () => {
setTimeout(() => {
this.finished = true;
this.update();
}, 300);
};
elementConnected = (): void => {
this.update();
};
public setFinished = () => {};
render = () => {
const renderLoader = (finished: boolean, loading: boolean) => {
if (!finished && !loading) {
console.log("Removing");
return html`<div class="loader --removing"></div>`;
} else if (loading) {
console.log("loading");
return html`<div class="loader --loading"></div>`;
}
return html``;
};
return html`${renderLoader(this.finished, this.loading)}`;
};
}
export type { AppLoaderElement };

View File

@@ -3,6 +3,7 @@ import { AppService, HttpClient, RouterService } from "core/services";
import { AuthStore } from "core/store"; import { AuthStore } from "core/store";
import { AppModalElement, AppRootElement } from "components/"; import { AppModalElement, AppRootElement } from "components/";
import { closest } from "core/utils"; import { closest } from "core/utils";
import { AppLoaderElement } from "components/app-loader/AppLoaderElement";
@controller @controller
class AppMainElement extends HTMLElement { class AppMainElement extends HTMLElement {
@@ -12,6 +13,7 @@ class AppMainElement extends HTMLElement {
public appService: AppService; public appService: AppService;
@target appModal: AppModalElement; @target appModal: AppModalElement;
@target mainRoot: AppRootElement; @target mainRoot: AppRootElement;
@target appLoader: AppLoaderElement;
@closest appMain: AppMainElement; @closest appMain: AppMainElement;
public domEvents: any = { public domEvents: any = {
routechanged: new Event("routechanged"), routechanged: new Event("routechanged"),
@@ -24,6 +26,7 @@ class AppMainElement extends HTMLElement {
} }
connectedCallback() { connectedCallback() {
if (this.appMain !== this) return; if (this.appMain !== this) return;
this.createLoader();
const mainRoot = this.createMainRoot(); const mainRoot = this.createMainRoot();
this.httpClient = new HttpClient(); this.httpClient = new HttpClient();
this.appService = new AppService(this, this.httpClient); this.appService = new AppService(this, this.httpClient);
@@ -129,6 +132,12 @@ class AppMainElement extends HTMLElement {
return _appModal; return _appModal;
}; };
private createLoader = () => {
const _loader = document.createElement("app-loader");
_loader.setAttribute("data-target", "app-main.appLoader");
this.appendChild(_loader);
};
private createModalContent = (element: string) => { private createModalContent = (element: string) => {
const _modalElement = document.createElement(element); const _modalElement = document.createElement(element);
const _divEl = document.createElement("div"); const _divEl = document.createElement("div");

View File

@@ -132,7 +132,7 @@ class AppMenuElement extends BaseComponentElement {
return html` return html`
<div data-target="app-menu.sidebar"> <div data-target="app-menu.sidebar">
${menuHeader("Wallets")} ${regularMenu("/", "Home")} ${menuHeader(__CONFIG__.appName)} ${regularMenu("/", "Home")}
${authMenu("/history", "Transaction History")} ${authMenu("/history", "Transaction History")}
${authMenu( ${authMenu(
"/wallet/all", "/wallet/all",

View File

@@ -6,5 +6,8 @@ export * from "./app-root/AppRootElement";
export * from "./app-slot/AppSlotElement"; export * from "./app-slot/AppSlotElement";
export * from "./app-menu/AppMenuElement"; export * from "./app-menu/AppMenuElement";
export * from "./input-field/InputFieldElement"; export * from "./input-field/InputFieldElement";
export * from "./app-loader/AppLoaderElement";
// LAST
export * from "./app-main/AppMainElement"; export * from "./app-main/AppMainElement";
export * from "./app-shadow/AppShadowElement"; export * from "./app-shadow/AppShadowElement";

View File

@@ -1,5 +1,6 @@
{ {
"apiUrl": "main-wallet--dtnyc2vcdgu2re9j-gtw.qovery.io", "apiUrl": "localhost:4000",
"apiVersion": "v1", "apiVersion": "v1",
"ssl": true "ssl": false,
"appName": "Wallets"
} }

View File

@@ -17,11 +17,13 @@ class AppService {
Authorization: `BEARER ${this.appMain?.authStore?.token}`, Authorization: `BEARER ${this.appMain?.authStore?.token}`,
}; };
try { try {
this?.appMain?.appLoader?.start?.();
const response = await this.httpClient.post( const response = await this.httpClient.post(
url, url,
data, data,
headersParam headersParam
); );
this?.appMain?.appLoader?.stop?.();
if ( if (
response?.statusCode == 400 || response?.statusCode == 400 ||
response?.statusCode == 500 || response?.statusCode == 500 ||
@@ -35,6 +37,7 @@ class AppService {
} }
return response; return response;
} catch (err) { } catch (err) {
this?.appMain?.appLoader?.stop?.();
throw err; throw err;
} }
}; };
@@ -49,7 +52,9 @@ class AppService {
Authorization: `BEARER ${this.appMain?.authStore?.token}`, Authorization: `BEARER ${this.appMain?.authStore?.token}`,
}; };
try { try {
this?.appMain?.appLoader?.start?.();
const response = await this.httpClient.put(url, data, headersParam); const response = await this.httpClient.put(url, data, headersParam);
this?.appMain?.appLoader?.stop?.();
if ( if (
response?.statusCode == 400 || response?.statusCode == 400 ||
response?.statusCode == 500 || response?.statusCode == 500 ||
@@ -63,6 +68,7 @@ class AppService {
} }
return response; return response;
} catch (err) { } catch (err) {
this?.appMain?.appLoader?.stop?.();
throw err; throw err;
} }
}; };
@@ -77,11 +83,13 @@ class AppService {
Authorization: `BEARER ${this.appMain?.authStore?.token}`, Authorization: `BEARER ${this.appMain?.authStore?.token}`,
}; };
try { try {
this?.appMain?.appLoader?.start?.();
const response = await this.httpClient.delete( const response = await this.httpClient.delete(
url, url,
data, data,
headersParam headersParam
); );
this?.appMain?.appLoader?.stop?.();
if ( if (
response?.statusCode == 400 || response?.statusCode == 400 ||
response?.statusCode == 500 || response?.statusCode == 500 ||
@@ -95,6 +103,7 @@ class AppService {
} }
return response; return response;
} catch (err) { } catch (err) {
this?.appMain?.appLoader?.stop?.();
throw err; throw err;
} }
}; };
@@ -109,11 +118,13 @@ class AppService {
Authorization: `BEARER ${this.appMain?.authStore?.token}`, Authorization: `BEARER ${this.appMain?.authStore?.token}`,
}; };
try { try {
this?.appMain?.appLoader?.start?.();
const response = await this.httpClient.get( const response = await this.httpClient.get(
url, url,
params, params,
headersParam headersParam
); );
this?.appMain?.appLoader?.stop?.();
if ( if (
response?.statusCode == 400 || response?.statusCode == 400 ||
response?.statusCode == 500 || response?.statusCode == 500 ||
@@ -127,6 +138,7 @@ class AppService {
} }
return response; return response;
} catch (err) { } catch (err) {
this?.appMain?.appLoader?.stop?.();
throw err; throw err;
} }
}; };

View File

@@ -1,11 +1,9 @@
import settings from "configs/development/app-settings.json";
class HttpClient { class HttpClient {
private url: string; private url: string;
constructor() { constructor() {
this.url = `${settings.ssl ? "https" : "http"}://${settings.apiUrl}/${ this.url = `${__CONFIG__.ssl ? "https" : "http"}://${
settings.apiVersion __CONFIG__.apiUrl
}`; }/${__CONFIG__.apiVersion}`;
} }
post(url: string, data: Object, headersParam: HeadersInit): Promise<any> { post(url: string, data: Object, headersParam: HeadersInit): Promise<any> {

View File

@@ -44,11 +44,13 @@ class AuthStore {
checkToken = async (token: string) => { checkToken = async (token: string) => {
try { try {
if (token && token !== "null") {
const response = await this.authService.checkToken({ token }); const response = await this.authService.checkToken({ token });
if (!(response && response.valid)) { if (!(response && response.valid)) {
this.token = null; this.token = null;
this.appMain.routerService.goTo("/token-expired"); this.appMain.routerService.goTo("/token-expired");
} }
}
} catch (err) { } catch (err) {
this.token = null; this.token = null;
this.appMain.routerService.goTo("/token-expired"); this.appMain.routerService.goTo("/token-expired");

View File

@@ -0,0 +1,27 @@
.loader {
position: absolute;
top: 0;
left: 0;
height: 5px;
width: 0;
background-color: $blue-09;
z-index: 2000;
&.--loading {
animation: animateBar 5s linear;
}
&.--removing {
width: 100%;
}
}
.progress .progress-bar {
}
@keyframes animateBar {
0% {
width: 0;
}
100% {
width: 100%;
}
}

View File

@@ -0,0 +1 @@
@import "./app-loader.scss";

View File

@@ -4,3 +4,4 @@
@import "./sidebar/index.scss"; @import "./sidebar/index.scss";
@import "./modal/index.scss"; @import "./modal/index.scss";
@import "./table/index.scss"; @import "./table/index.scss";
@import "./app-loader/index.scss";

View File

@@ -1,5 +1,7 @@
const path = require('path'); const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin'); const HtmlWebpackPlugin = require('html-webpack-plugin');
const settings = require("./src/configs/development/app-settings.json");
const { DefinePlugin } = require('webpack');
const alias = { const alias = {
common: path.resolve(__dirname, '/common'), common: path.resolve(__dirname, '/common'),
@@ -83,6 +85,9 @@ module.exports = {
new HtmlWebpackPlugin({ new HtmlWebpackPlugin({
template: './src/index.html' template: './src/index.html'
}), }),
new DefinePlugin({
__CONFIG__: JSON.stringify(settings)
})
], ],
resolve: { resolve: {
extensions: ['.js', '.ts'], extensions: ['.js', '.ts'],