Finish reimbursement loading and sync

This commit is contained in:
2020-10-30 15:04:24 +01:00
parent ec50e7deef
commit 7b1c3c813c
5 changed files with 61 additions and 40 deletions
@@ -2,6 +2,6 @@ import Component from '@glimmer/component';
import { sort } from '@ember/object/computed'; import { sort } from '@ember/object/computed';
export default class ReimbursementListComponent extends Component { export default class ReimbursementListComponent extends Component {
itemSorting = Object.freeze(['id:desc']); itemSorting = Object.freeze(['pendingStatus:asc', 'id:desc']);
@sort('args.items', 'itemSorting') itemsSorted; @sort('args.items', 'itemSorting') itemsSorted;
} }
+6 -1
View File
@@ -1,6 +1,7 @@
import EmberObject, { computed } from '@ember/object'; import EmberObject, { computed } from '@ember/object';
import { isPresent } from '@ember/utils';
import moment from 'moment'; import moment from 'moment';
import { notEmpty } from '@ember/object/computed';
import { isPresent } from '@ember/utils';
export default EmberObject.extend({ export default EmberObject.extend({
@@ -36,6 +37,10 @@ export default EmberObject.extend({
return isPresent(this.pendingTx); return isPresent(this.pendingTx);
}), }),
pendingStatus: computed('pendingTx', function() {
return isPresent(this.pendingTx) ? 'isPending' : 'notPending';
}),
serialize () { serialize () {
return JSON.stringify(this); return JSON.stringify(this);
} }
+14 -13
View File
@@ -10,24 +10,25 @@ export default class BudgetRoute extends Route {
async model () { async model () {
if (isPresent(this.kredits.reimbursements) && if (isPresent(this.kredits.reimbursements) &&
isEmpty(this.kredits.reimbursementsPending)) { 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; return;
}
const numCachedReimbursements = await this.browserCache.reimbursements.length();
if (numCachedReimbursements > 0) {
await this.kredits.loadObjectsFromCache('Reimbursement');
this.kredits.set('reimbursementsNeedSync', true);
} else { } 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() { afterModel() {
// TODO implement syncReimbursements if (this.kredits.reimbursementsNeedSync) {
// if (this.kredits.reimbursementsNeedSync) { schedule('afterRender', this.kredits.syncReimbursements,
// schedule('afterRender', this.kredits.syncReimbursements, this.kredits.syncReimbursements.perform);
// this.kredits.syncReimbursements.perform); }
// } schedule('afterRender', this.kredits.fetchMissingReimbursements,
this.kredits.fetchMissingReimbursements.perform);
} }
} }
+25 -10
View File
@@ -306,6 +306,7 @@ export default Service.extend({
syncContributors: task(function * () { syncContributors: task(function * () {
yield this.fetchContributors(); yield this.fetchContributors();
this.set('contributorsNeedSync', false);
}), }),
addContribution (attributes) { addContribution (attributes) {
@@ -372,6 +373,7 @@ export default Service.extend({
syncContributions: task(function * () { syncContributions: task(function * () {
yield this.fetchNewContributions.perform(); yield this.fetchNewContributions.perform();
yield this.syncUnconfirmedContributions.perform(); yield this.syncUnconfirmedContributions.perform();
this.set('contributionsNeedSync', false);
}).group('contributionTasks'), }).group('contributionTasks'),
fetchNewContributions: task(function * () { fetchNewContributions: task(function * () {
@@ -487,12 +489,15 @@ export default Service.extend({
const collection = objectClass.toLowerCase()+'s'; const collection = objectClass.toLowerCase()+'s';
return this.browserCache[collection].iterate((value/*, key , iterationNumber */) => { return this.browserCache[collection].iterate((value/*, key , iterationNumber */) => {
const obj = models[objectClass].create(JSON.parse(value)); const obj = models[objectClass].create(JSON.parse(value));
this.removeObjectFromCollectionIfLoaded(collection, obj.id)
this[collection].pushObject(obj); this[collection].pushObject(obj);
}).then((/* result */) => { }).then((/* result */) => {
console.debug(`[kredits] Loaded ${this[collection].length} ${collection} from cache`); console.debug(`[kredits] Loaded ${this[collection].length} ${collection} from cache`);
}); });
}, },
syncTaskGroup: taskGroup().enqueue(),
fetchNewObjects: task(function * (objectClass) { fetchNewObjects: task(function * (objectClass) {
const collection = objectClass.toLowerCase()+'s'; const collection = objectClass.toLowerCase()+'s';
const count = yield this.kredits[objectClass].functions[`${collection}Count`](); const count = yield this.kredits[objectClass].functions[`${collection}Count`]();
@@ -513,7 +518,7 @@ export default Service.extend({
fetchMissingObjects: task(function * (objectClass) { fetchMissingObjects: task(function * (objectClass) {
const collection = objectClass.toLowerCase()+'s'; 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()]; const allIds = [...Array(count+1).keys()];
allIds.shift(); // remove first item, which is 0 allIds.shift(); // remove first item, which is 0
const loadedObjects = new Set(this[collection].mapBy('id')); const loadedObjects = new Set(this[collection].mapBy('id'));
@@ -530,7 +535,7 @@ export default Service.extend({
continue; continue;
} else { } else {
const data = yield this.kredits[objectClass].getById(id); 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()); yield this.browserCache[collection].setItem(o.id.toString(), o.serialize());
countFetched++; countFetched++;
if (countFetched % 20 === 0) { if (countFetched % 20 === 0) {
@@ -539,13 +544,14 @@ export default Service.extend({
} }
} }
console.debug(`[kredits] Cached ${countFetched} past ${collection}`); console.debug(`[kredits] Cached ${countFetched} past ${collection}`);
}).group('syncTaskGroup'), }),
syncUnconfirmedObjects: task(function * (objectClass) { syncUnconfirmedObjects: task(function * (objectClass) {
const collection = objectClass.toLowerCase()+'s'; const collection = objectClass.toLowerCase()+'s';
if (this`${collection}Unconfirmed`.length > 0) { if (this.get(`${collection}Unconfirmed`).length > 0) {
console.debug(`[kredits] Syncing unconfirmed ${collection}`); console.debug(`[kredits] Syncing unconfirmed ${collection}`);
for (const o of this[`${collection}Unconfirmed`]) { for (const o of this[`${collection}Unconfirmed`]) {
if (isEmpty(o.id)) return;
const data = yield this.kredits[objectClass].getById(o.id); const data = yield this.kredits[objectClass].getById(o.id);
const object = this[`load${objectClass}FromData`](data); const object = this[`load${objectClass}FromData`](data);
yield this.browserCache[collection] 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 // Contract events
// //
@@ -681,17 +697,16 @@ export default Service.extend({
console.debug('[kredits] ReimbursementAdded event received', { id, addedByAccount, amount }); console.debug('[kredits] ReimbursementAdded event received', { id, addedByAccount, amount });
const pendingReimbursement = this.reimbursementsPending.find(r => { const pendingReimbursement = this.reimbursementsPending.find(r => {
return (this.currentUserAccounts.includes(addedByAccount)) && return r.amount.toString() === amount.toString();
(r.amount.toString() === amount.toString());
}); });
// debugger;
if (pendingReimbursement) { 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.reimbursements.removeObject(pendingReimbursement);
this.loadReimbursementFromData(data);
} }
const data = await this.kredits.Reimbursement.getById(id);
this.loadReimbursementFromData(data);
}, },
// //
+15 -15
View File
@@ -1,21 +1,21 @@
<main id="budget"> <main id="budget">
<div id="aside"> <div id="aside">
<section id="main-nav"> <!-- <section id="main&#45;nav"> -->
<header> <!-- <header> -->
<h2>Budget</h2> <!-- <h2>Budget</h2> -->
</header> <!-- </header> -->
<div class="content"> <!-- <div class="content"> -->
<ul> <!-- <ul> -->
<li> <!-- <li> -->
<LinkTo @route="budget.expenses">Expenses</LinkTo> <!-- <LinkTo @route="budget.expenses">Expenses</LinkTo> -->
</li> <!-- </li> -->
<li> <!-- <li> -->
<a href="#">Rewards</a> <!-- <a href="#">Rewards</a> -->
</li> <!-- </li> -->
</ul> <!-- </ul> -->
</div> <!-- </div> -->
</section> <!-- </section> -->
<section id="funds"> <section id="funds">
<header> <header>