mirror of
https://github.com/FJurmanovic/wallet-web.git
synced 2026-02-06 14:18:08 +00:00
changes to structure
This commit is contained in:
@@ -1,12 +1,10 @@
|
||||
import { attr, controller, target } from '@github/catalyst';
|
||||
import { closest, findMethod, firstUpper } from 'core/utils';
|
||||
import { html } from 'core/utils';
|
||||
import { closest, findMethod, attr, controller, target } from 'core/utils';
|
||||
import randomId from 'core/utils/random-id';
|
||||
import { validatorErrors } from 'core/constants';
|
||||
import { BaseComponentElement, Validator } from 'common/';
|
||||
import { AppFormElement } from 'components/app-form/AppFormElement';
|
||||
import { AppDropdownElementTemplate } from 'components/app-dropdown';
|
||||
|
||||
@controller
|
||||
@controller('app-dropdown')
|
||||
class AppDropdownElement extends BaseComponentElement {
|
||||
@attr name: string;
|
||||
@attr label: string;
|
||||
@@ -82,7 +80,7 @@ class AppDropdownElement extends BaseComponentElement {
|
||||
}
|
||||
|
||||
get required(): boolean {
|
||||
return this.rules.includes('required');
|
||||
return this.rules?.includes('required');
|
||||
}
|
||||
|
||||
get _value() {
|
||||
@@ -191,67 +189,21 @@ class AppDropdownElement extends BaseComponentElement {
|
||||
setItemValue = (itemValue) => {
|
||||
this.itemValue = itemValue;
|
||||
this.update();
|
||||
}
|
||||
|
||||
render = () => {
|
||||
const { label, error, errorMessage, isOpen, searchPhrase, items, selectedItem, displaykey, valuekey } = this;
|
||||
|
||||
const renderMessage = (label: string) => {
|
||||
if (label) {
|
||||
return html`<label app-action="click:app-dropdown#openDropdown">${label}${this.required ? ' (*)' : ''}</label>`;
|
||||
}
|
||||
return html``;
|
||||
};
|
||||
|
||||
const renderError = (error: string) => {
|
||||
if (error) {
|
||||
return html`<div class="input-error"><span>${error}</span></div>`;
|
||||
}
|
||||
return html``;
|
||||
};
|
||||
|
||||
const renderItem = (item) => {
|
||||
return html` <li
|
||||
class="dropdown-custom-listitem ${selectedItem?.[valuekey] == item[valuekey] ? '--selected' : ''}"
|
||||
app-action="click:app-dropdown#itemSelected"
|
||||
data-value="${item[valuekey]}"
|
||||
>
|
||||
${item[displaykey]}
|
||||
</li>`;
|
||||
};
|
||||
|
||||
const renderItems = (_items) => {
|
||||
return _items?.map((item) => renderItem(item));
|
||||
};
|
||||
|
||||
return html`
|
||||
<div class="app-dropdown">
|
||||
${renderMessage(this.label)} ${renderError(this.error)}
|
||||
<div class="dropdown-custom">
|
||||
<div class="dropdown-custom-top${isOpen ? ' --open' : ''}" app-action="click:app-dropdown#toggleDropdown">
|
||||
<span class="dropdown-custom-fieldname">${selectedItem ? selectedItem[displaykey] : 'Select'}</span>
|
||||
</div>
|
||||
${isOpen
|
||||
? html`
|
||||
<div class="dropdown-custom-open" data-target="app-dropdown.dropdowncontainer">
|
||||
<input
|
||||
class="dropdown-custom-search"
|
||||
type="text"
|
||||
value="${searchPhrase || ''}"
|
||||
id="${this.randId}"
|
||||
app-action="input:app-dropdown#phraseChange"
|
||||
autofocus
|
||||
/>
|
||||
<ul class="dropdown-custom-list">
|
||||
${renderItems(items)}
|
||||
</ul>
|
||||
</div>
|
||||
`
|
||||
: html``}
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
};
|
||||
|
||||
render = () =>
|
||||
AppDropdownElementTemplate({
|
||||
label: this.label,
|
||||
error: this.error,
|
||||
randId: this.randId,
|
||||
required: this.required,
|
||||
isOpen: this.isOpen,
|
||||
searchPhrase: this.searchPhrase,
|
||||
items: this.items,
|
||||
selectedItem: this.selectedItem,
|
||||
displaykey: this.displaykey,
|
||||
valuekey: this.valuekey,
|
||||
});
|
||||
}
|
||||
|
||||
export type { AppDropdownElement };
|
||||
|
||||
61
src/components/app-dropdown/AppDropdownElementTemplate.ts
Normal file
61
src/components/app-dropdown/AppDropdownElementTemplate.ts
Normal file
@@ -0,0 +1,61 @@
|
||||
import { html, nothing, TemplateResult } from 'core/utils';
|
||||
|
||||
export default (props): TemplateResult => {
|
||||
const { label, error, randId, required, isOpen, searchPhrase, items, selectedItem, displaykey, valuekey } = props;
|
||||
|
||||
const renderMessage = (label: string) => {
|
||||
if (label) {
|
||||
return html`<label app-action="click:app-dropdown#openDropdown">${label}${required ? ' (*)' : ''}</label>`;
|
||||
}
|
||||
return nothing;
|
||||
};
|
||||
|
||||
const renderError = (error: string) => {
|
||||
if (error) {
|
||||
return html`<div class="input-error"><span>${error}</span></div>`;
|
||||
}
|
||||
return nothing;
|
||||
};
|
||||
|
||||
const renderItem = (item) => {
|
||||
return html` <li
|
||||
class="dropdown-custom-listitem ${selectedItem?.[valuekey] == item[valuekey] ? '--selected' : ''}"
|
||||
app-action="click:app-dropdown#itemSelected"
|
||||
data-value="${item[valuekey]}"
|
||||
>
|
||||
${item[displaykey]}
|
||||
</li>`;
|
||||
};
|
||||
|
||||
const renderItems = (_items) => {
|
||||
return _items?.map((item) => renderItem(item));
|
||||
};
|
||||
|
||||
return html`
|
||||
<div class="app-dropdown">
|
||||
${renderMessage(label)} ${renderError(error)}
|
||||
<div class="dropdown-custom">
|
||||
<div class="dropdown-custom-top${isOpen ? ' --open' : ''}" app-action="click:app-dropdown#toggleDropdown">
|
||||
<span class="dropdown-custom-fieldname">${selectedItem ? selectedItem[displaykey] : 'Select'}</span>
|
||||
</div>
|
||||
${isOpen
|
||||
? html`
|
||||
<div class="dropdown-custom-open" data-target="app-dropdown.dropdowncontainer">
|
||||
<input
|
||||
class="dropdown-custom-search"
|
||||
type="text"
|
||||
value="${searchPhrase || ''}"
|
||||
id="${randId}"
|
||||
app-action="input:app-dropdown#phraseChange"
|
||||
autofocus
|
||||
/>
|
||||
<ul class="dropdown-custom-list">
|
||||
${renderItems(items)}
|
||||
</ul>
|
||||
</div>
|
||||
`
|
||||
: nothing}
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
};
|
||||
2
src/components/app-dropdown/index.ts
Normal file
2
src/components/app-dropdown/index.ts
Normal file
@@ -0,0 +1,2 @@
|
||||
export { default as AppDropdownElementTemplate } from './AppDropdownElementTemplate';
|
||||
export * from './AppDropdownElement';
|
||||
@@ -1,11 +1,11 @@
|
||||
import { attr, controller, target } from '@github/catalyst';
|
||||
import { html, TemplateResult } from 'core/utils';
|
||||
import { TemplateResult, attr, controller, target } from 'core/utils';
|
||||
import { BaseComponentElement } from 'common/';
|
||||
import { AppDropdownElement } from 'components/app-dropdown/AppDropdownElement';
|
||||
import { InputFieldElement } from 'components/input-field/InputFieldElement';
|
||||
import { findMethod, isTrue, querys } from 'core/utils';
|
||||
import { findMethod, querys } from 'core/utils';
|
||||
import { AppFormElementTemplate } from 'components/app-form';
|
||||
|
||||
@controller
|
||||
@controller('app-form')
|
||||
class AppFormElement extends BaseComponentElement {
|
||||
@target formElement: HTMLElement;
|
||||
@target innerSlot: HTMLElement;
|
||||
@@ -85,18 +85,18 @@ class AppFormElement extends BaseComponentElement {
|
||||
set = (data): any => {
|
||||
for (let i = 0; i < this.inputField.length; i++) {
|
||||
const input = this.inputField[i];
|
||||
if(data?.[input.name]) {
|
||||
input._value = data[input.name]
|
||||
this.update()
|
||||
if (data?.[input.name]) {
|
||||
input._value = data[input.name];
|
||||
this.update();
|
||||
}
|
||||
}
|
||||
this.appDropdown?.forEach((input: AppDropdownElement) => {
|
||||
if(data?.[input.name]) {
|
||||
input.setValue(data[input.name])
|
||||
this.update()
|
||||
if (data?.[input.name]) {
|
||||
input.setValue(data[input.name]);
|
||||
this.update();
|
||||
}
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
getInput = (name: string): InputFieldElement | AppDropdownElement => {
|
||||
let formObject;
|
||||
@@ -123,48 +123,14 @@ class AppFormElement extends BaseComponentElement {
|
||||
}
|
||||
};
|
||||
|
||||
render = (): TemplateResult => {
|
||||
const renderSubmit = (valid: boolean) => {
|
||||
if (!valid) {
|
||||
return html`
|
||||
<button class="btn btn-squared btn-primary --submit disabled" type="submit" disabled>Submit</button>
|
||||
`;
|
||||
}
|
||||
return html` <button class="btn btn-squared btn-primary --submit" type="submit">Submit</button> `;
|
||||
};
|
||||
const renderError = (error: string) => {
|
||||
if (error) {
|
||||
return html`<span>${error}</span>`;
|
||||
}
|
||||
return html``;
|
||||
};
|
||||
const renderCancel = (hasCancel: boolean) => {
|
||||
if (hasCancel) {
|
||||
return html`<button class="btn btn-squared btn-red --cancel" type="button" app-action="click:app-form#goBack">
|
||||
Cancel
|
||||
</button>`;
|
||||
}
|
||||
return html``;
|
||||
};
|
||||
|
||||
return html`
|
||||
<div class="app-form">
|
||||
<form
|
||||
app-action="submit:app-form#onSubmit"
|
||||
data-target="app-form.formElement"
|
||||
autocomplete="on"
|
||||
method="POST"
|
||||
action="javascript:void(0)"
|
||||
>
|
||||
${this.renderInput ? this.customRender() : html`<slot data-target="app-form.innerSlot"></slot>`}
|
||||
${renderError(this.error)}
|
||||
<div class="form-buttons">
|
||||
<div class="button-content">${renderSubmit(this.isValid)}${renderCancel(isTrue(this.hasCancel))}</div>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
`;
|
||||
};
|
||||
render = (): TemplateResult =>
|
||||
AppFormElementTemplate({
|
||||
renderInput: this.renderInput,
|
||||
customRender: this.customRender,
|
||||
error: this.error,
|
||||
isValid: this.isValid,
|
||||
hasCancel: this.hasCancel,
|
||||
});
|
||||
}
|
||||
|
||||
export type { AppFormElement };
|
||||
|
||||
44
src/components/app-form/AppFormElementTemplate.ts
Normal file
44
src/components/app-form/AppFormElementTemplate.ts
Normal file
@@ -0,0 +1,44 @@
|
||||
import { html, isTrue, nothing, TemplateResult } from 'core/utils';
|
||||
|
||||
export default (props): TemplateResult => {
|
||||
const { renderInput, customRender, error, isValid, hasCancel } = props;
|
||||
const renderSubmit = (valid: boolean) => {
|
||||
if (!valid) {
|
||||
return html`
|
||||
<button class="btn btn-squared btn-primary --submit disabled" type="submit" disabled>Submit</button>
|
||||
`;
|
||||
}
|
||||
return html` <button class="btn btn-squared btn-primary --submit" type="submit">Submit</button> `;
|
||||
};
|
||||
const renderError = (error: string) => {
|
||||
if (error) {
|
||||
return html`<span>${error}</span>`;
|
||||
}
|
||||
return html``;
|
||||
};
|
||||
const renderCancel = (hasCancel: boolean) => {
|
||||
if (hasCancel) {
|
||||
return html`<button class="btn btn-squared btn-red --cancel" type="button" app-action="click:app-form#goBack">
|
||||
Cancel
|
||||
</button>`;
|
||||
}
|
||||
return html``;
|
||||
};
|
||||
|
||||
return html`
|
||||
<div class="app-form">
|
||||
<form
|
||||
app-action="submit:app-form#onSubmit"
|
||||
data-target="app-form.formElement"
|
||||
autocomplete="on"
|
||||
method="POST"
|
||||
action="javascript:void(0)"
|
||||
>
|
||||
${renderInput ? customRender() : html`<slot data-target="app-form.innerSlot"></slot>`} ${renderError(error)}
|
||||
<div class="form-buttons">
|
||||
<div class="button-content">${renderSubmit(isValid)}${renderCancel(isTrue(hasCancel))}</div>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
`;
|
||||
};
|
||||
2
src/components/app-form/index.ts
Normal file
2
src/components/app-form/index.ts
Normal file
@@ -0,0 +1,2 @@
|
||||
export { default as AppFormElementTemplate } from './AppFormElementTemplate';
|
||||
export * from './AppFormElement';
|
||||
@@ -1,11 +1,10 @@
|
||||
import { attr, controller, target } from '@github/catalyst';
|
||||
import { isTrue } from 'core/utils';
|
||||
import { html, TemplateResult } from 'core/utils';
|
||||
import { TemplateResult, attr, controller, target } from 'core/utils';
|
||||
import { AppMainElement } from 'components/app-main/AppMainElement';
|
||||
import { RouterService } from 'core/services';
|
||||
import { BaseComponentElement } from 'common/';
|
||||
import { AppLinkElementTemplate } from 'components/app-link';
|
||||
|
||||
@controller
|
||||
@controller('app-link')
|
||||
class AppLinkElement extends BaseComponentElement {
|
||||
@attr to: string;
|
||||
@attr goBack: string;
|
||||
@@ -36,7 +35,7 @@ class AppLinkElement extends BaseComponentElement {
|
||||
};
|
||||
|
||||
attributeChangedCallback(changed) {
|
||||
if(this.initialized && changed == 'data-title') {
|
||||
if (this.initialized && changed == 'data-title') {
|
||||
this.update();
|
||||
}
|
||||
}
|
||||
@@ -58,23 +57,14 @@ class AppLinkElement extends BaseComponentElement {
|
||||
return false;
|
||||
}
|
||||
|
||||
render = (): TemplateResult => {
|
||||
return html`${this.disabled
|
||||
? html`<a
|
||||
class="btn btn-link btn-disabled${this.className ? ` ${this.className}` : ''}"
|
||||
data-target="app-link.main"
|
||||
style="color:grey"
|
||||
><span class="link-text">${this.title}</span></a
|
||||
>`
|
||||
: html`<a
|
||||
class="btn btn-link${this.className ? ` ${this.className}` : ''}"
|
||||
data-target="app-link.main"
|
||||
app-action="click:app-link#goTo ${this.customAction ? this.customAction : ''}"
|
||||
href="${this.to}"
|
||||
style="text-decoration: underline; cursor: pointer;"
|
||||
><span class="link-text">${this.title}</span></a
|
||||
>`}`;
|
||||
};
|
||||
render = (): TemplateResult =>
|
||||
AppLinkElementTemplate({
|
||||
disabled: this.disabled,
|
||||
className: this.classList,
|
||||
title: this.title,
|
||||
customAction: this.customAction,
|
||||
to: this.to,
|
||||
});
|
||||
}
|
||||
|
||||
export type { AppLinkElement };
|
||||
|
||||
18
src/components/app-link/AppLinkElementTemplate.ts
Normal file
18
src/components/app-link/AppLinkElementTemplate.ts
Normal file
@@ -0,0 +1,18 @@
|
||||
import { html, TemplateResult } from 'core/utils';
|
||||
|
||||
export default ({ disabled, className, title, customAction, to }): TemplateResult =>
|
||||
html`${disabled
|
||||
? html`<a
|
||||
class="btn btn-link btn-disabled${className ? ` ${className}` : ''}"
|
||||
data-target="app-link.main"
|
||||
style="color:grey"
|
||||
><span class="link-text">${title}</span></a
|
||||
>`
|
||||
: html`<a
|
||||
class="btn btn-link${className ? ` ${className}` : ''}"
|
||||
data-target="app-link.main"
|
||||
app-action="click:app-link#goTo ${customAction ? customAction : ''}"
|
||||
href="${to}"
|
||||
style="text-decoration: underline; cursor: pointer;"
|
||||
><span class="link-text">${title}</span></a
|
||||
>`}`;
|
||||
2
src/components/app-link/index.ts
Normal file
2
src/components/app-link/index.ts
Normal file
@@ -0,0 +1,2 @@
|
||||
export { default as AppLinkElementTemplate } from './AppLinkElementTemplate';
|
||||
export * from './AppLinkElement';
|
||||
@@ -1,8 +1,8 @@
|
||||
import { controller, target } from '@github/catalyst';
|
||||
import { html } from 'core/utils';
|
||||
import { controller } from 'core/utils';
|
||||
import { BaseComponentElement } from 'common/';
|
||||
import AppLoaderElementTemplate from './AppLoaderElementTemplate';
|
||||
|
||||
@controller
|
||||
@controller('app-loader')
|
||||
class AppLoaderElement extends BaseComponentElement {
|
||||
private finished: boolean = true;
|
||||
private _loading: number = 0;
|
||||
@@ -42,19 +42,7 @@ class AppLoaderElement extends BaseComponentElement {
|
||||
this.update();
|
||||
};
|
||||
|
||||
render = () => {
|
||||
const renderLoader = (finished: boolean, loading: boolean) => {
|
||||
if (!finished && !loading) {
|
||||
return html`<div class="loader --removing"></div>`;
|
||||
} else if (loading) {
|
||||
return html`<div class="loader --loading"></div>`;
|
||||
}
|
||||
return html``;
|
||||
};
|
||||
return html`<div class="loader-wrapper">
|
||||
<div class="loader-relative">${renderLoader(this.finished, this.loading)}</div>
|
||||
</div>`;
|
||||
};
|
||||
render = () => AppLoaderElementTemplate({ finished: this.finished, loading: this.loading });
|
||||
}
|
||||
|
||||
export type { AppLoaderElement };
|
||||
|
||||
16
src/components/app-loader/AppLoaderElementTemplate.ts
Normal file
16
src/components/app-loader/AppLoaderElementTemplate.ts
Normal file
@@ -0,0 +1,16 @@
|
||||
import { html, nothing, TemplateResult } from 'core/utils';
|
||||
|
||||
export default (props): TemplateResult => {
|
||||
const { finished, loading } = props;
|
||||
const renderLoader = (finished: boolean, loading: boolean) => {
|
||||
if (!finished && !loading) {
|
||||
return html`<div class="loader --removing"></div>`;
|
||||
} else if (loading) {
|
||||
return html`<div class="loader --loading"></div>`;
|
||||
}
|
||||
return nothing;
|
||||
};
|
||||
return html`<div class="loader-wrapper">
|
||||
<div class="loader-relative">${renderLoader(finished, loading)}</div>
|
||||
</div>`;
|
||||
};
|
||||
2
src/components/app-loader/index.ts
Normal file
2
src/components/app-loader/index.ts
Normal file
@@ -0,0 +1,2 @@
|
||||
export { default as AppLoaderElementTemplate } from './AppLoaderElementTemplate';
|
||||
export * from './AppLoaderElement';
|
||||
@@ -1,13 +1,12 @@
|
||||
import { controller, target } from '@github/catalyst';
|
||||
import { AppService, HttpClient, RouterService } from 'core/services';
|
||||
import { AuthStore } from 'core/store';
|
||||
import { AppModalElement, AppRootElement } from 'components/';
|
||||
import { closest } from 'core/utils';
|
||||
import { closest, controller, target } from 'core/utils';
|
||||
import { AppLoaderElement } from 'components/app-loader/AppLoaderElement';
|
||||
import { ToastPortalElement } from 'components/toast-portal/ToastPortalElement';
|
||||
import { BasePageElement } from 'common/';
|
||||
|
||||
@controller
|
||||
@controller('app-main')
|
||||
class AppMainElement extends HTMLElement {
|
||||
public routerService: RouterService;
|
||||
public authStore: AuthStore;
|
||||
|
||||
1
src/components/app-main/index.ts
Normal file
1
src/components/app-main/index.ts
Normal file
@@ -0,0 +1 @@
|
||||
export * from './AppMainElement';
|
||||
@@ -1,11 +1,11 @@
|
||||
import { controller, target } from '@github/catalyst';
|
||||
import { html, TemplateResult } from 'core/utils';
|
||||
import { html, TemplateResult, controller, target } from 'core/utils';
|
||||
import { BaseComponentElement } from 'common/';
|
||||
import { AppMainElement } from 'components/app-main/AppMainElement';
|
||||
import { MenuItemElement } from 'components/menu-item/MenuItemElement';
|
||||
import { WalletService } from 'services/';
|
||||
import AppMenuElementTemplate from './AppMenuElementTemplate';
|
||||
|
||||
@controller
|
||||
@controller('app-menu')
|
||||
class AppMenuElement extends BaseComponentElement {
|
||||
private walletService: WalletService;
|
||||
private walletData: Array<any>;
|
||||
@@ -96,61 +96,8 @@ class AppMenuElement extends BaseComponentElement {
|
||||
}
|
||||
};
|
||||
|
||||
render = (): TemplateResult => {
|
||||
const { isAuth, totalWallets, walletData } = this;
|
||||
|
||||
const regularMenu = (path: string, title: string, action?: string, className?: string): TemplateResult => {
|
||||
if (action) {
|
||||
return html`
|
||||
<menu-item class="${className || ''}" data-path="${path}" data-customaction="${action}" data-title="${title}"></menu-item>
|
||||
`;
|
||||
}
|
||||
return html`<menu-item class="${className || ''}" data-path="${path}" data-title="${title}"></menu-item>`;
|
||||
};
|
||||
const menuButton = (title: string, action?: string): TemplateResult => {
|
||||
return html` <div class="menu-item --retract" data-target="menu-item.itemEl">
|
||||
<button class="btn btn-link" data-target="app-link.main" app-action="${action}">
|
||||
${title}<span class="pseudo"></span>
|
||||
</button>
|
||||
</div>`;
|
||||
};
|
||||
const authMenu = (path: string, title: string, action?: string, className?: string): TemplateResult => {
|
||||
if (isAuth) {
|
||||
return regularMenu(path, title, action, className);
|
||||
}
|
||||
return html``;
|
||||
};
|
||||
const notAuthMenu = (path: string, title: string, action?: string): TemplateResult => {
|
||||
if (!isAuth) {
|
||||
return regularMenu(path, title, action);
|
||||
}
|
||||
return html``;
|
||||
};
|
||||
const renderWallets = (wallets: Array<any>) => {
|
||||
if (isAuth && totalWallets > 0) {
|
||||
return html`<div class="menu-item divider"></div>
|
||||
${wallets.map((wallet) => regularMenu(`/wallet/${wallet.id}`, wallet.name, '', '--wallet'))}`;
|
||||
}
|
||||
return html``;
|
||||
};
|
||||
const menuHeader = (title) =>
|
||||
html`<div class="menu-item menu-header"><span class="link-text">${title}</span></div>`;
|
||||
|
||||
return html`
|
||||
<div data-target="app-menu.sidebar">
|
||||
<div class="content">
|
||||
${menuHeader(__CONFIG__.appName)} ${regularMenu('/', 'Home')}
|
||||
${authMenu('/history', 'Transaction History', 'click:app-menu#modalTransaction')}
|
||||
${authMenu('/subscriptions', 'Subscriptions', 'click:app-menu#modalSubscription')}
|
||||
${authMenu('/wallet/all', 'My Wallets', 'click:app-menu#modalWallet')} ${renderWallets(walletData)}
|
||||
<span class="menu-item divider"></span>
|
||||
${authMenu('/logout', 'Logout', '', '--logout')} ${notAuthMenu('/login', 'Login')}
|
||||
${notAuthMenu('/register', 'Register')}
|
||||
</div>
|
||||
<div class="footer">${menuButton('Retract', 'click:menu-layout#retractMenu')}</div>
|
||||
</div>
|
||||
`;
|
||||
};
|
||||
render = (): TemplateResult =>
|
||||
AppMenuElementTemplate({ isAuth: this.isAuth, totalWallets: this.totalWallets, walletData: this.walletData });
|
||||
}
|
||||
|
||||
export type { AppMenuElement };
|
||||
|
||||
61
src/components/app-menu/AppMenuElementTemplate.ts
Normal file
61
src/components/app-menu/AppMenuElementTemplate.ts
Normal file
@@ -0,0 +1,61 @@
|
||||
import { html, nothing, TemplateResult } from 'core/utils';
|
||||
|
||||
export default (props): TemplateResult => {
|
||||
const { isAuth, totalWallets, walletData } = props;
|
||||
|
||||
const regularMenu = (path: string, title: string, action?: string, className?: string): TemplateResult => {
|
||||
if (action) {
|
||||
return html`
|
||||
<menu-item
|
||||
class="${className || ''}"
|
||||
data-path="${path}"
|
||||
data-customaction="${action}"
|
||||
data-title="${title}"
|
||||
></menu-item>
|
||||
`;
|
||||
}
|
||||
return html`<menu-item class="${className || ''}" data-path="${path}" data-title="${title}"></menu-item>`;
|
||||
};
|
||||
const menuButton = (title: string, action?: string): TemplateResult => {
|
||||
return html` <div class="menu-item --retract" data-target="menu-item.itemEl">
|
||||
<button class="btn btn-link" data-target="app-link.main" app-action="${action}">
|
||||
${title}<span class="pseudo"></span>
|
||||
</button>
|
||||
</div>`;
|
||||
};
|
||||
const authMenu = (path: string, title: string, action?: string, className?: string): TemplateResult => {
|
||||
if (isAuth) {
|
||||
return regularMenu(path, title, action, className);
|
||||
}
|
||||
return html``;
|
||||
};
|
||||
const notAuthMenu = (path: string, title: string, action?: string): TemplateResult => {
|
||||
if (!isAuth) {
|
||||
return regularMenu(path, title, action);
|
||||
}
|
||||
return html``;
|
||||
};
|
||||
const renderWallets = (wallets: Array<any>) => {
|
||||
if (isAuth && totalWallets > 0) {
|
||||
return html`<div class="menu-item divider"></div>
|
||||
${wallets.map((wallet) => regularMenu(`/wallet/${wallet.id}`, wallet.name, '', '--wallet'))}`;
|
||||
}
|
||||
return nothing;
|
||||
};
|
||||
const menuHeader = (title) => html`<div class="menu-item menu-header"><span class="link-text">${title}</span></div>`;
|
||||
|
||||
return html`
|
||||
<div data-target="app-menu.sidebar">
|
||||
<div class="content">
|
||||
${menuHeader(__CONFIG__.appName)} ${regularMenu('/', 'Home')}
|
||||
${authMenu('/history', 'Transaction History', 'click:app-menu#modalTransaction')}
|
||||
${authMenu('/subscriptions', 'Subscriptions', 'click:app-menu#modalSubscription')}
|
||||
${authMenu('/wallet/all', 'My Wallets', 'click:app-menu#modalWallet')} ${renderWallets(walletData)}
|
||||
<span class="menu-item divider"></span>
|
||||
${authMenu('/logout', 'Logout', '', '--logout')} ${notAuthMenu('/login', 'Login')}
|
||||
${notAuthMenu('/register', 'Register')}
|
||||
</div>
|
||||
<div class="footer">${menuButton('Retract', 'click:menu-layout#retractMenu')}</div>
|
||||
</div>
|
||||
`;
|
||||
};
|
||||
2
src/components/app-menu/index.ts
Normal file
2
src/components/app-menu/index.ts
Normal file
@@ -0,0 +1,2 @@
|
||||
export { default as AppMenuElementTemplate } from './AppMenuElementTemplate';
|
||||
export * from './AppMenuElement';
|
||||
@@ -1,7 +1,7 @@
|
||||
import { controller, target } from '@github/catalyst';
|
||||
import { controller, target } from 'core/utils';
|
||||
import { BaseComponentElement } from 'common/';
|
||||
|
||||
@controller
|
||||
@controller('app-modal')
|
||||
class AppModalElement extends BaseComponentElement {
|
||||
@target modalElement: HTMLElement;
|
||||
@target modalContent: HTMLElement;
|
||||
|
||||
1
src/components/app-modal/index.ts
Normal file
1
src/components/app-modal/index.ts
Normal file
@@ -0,0 +1 @@
|
||||
export * from './AppModalElement';
|
||||
@@ -1,10 +1,8 @@
|
||||
import { attr, controller, target } from '@github/catalyst';
|
||||
import { html, TemplateResult } from 'core/utils';
|
||||
import { attr, controller, TemplateResult } from 'core/utils';
|
||||
import { BaseComponentElement } from 'common/';
|
||||
import { CircleLoaderElement } from 'components/circle-loader/CircleLoaderElement';
|
||||
import dayjs from 'dayjs';
|
||||
import { AppPaginationElementTemplate } from 'components/app-pagination';
|
||||
|
||||
@controller
|
||||
@controller('app-pagination')
|
||||
class AppPaginationElement extends BaseComponentElement {
|
||||
public items: Array<any>;
|
||||
@attr page: number;
|
||||
@@ -47,10 +45,10 @@ class AppPaginationElement extends BaseComponentElement {
|
||||
defaultFetch = () => {
|
||||
const options = {
|
||||
rpp: this.rpp || 10,
|
||||
page: 1
|
||||
}
|
||||
page: 1,
|
||||
};
|
||||
this.executeFetch(options);
|
||||
}
|
||||
};
|
||||
|
||||
setCustomRenderItems = (customRenderItems: () => TemplateResult) => {
|
||||
this.customRenderItems = customRenderItems;
|
||||
@@ -109,96 +107,25 @@ class AppPaginationElement extends BaseComponentElement {
|
||||
this.appMain.closeModal();
|
||||
} else {
|
||||
this.appMain.createModal('transaction-edit', {
|
||||
id: id
|
||||
id: id,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
render = (): TemplateResult => {
|
||||
const { rpp, totalItems, page, items } = this;
|
||||
|
||||
const renderItem = this.customRenderItem
|
||||
? this.customRenderItem
|
||||
: (item, iter) => html`<tr class="${this.colLayout ? this.colLayout : ''}">
|
||||
<td class="--left">${dayjs(item.transactionDate).format("MMM DD 'YY")}</td>
|
||||
<td class="--left">${item.description}</td>
|
||||
<td class="balance-cell --right">
|
||||
<span
|
||||
class="balance ${item.amount > 0 && item?.transactionType?.type != 'expense'
|
||||
? '--positive'
|
||||
: '--negative'}"
|
||||
>
|
||||
${item?.transactionType?.type == 'expense' ? '- ' : ''}
|
||||
${Number(item.amount).toLocaleString('en-US', {
|
||||
maximumFractionDigits: 2,
|
||||
minimumFractionDigits: 2,
|
||||
})}
|
||||
</span>
|
||||
<span class="currency">(${item.currency ? item.currency : 'USD'})</span>
|
||||
</td>
|
||||
<td class="--right">
|
||||
<span><button class="btn btn-rounded btn-gray" @click=${() => this.transactionEdit(item.id)}}>Edit</button></span>
|
||||
</td>
|
||||
</tr>`;
|
||||
|
||||
const renderItems = this.customRenderItems
|
||||
? this.customRenderItems
|
||||
: () => {
|
||||
if (this.loader && this.loader.loading && !this.initial) {
|
||||
return html``;
|
||||
} else {
|
||||
if (items?.length > 0) {
|
||||
return items?.map((item, iter) => renderItem(item, iter));
|
||||
}
|
||||
return html`<tr>
|
||||
<td>No data</td>
|
||||
</tr>`;
|
||||
}
|
||||
};
|
||||
|
||||
const renderPagination = () => {
|
||||
if (totalItems > items?.length) {
|
||||
const pageRange = Math.ceil(totalItems / rpp);
|
||||
return html`
|
||||
<div class="paginate">
|
||||
<span class="--total">(${items?.length}) / ${totalItems} Total Items</span>
|
||||
<div class="--footer">
|
||||
<span class="--pages">Page ${page} of ${pageRange}</span>
|
||||
${page <= 1 || this.loader.loading
|
||||
? html` <button
|
||||
class="btn btn-primary btn-squared disabled"
|
||||
disabled
|
||||
app-action="click:app-pagination#pageBack"
|
||||
>
|
||||
Prev
|
||||
</button>`
|
||||
: html` <button class="btn btn-primary btn-squared" app-action="click:app-pagination#pageBack">
|
||||
Prev
|
||||
</button>`}
|
||||
${page >= pageRange || this.loader.loading
|
||||
? html` <button
|
||||
class="btn btn-primary btn-squared disabled"
|
||||
disabled
|
||||
app-action="click:app-pagination#pageNext"
|
||||
>
|
||||
Next
|
||||
</button>`
|
||||
: html`<button class="btn btn-primary btn-squared" app-action="click:app-pagination#pageNext">
|
||||
Next
|
||||
</button>`}
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
}
|
||||
};
|
||||
|
||||
return html`<div class="app-pagination">
|
||||
<table class="${this.tableLayout} ${this.loader && this.loader.loading ? '--loading' : ''}">
|
||||
${renderItems()} ${renderPagination()}
|
||||
</table>
|
||||
${this.loader && this.loader.loading ? html`<circle-loader></circle-loader>` : html``}
|
||||
</div>`;
|
||||
};
|
||||
|
||||
render = (): TemplateResult =>
|
||||
AppPaginationElementTemplate({
|
||||
rpp: this.rpp,
|
||||
totalItems: this.totalItems,
|
||||
page: this.page,
|
||||
items: this.items,
|
||||
customRenderItem: this.customRenderItem,
|
||||
colLayout: this.colLayout,
|
||||
transactionEdit: this.transactionEdit,
|
||||
customRenderItems: this.customRenderItems,
|
||||
loader: this.loader,
|
||||
initial: this.initial,
|
||||
tableLayout: this.tableLayout,
|
||||
});
|
||||
}
|
||||
|
||||
export type { AppPaginationElement };
|
||||
|
||||
100
src/components/app-pagination/AppPaginationElementTemplate.ts
Normal file
100
src/components/app-pagination/AppPaginationElementTemplate.ts
Normal file
@@ -0,0 +1,100 @@
|
||||
import { html, nothing, TemplateResult } from 'core/utils';
|
||||
import dayjs from 'dayjs';
|
||||
|
||||
export default (props): TemplateResult => {
|
||||
const {
|
||||
rpp,
|
||||
totalItems,
|
||||
page,
|
||||
items,
|
||||
customRenderItem,
|
||||
colLayout,
|
||||
transactionEdit,
|
||||
customRenderItems,
|
||||
loader,
|
||||
initial,
|
||||
tableLayout,
|
||||
} = props;
|
||||
|
||||
const renderItem = customRenderItem
|
||||
? customRenderItem
|
||||
: (item, iter) => html`<tr class="${colLayout ? colLayout : ''}">
|
||||
<td class="--left">${dayjs(item.transactionDate).format("MMM DD 'YY")}</td>
|
||||
<td class="--left">${item.description}</td>
|
||||
<td class="balance-cell --right">
|
||||
<span
|
||||
class="balance ${item.amount > 0 && item?.transactionType?.type != 'expense' ? '--positive' : '--negative'}"
|
||||
>
|
||||
${item?.transactionType?.type == 'expense' ? '- ' : ''}
|
||||
${Number(item.amount).toLocaleString('en-US', {
|
||||
maximumFractionDigits: 2,
|
||||
minimumFractionDigits: 2,
|
||||
})}
|
||||
</span>
|
||||
<span class="currency">(${item.currency ? item.currency : 'USD'})</span>
|
||||
</td>
|
||||
<td class="--right">
|
||||
<span
|
||||
><button class="btn btn-rounded btn-gray" @click="${() => transactionEdit(item.id)}}">Edit</button></span
|
||||
>
|
||||
</td>
|
||||
</tr>`;
|
||||
|
||||
const renderItems = customRenderItems
|
||||
? customRenderItems
|
||||
: () => {
|
||||
if (loader && loader.loading && !initial) {
|
||||
return nothing;
|
||||
} else {
|
||||
if (items?.length > 0) {
|
||||
return items?.map((item, iter) => renderItem(item, iter));
|
||||
}
|
||||
return html`<tr>
|
||||
<td>No data</td>
|
||||
</tr>`;
|
||||
}
|
||||
};
|
||||
|
||||
const renderPagination = () => {
|
||||
if (totalItems > items?.length) {
|
||||
const pageRange = Math.ceil(totalItems / rpp);
|
||||
return html`
|
||||
<div class="paginate">
|
||||
<span class="--total">(${items?.length}) / ${totalItems} Total Items</span>
|
||||
<div class="--footer">
|
||||
<span class="--pages">Page ${page} of ${pageRange}</span>
|
||||
${page <= 1 || loader.loading
|
||||
? html` <button
|
||||
class="btn btn-primary btn-squared disabled"
|
||||
disabled
|
||||
app-action="click:app-pagination#pageBack"
|
||||
>
|
||||
Prev
|
||||
</button>`
|
||||
: html` <button class="btn btn-primary btn-squared" app-action="click:app-pagination#pageBack">
|
||||
Prev
|
||||
</button>`}
|
||||
${page >= pageRange || loader.loading
|
||||
? html` <button
|
||||
class="btn btn-primary btn-squared disabled"
|
||||
disabled
|
||||
app-action="click:app-pagination#pageNext"
|
||||
>
|
||||
Next
|
||||
</button>`
|
||||
: html`<button class="btn btn-primary btn-squared" app-action="click:app-pagination#pageNext">
|
||||
Next
|
||||
</button>`}
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
}
|
||||
};
|
||||
|
||||
return html`<div class="app-pagination">
|
||||
<table class="${tableLayout} ${loader && loader.loading ? '--loading' : ''}">
|
||||
${renderItems()} ${renderPagination()}
|
||||
</table>
|
||||
${loader && loader.loading ? html`<circle-loader></circle-loader>` : nothing}
|
||||
</div>`;
|
||||
};
|
||||
2
src/components/app-pagination/index.ts
Normal file
2
src/components/app-pagination/index.ts
Normal file
@@ -0,0 +1,2 @@
|
||||
export { default as AppPaginationElementTemplate } from './AppPaginationElementTemplate';
|
||||
export * from './AppPaginationElement';
|
||||
1
src/components/app-root/index.ts
Normal file
1
src/components/app-root/index.ts
Normal file
@@ -0,0 +1 @@
|
||||
export * from './AppRootElement';
|
||||
@@ -1,11 +1,10 @@
|
||||
import { controller } from '@github/catalyst';
|
||||
import { AppMainElement } from 'components/app-main/AppMainElement';
|
||||
import { controller } from 'core/utils';
|
||||
import style from 'styles/main.scss';
|
||||
|
||||
(function () {
|
||||
const _shadow = new WeakMap();
|
||||
|
||||
@controller
|
||||
@controller('app-shadow')
|
||||
class AppShadowElement extends HTMLElement {
|
||||
constructor() {
|
||||
super();
|
||||
@@ -15,7 +14,6 @@ import style from 'styles/main.scss';
|
||||
connectedCallback() {
|
||||
const _root = _shadow.get(this);
|
||||
const _appMain = document.createElement('app-main');
|
||||
(_appMain as AppMainElement).shadow = _root;
|
||||
const _style = document.createElement('style');
|
||||
_style.innerHTML = style;
|
||||
|
||||
|
||||
1
src/components/app-shadow/index.ts
Normal file
1
src/components/app-shadow/index.ts
Normal file
@@ -0,0 +1 @@
|
||||
export * from './AppShadowElement';
|
||||
@@ -1,7 +1,7 @@
|
||||
import { controller, target } from '@github/catalyst';
|
||||
import { controller, target } from 'core/utils';
|
||||
import { BaseComponentElement } from 'common/';
|
||||
|
||||
@controller
|
||||
@controller('app-slot')
|
||||
class AppSlotElement extends BaseComponentElement {
|
||||
@target slotElement: HTMLElement;
|
||||
constructor() {
|
||||
|
||||
1
src/components/app-slot/index.ts
Normal file
1
src/components/app-slot/index.ts
Normal file
@@ -0,0 +1 @@
|
||||
export * from './AppSlotElement';
|
||||
@@ -1,8 +1,8 @@
|
||||
import { attr, controller } from '@github/catalyst';
|
||||
import { html } from 'core/utils';
|
||||
import { attr, controller, TemplateResult } from 'core/utils';
|
||||
import { BaseComponentElement } from 'common/';
|
||||
import { CircleLoaderElementTemplate } from 'components/circle-loader';
|
||||
|
||||
@controller
|
||||
@controller('circle-loader')
|
||||
class CircleLoaderElement extends BaseComponentElement {
|
||||
@attr size: string;
|
||||
constructor() {
|
||||
@@ -13,9 +13,7 @@ class CircleLoaderElement extends BaseComponentElement {
|
||||
this.update();
|
||||
};
|
||||
|
||||
render = () => {
|
||||
return html`<div class="circle-loader ${this.size ? `-${this.size}` : ''}"></div>`;
|
||||
};
|
||||
render = (): TemplateResult => CircleLoaderElementTemplate({ size: this.size });
|
||||
}
|
||||
|
||||
export type { CircleLoaderElement };
|
||||
|
||||
@@ -0,0 +1,3 @@
|
||||
import { html, TemplateResult } from 'core/utils';
|
||||
|
||||
export default ({ size }): TemplateResult => html`<div class="circle-loader ${size ? `-${size}` : ''}"></div>`;
|
||||
2
src/components/circle-loader/index.ts
Normal file
2
src/components/circle-loader/index.ts
Normal file
@@ -0,0 +1,2 @@
|
||||
export { default as CircleLoaderElementTemplate } from './CircleLoaderElementTemplate';
|
||||
export * from './CircleLoaderElement';
|
||||
@@ -1,18 +1,18 @@
|
||||
export * from './app-link/AppLinkElement';
|
||||
export * from './menu-item/MenuItemElement';
|
||||
export * from './app-pagination/AppPaginationElement';
|
||||
export * from './app-modal/AppModalElement';
|
||||
export * from './app-root/AppRootElement';
|
||||
export * from './app-slot/AppSlotElement';
|
||||
export * from './app-menu/AppMenuElement';
|
||||
export * from './input-field/InputFieldElement';
|
||||
export * from './app-dropdown/AppDropdownElement';
|
||||
export * from './app-loader/AppLoaderElement';
|
||||
export * from './circle-loader/CircleLoaderElement';
|
||||
export * from './app-form/AppFormElement';
|
||||
export * from './wallet-header/WalletHeaderElement';
|
||||
export * from './toast-portal/ToastPortalElement';
|
||||
export * from './app-link';
|
||||
export * from './menu-item';
|
||||
export * from './app-pagination';
|
||||
export * from './app-modal';
|
||||
export * from './app-root';
|
||||
export * from './app-slot';
|
||||
export * from './app-menu';
|
||||
export * from './input-field';
|
||||
export * from './app-dropdown';
|
||||
export * from './app-loader';
|
||||
export * from './circle-loader';
|
||||
export * from './app-form';
|
||||
export * from './wallet-header';
|
||||
export * from './toast-portal';
|
||||
|
||||
// LAST
|
||||
export * from './app-main/AppMainElement';
|
||||
export * from './app-shadow/AppShadowElement';
|
||||
export * from './app-main';
|
||||
export * from './app-shadow';
|
||||
|
||||
@@ -1,13 +1,10 @@
|
||||
import { attr, controller, target } from '@github/catalyst';
|
||||
import { closest, firstUpper } from 'core/utils';
|
||||
import { html, TemplateResult } from 'core/utils';
|
||||
import { closest, attr, controller, target, html, TemplateResult } from 'core/utils';
|
||||
import randomId from 'core/utils/random-id';
|
||||
import { validatorErrors } from 'core/constants';
|
||||
import { BaseComponentElement, Validator } from 'common/';
|
||||
import { AppFormElement } from 'components/app-form/AppFormElement';
|
||||
import { validator } from 'core/utils';
|
||||
import { InputFieldElementTemplate } from 'components/input-field';
|
||||
|
||||
@controller
|
||||
@controller('input-field')
|
||||
class InputFieldElement extends BaseComponentElement {
|
||||
@attr name: string;
|
||||
@attr type: string;
|
||||
@@ -34,7 +31,6 @@ class InputFieldElement extends BaseComponentElement {
|
||||
this.validator = new Validator(this, this.appForm, this.rules);
|
||||
this.randId = `${name}${randomId()}`;
|
||||
this.update();
|
||||
//this.validate();
|
||||
};
|
||||
|
||||
attributeChangedCallback() {
|
||||
@@ -54,7 +50,7 @@ class InputFieldElement extends BaseComponentElement {
|
||||
}
|
||||
|
||||
get required(): boolean {
|
||||
return this.rules.includes('required');
|
||||
return this.rules?.includes('required');
|
||||
}
|
||||
|
||||
get _value() {
|
||||
@@ -63,16 +59,16 @@ class InputFieldElement extends BaseComponentElement {
|
||||
}
|
||||
return (this.inp as HTMLInputElement)?.value;
|
||||
}
|
||||
|
||||
|
||||
get _disabled() {
|
||||
return this.disabled == "true"
|
||||
return this.disabled == 'true';
|
||||
}
|
||||
|
||||
set _value(value) {
|
||||
if (this.type == 'checkbox') {
|
||||
(this.inp as HTMLInputElement).checked = (value as boolean);
|
||||
(this.inp as HTMLInputElement).checked = value as boolean;
|
||||
} else {
|
||||
(this.inp as HTMLInputElement).value = (value as string);
|
||||
(this.inp as HTMLInputElement).value = value as string;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -103,62 +99,20 @@ class InputFieldElement extends BaseComponentElement {
|
||||
if (!this.changed && e?.target?.value) {
|
||||
this.changed = true;
|
||||
}
|
||||
//this.validate();
|
||||
this.appForm?.inputChange(e);
|
||||
};
|
||||
|
||||
render = (): TemplateResult => {
|
||||
const renderMessage = (label: string) => {
|
||||
if (this.label) {
|
||||
return html`<label for="${this.randId}">${this.label}${this.required ? ' (*)' : ''}</label>`;
|
||||
}
|
||||
return html``;
|
||||
};
|
||||
|
||||
const renderError = (error: string) => {
|
||||
if (error) {
|
||||
return html`<div class="input-error"><span>${error}</span></div>`;
|
||||
}
|
||||
return html``;
|
||||
};
|
||||
|
||||
const renderInput = (type) => {
|
||||
if (this.pattern) {
|
||||
return html` <input
|
||||
name="${this.name}"
|
||||
autocomplete="${this.name}"
|
||||
type="${this.type}"
|
||||
pattern="${this.pattern}"
|
||||
step="0.01"
|
||||
data-target="input-field.inp"
|
||||
id="${this.randId}"
|
||||
?disabled=${this._disabled}
|
||||
app-action=" input:input-field#inputChange blur:input-field#validateDisplay
|
||||
${this.customAction ? this.customAction : ''} "
|
||||
/>`;
|
||||
}
|
||||
return html` <input
|
||||
name="${this.name}"
|
||||
autocomplete="${this.name}"
|
||||
type="${this.type}"
|
||||
data-target="input-field.inp"
|
||||
?disabled=${this._disabled}
|
||||
id="${this.randId}"
|
||||
app-action="
|
||||
input:input-field#inputChange
|
||||
blur:input-field#validateDisplay
|
||||
${this.customAction ? this.customAction : ''}
|
||||
"
|
||||
/>`;
|
||||
};
|
||||
|
||||
return html`<div
|
||||
class="input-main${this.type === 'checkbox' ? ' input-main--checkbox' : ''}"
|
||||
data-target="input-field.main"
|
||||
>
|
||||
${renderMessage(this.label)}${renderError(this.error)} ${renderInput(this.type)}
|
||||
</div>`;
|
||||
};
|
||||
render = (): TemplateResult =>
|
||||
InputFieldElementTemplate({
|
||||
randId: this.randId,
|
||||
required: this.required,
|
||||
pattern: this.pattern,
|
||||
_disabled: this._disabled,
|
||||
customAction: this.customAction,
|
||||
type: this.type,
|
||||
error: this.error,
|
||||
label: this.label,
|
||||
});
|
||||
}
|
||||
|
||||
export type { InputFieldElement };
|
||||
|
||||
55
src/components/input-field/InputFieldElementTemplate.ts
Normal file
55
src/components/input-field/InputFieldElementTemplate.ts
Normal file
@@ -0,0 +1,55 @@
|
||||
import { html, nothing, TemplateResult } from 'core/utils';
|
||||
|
||||
export default (props): TemplateResult => {
|
||||
const { randId, required, pattern, _disabled, customAction, type, error, label } = props;
|
||||
const renderMessage = (label: string) => {
|
||||
if (label) {
|
||||
return html`<label for="${randId}">${label}${required ? ' (*)' : ''}</label>`;
|
||||
}
|
||||
return nothing;
|
||||
};
|
||||
|
||||
const renderError = (error: string) => {
|
||||
if (error) {
|
||||
return html`<div class="input-error"><span>${error}</span></div>`;
|
||||
}
|
||||
return nothing;
|
||||
};
|
||||
|
||||
const renderInput = (type) => {
|
||||
if (pattern) {
|
||||
return html` <input
|
||||
name="${name}"
|
||||
autocomplete="${name}"
|
||||
type="${type}"
|
||||
pattern="${pattern}"
|
||||
step="0.01"
|
||||
data-target="input-field.inp"
|
||||
id="${randId}"
|
||||
?disabled=${_disabled}
|
||||
app-action=" input:input-field#inputChange blur:input-field#validateDisplay
|
||||
${customAction ? customAction : ''} "
|
||||
/>`;
|
||||
}
|
||||
return html` <input
|
||||
name="${name}"
|
||||
autocomplete="${name}"
|
||||
type="${type}"
|
||||
data-target="input-field.inp"
|
||||
?disabled=${_disabled}
|
||||
id="${randId}"
|
||||
app-action="
|
||||
input:input-field#inputChange
|
||||
blur:input-field#validateDisplay
|
||||
${customAction ? customAction : ''}
|
||||
"
|
||||
/>`;
|
||||
};
|
||||
|
||||
return html`<div
|
||||
class="input-main${type === 'checkbox' ? ' input-main--checkbox' : ''}"
|
||||
data-target="input-field.main"
|
||||
>
|
||||
${renderMessage(label)}${renderError(error)} ${renderInput(type)}
|
||||
</div>`;
|
||||
};
|
||||
2
src/components/input-field/index.ts
Normal file
2
src/components/input-field/index.ts
Normal file
@@ -0,0 +1,2 @@
|
||||
export { default as InputFieldElementTemplate } from './InputFieldElementTemplate';
|
||||
export * from './InputFieldElement';
|
||||
@@ -1,11 +1,11 @@
|
||||
import { attr, controller, target } from '@github/catalyst';
|
||||
import { html, TemplateResult } from 'core/utils';
|
||||
import { TemplateResult, attr, controller, target } from 'core/utils';
|
||||
import { AppMainElement } from 'components/app-main/AppMainElement';
|
||||
import { BaseComponentElement } from 'common/';
|
||||
import { deviceWidths } from 'core/constants';
|
||||
import { MenuLayoutElement } from 'layouts/';
|
||||
import { MenuItemElementTemplate } from 'components/menu-item';
|
||||
|
||||
@controller
|
||||
@controller('menu-item')
|
||||
class MenuItemElement extends BaseComponentElement {
|
||||
@attr path: string;
|
||||
@attr title: string;
|
||||
@@ -32,7 +32,7 @@ class MenuItemElement extends BaseComponentElement {
|
||||
};
|
||||
|
||||
attributeChangedCallback(changed) {
|
||||
if(this.initialized && changed == 'data-title') {
|
||||
if (this.initialized && changed == 'data-title') {
|
||||
this.update();
|
||||
}
|
||||
}
|
||||
@@ -47,17 +47,14 @@ class MenuItemElement extends BaseComponentElement {
|
||||
}
|
||||
};
|
||||
|
||||
render = (): TemplateResult => {
|
||||
return html`
|
||||
<div class="${this.current ? 'selected ' : ''}menu-item" data-target="menu-item.itemEl">
|
||||
<app-link class="${this.className}" data-to="${this.path}" data-custom-action="click:menu-item#itemClick" data-title="${this.title}"></app-link
|
||||
>
|
||||
${this.customaction
|
||||
? html`<div data-target="menu-item.customButton" app-action="${this.customaction}">+</div>`
|
||||
: html``}
|
||||
</div>
|
||||
`;
|
||||
};
|
||||
render = (): TemplateResult =>
|
||||
MenuItemElementTemplate({
|
||||
current: this.current,
|
||||
className: this.className,
|
||||
path: this.path,
|
||||
title: this.title,
|
||||
customaction: this.customaction,
|
||||
});
|
||||
}
|
||||
|
||||
export type { MenuItemElement };
|
||||
|
||||
13
src/components/menu-item/MenuItemElementTemplate.ts
Normal file
13
src/components/menu-item/MenuItemElementTemplate.ts
Normal file
@@ -0,0 +1,13 @@
|
||||
import { html, TemplateResult } from 'core/utils';
|
||||
|
||||
export default ({ current, className, path, title, customaction }): TemplateResult => html`
|
||||
<div class="${current ? 'selected ' : ''}menu-item" data-target="menu-item.itemEl">
|
||||
<app-link
|
||||
class="${className}"
|
||||
data-to="${path}"
|
||||
data-custom-action="click:menu-item#itemClick"
|
||||
data-title="${title}"
|
||||
></app-link>
|
||||
${customaction ? html`<div data-target="menu-item.customButton" app-action="${customaction}">+</div>` : html``}
|
||||
</div>
|
||||
`;
|
||||
2
src/components/menu-item/index.ts
Normal file
2
src/components/menu-item/index.ts
Normal file
@@ -0,0 +1,2 @@
|
||||
export { default as MenuItemElementTemplate } from './MenuItemElementTemplate';
|
||||
export * from './MenuItemElement';
|
||||
@@ -1,8 +1,8 @@
|
||||
import { controller, targets } from '@github/catalyst';
|
||||
import { delay, html, Timer } from 'core/utils';
|
||||
import { Timer, controller, targets } from 'core/utils';
|
||||
import { BaseComponentElement } from 'common/';
|
||||
import { ToastPortalElementTemplate } from 'components/toast-portal';
|
||||
|
||||
@controller
|
||||
@controller('toast-portal')
|
||||
class ToastPortalElement extends BaseComponentElement {
|
||||
@targets toastElement: HTMLElement;
|
||||
toasts: Array<Toast> = [];
|
||||
@@ -26,10 +26,6 @@ class ToastPortalElement extends BaseComponentElement {
|
||||
}
|
||||
}, 5000);
|
||||
}
|
||||
// const interval = setInterval(() => {
|
||||
// this.popToast();
|
||||
// clearInterval(interval);
|
||||
// }, 5000);
|
||||
this.update();
|
||||
};
|
||||
|
||||
@@ -41,30 +37,10 @@ class ToastPortalElement extends BaseComponentElement {
|
||||
this.update();
|
||||
};
|
||||
|
||||
render = () => {
|
||||
const renderToast = (note: string, type: string) => {
|
||||
const message = () =>
|
||||
html`
|
||||
<div class="toast ${type ? `--${type}` : '--default'}">
|
||||
<span class="toast-text">${note}</span>
|
||||
</div>
|
||||
`;
|
||||
return html`${message()}`;
|
||||
};
|
||||
|
||||
const renderToasts = (toasts: Array<Toast>) => {
|
||||
if (toasts) {
|
||||
return html`<div class="toast-list">
|
||||
${toasts.map(({ type, message }, i) => (i < 3 ? renderToast(message, type) : html``))}
|
||||
</div>`;
|
||||
}
|
||||
return html``;
|
||||
};
|
||||
return html`<div class="toast-portal">${renderToasts(this.toasts)}</div>`;
|
||||
};
|
||||
render = () => ToastPortalElementTemplate({ toasts: this.toasts });
|
||||
}
|
||||
|
||||
type Toast = {
|
||||
export type Toast = {
|
||||
type: string;
|
||||
message: string;
|
||||
};
|
||||
|
||||
25
src/components/toast-portal/ToastPortalElementTemplate.ts
Normal file
25
src/components/toast-portal/ToastPortalElementTemplate.ts
Normal file
@@ -0,0 +1,25 @@
|
||||
import { html, nothing, TemplateResult } from 'core/utils';
|
||||
import { Toast } from './';
|
||||
|
||||
export default (props): TemplateResult => {
|
||||
const { toasts } = props;
|
||||
const renderToast = (note: string, type: string) => {
|
||||
const message = () =>
|
||||
html`
|
||||
<div class="toast ${type ? `--${type}` : '--default'}">
|
||||
<span class="toast-text">${note}</span>
|
||||
</div>
|
||||
`;
|
||||
return html`${message()}`;
|
||||
};
|
||||
|
||||
const renderToasts = (toasts: Array<Toast>) => {
|
||||
if (toasts) {
|
||||
return html`<div class="toast-list">
|
||||
${toasts.map(({ type, message }, i) => (i < 3 ? renderToast(message, type) : nothing))}
|
||||
</div>`;
|
||||
}
|
||||
return nothing;
|
||||
};
|
||||
return html`<div class="toast-portal">${renderToasts(toasts)}</div>`;
|
||||
};
|
||||
2
src/components/toast-portal/index.ts
Normal file
2
src/components/toast-portal/index.ts
Normal file
@@ -0,0 +1,2 @@
|
||||
export { default as ToastPortalElementTemplate } from './ToastPortalElementTemplate';
|
||||
export * from './ToastPortalElement';
|
||||
@@ -1,8 +1,7 @@
|
||||
import { attr, controller, target } from '@github/catalyst';
|
||||
import { html, TemplateResult } from 'core/utils';
|
||||
import { TemplateResult, attr, controller } from 'core/utils';
|
||||
import { BaseComponentElement } from 'common/';
|
||||
import { CircleLoaderElement } from 'components/circle-loader/CircleLoaderElement';
|
||||
import { findMethod } from 'core/utils';
|
||||
import { WalletHeaderElementTemplate } from 'components/wallet-header';
|
||||
|
||||
@controller
|
||||
class WalletHeaderElement extends BaseComponentElement {
|
||||
@@ -44,31 +43,15 @@ class WalletHeaderElement extends BaseComponentElement {
|
||||
}
|
||||
};
|
||||
|
||||
render = (): TemplateResult => {
|
||||
const { currentBalance, currency, lastMonth, nextMonth } = this;
|
||||
|
||||
const renderItem = (header, balance, currency) => html`<div class="header-item">
|
||||
<div class="--header">${header}</div>
|
||||
<div class="--content">
|
||||
<span class="--balance ${balance > 0 ? '--positive' : '--negative'}"
|
||||
>${Number(balance).toLocaleString('en-US', { maximumFractionDigits: 2, minimumFractionDigits: 2 })}</span
|
||||
><span class="--currency">(${currency})</span>
|
||||
</div>
|
||||
</div>`;
|
||||
|
||||
const renderHeader = () => {
|
||||
if (this.loader && this.loader.loading && !this.initial) {
|
||||
return html``;
|
||||
}
|
||||
return html`${renderItem('Last Month', lastMonth, currency)}${renderItem(
|
||||
'Current Balance',
|
||||
currentBalance,
|
||||
currency
|
||||
)}${renderItem('Next Month', nextMonth, currency)}`;
|
||||
};
|
||||
|
||||
return html`<div class="wallet-header">${renderHeader()}</div>`;
|
||||
};
|
||||
render = (): TemplateResult =>
|
||||
WalletHeaderElementTemplate({
|
||||
currentBalance: this.currentBalance,
|
||||
currency: this.currency,
|
||||
lastMonth: this.lastMonth,
|
||||
nextMonth: this.nextMonth,
|
||||
loader: this.loader,
|
||||
initial: this.initial,
|
||||
});
|
||||
}
|
||||
|
||||
export type { WalletHeaderElement };
|
||||
|
||||
27
src/components/wallet-header/WalletHeaderElementTemplate.ts
Normal file
27
src/components/wallet-header/WalletHeaderElementTemplate.ts
Normal file
@@ -0,0 +1,27 @@
|
||||
import { html, nothing, TemplateResult } from 'core/utils';
|
||||
|
||||
export default (props): TemplateResult => {
|
||||
const { currentBalance, currency, lastMonth, nextMonth, loader, initial } = props;
|
||||
|
||||
const renderItem = (header, balance, currency) => html`<div class="header-item">
|
||||
<div class="--header">${header}</div>
|
||||
<div class="--content">
|
||||
<span class="--balance ${balance > 0 ? '--positive' : '--negative'}"
|
||||
>${Number(balance).toLocaleString('en-US', { maximumFractionDigits: 2, minimumFractionDigits: 2 })}</span
|
||||
><span class="--currency">(${currency})</span>
|
||||
</div>
|
||||
</div>`;
|
||||
|
||||
const renderHeader = () => {
|
||||
if (loader && loader.loading && !initial) {
|
||||
return nothing;
|
||||
}
|
||||
return html`${renderItem('Last Month', lastMonth, currency)}${renderItem(
|
||||
'Current Balance',
|
||||
currentBalance,
|
||||
currency
|
||||
)}${renderItem('Next Month', nextMonth, currency)}`;
|
||||
};
|
||||
|
||||
return html`<div class="wallet-header">${renderHeader()}</div>`;
|
||||
};
|
||||
2
src/components/wallet-header/index.ts
Normal file
2
src/components/wallet-header/index.ts
Normal file
@@ -0,0 +1,2 @@
|
||||
export { default as WalletHeaderElementTemplate } from './WalletHeaderElementTemplate';
|
||||
export * from './WalletHeaderElement';
|
||||
Reference in New Issue
Block a user