From 8ef770921ec04faf026307c16024ee205fcc463d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fran=20Jurmanovi=C4=87?= Date: Sat, 5 Jun 2021 20:38:12 +0200 Subject: [PATCH] implemented custom circle loaders --- src/common/core/BaseElement/BaseElement.ts | 24 +++ src/components/app-loader/AppLoaderElement.ts | 5 - src/components/app-menu/AppMenuElement.ts | 3 +- .../app-pagination/AppPaginationElement.ts | 20 +- .../circle-loader/CircleLoaderElement.ts | 23 +++ src/components/index.ts | 1 + src/configs/testing/app-settings.json | 6 + src/styles/circle-loader/circle-loader.scss | 44 +++++ src/styles/circle-loader/index.scss | 1 + src/styles/main.scss | 1 + webpack.config.js | 175 ++++++++++-------- 11 files changed, 210 insertions(+), 93 deletions(-) create mode 100644 src/components/circle-loader/CircleLoaderElement.ts create mode 100644 src/configs/testing/app-settings.json create mode 100644 src/styles/circle-loader/circle-loader.scss create mode 100644 src/styles/circle-loader/index.scss diff --git a/src/common/core/BaseElement/BaseElement.ts b/src/common/core/BaseElement/BaseElement.ts index a4abdc4..59e1c64 100644 --- a/src/common/core/BaseElement/BaseElement.ts +++ b/src/common/core/BaseElement/BaseElement.ts @@ -12,11 +12,13 @@ import { closest } from "core/utils"; class BaseElement extends HTMLElement { @closest appMain: AppMainElement; private _appMain: AppMainElement; + public loader: Loader; private elementDisconnectCallbacks: Array = []; constructor() { super(); this.connectedCallback = this.connectedCallback.bind(this); this.disconnectedCallback = this.disconnectedCallback.bind(this); + this.loader = new Loader(this); } public get routerService(): RouterService { @@ -115,3 +117,25 @@ class BaseElement extends HTMLElement { } export default BaseElement; + +class Loader { + private _loading: number = 0; + + constructor(private _main: BaseElement) {} + + public start = () => { + this._loading++; + this._main?.update?.(); + }; + + public stop = () => { + if (this._loading > 0) { + this._loading--; + this._main?.update?.(); + } + }; + + public get loading() { + return this._loading > 0; + } +} diff --git a/src/components/app-loader/AppLoaderElement.ts b/src/components/app-loader/AppLoaderElement.ts index f2c0bc7..1c9a96e 100644 --- a/src/components/app-loader/AppLoaderElement.ts +++ b/src/components/app-loader/AppLoaderElement.ts @@ -21,7 +21,6 @@ class AppLoaderElement extends BaseComponentElement { if (this._loading > 0) { this._loading--; } - console.log(this._loading); if (this._loading == 0) { this.finishInitiate(); } @@ -43,15 +42,11 @@ class AppLoaderElement extends BaseComponentElement { this.update(); }; - public setFinished = () => {}; - render = () => { const renderLoader = (finished: boolean, loading: boolean) => { if (!finished && !loading) { - console.log("Removing"); return html`
`; } else if (loading) { - console.log("loading"); return html`
`; } return html``; diff --git a/src/components/app-menu/AppMenuElement.ts b/src/components/app-menu/AppMenuElement.ts index a3bd451..fb2b7a8 100644 --- a/src/components/app-menu/AppMenuElement.ts +++ b/src/components/app-menu/AppMenuElement.ts @@ -19,9 +19,8 @@ class AppMenuElement extends BaseComponentElement { this.walletService = new WalletService(this.appMain?.appService); if (this.appMain.isAuth) { this.getWallets(); - } else { - this.update(); } + this.update(); this.appMain.addEventListener("tokenchange", this.updateToken); this.appMain.addEventListener("walletupdate", this.updateToken); }; diff --git a/src/components/app-pagination/AppPaginationElement.ts b/src/components/app-pagination/AppPaginationElement.ts index 0a11f0d..ba686bb 100644 --- a/src/components/app-pagination/AppPaginationElement.ts +++ b/src/components/app-pagination/AppPaginationElement.ts @@ -1,6 +1,7 @@ -import { attr, controller } from "@github/catalyst"; +import { attr, controller, target } from "@github/catalyst"; import { html, TemplateResult } from "@github/jtml"; import { BaseComponentElement } from "common/"; +import { CircleLoaderElement } from "components/circle-loader/CircleLoaderElement"; @controller class AppPaginationElement extends BaseComponentElement { @@ -58,12 +59,15 @@ class AppPaginationElement extends BaseComponentElement { } try { + this.loader?.start?.(); const response = await this.fetchFunc(options); + this.loader?.stop?.(); this.setItems(response?.items); this.totalItems = response?.totalRecords; this.page = response?.page; this.rpp = response?.rpp; } catch (err) { + this.loader?.stop?.(); console.error(err); } }; @@ -98,12 +102,16 @@ class AppPaginationElement extends BaseComponentElement { const renderItems = this.customRenderItems ? this.customRenderItems : () => { - if (items?.length > 0) { - return html`
- ${items?.map((item) => renderItem(item))} -
`; + if (this.loader && this.loader.loading) { + return html``; + } else { + if (items?.length > 0) { + return html`
+ ${items?.map((item) => renderItem(item))} +
`; + } + return html``; } - return html``; }; const renderPagination = () => { diff --git a/src/components/circle-loader/CircleLoaderElement.ts b/src/components/circle-loader/CircleLoaderElement.ts new file mode 100644 index 0000000..bd3beee --- /dev/null +++ b/src/components/circle-loader/CircleLoaderElement.ts @@ -0,0 +1,23 @@ +import { attr, controller } from "@github/catalyst"; +import { html } from "@github/jtml"; +import { BaseComponentElement } from "common/"; + +@controller +class CircleLoaderElement extends BaseComponentElement { + @attr size: string; + constructor() { + super(); + } + + elementConnected = (): void => { + this.update(); + }; + + render = () => { + return html`
`; + }; +} + +export type { CircleLoaderElement }; diff --git a/src/components/index.ts b/src/components/index.ts index 029ce17..ef901af 100644 --- a/src/components/index.ts +++ b/src/components/index.ts @@ -7,6 +7,7 @@ export * from "./app-slot/AppSlotElement"; export * from "./app-menu/AppMenuElement"; export * from "./input-field/InputFieldElement"; export * from "./app-loader/AppLoaderElement"; +export * from "./circle-loader/CircleLoaderElement"; // LAST export * from "./app-main/AppMainElement"; diff --git a/src/configs/testing/app-settings.json b/src/configs/testing/app-settings.json new file mode 100644 index 0000000..2a9649d --- /dev/null +++ b/src/configs/testing/app-settings.json @@ -0,0 +1,6 @@ +{ + "apiUrl": "main-wallet--dtnyc2vcdgu2re9j-gtw.qovery.io", + "apiVersion": "v1", + "ssl": true, + "appName": "Wallets Testing" +} \ No newline at end of file diff --git a/src/styles/circle-loader/circle-loader.scss b/src/styles/circle-loader/circle-loader.scss new file mode 100644 index 0000000..f8f0607 --- /dev/null +++ b/src/styles/circle-loader/circle-loader.scss @@ -0,0 +1,44 @@ +.circle-loader { + $--loader-border: 6px; + $--loader-size: 45px; + border: $--loader-border solid $gray-02; + border-top: $--loader-border solid $blue-08; + width: $--loader-size; + height: $--loader-size; + border-radius: 50%; + animation: spin 2s linear infinite; + margin: 5px; + &.-sml { + $--loader-border: 3px; + $--loader-size: 22px; + border: $--loader-border solid $gray-02; + border-top: $--loader-border solid $blue-08; + width: $--loader-size; + height: $--loader-size; + } + &.-med { + $--loader-border: 9px; + $--loader-size: 67px; + border: $--loader-border solid $gray-02; + border-top: $--loader-border solid $blue-08; + width: $--loader-size; + height: $--loader-size; + } + &.-lrg { + $--loader-border: 12px; + $--loader-size: 90px; + border: $--loader-border solid $gray-02; + border-top: $--loader-border solid $blue-08; + width: $--loader-size; + height: $--loader-size; + } +} + +@keyframes spin { + 0% { + transform: rotate(0deg); + } + 100% { + transform: rotate(360deg); + } +} diff --git a/src/styles/circle-loader/index.scss b/src/styles/circle-loader/index.scss new file mode 100644 index 0000000..ac71614 --- /dev/null +++ b/src/styles/circle-loader/index.scss @@ -0,0 +1 @@ +@import "./circle-loader.scss"; diff --git a/src/styles/main.scss b/src/styles/main.scss index ee309ce..94a152c 100644 --- a/src/styles/main.scss +++ b/src/styles/main.scss @@ -5,3 +5,4 @@ @import "./modal/index.scss"; @import "./table/index.scss"; @import "./app-loader/index.scss"; +@import "./circle-loader/index.scss"; diff --git a/webpack.config.js b/webpack.config.js index 16282f7..b050cab 100644 --- a/webpack.config.js +++ b/webpack.config.js @@ -1,6 +1,5 @@ const path = require('path'); const HtmlWebpackPlugin = require('html-webpack-plugin'); -const settings = require("./src/configs/development/app-settings.json"); const { DefinePlugin } = require('webpack'); const alias = { @@ -14,86 +13,102 @@ const alias = { styles: path.resolve(__dirname, "/styles"), }; -module.exports = { - entry: { - app: ['babel-polyfill', './src/index'] - }, - optimization: { - runtimeChunk: 'single', - splitChunks: { - chunks: 'all', - cacheGroups: { - commons: { - test: /[\\/]node_modules[\\/]/, - name: "vendor", - chunks: "initial", - minSize: 200000, - maxSize: 400000 - }, - styles: { - name: 'styles', - test: /\.scss$/, - chunks: 'all' - } - } + +module.exports = (env, args) => { + let settings = {} + if (env && env.env) { + switch (env.env) { + case "testing": + settings = require("./src/configs/testing/app-settings.json"); + break; + case "develop": + default: + settings = require("./src/configs/development/app-settings.json"); } - }, - output: { - path: path.join(__dirname, 'public'), - filename: '[name].[contenthash].js', - publicPath: '/' - }, - module: { - rules: [ - { - test: /\.(js|ts)?$/, - exclude: /node_modules/, - use: { - loader: 'babel-loader' - } - }, - { - test: /\.m?js/, - resolve: { - fullySpecified: false - } - }, - { - test: /\.css$/, - use: { - loader: 'css-loader' - } - }, - { - test: /\.(scss|css)$/, - exclude: /node_modules/, - use: [ - "sass-to-string", - { - loader: "sass-loader", - options: { - sassOptions: { - outputStyle: "compressed", - }, - } + } else { + settings = require("./src/configs/development/app-settings.json"); + } + return { + entry: { + app: ['babel-polyfill', './src/index'] + }, + optimization: { + runtimeChunk: 'single', + splitChunks: { + chunks: 'all', + cacheGroups: { + commons: { + test: /[\\/]node_modules[\\/]/, + name: "vendor", + chunks: "initial", + minSize: 200000, + maxSize: 400000 }, - ] + styles: { + name: 'styles', + test: /\.scss$/, + chunks: 'all' + } + } } - ] - }, - plugins: [ - new HtmlWebpackPlugin({ - template: './src/index.html' - }), - new DefinePlugin({ - __CONFIG__: JSON.stringify(settings) - }) - ], - resolve: { - extensions: ['.js', '.ts'], - alias: alias - }, - devServer: { - historyApiFallback: true, - } + }, + output: { + path: path.join(__dirname, 'public'), + filename: '[name].[contenthash].js', + publicPath: '/' + }, + module: { + rules: [ + { + test: /\.(js|ts)?$/, + exclude: /node_modules/, + use: { + loader: 'babel-loader' + } + }, + { + test: /\.m?js/, + resolve: { + fullySpecified: false + } + }, + { + test: /\.css$/, + use: { + loader: 'css-loader' + } + }, + { + test: /\.(scss|css)$/, + exclude: /node_modules/, + use: [ + "sass-to-string", + { + loader: "sass-loader", + options: { + sassOptions: { + outputStyle: "compressed", + }, + } + }, + ] + } + ] + }, + plugins: [ + new HtmlWebpackPlugin({ + template: './src/index.html' + }), + new DefinePlugin({ + __CONFIG__: JSON.stringify(settings) + }) + ], + resolve: { + extensions: ['.js', '.ts'], + alias: alias + }, + devServer: { + historyApiFallback: true, + } + } } \ No newline at end of file