diff --git a/.changeset/happy-ties-rule.md b/.changeset/happy-ties-rule.md new file mode 100644 index 000000000..45b007a08 --- /dev/null +++ b/.changeset/happy-ties-rule.md @@ -0,0 +1,5 @@ +--- +"druxt-menu": minor +--- + +feat(#684): added druxtMenu/flushEntities Vuex mutation. diff --git a/packages/menu/src/components/DruxtMenu.vue b/packages/menu/src/components/DruxtMenu.vue index fce0aa976..4aaecb12a 100644 --- a/packages/menu/src/components/DruxtMenu.vue +++ b/packages/menu/src/components/DruxtMenu.vue @@ -222,6 +222,7 @@ export default { mounted() { // If logged in and statically generated, re-fetch the menu. if (this?.$auth?.loggedIn && this?.$store?.app?.context?.isStatic) { + this.$store.commit('druxtMenu/flushEntities', { prefix: this.lang }) const settings = this.$options.druxt.settings(this, this.component.settings) this.$options.druxt.fetchData.call(this, settings) } diff --git a/packages/menu/src/stores/menu.js b/packages/menu/src/stores/menu.js index 24c0f99e6..b83dfaeb8 100644 --- a/packages/menu/src/stores/menu.js +++ b/packages/menu/src/stores/menu.js @@ -49,7 +49,21 @@ const DruxtMenuStore = ({ store }) => { const entity = entities[index] Vue.set(state.entities[prefix], entity.id, entity) } - } + }, + + /** + * @name flushEntities + * @mutator {object} flushEntities=entities Removes JSON:API menu item entities from the Vuex state object. + * @param {flushEntitiesContext} context + * + * @example @lang js + * // Flush all menu entities. + * this.$store.commit('druxt/flushCollection', {}) + */ + flushEntities (state, { prefix }) { + if (!prefix || typeof state.entities !== 'object') Vue.set(state, 'entities', {}) + if (prefix) Vue.set(state.entities, prefix, {}) + }, }, /** @@ -120,3 +134,16 @@ export { DruxtMenuStore } * @typedef {object} State * @property {object} entities - The Drupal JSON:API Menu Item entities. */ + +/** + * Parameters for the `flushEntities` mutation. + * + * @typedef {object} flushEntitiesContext + * + * @param {string} [prefix] - (Optional) The JSON:API endpoint prefix or langcode. + * + * @example @lang js + * { + * prefix: 'en' + * } + */ diff --git a/packages/menu/test/stores/menu.test.js b/packages/menu/test/stores/menu.test.js index fa47e805f..79847b3ba 100644 --- a/packages/menu/test/stores/menu.test.js +++ b/packages/menu/test/stores/menu.test.js @@ -33,4 +33,22 @@ describe('DruxtStore', () => { expect(store.$druxtMenu.get).toHaveBeenCalledWith('main', { test: true }, undefined) store.dispatch('druxtMenu/get', 'name') }) + + test('AddEntities', async () => { + expect(store.state.druxtMenu.entities).toStrictEqual({}) + store.commit('druxtMenu/addEntities', { entities: [{ id: 'test' }] }) + expect(Object.entries(store.state.druxtMenu.entities[undefined]).length).toBe(1) + expect(store.state.druxtMenu.entities[undefined].test).toStrictEqual({ id: 'test' }) + }) + + test('flushEntities', async () => { + expect(store.state.druxtMenu.entities).toStrictEqual({}) + store.commit('druxtMenu/addEntities', { entities: [{ id: 'test' }] }) + store.commit('druxtMenu/addEntities', { entities: [{ id: 'test2' }], prefix: 'es' }) + expect(Object.entries(store.state.druxtMenu.entities[undefined]).length).toBe(1) + store.commit('druxtMenu/flushEntities', { prefix: 'undefined' }) + expect(Object.entries(store.state.druxtMenu.entities[undefined]).length).toBe(0) + store.commit('druxtMenu/flushEntities', {}) + expect(Object.entries(store.state.druxtMenu.entities).length).toBe(0) + }) })