From 93a17ac4a25fad13930e2dc84fe60f4f13a664d1 Mon Sep 17 00:00:00 2001 From: Alex Harding Date: Fri, 13 Sep 2024 15:16:09 -0400 Subject: [PATCH] adding the ability to run loadData after setFilter --- src/store/actions.js | 3 +- src/store/filters.js | 5 ++- src/store/state.js | 1 + src/store/subscriptions.js | 84 ++++++++++++++++++++++++++------------ 4 files changed, 65 insertions(+), 28 deletions(-) diff --git a/src/store/actions.js b/src/store/actions.js index 255bf0e..30111c7 100644 --- a/src/store/actions.js +++ b/src/store/actions.js @@ -8,8 +8,9 @@ export default function getActions(pageDefinition) { const actions = {}; const filters = pageDefinition.filters(); for (const filterKey in filters) { - const filterAction = async function (payload) { + const filterAction = async function (payload, triggerLoadData = true) { this[`${filterKey}Filter`] = payload; + this[`${filterKey}TriggerLoadData`] = triggerLoadData; }; const optionsAction = async function (payload) { this[`${filterKey}Options`] = payload; diff --git a/src/store/filters.js b/src/store/filters.js index a7273b4..6a68a70 100644 --- a/src/store/filters.js +++ b/src/store/filters.js @@ -243,11 +243,12 @@ export function getFilterActions() { * * @param {String} key a filter key * @param {any} payload a payload to set + * @param {Boolean} triggerLoadData=true optional variable, if true will trigger a loadData action * @memberof module:pageStore */ - setFilter(key, payload) { + setFilter(key, payload, triggerLoadData = true) { this._validFilterKey(key); - this[`set${capitalize(key)}Filter`](payload); + this[`set${capitalize(key)}Filter`](payload, triggerLoadData); }, /** diff --git a/src/store/state.js b/src/store/state.js index 3821a29..68a84ed 100644 --- a/src/store/state.js +++ b/src/store/state.js @@ -18,6 +18,7 @@ export default function getState(pageDefinition) { filters[filterKey].options, ); state[`${filterKey}Options`] = filters[filterKey].options || []; + state[`${filterKey}TriggerLoadData`] = true; } // add chart data container for each chart type diff --git a/src/store/subscriptions.js b/src/store/subscriptions.js index 4c8ad43..096ba0c 100644 --- a/src/store/subscriptions.js +++ b/src/store/subscriptions.js @@ -1,50 +1,84 @@ import { capitalize } from "./utils.js"; export default function subscribeActions(store, pageDefinition) { - store.$onAction(({ name, store, args, after }) => { + store.$onAction(async ({ name, store, args, after }) => { //before action is called - runSubscriptions(name, args, store, pageDefinition, "before"); - after(() => { - runSubscriptions(name, args, store, pageDefinition, "after"); + after(async () => { + await runSubscriptions(name, args, store, pageDefinition, "after"); + await checkForLoadData(name, store); }); + + await runSubscriptions(name, args, store, pageDefinition, "before"); }); } -function runSubscriptions(name, args, store, pageDefinition, hook) { +async function runSubscriptions(name, args, store, pageDefinition, hook) { // for loadData actions, both toggle the dataLoading state variable // and also check for before/after loadData hooks if (name === "loadData") { store.toggleDataLoading(); if (pageDefinition[`${hook}LoadData`]) { - pageDefinition[`${hook}LoadData`]({ name, args }, store); + await pageDefinition[`${hook}LoadData`]({ name, args }, store); } } else if (name.includes("Filter") && name !== "setFilter") { // iterate over filters to find if any match the action name // and run their before/after hooks - Object.keys(store.getFilters).forEach((filterKey) => { - const filterActionString = `set${capitalize(filterKey)}Filter`; - if ( - name === filterActionString && - store.getFilters[filterKey][`${hook}Set`] - ) { - store.getFilters[filterKey][`${hook}Set`]({ name, args }, store); - } - }); + await Promise.all( + Object.keys(store.getFilters).map(async (filterKey) => { + const filterActionString = `set${capitalize(filterKey)}Filter`; + if ( + name === filterActionString && + store.getFilters[filterKey][`${hook}Set`] + ) { + await store.getFilters[filterKey][`${hook}Set`]( + { name, args }, + store, + ); + } + }), + ); } else if (name.includes("ChartData") && name !== "setChartData") { - // iterate over hcarts to find if any match the action name + // iterate over charts to find if any match the action name // and run their before/after hooks - Object.keys(store.getCharts).forEach((chartKey) => { - const chartActionString = `set${capitalize(chartKey)}ChartData`; - if ( - name === chartActionString && - store.getCharts[chartKey][`${hook}Set`] - ) { - store.getCharts[chartKey][`${hook}Set`]({ name, args }, store); - } - }); + await Promise.all( + Object.keys(store.getCharts).map(async (chartKey) => { + const chartActionString = `set${capitalize(chartKey)}ChartData`; + if ( + name === chartActionString && + store.getCharts[chartKey][`${hook}Set`] + ) { + await store.getCharts[chartKey][`${hook}Set`]({ name, args }, store); + } + }), + ); } if (pageDefinition.extendSubscriptions) { pageDefinition.extendSubscriptions(name, args, store, pageDefinition, hook); } + return Promise.resolve(); +} + +// checks to see if the action is a filter action and if so, checks if the filter is synchronous +// if not, it will trigger a loadData action +async function checkForLoadData(name, store) { + if (name.includes("Filter") && name !== "setFilter") { + // get filter name from action + const filterName = name.slice(3, -6); + // find the matching filter key and retrieve definition + const filterKey = store.getFilterKeys.find( + (filter) => capitalize(filter) === filterName, + ); + const filterObj = store.getFilterDefinition(filterKey); + + if ( + store[`${filterKey}TriggerLoadData`] && + !( + Object.hasOwn(filterObj, "triggerLoadData") && + filterObj.triggerLoadData == false + ) + ) { + await store.loadData(); + } + } }