Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

various fixes for ynab update #3145

Merged
merged 1 commit into from
Jun 12, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -114,7 +114,7 @@
"@babel/preset-env": "^7.20.2",
"@babel/preset-react": "^7.18.6",
"@types/chrome": "^0.0.202",
"@types/ember": "^4.0.2",
"@types/ember": "^4.0.3",
"@types/jest": "^29.2.3",
"@types/jquery": "^3.5.14",
"@types/react": "^17.0.11",
Expand Down
35 changes: 23 additions & 12 deletions src/extension/features/accounts/reconciled-text-color/index.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { Feature } from 'toolkit/extension/features/feature';
import { getEmberView } from 'toolkit/extension/utils/ember';
import { getEntityManager } from 'toolkit/extension/utils/ynab';

const TOOLKIT_RECONCILED_CLASS = 'tk-is-reconciled';
const YNAB_IS_CHECKED_CLASS = 'is-checked';
Expand All @@ -26,27 +26,38 @@ export class ReconciledTextColor extends Feature {
}

invoke() {
this.addToolkitEmberHook('register/grid-sub', 'didInsertElement', this.addClass);
this.addToolkitEmberHook('register/grid-row', 'didInsertElement', this.addClass);
const gridRows = document.querySelectorAll('.ynab-grid-body-row');
gridRows.forEach((row) => {
if (row.dataset && row.dataset.rowId) {
this.addClass(row);
}
});
}

this.addToolkitEmberHook('register/grid-sub', 'didUpdate', this.addClass);
this.addToolkitEmberHook('register/grid-row', 'didUpdate', this.addClass);
observe() {
if (document.querySelector('.ynab-grid-body') !== null) {
this.invoke();
}
}

destroy() {
$(`.${TOOLKIT_RECONCILED_CLASS}`).removeClass(TOOLKIT_RECONCILED_CLASS);
}

