From 61fc30b95c5089cc59f1a9b076b030dd5573c58e Mon Sep 17 00:00:00 2001 From: JhumanJ Date: Tue, 27 May 2025 17:44:51 +0200 Subject: [PATCH] Enhance Pinia History Plugin with State Filtering and Configuration Options - Added an `ignoreKeys` option in the `mergeOptions` function of `pinia-history.js` to specify keys that should be excluded from history tracking, improving the plugin's flexibility. - Introduced a new `filterState` function to filter out ignored keys from the state object, ensuring that only relevant state changes are tracked. - Updated the history management logic to utilize the filtered state, enhancing the accuracy of undo/redo functionality. - Modified the `working_form.js` store to include default ignored keys for history tracking, streamlining the configuration process. These changes aim to improve the usability and performance of the Pinia history plugin by allowing developers to customize which state properties are tracked, thereby reducing unnecessary history entries. --- client/plugins/pinia-history.js | 42 +++++++++++++++++++++++++++------ client/stores/working_form.js | 4 +++- 2 files changed, 38 insertions(+), 8 deletions(-) diff --git a/client/plugins/pinia-history.js b/client/plugins/pinia-history.js index 1940dc52..a410b14e 100644 --- a/client/plugins/pinia-history.js +++ b/client/plugins/pinia-history.js @@ -25,7 +25,8 @@ function mergeOptions(options) { } } }, - debounceWait: 300 + debounceWait: 300, + ignoreKeys: [] // Keys to ignore in history tracking } return { @@ -34,6 +35,25 @@ function mergeOptions(options) { } } +/** + * Filters out ignored keys from the state object + * @param {Object} state - The state object to filter + * @param {Array} ignoreKeys - Array of keys to ignore + * @returns {Object} Filtered state object + */ +function filterState(state, ignoreKeys) { + if (!ignoreKeys || ignoreKeys.length === 0) { + return state + } + + const filteredState = { ...state } + ignoreKeys.forEach(key => { + delete filteredState[key] + }) + + return filteredState +} + /** * Adds undo/redo functionality to a Pinia store. * @param {PiniaPluginContext} context - The context provided by Pinia. @@ -46,7 +66,7 @@ const PiniaHistory = (context) => { return } const mergedOptions = mergeOptions(history) - const {max, persistent, persistentStrategy} = mergedOptions + const {max, persistent, persistentStrategy, ignoreKeys} = mergedOptions const $history = reactive({ max, @@ -54,19 +74,23 @@ const PiniaHistory = (context) => { persistentStrategy, done: [], undone: [], - current: JSON.stringify(store.$state), + current: JSON.stringify(filterState(store.$state, ignoreKeys)), trigger: true, }) const debouncedStoreUpdate = debounce((state) => { - if (hash($history.current) === hash(JSON.stringify(state))) { // Not a real change here + const filteredState = filterState(state, ignoreKeys) + const currentStateHash = hash($history.current) + const newStateHash = hash(JSON.stringify(filteredState)) + + if (currentStateHash === newStateHash) { // Not a real change here return } if ($history.done.length >= max) $history.done.shift() // Remove oldest state if needed $history.done.push($history.current) $history.undone = [] // Clear redo history on new action - $history.current = JSON.stringify(state) + $history.current = JSON.stringify(filteredState) if (persistent) { persistentStrategy.set(store, 'undo', $history.done) @@ -90,7 +114,9 @@ const PiniaHistory = (context) => { $history.undone.push($history.current) // Save current state for redo $history.trigger = false - store.$patch(JSON.parse(state)) + // Only patch the state that was tracked (filtered state) + const stateToRestore = JSON.parse(state) + store.$patch(stateToRestore) nextTick(() => { $history.current = state $history.trigger = true @@ -114,7 +140,9 @@ const PiniaHistory = (context) => { $history.done.push($history.current) // Save current state for undo $history.trigger = false - store.$patch(JSON.parse(state)) + // Only patch the state that was tracked (filtered state) + const stateToRestore = JSON.parse(state) + store.$patch(stateToRestore) nextTick(() => { $history.current = state $history.trigger = true diff --git a/client/stores/working_form.js b/client/stores/working_form.js index 9906c2a0..0c5f1207 100644 --- a/client/stores/working_form.js +++ b/client/stores/working_form.js @@ -253,5 +253,7 @@ export const useWorkingFormStore = defineStore("working_form", { this.setProperties(newFields) } }, - history: {} + history: { + ignoreKeys: ['structureService', 'blockForm'] + } })