diff --git a/js/sources/coa_source.js b/js/sources/coa_source.js index bf1d8d0f..3a949a1b 100644 --- a/js/sources/coa_source.js +++ b/js/sources/coa_source.js @@ -7,9 +7,9 @@ import EditionActions from '../actions/edition_actions'; const CoaSource = { lookupCoa: { - remote(state) { + remote(state, coaId) { return requests - .get('coa', { id: state.edition.coa }) + .get('coa', { id: coaId }) .then((res) => { // If no coa is found here, fake a 404 error so the error action can pick it up return (res && res.coa) ? res : Promise.reject({ json: { status: 404 } }); @@ -20,10 +20,11 @@ const CoaSource = { error: EditionActions.errorCoa }, - performCreateCoa: { - remote(state) { - return requests.post('coa_create', {body: { bitcoin_id: state.edition.bitcoin_id }}); + performCreateCoaForEdition: { + remote(state, editionId) { + return requests.post('coa_create', { body: { bitcoin_id: editionId } }); }, + success: EditionActions.successFetchCoa, error: EditionActions.errorCoa } diff --git a/js/sources/edition_source.js b/js/sources/edition_source.js index 3e48d257..dd295352 100644 --- a/js/sources/edition_source.js +++ b/js/sources/edition_source.js @@ -7,8 +7,8 @@ import EditionActions from '../actions/edition_actions'; const EditionSource = { lookupEdition: { - remote(state) { - return requests.get('edition', { bitcoin_id: state.editionMeta.idToFetch }); + remote(state, editionId) { + return requests.get('edition', { bitcoin_id: editionId }); }, success: EditionActions.successFetchEdition, @@ -16,4 +16,4 @@ const EditionSource = { } }; -export default EditionSource; \ No newline at end of file +export default EditionSource; diff --git a/js/sources/user_source.js b/js/sources/user_source.js index 872b060b..04e36fb9 100644 --- a/js/sources/user_source.js +++ b/js/sources/user_source.js @@ -13,12 +13,14 @@ const UserSource = { }, local(state) { - return state.currentUser && state.currentUser.email ? state : {}; + return !Object.keys(state.currentUser).length ? state : {}; }, + success: UserActions.successFetchCurrentUser, error: UserActions.errorCurrentUser, - shouldFetch(state) { - return state.userMeta.invalidateCache || state.currentUser && !state.currentUser.email; + + shouldFetch(state, invalidateCache) { + return invalidateCache || !Object.keys(state.currentUser).length; } }, @@ -26,9 +28,10 @@ const UserSource = { remote() { return requests.get(ApiUrls.users_logout); }, + success: UserActions.successLogoutCurrentUser, error: UserActions.errorCurrentUser } }; -export default UserSource; \ No newline at end of file +export default UserSource; diff --git a/js/sources/webhook_source.js b/js/sources/webhook_source.js index 5351c89c..7174d74a 100644 --- a/js/sources/webhook_source.js +++ b/js/sources/webhook_source.js @@ -10,13 +10,16 @@ const WebhookSource = { remote() { return requests.get('webhooks'); }, + local(state) { - return state.webhooks && !Object.keys(state.webhooks).length ? state : {}; + return !Object.keys(state.webhooks).length ? state : {}; }, + success: WebhookActions.successFetchWebhooks, error: WebhookActions.errorWebhooks, - shouldFetch(state) { - return state.webhookMeta.invalidateCache || state.webhooks && !Object.keys(state.webhooks).length; + + shouldFetch(state, invalidateCache) { + return invalidateCache || !Object.keys(state.webhooks).length; } }, @@ -24,23 +27,27 @@ const WebhookSource = { remote() { return requests.get('webhooks_events'); }, + local(state) { - return state.webhookEvents && !Object.keys(state.webhookEvents).length ? state : {}; + return !Object.keys(state.webhookEvents).length ? state : {}; }, + success: WebhookActions.successFetchWebhookEvents, error: WebhookActions.errorWebhookEvents, - shouldFetch(state) { - return state.webhookEventsMeta.invalidateCache || state.webhookEvents && !Object.keys(state.webhookEvents).length; + + shouldFetch(state, invalidateCache) { + return invalidateCache || !Object.keys(state.webhookEvents).length; } }, performRemoveWebhook: { - remote(state) { - return requests.delete('webhook', {'webhook_id': state.webhookMeta.idToDelete }); + remote(state, webhookId) { + return requests.delete('webhook', { 'webhook_id': webhookId }); }, + success: WebhookActions.successRemoveWebhook, error: WebhookActions.errorWebhooks } }; -export default WebhookSource; \ No newline at end of file +export default WebhookSource; diff --git a/js/sources/whitelabel_source.js b/js/sources/whitelabel_source.js index 07bea746..3d5770ad 100644 --- a/js/sources/whitelabel_source.js +++ b/js/sources/whitelabel_source.js @@ -9,17 +9,20 @@ import { getSubdomain } from '../utils/general_utils'; const WhitelabelSource = { lookupWhitelabel: { remote() { - return requests.get('whitelabel_settings', {'subdomain': getSubdomain()}); + return requests.get('whitelabel_settings', { 'subdomain': getSubdomain() }); }, + local(state) { - return Object.keys(state.whitelabel).length > 0 ? state : {}; + return Object.keys(state.whitelabel).length ? state : {}; }, + success: WhitelabelActions.successFetchWhitelabel, error: WhitelabelActions.errorWhitelabel, - shouldFetch(state) { - return state.whitelabelMeta.invalidateCache || Object.keys(state.whitelabel).length === 0; + + shouldFetch(state, invalidateCache) { + return invalidateCache || !Object.keys(state.whitelabel).length; } } }; -export default WhitelabelSource; \ No newline at end of file +export default WhitelabelSource; diff --git a/js/stores/edition_store.js b/js/stores/edition_store.js index 3bf01a90..eb138fae 100644 --- a/js/stores/edition_store.js +++ b/js/stores/edition_store.js @@ -14,8 +14,7 @@ class EditionStore { constructor() { this.edition = {}; this.editionMeta = { - err: null, - idToFetch: null + err: null }; this.coaMeta = { err: null @@ -25,26 +24,27 @@ class EditionStore { this.registerAsync(mergeOptions(EditionSource, CoaSource)); } - onFetchEdition(idToFetch) { - this.editionMeta.idToFetch = idToFetch; + onFetchEdition(editionId) { + this.getInstance().lookupEdition(editionId); - this.getInstance().lookupEdition(); } onSuccessFetchEdition({ edition }) { if (edition) { this.edition = edition; this.editionMeta.err = null; - this.editionMeta.idToFetch = null; - if (this.edition.coa && this.edition.acl.acl_coa && - typeof this.edition.coa.constructor !== Object) { - this.getInstance().lookupCoa(); - } else if (!this.edition.coa && this.edition.acl.acl_coa) { - this.getInstance().performCreateCoa(); + // Also fetch coa if allowed + if (edition.acl.acl_coa) { + if (edition.coa && typeof edition.coa.constructor !== Object) { + this.getInstance().lookupCoa(edition.coa); + } else if (!edition.coa) { + this.getInstance().performCreateCoaForEdition(edition.bitcoin_id); + } } } else { this.editionMeta.err = new Error('Problem fetching the edition'); + console.logGlobal(this.editionMeta.err); } } @@ -54,6 +54,7 @@ class EditionStore { this.coaMeta.err = null; } else { this.coaMeta.err = new Error('Problem generating/fetching the COA'); + console.logGlobal(this.coaMeta.err); } } @@ -69,14 +70,16 @@ class EditionStore { } onErrorEdition(err) { + console.logGlobal(err); this.editionMeta.err = err; } onErrorCoa(err) { // On 404s, create a new COA as the COA has not been made yet if (err && err.json && err.json.status === 404) { - this.getInstance().performCreateCoa(); + this.getInstance().performCreateCoaForEdition(this.edition.bitcoin_id); } else { + console.logGlobal(err); this.coaMeta.err = err; } } diff --git a/js/stores/user_store.js b/js/stores/user_store.js index 64b170dc..6fe6e0cf 100644 --- a/js/stores/user_store.js +++ b/js/stores/user_store.js @@ -1,6 +1,7 @@ 'use strict'; import { altUser } from '../alt'; + import UserActions from '../actions/user_actions'; import UserSource from '../sources/user_source'; @@ -10,7 +11,6 @@ class UserStore { constructor() { this.currentUser = {}; this.userMeta = { - invalidateCache: false, err: null }; @@ -19,15 +19,12 @@ class UserStore { } onFetchCurrentUser(invalidateCache) { - this.userMeta.invalidateCache = invalidateCache; - - if(!this.getInstance().isLoading()) { - this.getInstance().lookupCurrentUser(); + if (invalidateCache || !this.getInstance().isLoading()) { + this.getInstance().lookupCurrentUser(invalidateCache); } } - onSuccessFetchCurrentUser({users: [user = {}]}) { - this.userMeta.invalidateCache = false; + onSuccessFetchCurrentUser({ users: [ user = {} ] }) { this.userMeta.err = null; this.currentUser = user; } @@ -37,6 +34,7 @@ class UserStore { } onSuccessLogoutCurrentUser() { + this.userMeta.err = null; this.currentUser = {}; } diff --git a/js/stores/webhook_store.js b/js/stores/webhook_store.js index 942ff748..70fe185b 100644 --- a/js/stores/webhook_store.js +++ b/js/stores/webhook_store.js @@ -1,6 +1,7 @@ 'use strict'; import { alt } from '../alt'; + import WebhookActions from '../actions/webhook_actions'; import WebhookSource from '../sources/webhook_source'; @@ -10,12 +11,9 @@ class WebhookStore { this.webhooks = []; this.webhookEvents = []; this.webhookMeta = { - invalidateCache: false, - err: null, - idToDelete: null + err: null }; this.webhookEventsMeta = { - invalidateCache: false, err: null }; @@ -24,54 +22,46 @@ class WebhookStore { } onFetchWebhooks(invalidateCache) { - this.webhookMeta.invalidateCache = invalidateCache; - this.getInstance().lookupWebhooks(); + if (invalidateCache || !this.getInstance().isLoading()) { + this.getInstance().lookupWebhooks(invalidateCache); + } } onSuccessFetchWebhooks({ webhooks = [] }) { - this.webhookMeta.invalidateCache = false; this.webhookMeta.err = null; this.webhooks = webhooks; - this.webhookEventsMeta.invalidateCache = true; - this.getInstance().lookupWebhookEvents(); + this.onFetchWebhookEvents(true); } onFetchWebhookEvents(invalidateCache) { - this.webhookEventsMeta.invalidateCache = invalidateCache; - this.getInstance().lookupWebhookEvents(); + if (invalidateCache || !this.getInstance().isLoading()) { + this.getInstance().lookupWebhookEvents(invalidateCache); + } } onSuccessFetchWebhookEvents({ events }) { - this.webhookEventsMeta.invalidateCache = false; this.webhookEventsMeta.err = null; // remove all events that have already been used. const usedEvents = this.webhooks - .reduce((tempUsedEvents, webhook) => { - tempUsedEvents.push(webhook.event.split('.')[0]); - return tempUsedEvents; - }, []); + .reduce((tempUsedEvents, webhook) => { + tempUsedEvents.push(webhook.event.split('.')[0]); + return tempUsedEvents; + }, []); this.webhookEvents = events.filter((event) => { return usedEvents.indexOf(event) === -1; }); } - onRemoveWebhook(id) { - this.webhookMeta.invalidateCache = true; - this.webhookMeta.idToDelete = id; + onRemoveWebhook(webhookId) { + this.getInstance().performRemoveWebhook(webhookId); - if(!this.getInstance().isLoading()) { - this.getInstance().performRemoveWebhook(); - } } onSuccessRemoveWebhook() { - this.webhookMeta.idToDelete = null; - if(!this.getInstance().isLoading()) { - this.getInstance().lookupWebhooks(); - } + this.getInstance().lookupWebhooks(true); } onErrorWebhooks(err) { diff --git a/js/stores/whitelabel_store.js b/js/stores/whitelabel_store.js index b6cd0662..3f03228a 100644 --- a/js/stores/whitelabel_store.js +++ b/js/stores/whitelabel_store.js @@ -1,7 +1,9 @@ 'use strict'; import { altWhitelabel } from '../alt'; + import WhitelabelActions from '../actions/whitelabel_actions'; + import WhitelabelSource from '../sources/whitelabel_source'; @@ -9,7 +11,6 @@ class WhitelabelStore { constructor() { this.whitelabel = {}; this.whitelabelMeta = { - invalidateCache: false, err: null }; @@ -18,15 +19,12 @@ class WhitelabelStore { } onFetchWhitelabel(invalidateCache) { - this.whitelabelMeta.invalidateCache = invalidateCache; - - if(!this.getInstance().isLoading()) { - this.getInstance().lookupWhitelabel(); + if (invalidateCache || !this.getInstance().isLoading()) { + this.getInstance().lookupWhitelabel(invalidateCache); } } onSuccessFetchWhitelabel({ whitelabel = {} }) { - this.whitelabelMeta.invalidateCache = false; this.whitelabelMeta.err = null; this.whitelabel = whitelabel; } diff --git a/js/utils/store_utils.js b/js/utils/store_utils.js new file mode 100644 index 00000000..ef78619f --- /dev/null +++ b/js/utils/store_utils.js @@ -0,0 +1,10 @@ +'use strict' + +export function onChangeOnce(component, store) { + const onChange = (state) => { + component.setState(state); + store.unlisten(onChange); + }; + + store.listen(onChange); +}