diff --git a/app/components/reimbursement-list/component.js b/app/components/reimbursement-list/component.js index 6f2b5cb..75a5770 100644 --- a/app/components/reimbursement-list/component.js +++ b/app/components/reimbursement-list/component.js @@ -2,6 +2,6 @@ import Component from '@glimmer/component'; import { sort } from '@ember/object/computed'; export default class ReimbursementListComponent extends Component { - itemSorting = Object.freeze(['id:desc']); + itemSorting = Object.freeze(['pendingStatus:asc', 'id:desc']); @sort('args.items', 'itemSorting') itemsSorted; } diff --git a/app/models/reimbursement.js b/app/models/reimbursement.js index 13559a7..0e4c6dd 100644 --- a/app/models/reimbursement.js +++ b/app/models/reimbursement.js @@ -1,6 +1,7 @@ import EmberObject, { computed } from '@ember/object'; -import { isPresent } from '@ember/utils'; import moment from 'moment'; +import { notEmpty } from '@ember/object/computed'; +import { isPresent } from '@ember/utils'; export default EmberObject.extend({ @@ -36,6 +37,10 @@ export default EmberObject.extend({ return isPresent(this.pendingTx); }), + pendingStatus: computed('pendingTx', function() { + return isPresent(this.pendingTx) ? 'isPending' : 'notPending'; + }), + serialize () { return JSON.stringify(this); } diff --git a/app/routes/budget.js b/app/routes/budget.js index 18901a9..c3d2f39 100644 --- a/app/routes/budget.js +++ b/app/routes/budget.js @@ -10,24 +10,25 @@ export default class BudgetRoute extends Route { async model () { if (isPresent(this.kredits.reimbursements) && isEmpty(this.kredits.reimbursementsPending)) { - // reimbursements loaded before, no need to sync or load + console.debug('[route:budget] Reimbursements loaded before, no need to sync or load'); return; - } - - const numCachedReimbursements = await this.browserCache.reimbursements.length(); - if (numCachedReimbursements > 0) { - await this.kredits.loadObjectsFromCache('Reimbursement'); - this.kredits.set('reimbursementsNeedSync', true); } else { - await this.kredits.fetchObjects('Reimbursement', { page: { size: 10 } }); + const numCachedReimbursements = await this.browserCache.reimbursements.length(); + if (numCachedReimbursements > 0) { + await this.kredits.loadObjectsFromCache('Reimbursement'); + this.kredits.set('reimbursementsNeedSync', true); + } else { + await this.kredits.fetchObjects('Reimbursement', { page: { size: 10 } }); + } } } afterModel() { - // TODO implement syncReimbursements - // if (this.kredits.reimbursementsNeedSync) { - // schedule('afterRender', this.kredits.syncReimbursements, - // this.kredits.syncReimbursements.perform); - // } + if (this.kredits.reimbursementsNeedSync) { + schedule('afterRender', this.kredits.syncReimbursements, + this.kredits.syncReimbursements.perform); + } + schedule('afterRender', this.kredits.fetchMissingReimbursements, + this.kredits.fetchMissingReimbursements.perform); } } diff --git a/app/services/kredits.js b/app/services/kredits.js index ad12386..27faa93 100644 --- a/app/services/kredits.js +++ b/app/services/kredits.js @@ -306,6 +306,7 @@ export default Service.extend({ syncContributors: task(function * () { yield this.fetchContributors(); + this.set('contributorsNeedSync', false); }), addContribution (attributes) { @@ -372,6 +373,7 @@ export default Service.extend({ syncContributions: task(function * () { yield this.fetchNewContributions.perform(); yield this.syncUnconfirmedContributions.perform(); + this.set('contributionsNeedSync', false); }).group('contributionTasks'), fetchNewContributions: task(function * () { @@ -487,12 +489,15 @@ export default Service.extend({ const collection = objectClass.toLowerCase()+'s'; return this.browserCache[collection].iterate((value/*, key , iterationNumber */) => { const obj = models[objectClass].create(JSON.parse(value)); + this.removeObjectFromCollectionIfLoaded(collection, obj.id) this[collection].pushObject(obj); }).then((/* result */) => { console.debug(`[kredits] Loaded ${this[collection].length} ${collection} from cache`); }); }, + syncTaskGroup: taskGroup().enqueue(), + fetchNewObjects: task(function * (objectClass) { const collection = objectClass.toLowerCase()+'s'; const count = yield this.kredits[objectClass].functions[`${collection}Count`](); @@ -513,7 +518,7 @@ export default Service.extend({ fetchMissingObjects: task(function * (objectClass) { const collection = objectClass.toLowerCase()+'s'; - const count = yield this.kredits[objectClass].count(); + const count = yield this.kredits[objectClass].functions[`${collection}Count`](); const allIds = [...Array(count+1).keys()]; allIds.shift(); // remove first item, which is 0 const loadedObjects = new Set(this[collection].mapBy('id')); @@ -530,7 +535,7 @@ export default Service.extend({ continue; } else { const data = yield this.kredits[objectClass].getById(id); - const o = this[`load${objectClass}fromData`](data); + const o = this[`load${objectClass}FromData`](data); yield this.browserCache[collection].setItem(o.id.toString(), o.serialize()); countFetched++; if (countFetched % 20 === 0) { @@ -539,13 +544,14 @@ export default Service.extend({ } } console.debug(`[kredits] Cached ${countFetched} past ${collection}`); - }).group('syncTaskGroup'), + }), syncUnconfirmedObjects: task(function * (objectClass) { const collection = objectClass.toLowerCase()+'s'; - if (this`${collection}Unconfirmed`.length > 0) { + if (this.get(`${collection}Unconfirmed`).length > 0) { console.debug(`[kredits] Syncing unconfirmed ${collection}`); for (const o of this[`${collection}Unconfirmed`]) { + if (isEmpty(o.id)) return; const data = yield this.kredits[objectClass].getById(o.id); const object = this[`load${objectClass}FromData`](data); yield this.browserCache[collection] @@ -607,6 +613,16 @@ export default Service.extend({ }); }, + syncReimbursements: task(function * () { + yield this.fetchNewObjects.perform('Reimbursement'); + yield this.syncUnconfirmedObjects.perform('Reimbursement'); + this.set('reimbursementsNeedSync', false); + }).group('syncTaskGroup'), + + fetchMissingReimbursements: task(function * () { + yield this.fetchMissingObjects.perform('Reimbursement'); + }).group('syncTaskGroup'), + // // Contract events // @@ -681,17 +697,16 @@ export default Service.extend({ console.debug('[kredits] ReimbursementAdded event received', { id, addedByAccount, amount }); const pendingReimbursement = this.reimbursementsPending.find(r => { - return (this.currentUserAccounts.includes(addedByAccount)) && - (r.amount.toString() === amount.toString()); + return r.amount.toString() === amount.toString(); }); - // debugger; - if (pendingReimbursement) { - const data = await this.kredits.Reimbursement.getById(id); + console.debug('[kredits] Found a pending reimbursement matching the event. Replacing it with the final record...'); this.reimbursements.removeObject(pendingReimbursement); - this.loadReimbursementFromData(data); } + + const data = await this.kredits.Reimbursement.getById(id); + this.loadReimbursementFromData(data); }, // diff --git a/app/templates/budget.hbs b/app/templates/budget.hbs index fcac21c..36aa961 100644 --- a/app/templates/budget.hbs +++ b/app/templates/budget.hbs @@ -1,21 +1,21 @@
- + + + + + + + + + + + + + + +