From 77bbd87bcbc3a49b631011c9336f9d88d2d3daf7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mykhailo=20Delegan=20=E2=98=95=EF=B8=8F=F0=9F=87=BA?= =?UTF-8?q?=F0=9F=87=A6?= Date: Wed, 29 Apr 2026 17:37:27 -0700 Subject: [PATCH] feat: add progress dialog to Questrade single account sync - Show step-by-step progress dialog (balance, positions, orders, activity) for single account sync, matching the all-accounts sync experience - Mirrors Wealthsimple's uploadSingleAccountWithProgress pattern - Replace processAccountBalanceHistory with direct syncAccountToMonarch call - Add cancel support with summary display on completion/error --- README.md | 2 +- package.json | 2 +- src/scriptInfo.json | 2 +- src/ui/questrade/components/uploadButton.ts | 45 ++++++++++++++++++--- 4 files changed, 43 insertions(+), 8 deletions(-) diff --git a/README.md b/README.md index bb9df04..84dcb09 100644 --- a/README.md +++ b/README.md @@ -3,7 +3,7 @@ [![CI](https://github.com/meseer/monarch-uploader/actions/workflows/ci.yml/badge.svg)](https://github.com/meseer/monarch-uploader/actions/workflows/ci.yml) [![codecov](https://codecov.io/gh/meseer/monarch-uploader/branch/main/graph/badge.svg)](https://codecov.io/gh/meseer/monarch-uploader) -[![Version](https://img.shields.io/badge/version-6.11.2-blue)](https://github.com/meseer/monarch-uploader) +[![Version](https://img.shields.io/badge/version-6.12.0-blue)](https://github.com/meseer/monarch-uploader) [![License: CC BY-NC-SA 4.0](https://img.shields.io/badge/License-CC%20BY--NC--SA%204.0-lightgrey.svg)](https://creativecommons.org/licenses/by-nc-sa/4.0/) A userscript that automatically syncs balance history, transactions, holdings, and more from Canadian financial institutions to [Monarch Money](https://www.monarchmoney.com/). diff --git a/package.json b/package.json index 573d782..950424f 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "monarch-uploader", - "version": "6.11.2", + "version": "6.12.0", "description": "Violentmonkey userscript for uploading Questrade, Wealthsimple, Canada Life, and Rogers Bank data to Monarch Money", "main": "dist/monarch-uploader.user.js", "scripts": { diff --git a/src/scriptInfo.json b/src/scriptInfo.json index 4d49966..6eebbe1 100644 --- a/src/scriptInfo.json +++ b/src/scriptInfo.json @@ -1,4 +1,4 @@ { - "version": "6.11.2", + "version": "6.12.0", "gistUrl": "https://gist.github.com/meseer/f00fb552c96efeb3eb4e4e1fd520d4e7/raw/monarch-uploader.user.js" } diff --git a/src/ui/questrade/components/uploadButton.ts b/src/ui/questrade/components/uploadButton.ts index 12edb34..b4f86db 100644 --- a/src/ui/questrade/components/uploadButton.ts +++ b/src/ui/questrade/components/uploadButton.ts @@ -9,9 +9,9 @@ import { debugLog, calculateFromDateWithLookback, getTodayLocal, formatDate } fr import { STORAGE } from '../../../core/config'; import stateManager from '../../../core/state'; import toast from '../../toast'; -import { processAccountBalanceHistory } from '../../../services/questrade/account'; import { ensureMonarchAuthentication } from '../../components/monarchLoginLink'; -import { syncAllAccountsToMonarch } from '../../../services/questrade/sync'; +import { showProgressDialog } from '../../components/progressDialog'; +import syncService, { syncAllAccountsToMonarch } from '../../../services/questrade/sync'; import { uploadAllAccountsActivityToMonarch, uploadSingleAccountActivityToMonarch } from '../../../services/questrade/transactions'; import { getAccountCreationDate, @@ -156,6 +156,7 @@ function createButtonGroup(): HTMLDivElement { /** * Creates a single-account upload button that responds to state changes. + * Shows a progress dialog with step-by-step details (same as all-accounts sync). * Automatically determines the start date using the same logic as the all-accounts sync: * - Subsequent sync: last sync date minus lookback period * - First sync: account creation date @@ -180,21 +181,55 @@ function createSingleAccountUploadButton(fallbackAccountId: string, fallbackAcco ? currentState.currentAccount.nickname : fallbackAccountName; + let progressDialog: ReturnType | null = null; + try { // Automatically calculate dates (same logic as all-accounts sync) const fromDate = calculateSingleAccountStartDate(currentAccountId); const toDate = getTodayLocal(); - // Process upload directly without date picker - await processAccountBalanceHistory( + // Create progress dialog for single account (same as Wealthsimple pattern) + const accountsForDialog = [{ + key: currentAccountId, + nickname: currentAccountName, + name: currentAccountName, + }]; + progressDialog = showProgressDialog(accountsForDialog, `Syncing ${currentAccountName} to Monarch`); + + // Set up cancel callback + let isCancelled = false; + progressDialog.onCancel(() => { + debugLog('Single account sync cancellation requested'); + isCancelled = true; + toast.show('Sync cancelled by user', 'info'); + }); + + // Check for cancellation before sync + if (isCancelled) { + progressDialog.hideCancel(); + return; + } + + // Sync account with progress dialog (balance + positions + orders + activity) + await syncService.syncAccountToMonarch( currentAccountId, currentAccountName, fromDate, toDate, + progressDialog, ); + + // Show success summary + progressDialog.showSummary({ success: 1, failed: 0, skipped: 0 }); + progressDialog.hideCancel(); } catch (error) { - toast.show(`Error: ${(error as Error).message}`, 'error'); debugLog('Error in single account sync:', error); + toast.show(`Sync failed: ${(error as Error).message}`, 'error'); + + if (progressDialog) { + progressDialog.showSummary({ success: 0, failed: 1, skipped: 0 }); + progressDialog.hideCancel(); + } } });