addClass(element) {
let content;
const emberView = getEmberView(element.id);
if (emberView) {
content = emberView.content;
const $element = $(element);

let transaction;
if (element.dataset && element.dataset.rowId) {
transaction = getEntityManager().getTransactionById(element.dataset.rowId);
}

if (!transaction) {
return;
}

const $element = $(element);
const isChecked = $element.hasClass(YNAB_IS_CHECKED_CLASS);
const isReconciled = content.cleared === ynab.constants.TransactionState.Reconciled;
const isReconciled = transaction.cleared === ynab.constants.TransactionState.Reconciled;

if (isChecked) {
$element.removeClass(TOOLKIT_RECONCILED_CLASS);
Expand All @@ -57,7 +68,7 @@ export class ReconciledTextColor extends Feature {
// I'm not sure how intensive it would be to go find the IDs of sub transactions in a
// split so rather than do that, just continue down the line of sub transactions after
// a split and update the classes accordingly
if (content.isSplit) {
if (transaction.isSplit) {
let $nextTransaction = $element.next();
while ($nextTransaction.hasClass(YNAB_GRID_BODY_SUB_CLASS)) {
if (isChecked) {
Expand Down
6 changes: 4 additions & 2 deletions src/extension/features/accounts/right-click-to-edit/index.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
import { Feature } from 'toolkit/extension/features/feature';
import { controllerLookup, containerLookup, serviceLookup } from 'toolkit/extension/utils/ember';
import { isCurrentRouteAccountsPage } from 'toolkit/extension/utils/ynab';
import { isCurrentRouteAccountsPage, ynabRequire } from 'toolkit/extension/utils/ynab';

const { next } = ynabRequire('@ember/runloop');

export class RightClickToEdit extends Feature {
isCurrentlyRunning = false;
Expand Down Expand Up @@ -62,7 +64,7 @@ export class RightClickToEdit extends Feature {

this.isCurrentlyRunning = true;

Ember.run.next(this, function () {
next(this, function () {
$('.ynab-grid').off('contextmenu', '.ynab-grid-body-row > div', this.displayContextMenu);
$('.ynab-grid').on('contextmenu', '.ynab-grid-body-row > div', this.displayContextMenu);

Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { Feature } from 'toolkit/extension/features/feature';
import { Ember } from 'toolkit/extension/utils/ember';

export class ScrollableEditMenu extends Feature {
injectCSS() {
Expand Down
6 changes: 4 additions & 2 deletions src/extension/features/accounts/spare-change/index.js
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
import { Feature } from 'toolkit/extension/features/feature';
import { isCurrentRouteAccountsPage } from 'toolkit/extension/utils/ynab';
import { isCurrentRouteAccountsPage, ynabRequire } from 'toolkit/extension/utils/ynab';
import { containerLookup } from 'toolkit/extension/utils/ember';
import { formatCurrency } from 'toolkit/extension/utils/currency';

const { once } = ynabRequire('@ember/runloop');

export class SpareChange extends Feature {
injectCSS() {
return require('./index.css');
Expand All @@ -25,7 +27,7 @@ export class SpareChange extends Feature {

calculateSpareChange() {
// Running this code straight away in the callback seems to break some YNAB features - schedule it to run later
Ember.run.once(this, () => {
once(this, () => {
const areChecked = containerLookup('service:accounts').areChecked;
if (!areChecked.length) {
$('#tk-spare-change').remove();
Expand Down
8 changes: 1 addition & 7 deletions src/extension/features/general/hide-help/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,7 @@ export class HideHelp extends Feature {
}

shouldInvoke() {
return (
$('#tk-hide-help').length === 0 &&
!!serviceLookup<YNABModalService>('modal')?.isModalOpen &&
!!document.querySelector('.ynab-new-settings-menu')
);
return true;
}

insertHideHelp(element: Element) {
Expand All @@ -43,8 +39,6 @@ export class HideHelp extends Feature {
}

observe(nodes: Set<string>) {
if (!this.shouldInvoke()) return;

if (nodes.has('modal-overlay active ynab-u ynab-new-settings-menu')) {
this.invoke();
}
Expand Down
5 changes: 4 additions & 1 deletion src/extension/listeners/observeListener.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
import { withToolkitError } from 'toolkit/core/common/errors/with-toolkit-error';
import { ynabRequire } from '../utils/ynab';

const { later } = ynabRequire('@ember/runloop');

const IGNORE_UPDATES = new Set([
// every time you hover a budget row, one of these nodes change which is _just a lot_.
Expand Down Expand Up @@ -105,7 +108,7 @@ export class ObserveListener {
this.features.forEach((feature) => {
const observe = feature.observe.bind(feature, this.changedNodes);
const wrapped = withToolkitError(observe, feature);
Ember.run.later(() => {
later(() => {
const startFeatureObserve = Date.now();

wrapped();
Expand Down
13 changes: 8 additions & 5 deletions src/extension/listeners/routeChangeListener.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
import { controllerLookup } from 'toolkit/extension/utils/ember';
import { withToolkitError } from 'toolkit/core/common/errors/with-toolkit-error';
import { getRouter } from 'toolkit/extension/utils/ember';
import { ynabRequire } from '../utils/ynab';

const { later, scheduleOnce } = ynabRequire('@ember/runloop');

export class RouteChangeListener {
constructor() {
Expand All @@ -13,7 +16,7 @@ export class RouteChangeListener {
routeChangeListener.features.forEach((feature) => {
const observe = feature.onRouteChanged.bind(feature, currentRoute);
const wrapped = withToolkitError(observe, feature);
Ember.run.later(wrapped, 0);
later(wrapped, 0);
});
}

Expand All @@ -23,17 +26,17 @@ export class RouteChangeListener {
routeChangeListener.features.forEach((feature) => {
const observe = feature.onBudgetChanged.bind(feature, currentRoute);
const wrapped = withToolkitError(observe, feature);
Ember.run.later(wrapped, 0);
later(wrapped, 0);
});
}

getRouter().addObserver('currentState', ({ location, targetState: { routerJsState } }) => {
if (routerJsState && routerJsState.params && routerJsState.params.index) {
if (location.location.href.includes(routerJsState.params.index.budgetVersionId)) {
Ember.run.scheduleOnce('afterRender', null, emitSameBudgetRouteChange);
scheduleOnce('afterRender', null, emitSameBudgetRouteChange);
} else {
Ember.run.scheduleOnce('afterRender', null, emitBudgetRouteChange);
Ember.run.scheduleOnce('afterRender', null, emitSameBudgetRouteChange);
scheduleOnce('afterRender', null, emitBudgetRouteChange);
scheduleOnce('afterRender', null, emitSameBudgetRouteChange);
}
}
});
Expand Down
3 changes: 3 additions & 0 deletions src/extension/utils/ember.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
export const Ember = window.requireModule<{ default: Ember }>('ember').default;
export const __ynabapp__ = Ember.Namespace.NAMESPACES[0];

export function getEmberView<T extends unknown>(viewId: string | undefined): T | undefined {
if (!viewId) {
return undefined;
Expand Down
9 changes: 6 additions & 3 deletions src/extension/utils/ynab.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
import { YNABModalService } from 'toolkit/types/ynab/services/YNABModalService';
import { controllerLookup, serviceLookup } from './ember';
import { controllerLookup, getRouter, serviceLookup } from './ember';

export function ynabRequire<T = any>(module: string): T {
return window.requireModule<T>(module);
}

export function getApplicationController() {
return controllerLookup<YNABApplicationController>('application');
Expand Down Expand Up @@ -65,7 +69,7 @@ export function getSelectedAccount() {
}

export function getCurrentRouteName() {
return getApplicationController()?.currentRouteName;
return getRouter()?.currentRouteName;
}

export function getAllBudgetMonthsViewModel() {
Expand Down Expand Up @@ -109,7 +113,6 @@ export function isCurrentMonthSelected() {

export function isYNABReady() {
return (
typeof Ember !== 'undefined' &&
typeof $ !== 'undefined' &&
!$('.ember-view.is-loading').length &&
typeof ynabToolKit !== 'undefined' &&
Expand Down
8 changes: 4 additions & 4 deletions src/extension/ynab-toolkit.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,14 +6,14 @@ import * as Collections from 'toolkit/extension/utils/collections';
import { isFeatureEnabled } from 'toolkit/extension/utils/feature';
import { getToolkitStorageKey, setToolkitStorageKey } from 'toolkit/extension/utils/toolkit';
import { logToolkitError, withToolkitError } from 'toolkit/core/common/errors/with-toolkit-error';
import { forEachRenderedComponent } from './utils/ember';
import { Ember, forEachRenderedComponent } from './utils/ember';
import { compareSemanticVersion } from './utils/helpers';
import { componentAppend } from './utils/react';
import { ToolkitReleaseModal } from 'toolkit/core/components/toolkit-release-modal';
import { Feature } from './features/feature';
import { InboundMessage, InboundMessageType, OutboundMessageType } from 'toolkit/core/messages';
import { ObserveListener, RouteChangeListener } from './listeners';
import { getUnclearedTransactions } from './features/accounts/reconcile-assistant/reconcileAssistantUtils';
const { later } = ynabUtils.ynabRequire('@ember/runloop');

export let observeListener: ObserveListener;
export let routeChangeListener: RouteChangeListener;
Expand Down Expand Up @@ -305,9 +305,9 @@ export class YNABToolkit {
// Hook up listeners and then invoke any features that are ready to go.
self.invokeFeatureInstances();

Ember.run.later(self.invokeAllHooks, 100);
later(self.invokeAllHooks, 100);
} else if (typeof Ember !== 'undefined') {
Ember.run.later(poll, 250);
later(poll, 250);
} else {
setTimeout(poll, 250);
}
Expand Down
3 changes: 1 addition & 2 deletions src/types/window.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,14 @@ import { YNABApp, YNABGlobal } from './ynab/window';
import { YNABToolkitObject } from './toolkit';

declare global {
const Ember: Ember;
const ynab: YNABGlobal;
const ynabToolKit: YNABToolkitObject;
const YNABFEATURES: any;
const __ynabapp__: YNABApp;
const __toolkitUtils: unknown;

interface Window {
__toolkitUtils: unknown;
ynabToolKit: YNABToolkitObject;
requireModule<T>(moduleName: string): T;
}
}
4 changes: 3 additions & 1 deletion src/types/ynab/controllers/YNABRouter.d.ts
Original file line number Diff line number Diff line change
@@ -1 +1,3 @@
interface YNABRouter {}
interface YNABRouter {
currentRouteName: string;
}
4 changes: 4 additions & 0 deletions src/types/ynab/ember/index.d.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import Component from '@ember/component';
import { run } from '@ember/runloop';
import { Feature } from 'toolkit/extension/features/feature';
import { YNABApp } from '../window';

declare global {
interface ToolkitEmberHook {
Expand Down Expand Up @@ -35,5 +36,8 @@ declare global {
interface Ember {
run: typeof run;
Component: EmberComponent;
Namespace: {
NAMESPACES: [YNABApp];
};
}
}
1 change: 1 addition & 0 deletions src/types/ynab/window/ynab-entity-manager/index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import { YNABTransactionCollection } from '../../data/transaction-collection';

interface YNABEntityManager {
getAccountById(entityId: string): YNABAccount;
getTransactionById(transactionId: string): YNABTransaction;
getSubTransactionsBySubCategoryId(subCategoryId: string): YNABTransaction[];
getTransactionsBySubCategoryId(subCategoryId: string): YNABTransaction[];
transactionsCollection: YNABTransactionCollection;
Expand Down