diff options
Diffstat (limited to 'app/assets/javascripts/vue_shared/components/local_storage_sync.vue')
-rw-r--r-- | app/assets/javascripts/vue_shared/components/local_storage_sync.vue | 48 |
1 files changed, 42 insertions, 6 deletions
diff --git a/app/assets/javascripts/vue_shared/components/local_storage_sync.vue b/app/assets/javascripts/vue_shared/components/local_storage_sync.vue index b5d6b872547..80c03342f11 100644 --- a/app/assets/javascripts/vue_shared/components/local_storage_sync.vue +++ b/app/assets/javascripts/vue_shared/components/local_storage_sync.vue @@ -1,4 +1,6 @@ <script> +import { isEqual } from 'lodash'; + export default { props: { storageKey: { @@ -6,31 +8,65 @@ export default { required: true, }, value: { - type: String, + type: [String, Number, Boolean, Array, Object], required: false, default: '', }, + asJson: { + type: Boolean, + required: false, + default: false, + }, + persist: { + type: Boolean, + required: false, + default: true, + }, }, watch: { value(newVal) { - this.saveValue(newVal); + this.saveValue(this.serialize(newVal)); }, }, mounted() { // On mount, trigger update if we actually have a localStorageValue - const value = this.getValue(); + const { exists, value } = this.getStorageValue(); - if (value && this.value !== value) { + if (exists && !isEqual(value, this.value)) { this.$emit('input', value); } }, methods: { - getValue() { - return localStorage.getItem(this.storageKey); + getStorageValue() { + const value = localStorage.getItem(this.storageKey); + + if (value === null) { + return { exists: false }; + } + + try { + return { exists: true, value: this.deserialize(value) }; + } catch { + // eslint-disable-next-line no-console + console.warn( + `[gitlab] Failed to deserialize value from localStorage (key=${this.storageKey})`, + value, + ); + // default to "don't use localStorage value" + return { exists: false }; + } }, saveValue(val) { + if (!this.persist) return; + localStorage.setItem(this.storageKey, val); }, + serialize(val) { + return this.asJson ? JSON.stringify(val) : val; + }, + deserialize(val) { + return this.asJson ? JSON.parse(val) : val; + }, }, render() { return this.$slots.default; |