From db25f78a84d7745c8ac423f3b083aaff3cf8f84f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fran=20Jurmanovi=C4=87?= Date: Sun, 7 Nov 2021 15:16:03 +0100 Subject: [PATCH 1/4] check for pending transactions --- src/components/app-main/AppMainElement.ts | 16 ++++++++++++++++ src/pages/history-page/HistoryPageElement.ts | 1 + src/pages/wallet-page/WalletPageElement.ts | 1 + src/services/TransactionsService.ts | 4 ++++ 4 files changed, 22 insertions(+) diff --git a/src/components/app-main/AppMainElement.ts b/src/components/app-main/AppMainElement.ts index 5628263..a8a5720 100644 --- a/src/components/app-main/AppMainElement.ts +++ b/src/components/app-main/AppMainElement.ts @@ -5,6 +5,7 @@ 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/'; +import { TransactionsService } from 'services/'; @controller('app-main') class AppMainElement extends HTMLElement { @@ -12,6 +13,8 @@ class AppMainElement extends HTMLElement { public authStore: AuthStore; private httpClient: HttpClient; public appService: AppService; + private transactionsService: TransactionsService; + private subscriptionChecked: boolean = false; //public shadow: any; @target appModal: AppModalElement; @target mainRoot: AppRootElement; @@ -36,6 +39,7 @@ class AppMainElement extends HTMLElement { this.httpClient = new HttpClient(); this.appService = new AppService(this, this.httpClient); this.routerService = new RouterService(this, mainRoot); + this.transactionsService = new TransactionsService(this.appService); this.authStore = new AuthStore(this, this.appService); this.routerService.setRoutes([ { @@ -113,6 +117,8 @@ class AppMainElement extends HTMLElement { this.routerService.init(); this.addEventListener('mousedown', this.setActiveElement, false); this.addEventListener('tokenchange', this.closeOffToken); + this.addEventListener('routechanged', this.checkSubscriptions); + this.checkSubscriptions(); } closeOffToken = () => { @@ -121,9 +127,19 @@ class AppMainElement extends HTMLElement { } }; + checkSubscriptions = async () => { + if (this.isAuth && !this.subscriptionChecked) { + const checked = await this.transactionsService.check(); + console.log(checked); + this.subscriptionChecked = true; + this.removeEventListener('routechanged', this.checkSubscriptions); + } + }; + disconnectedCallback = () => { this.removeEventListener('mousedown', this.setActiveElement); this.removeEventListener('tokenchange', this.closeOffToken); + this.removeEventListener('routechanged', this.checkSubscriptions); }; setActiveElement = (e) => { diff --git a/src/pages/history-page/HistoryPageElement.ts b/src/pages/history-page/HistoryPageElement.ts index 7be7d33..e54913a 100644 --- a/src/pages/history-page/HistoryPageElement.ts +++ b/src/pages/history-page/HistoryPageElement.ts @@ -41,6 +41,7 @@ class HistoryPageElement extends BasePageElement { } options.embed = 'TransactionType'; options.sortBy = 'transactionDate|desc'; + options.noPending = true; const response = await this.transactionsService.getAll(options); return response; } catch (err) { diff --git a/src/pages/wallet-page/WalletPageElement.ts b/src/pages/wallet-page/WalletPageElement.ts index bf17dd4..5082c1f 100644 --- a/src/pages/wallet-page/WalletPageElement.ts +++ b/src/pages/wallet-page/WalletPageElement.ts @@ -70,6 +70,7 @@ class WalletPageElement extends BasePageElement { } options.embed = 'TransactionType'; options.sortBy = 'transactionDate|desc'; + options.noPending = true; const response = await this.transactionsService.getAll(options); return response; } catch (err) { diff --git a/src/services/TransactionsService.ts b/src/services/TransactionsService.ts index 4874668..5e1c521 100644 --- a/src/services/TransactionsService.ts +++ b/src/services/TransactionsService.ts @@ -4,6 +4,10 @@ class TransactionsService extends BaseService { constructor(appService: AppService) { super('/transaction', appService); } + + check = (params?: Object, headers?: HeadersInit) => { + return this.appService.get(this.endpoint + '/check', params, headers); + }; } export default TransactionsService; From 06dd67e6c594e5d318a46051e06ab54bd08eb08d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fran=20Jurmanovi=C4=87?= Date: Sat, 11 Dec 2021 21:15:10 +0100 Subject: [PATCH 2/4] added transaction check list --- src/components/app-main/AppMainElement.ts | 4 +- .../app-pagination/AppPaginationElement.ts | 4 +- .../input-field/InputFieldElement.ts | 4 + src/pages/index.ts | 1 + .../TransactionCheckElement.ts | 87 +++++++++++++++++++ .../TransactionCheckElementTemplate.ts | 16 ++++ src/pages/transaction-check/index.ts | 2 + 7 files changed, 115 insertions(+), 3 deletions(-) create mode 100644 src/pages/transaction-check/TransactionCheckElement.ts create mode 100644 src/pages/transaction-check/TransactionCheckElementTemplate.ts create mode 100644 src/pages/transaction-check/index.ts diff --git a/src/components/app-main/AppMainElement.ts b/src/components/app-main/AppMainElement.ts index a8a5720..556c574 100644 --- a/src/components/app-main/AppMainElement.ts +++ b/src/components/app-main/AppMainElement.ts @@ -130,7 +130,9 @@ class AppMainElement extends HTMLElement { checkSubscriptions = async () => { if (this.isAuth && !this.subscriptionChecked) { const checked = await this.transactionsService.check(); - console.log(checked); + this.createModal('transaction-check', { + data: checked, + }); this.subscriptionChecked = true; this.removeEventListener('routechanged', this.checkSubscriptions); } diff --git a/src/components/app-pagination/AppPaginationElement.ts b/src/components/app-pagination/AppPaginationElement.ts index 4875b03..e3e84a4 100644 --- a/src/components/app-pagination/AppPaginationElement.ts +++ b/src/components/app-pagination/AppPaginationElement.ts @@ -60,7 +60,7 @@ class AppPaginationElement extends BaseComponentElement { this.update(); }; - executeFetch = async (options?): Promise => { + executeFetch = async (options?, fetchFunc = this.fetchFunc): Promise => { if (!options) { options = { rpp: this.rpp || 5, @@ -70,7 +70,7 @@ class AppPaginationElement extends BaseComponentElement { try { this.loader?.start?.(); - const response = await this.fetchFunc(options); + const response = await fetchFunc(options); this.loader?.stop?.(); this.setItems(response?.items); this.totalItems = response?.totalRecords; diff --git a/src/components/input-field/InputFieldElement.ts b/src/components/input-field/InputFieldElement.ts index 70ae9b4..85c9758 100644 --- a/src/components/input-field/InputFieldElement.ts +++ b/src/components/input-field/InputFieldElement.ts @@ -12,6 +12,7 @@ class InputFieldElement extends BaseComponentElement { @attr rules: string; @attr pattern: string; @attr customAction: string; + @attr initialValue: string; @target main: HTMLElement; @target inp: HTMLElement; @closest appForm: AppFormElement; @@ -31,6 +32,9 @@ class InputFieldElement extends BaseComponentElement { this.validator = new Validator(this, this.appForm, this.rules); this.randId = `${name}${randomId()}`; this.update(); + if (this.initialValue) { + this._value = this.initialValue; + } }; attributeChangedCallback() { diff --git a/src/pages/index.ts b/src/pages/index.ts index 6766e30..5837b23 100644 --- a/src/pages/index.ts +++ b/src/pages/index.ts @@ -13,3 +13,4 @@ export * from './wallet-page'; export * from './subscription-edit'; export * from './transaction-edit'; export * from './wallet-edit'; +export * from './transaction-check'; diff --git a/src/pages/transaction-check/TransactionCheckElement.ts b/src/pages/transaction-check/TransactionCheckElement.ts new file mode 100644 index 0000000..eb92d55 --- /dev/null +++ b/src/pages/transaction-check/TransactionCheckElement.ts @@ -0,0 +1,87 @@ +import { TemplateResult, controller, target, html } from 'core/utils'; +import { TransactionsService } from 'services/'; +import { AppMainElement, AppPaginationElement } from 'components/'; +import { BasePageElement } from 'common/'; +import { TransactionCheckElementTemplate } from 'pages/transaction-check'; +import dayjs from 'dayjs'; + +@controller('transaction-check') +class TransactionCheckElement extends BasePageElement { + private transactionsService: TransactionsService; + @target pagination: AppPaginationElement; + modalData: any = null; + constructor() { + super({ + title: 'Transaction Check', + }); + } + + elementConnected = (): void => { + this.transactionsService = new TransactionsService(this.appMain?.appService); + this.update(); + this.pagination?.setCustomRenderItem?.(this.renderSubscription)!; + this.pagination?.setFetchFunc?.(this.getTransactions, false)!; + this.modalData = this.getData(); + this.pagination?.executeFetch?.(null, () => this.mappedData(this.modalData.data)); + }; + + mappedData = (data) => { + for (const item of data?.items) { + item.formattedDate = dayjs(item.transactionDate).format('YYYY-MM-DD'); + } + return data; + }; + + renderSubscription = (item) => html` + ${!item.isEdit + ? html`${dayjs(item.transactionDate).format("MMM DD 'YY")}` + : html``} + ${item.description} + + + ${item?.transactionType?.type == 'expense' ? '- ' : ''} + ${Number(item.amount).toLocaleString('en-US', { + maximumFractionDigits: 2, + minimumFractionDigits: 2, + })} + + (${item.currency ? item.currency : 'USD'}) + + + + + `; + + transactionEdit = (item) => { + item.isEdit = !item.isEdit; + this.pagination?.update(); + }; + + transactionUpdated = () => { + this.pagination?.executeFetch(); + }; + + getTransactions = async (options): Promise => { + try { + options.embed = 'TransactionType'; + options.sortBy = 'dateCreated|desc'; + const response = await this.transactionsService.check(options); + return response; + } catch (err) { + throw err; + } + }; + + render = (): TemplateResult => + TransactionCheckElementTemplate({ walletId: this.routerService?.routerState?.data?.walletId }); +} + +export type { TransactionCheckElement }; diff --git a/src/pages/transaction-check/TransactionCheckElementTemplate.ts b/src/pages/transaction-check/TransactionCheckElementTemplate.ts new file mode 100644 index 0000000..ad9c3d1 --- /dev/null +++ b/src/pages/transaction-check/TransactionCheckElementTemplate.ts @@ -0,0 +1,16 @@ +import { html, nothing, TemplateResult } from 'core/utils'; + +export default (props): TemplateResult => { + const { walletId } = props; + const renderWallet = () => { + if (walletId) { + return html`${walletId}`; + } + return nothing; + }; + + return html`
+ ${renderWallet()} + +
`; +}; diff --git a/src/pages/transaction-check/index.ts b/src/pages/transaction-check/index.ts new file mode 100644 index 0000000..dcdccfe --- /dev/null +++ b/src/pages/transaction-check/index.ts @@ -0,0 +1,2 @@ +export { default as TransactionCheckElementTemplate } from './TransactionCheckElementTemplate'; +export * from './TransactionCheckElement'; From b1994081374003208f85667d1877f4949c003d89 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fran=20Jurmanovi=C4=87?= Date: Sun, 12 Dec 2021 10:23:47 +0100 Subject: [PATCH 3/4] save or complete transaction check --- .eslintrc.json | 4 +- src/components/app-main/AppMainElement.ts | 2 +- .../TransactionCheckElement.ts | 113 +++++++++++++----- .../TransactionCheckElementTemplate.ts | 9 -- src/services/TransactionStatusService.ts | 9 ++ src/services/index.ts | 1 + 6 files changed, 97 insertions(+), 41 deletions(-) create mode 100644 src/services/TransactionStatusService.ts diff --git a/.eslintrc.json b/.eslintrc.json index 7900fa6..314b170 100644 --- a/.eslintrc.json +++ b/.eslintrc.json @@ -32,6 +32,8 @@ { "ignoreRestSiblings": true } - ] + ], + "no-console": "warn", + "no-debugger": "warn" } } \ No newline at end of file diff --git a/src/components/app-main/AppMainElement.ts b/src/components/app-main/AppMainElement.ts index 556c574..fe78527 100644 --- a/src/components/app-main/AppMainElement.ts +++ b/src/components/app-main/AppMainElement.ts @@ -129,7 +129,7 @@ class AppMainElement extends HTMLElement { checkSubscriptions = async () => { if (this.isAuth && !this.subscriptionChecked) { - const checked = await this.transactionsService.check(); + const checked = await this.transactionsService.check({ sortBy: 'transactionDate asc' }); this.createModal('transaction-check', { data: checked, }); diff --git a/src/pages/transaction-check/TransactionCheckElement.ts b/src/pages/transaction-check/TransactionCheckElement.ts index eb92d55..bed2ce3 100644 --- a/src/pages/transaction-check/TransactionCheckElement.ts +++ b/src/pages/transaction-check/TransactionCheckElement.ts @@ -1,6 +1,6 @@ import { TemplateResult, controller, target, html } from 'core/utils'; -import { TransactionsService } from 'services/'; -import { AppMainElement, AppPaginationElement } from 'components/'; +import { TransactionsService, TransactionStatusService } from 'services/'; +import { AppPaginationElement } from 'components/'; import { BasePageElement } from 'common/'; import { TransactionCheckElementTemplate } from 'pages/transaction-check'; import dayjs from 'dayjs'; @@ -8,6 +8,8 @@ import dayjs from 'dayjs'; @controller('transaction-check') class TransactionCheckElement extends BasePageElement { private transactionsService: TransactionsService; + private transactionStatusService: TransactionStatusService; + transactionStatuses: []; @target pagination: AppPaginationElement; modalData: any = null; constructor() { @@ -16,7 +18,9 @@ class TransactionCheckElement extends BasePageElement { }); } - elementConnected = (): void => { + elementConnected = async (): Promise => { + this.transactionStatusService = new TransactionStatusService(this.appMain?.appService); + await this.fetchTransactionStatus(); this.transactionsService = new TransactionsService(this.appMain?.appService); this.update(); this.pagination?.setCustomRenderItem?.(this.renderSubscription)!; @@ -32,39 +36,77 @@ class TransactionCheckElement extends BasePageElement { return data; }; - renderSubscription = (item) => html` - ${!item.isEdit - ? html`${dayjs(item.transactionDate).format("MMM DD 'YY")}` - : html``} - ${item.description} - - { + const renderEditActions = () => html``; + const renderRegularActions = () => html` - ${item?.transactionType?.type == 'expense' ? '- ' : ''} - ${Number(item.amount).toLocaleString('en-US', { - maximumFractionDigits: 2, - minimumFractionDigits: 2, - })} - - (${item.currency ? item.currency : 'USD'}) - - - - - `; + `; + return html` + ${!item.isEdit + ? html`${dayjs(item.transactionDate).format("MMM DD 'YY")}` + : html``} + ${item.description} + + + ${item?.transactionType?.type == 'expense' ? '- ' : ''} + ${Number(item.amount).toLocaleString('en-US', { + maximumFractionDigits: 2, + minimumFractionDigits: 2, + })} + + (${item.currency ? item.currency : 'USD'}) + + ${item.isEdit ? renderEditActions() : renderRegularActions()} + `; + }; + + fetchTransactionStatus = async () => { + this.transactionStatuses = await this.transactionStatusService.getAll(); + }; transactionEdit = (item) => { item.isEdit = !item.isEdit; this.pagination?.update(); }; + transactionEditSave = async (item) => { + const resource = { + transactionDate: dayjs(item.newTransactionDate || item.transactionDate) + .utc(true) + .format(), + }; + await this.updateTransaction(item.id, resource); + }; + + transactionEditComplete = async (item) => { + const completedStatusId = (this.transactionStatuses?.find((item: any) => item.status === 'completed') as any)?.id!; + if (completedStatusId) { + const resource = { + transactionStatusId: completedStatusId, + }; + await this.updateTransaction(item.id, resource); + } + }; + transactionUpdated = () => { this.pagination?.executeFetch(); }; @@ -72,11 +114,22 @@ class TransactionCheckElement extends BasePageElement { getTransactions = async (options): Promise => { try { options.embed = 'TransactionType'; - options.sortBy = 'dateCreated|desc'; + options.sortBy = 'transactionDate|asc'; const response = await this.transactionsService.check(options); + return this.mappedData(response); + } catch (err) { + throw err; + } + }; + + updateTransaction = async (id, resource): Promise => { + try { + const response = await this.transactionsService.put(id, resource); return response; } catch (err) { throw err; + } finally { + this.pagination?.defaultFetch(); } }; diff --git a/src/pages/transaction-check/TransactionCheckElementTemplate.ts b/src/pages/transaction-check/TransactionCheckElementTemplate.ts index ad9c3d1..b06fa27 100644 --- a/src/pages/transaction-check/TransactionCheckElementTemplate.ts +++ b/src/pages/transaction-check/TransactionCheckElementTemplate.ts @@ -1,16 +1,7 @@ import { html, nothing, TemplateResult } from 'core/utils'; export default (props): TemplateResult => { - const { walletId } = props; - const renderWallet = () => { - if (walletId) { - return html`${walletId}`; - } - return nothing; - }; - return html`
- ${renderWallet()}
`; }; diff --git a/src/services/TransactionStatusService.ts b/src/services/TransactionStatusService.ts new file mode 100644 index 0000000..0918cf2 --- /dev/null +++ b/src/services/TransactionStatusService.ts @@ -0,0 +1,9 @@ +import { AppService, BaseService } from 'core/services'; + +class TransactionStatusService extends BaseService { + constructor(appService: AppService) { + super('/transaction-status', appService); + } +} + +export default TransactionStatusService; diff --git a/src/services/index.ts b/src/services/index.ts index 31edfd1..61ba003 100644 --- a/src/services/index.ts +++ b/src/services/index.ts @@ -5,3 +5,4 @@ export { default as TransactionsService } from './TransactionsService'; export { default as TransactionTypeService } from './TransactionTypeService'; export { default as SubscriptionService } from './SubscriptionService'; export { default as SubscriptionTypeService } from './SubscriptionTypeService'; +export { default as TransactionStatusService } from './TransactionStatusService'; From 3970c01019741808a0bb2e5d13a961487a442ec1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fran=20Jurmanovi=C4=87?= Date: Sun, 12 Dec 2021 19:19:25 +0100 Subject: [PATCH 4/4] fixed transaction check layout --- .../pages/BasePageElement/BasePageElement.ts | 7 +- src/components/app-main/AppMainElement.ts | 3 +- src/pages/history-page/HistoryPageElement.ts | 6 + .../HistoryPageElementTemplate.ts | 14 +-- .../TransactionCheckElement.ts | 41 +++--- src/styles/app-pagination/app-pagination.scss | 3 + src/styles/core/main.scss | 118 ++++++++++-------- 7 files changed, 107 insertions(+), 85 deletions(-) diff --git a/src/common/pages/BasePageElement/BasePageElement.ts b/src/common/pages/BasePageElement/BasePageElement.ts index c13dedd..b1df69c 100644 --- a/src/common/pages/BasePageElement/BasePageElement.ts +++ b/src/common/pages/BasePageElement/BasePageElement.ts @@ -5,6 +5,7 @@ import { isTrue } from 'core/utils'; class BasePageElement extends BaseElement { public _pageTitle: string = ''; + public hideTitleHead: boolean = false; @attr hidetitle: string; @attr customtitle: string; private _data: any; @@ -13,6 +14,7 @@ class BasePageElement extends BaseElement { if (options?.title) { this._pageTitle = options?.title; } + this.hideTitleHead = options?.hideTitleHead || false; this.connectedCallback = this.connectedCallback.bind(this); this.disconnectedCallback = this.disconnectedCallback.bind(this); } @@ -36,7 +38,9 @@ class BasePageElement extends BaseElement { }; connectedCallback() { - this.appMain.setTitle(this.pageTitle); + if (!this.hideTitleHead) { + this.appMain.setTitle(this.pageTitle); + } super.connectedCallback(); } @@ -53,4 +57,5 @@ export default BasePageElement; export type OptionType = { title?: string; + hideTitleHead?: boolean; }; diff --git a/src/components/app-main/AppMainElement.ts b/src/components/app-main/AppMainElement.ts index fe78527..64b19d0 100644 --- a/src/components/app-main/AppMainElement.ts +++ b/src/components/app-main/AppMainElement.ts @@ -129,9 +129,10 @@ class AppMainElement extends HTMLElement { checkSubscriptions = async () => { if (this.isAuth && !this.subscriptionChecked) { - const checked = await this.transactionsService.check({ sortBy: 'transactionDate asc' }); + const checked = await this.transactionsService.check({ sortBy: 'transactionDate asc', rpp: 10 }); this.createModal('transaction-check', { data: checked, + autoInit: false, }); this.subscriptionChecked = true; this.removeEventListener('routechanged', this.checkSubscriptions); diff --git a/src/pages/history-page/HistoryPageElement.ts b/src/pages/history-page/HistoryPageElement.ts index e54913a..1890809 100644 --- a/src/pages/history-page/HistoryPageElement.ts +++ b/src/pages/history-page/HistoryPageElement.ts @@ -49,6 +49,12 @@ class HistoryPageElement extends BasePageElement { } }; + transactionCheck = () => { + this.appMain.createModal('transaction-check', { + autoInit: true, + }); + }; + render = (): TemplateResult => HistoryPageElementTemplate({ walletId: this.routerService?.routerState?.data?.walletId }); } diff --git a/src/pages/history-page/HistoryPageElementTemplate.ts b/src/pages/history-page/HistoryPageElementTemplate.ts index 17557d4..dedf3d8 100644 --- a/src/pages/history-page/HistoryPageElementTemplate.ts +++ b/src/pages/history-page/HistoryPageElementTemplate.ts @@ -1,16 +1,12 @@ import { html, nothing, TemplateResult } from 'core/utils'; export default (props): TemplateResult => { - const { walletId } = props; - const renderWallet = () => { - if (walletId) { - return html`${walletId}`; - } - return nothing; - }; - return html`
- ${renderWallet()} +
+ +
`; }; diff --git a/src/pages/transaction-check/TransactionCheckElement.ts b/src/pages/transaction-check/TransactionCheckElement.ts index bed2ce3..267ceac 100644 --- a/src/pages/transaction-check/TransactionCheckElement.ts +++ b/src/pages/transaction-check/TransactionCheckElement.ts @@ -15,6 +15,7 @@ class TransactionCheckElement extends BasePageElement { constructor() { super({ title: 'Transaction Check', + hideTitleHead: true, }); } @@ -23,10 +24,12 @@ class TransactionCheckElement extends BasePageElement { await this.fetchTransactionStatus(); this.transactionsService = new TransactionsService(this.appMain?.appService); this.update(); - this.pagination?.setCustomRenderItem?.(this.renderSubscription)!; - this.pagination?.setFetchFunc?.(this.getTransactions, false)!; this.modalData = this.getData(); - this.pagination?.executeFetch?.(null, () => this.mappedData(this.modalData.data)); + this.pagination?.setCustomRenderItem?.(this.renderSubscription)!; + this.pagination?.setFetchFunc?.(this.getTransactions, this.modalData?.autoInit)!; + if (!this.modalData?.autoInit) { + this.pagination?.executeFetch?.(null, () => this.mappedData(this.modalData.data)); + } }; mappedData = (data) => { @@ -37,22 +40,15 @@ class TransactionCheckElement extends BasePageElement { }; renderSubscription = (item) => { - const renderEditActions = () => html``; - const renderRegularActions = () => html` - `; - return html` + const renderEditActions = () => html`
+ + +
`; + const renderRegularActions = () => html`
+ + +
`; + return html` ${!item.isEdit ? html`${dayjs(item.transactionDate).format("MMM DD 'YY")}` : html` *:not(summary) { - display: none !important; - } - } - } + details { + summary { + cursor: pointer; + } + &:not([open]) { + > *:not(summary) { + display: none !important; + } + } + } - [hidden][hidden] { - display: none !important; - } + [hidden][hidden] { + display: none !important; + } +} + +.d { + &--flex { + display: flex; + > * { + flex: 1; + margin: 0 4px; + } + } }