fix(editor): Handle localStorage being blocked/unavailable (#7348)

This commit is contained in:
कारतोफ्फेलस्क्रिप्ट™ 2023-10-27 15:51:20 +02:00 committed by GitHub
parent 739a4d4ecf
commit c05bc6728d
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
10 changed files with 69 additions and 45 deletions

View file

@ -47,8 +47,8 @@
"@jsplumb/util": "^5.13.2", "@jsplumb/util": "^5.13.2",
"@lezer/common": "^1.0.4", "@lezer/common": "^1.0.4",
"@n8n/codemirror-lang-sql": "^1.0.2", "@n8n/codemirror-lang-sql": "^1.0.2",
"@vueuse/components": "^10.2.0", "@vueuse/components": "^10.5.0",
"@vueuse/core": "^10.2.0", "@vueuse/core": "^10.5.0",
"axios": "^0.21.1", "axios": "^0.21.1",
"codemirror-lang-html-n8n": "^1.0.0", "codemirror-lang-html-n8n": "^1.0.0",
"codemirror-lang-n8n-expression": "^0.2.0", "codemirror-lang-n8n-expression": "^0.2.0",

View file

@ -35,6 +35,7 @@
<script lang="ts"> <script lang="ts">
import { defineComponent } from 'vue'; import { defineComponent } from 'vue';
import { mapStores } from 'pinia'; import { mapStores } from 'pinia';
import { useStorage } from '@vueuse/core';
import BannerStack from '@/components/banners/BannerStack.vue'; import BannerStack from '@/components/banners/BannerStack.vue';
import Modals from '@/components/Modals.vue'; import Modals from '@/components/Modals.vue';
@ -212,7 +213,7 @@ export default defineComponent({
return; return;
}, },
setTheme() { setTheme() {
const theme = window.localStorage.getItem(LOCAL_STORAGE_THEME); const theme = useStorage(LOCAL_STORAGE_THEME, undefined).value;
if (theme) { if (theme) {
window.document.body.classList.add(`theme-${theme}`); window.document.body.classList.add(`theme-${theme}`);
} }

View file

@ -41,6 +41,7 @@ import { defineComponent } from 'vue';
import type { PropType } from 'vue'; import type { PropType } from 'vue';
import { mapStores } from 'pinia'; import { mapStores } from 'pinia';
import { get } from 'lodash-es'; import { get } from 'lodash-es';
import { useStorage } from '@vueuse/core';
import type { INodeTypeDescription } from 'n8n-workflow'; import type { INodeTypeDescription } from 'n8n-workflow';
import PanelDragButton from './PanelDragButton.vue'; import PanelDragButton from './PanelDragButton.vue';
@ -345,9 +346,10 @@ export default defineComponent({
); );
}, },
restorePositionData() { restorePositionData() {
const storedPanelWidthData = window.localStorage.getItem( const storedPanelWidthData = useStorage(
`${LOCAL_STORAGE_MAIN_PANEL_RELATIVE_WIDTH}_${this.currentNodePaneType}`, `${LOCAL_STORAGE_MAIN_PANEL_RELATIVE_WIDTH}_${this.currentNodePaneType}`,
); undefined,
).value;
if (storedPanelWidthData) { if (storedPanelWidthData) {
const parsedWidth = parseFloat(storedPanelWidthData); const parsedWidth = parseFloat(storedPanelWidthData);

View file

@ -170,6 +170,7 @@
<script lang="ts"> <script lang="ts">
import { defineComponent } from 'vue'; import { defineComponent } from 'vue';
import { mapStores } from 'pinia'; import { mapStores } from 'pinia';
import { useStorage } from '@vueuse/core';
import { import {
CUSTOM_API_CALL_KEY, CUSTOM_API_CALL_KEY,
LOCAL_STORAGE_PIN_DATA_DISCOVERY_CANVAS_FLAG, LOCAL_STORAGE_PIN_DATA_DISCOVERY_CANVAS_FLAG,
@ -579,9 +580,10 @@ export default defineComponent({
}, },
}, },
created() { created() {
const hasSeenPinDataTooltip = localStorage.getItem( const hasSeenPinDataTooltip = useStorage(
LOCAL_STORAGE_PIN_DATA_DISCOVERY_CANVAS_FLAG, LOCAL_STORAGE_PIN_DATA_DISCOVERY_CANVAS_FLAG,
); undefined,
).value;
if (!hasSeenPinDataTooltip) { if (!hasSeenPinDataTooltip) {
this.unwatchWorkflowDataItems = this.$watch('workflowDataItems', (dataItemsCount: number) => { this.unwatchWorkflowDataItems = this.$watch('workflowDataItems', (dataItemsCount: number) => {
this.showPinDataDiscoveryTooltip(dataItemsCount); this.showPinDataDiscoveryTooltip(dataItemsCount);

View file

@ -495,6 +495,7 @@
import { defineAsyncComponent, defineComponent } from 'vue'; import { defineAsyncComponent, defineComponent } from 'vue';
import type { PropType } from 'vue'; import type { PropType } from 'vue';
import { mapStores } from 'pinia'; import { mapStores } from 'pinia';
import { useStorage } from '@vueuse/core';
import { saveAs } from 'file-saver'; import { saveAs } from 'file-saver';
import type { import type {
ConnectionTypes, ConnectionTypes,
@ -975,12 +976,12 @@ export default defineComponent({
return; return;
} }
if ( const pinDataDiscoveryFlag = useStorage(
value && LOCAL_STORAGE_PIN_DATA_DISCOVERY_NDV_FLAG,
value.length > 0 && undefined,
!this.isReadOnlyRoute && ).value;
!localStorage.getItem(LOCAL_STORAGE_PIN_DATA_DISCOVERY_NDV_FLAG)
) { if (value && value.length > 0 && !this.isReadOnlyRoute && !pinDataDiscoveryFlag) {
this.pinDataDiscoveryComplete(); this.pinDataDiscoveryComplete();
setTimeout(() => { setTimeout(() => {

View file

@ -1,5 +1,6 @@
import { defineComponent } from 'vue'; import { defineComponent } from 'vue';
import { mapStores } from 'pinia'; import { mapStores } from 'pinia';
import { useStorage } from '@vueuse/core';
import { externalHooks } from '@/mixins/externalHooks'; import { externalHooks } from '@/mixins/externalHooks';
import { workflowHelpers } from '@/mixins/workflowHelpers'; import { workflowHelpers } from '@/mixins/workflowHelpers';
@ -121,7 +122,7 @@ export const workflowActivate = defineComponent({
if (isCurrentWorkflow) { if (isCurrentWorkflow) {
if ( if (
newActiveState && newActiveState &&
window.localStorage.getItem(LOCAL_STORAGE_ACTIVATION_FLAG) !== 'true' useStorage(LOCAL_STORAGE_ACTIVATION_FLAG, undefined).value !== 'true'
) { ) {
this.uiStore.openModal(WORKFLOW_ACTIVE_MODAL_KEY); this.uiStore.openModal(WORKFLOW_ACTIVE_MODAL_KEY);
} else { } else {

View file

@ -1,3 +1,4 @@
import { useStorage } from '@vueuse/core';
import ChangePasswordView from './views/ChangePasswordView.vue'; import ChangePasswordView from './views/ChangePasswordView.vue';
import ErrorView from './views/ErrorView.vue'; import ErrorView from './views/ErrorView.vue';
import ForgotMyPasswordView from './views/ForgotMyPasswordView.vue'; import ForgotMyPasswordView from './views/ForgotMyPasswordView.vue';
@ -794,7 +795,7 @@ export const routes = [
role: [ROLE.Owner], role: [ROLE.Owner],
}, },
deny: { deny: {
shouldDeny: () => !window.localStorage.getItem('audit-logs'), shouldDeny: () => !useStorage('audit-logs', undefined).value,
}, },
}, },
}, },

View file

@ -1,3 +1,4 @@
import { useStorage } from '@vueuse/core';
import { LOCAL_STORAGE_MAPPING_IS_ONBOARDED, STORES } from '@/constants'; import { LOCAL_STORAGE_MAPPING_IS_ONBOARDED, STORES } from '@/constants';
import type { import type {
INodeUi, INodeUi,
@ -48,7 +49,7 @@ export const useNDVStore = defineStore(STORES.NDV, {
canDrop: false, canDrop: false,
stickyPosition: null, stickyPosition: null,
}, },
isMappingOnboarded: window.localStorage.getItem(LOCAL_STORAGE_MAPPING_IS_ONBOARDED) === 'true', isMappingOnboarded: useStorage(LOCAL_STORAGE_MAPPING_IS_ONBOARDED, undefined).value === 'true',
}), }),
getters: { getters: {
activeNode(): INodeUi | null { activeNode(): INodeUi | null {

View file

@ -1,6 +1,7 @@
import type { Ref } from 'vue'; import type { Ref } from 'vue';
import { ref } from 'vue'; import { ref } from 'vue';
import { defineStore } from 'pinia'; import { defineStore } from 'pinia';
import { useStorage } from '@vueuse/core';
import { useUsersStore } from '@/stores/users.store'; import { useUsersStore } from '@/stores/users.store';
import { useRootStore } from '@/stores/n8nRoot.store'; import { useRootStore } from '@/stores/n8nRoot.store';
import { useSettingsStore } from '@/stores/settings.store'; import { useSettingsStore } from '@/stores/settings.store';
@ -40,11 +41,11 @@ export const usePostHog = defineStore('posthog', () => {
if (!window.featureFlags) { if (!window.featureFlags) {
// for testing // for testing
const cachedOverrdies = localStorage.getItem(LOCAL_STORAGE_EXPERIMENT_OVERRIDES); const cachedOverrides = useStorage(LOCAL_STORAGE_EXPERIMENT_OVERRIDES, undefined).value;
if (cachedOverrdies) { if (cachedOverrides) {
try { try {
console.log('Overriding feature flags', cachedOverrdies); console.log('Overriding feature flags', cachedOverrides);
overrides.value = JSON.parse(cachedOverrdies); overrides.value = JSON.parse(cachedOverrides);
} catch (e) { } catch (e) {
console.log('Could not override experiment', e); console.log('Could not override experiment', e);
} }

View file

@ -846,11 +846,11 @@ importers:
specifier: ^1.0.2 specifier: ^1.0.2
version: 1.0.2(@codemirror/view@6.5.1)(@lezer/common@1.1.0) version: 1.0.2(@codemirror/view@6.5.1)(@lezer/common@1.1.0)
'@vueuse/components': '@vueuse/components':
specifier: ^10.2.0 specifier: ^10.5.0
version: 10.2.0(vue@3.3.4) version: 10.5.0(vue@3.3.4)
'@vueuse/core': '@vueuse/core':
specifier: ^10.2.0 specifier: ^10.5.0
version: 10.2.0(vue@3.3.4) version: 10.5.0(vue@3.3.4)
axios: axios:
specifier: ^0.21.1 specifier: ^0.21.1
version: 0.21.4 version: 0.21.4
@ -6824,7 +6824,7 @@ packages:
ts-dedent: 2.2.0 ts-dedent: 2.2.0
type-fest: 3.13.1 type-fest: 3.13.1
vue: 3.3.4 vue: 3.3.4
vue-component-type-helpers: 1.8.21 vue-component-type-helpers: 1.8.22
transitivePeerDependencies: transitivePeerDependencies:
- encoding - encoding
- supports-color - supports-color
@ -7640,8 +7640,8 @@ packages:
resolution: {integrity: sha512-oh8q2Zc32S6gd/j50GowEjKLoOVOwHP/bWVjKJInBwQqdOYMdPrf1oVlelTlyfFK3CKxL1uahMDAr+vy8T7yMQ==} resolution: {integrity: sha512-oh8q2Zc32S6gd/j50GowEjKLoOVOwHP/bWVjKJInBwQqdOYMdPrf1oVlelTlyfFK3CKxL1uahMDAr+vy8T7yMQ==}
dev: false dev: false
/@types/web-bluetooth@0.0.17: /@types/web-bluetooth@0.0.18:
resolution: {integrity: sha512-4p9vcSmxAayx72yn70joFoL44c9MO/0+iVEBIQXe3v2h2SiAsEIo/G5v6ObFWvNKRFjbrVadNf9LqEEZeQPzdA==} resolution: {integrity: sha512-v/ZHEj9xh82usl8LMR3GarzFY1IrbXJw5L4QfQhokjRV91q+SelFqxQWSep1ucXEZ22+dSTwLFkXeur25sPIbw==}
dev: false dev: false
/@types/webidl-conversions@7.0.0: /@types/webidl-conversions@7.0.0:
@ -8247,24 +8247,24 @@ packages:
- typescript - typescript
dev: true dev: true
/@vueuse/components@10.2.0(vue@3.3.4): /@vueuse/components@10.5.0(vue@3.3.4):
resolution: {integrity: sha512-fpGtxx8G3BCJUoTd6d4xI7qELvm4nwVKLZYgIVdv7weqprKWwK5IO+t3LULovPuS7W2guVZgpyMy9NkD4qa2Bw==} resolution: {integrity: sha512-zWQZ8zkNBvX++VHfyiUaQ4otb+4PWI8679GR8FvdrNnj+01LXnqvrkyKd8yTCMJ9nHqwRRTJikS5fu4Zspn9DQ==}
dependencies: dependencies:
'@vueuse/core': 10.2.0(vue@3.3.4) '@vueuse/core': 10.5.0(vue@3.3.4)
'@vueuse/shared': 10.2.0(vue@3.3.4) '@vueuse/shared': 10.5.0(vue@3.3.4)
vue-demi: 0.14.5(vue@3.3.4) vue-demi: 0.14.6(vue@3.3.4)
transitivePeerDependencies: transitivePeerDependencies:
- '@vue/composition-api' - '@vue/composition-api'
- vue - vue
dev: false dev: false
/@vueuse/core@10.2.0(vue@3.3.4): /@vueuse/core@10.5.0(vue@3.3.4):
resolution: {integrity: sha512-aHBnoCteIS3hFu7ZZkVB93SanVDY6t4TIb7XDLxJT/HQdAZz+2RdIEJ8rj5LUoEJr7Damb5+sJmtpCwGez5ozQ==} resolution: {integrity: sha512-z/tI2eSvxwLRjOhDm0h/SXAjNm8N5ld6/SC/JQs6o6kpJ6Ya50LnEL8g5hoYu005i28L0zqB5L5yAl8Jl26K3A==}
dependencies: dependencies:
'@types/web-bluetooth': 0.0.17 '@types/web-bluetooth': 0.0.18
'@vueuse/metadata': 10.2.0 '@vueuse/metadata': 10.5.0
'@vueuse/shared': 10.2.0(vue@3.3.4) '@vueuse/shared': 10.5.0(vue@3.3.4)
vue-demi: 0.14.5(vue@3.3.4) vue-demi: 0.14.6(vue@3.3.4)
transitivePeerDependencies: transitivePeerDependencies:
- '@vue/composition-api' - '@vue/composition-api'
- vue - vue
@ -8282,18 +8282,18 @@ packages:
- vue - vue
dev: false dev: false
/@vueuse/metadata@10.2.0: /@vueuse/metadata@10.5.0:
resolution: {integrity: sha512-IR7Mkq6QSgZ38q/2ZzOt+Zz1OpcEsnwE64WBumDQ+RGKrosFCtUA2zgRrOqDEzPBXrVB+4HhFkwDjQMu0fDBKw==} resolution: {integrity: sha512-fEbElR+MaIYyCkeM0SzWkdoMtOpIwO72x8WsZHRE7IggiOlILttqttM69AS13nrDxosnDBYdyy3C5mR1LCxHsw==}
dev: false dev: false
/@vueuse/metadata@9.13.0: /@vueuse/metadata@9.13.0:
resolution: {integrity: sha512-gdU7TKNAUVlXXLbaF+ZCfte8BjRJQWPCa2J55+7/h+yDtzw3vOoGQDRXzI6pyKyo6bXFT5/QoPE4hAknExjRLQ==} resolution: {integrity: sha512-gdU7TKNAUVlXXLbaF+ZCfte8BjRJQWPCa2J55+7/h+yDtzw3vOoGQDRXzI6pyKyo6bXFT5/QoPE4hAknExjRLQ==}
dev: false dev: false
/@vueuse/shared@10.2.0(vue@3.3.4): /@vueuse/shared@10.5.0(vue@3.3.4):
resolution: {integrity: sha512-dIeA8+g9Av3H5iF4NXR/sft4V6vys76CpZ6hxwj8eMXybXk2WRl3scSsOVi+kQ9SX38COR7AH7WwY83UcuxbSg==} resolution: {integrity: sha512-18iyxbbHYLst9MqU1X1QNdMHIjks6wC7XTVf0KNOv5es/Ms6gjVFCAAWTVP2JStuGqydg3DT+ExpFORUEi9yhg==}
dependencies: dependencies:
vue-demi: 0.14.5(vue@3.3.4) vue-demi: 0.14.6(vue@3.3.4)
transitivePeerDependencies: transitivePeerDependencies:
- '@vue/composition-api' - '@vue/composition-api'
- vue - vue
@ -21803,8 +21803,8 @@ packages:
vue: 3.3.4 vue: 3.3.4
dev: false dev: false
/vue-component-type-helpers@1.8.21: /vue-component-type-helpers@1.8.22:
resolution: {integrity: sha512-XL37QbmiqqbKrAFHPxqryMXpNgO0KMKd5bIo7LO9QABPMNEysd8xmYRIjwZhh0t2abveXjAJ//ZcAzwdxp/S3Q==} resolution: {integrity: sha512-LK3wJHs3vJxHG292C8cnsRusgyC5SEZDCzDCD01mdE/AoREFMl2tzLRuzwyuEsOIz13tqgBcnvysN3Lxsa14Fw==}
dev: true dev: true
/vue-component-type-helpers@1.8.4: /vue-component-type-helpers@1.8.4:
@ -21824,6 +21824,20 @@ packages:
dependencies: dependencies:
vue: 3.3.4 vue: 3.3.4
/vue-demi@0.14.6(vue@3.3.4):
resolution: {integrity: sha512-8QA7wrYSHKaYgUxDA5ZC24w+eHm3sYCbp0EzcDwKqN3p6HqtTCGR/GVsPyZW92unff4UlcSh++lmqDWN3ZIq4w==}
engines: {node: '>=12'}
hasBin: true
peerDependencies:
'@vue/composition-api': ^1.0.0-rc.1
vue: ^3.0.0-0 || ^2.6.0
peerDependenciesMeta:
'@vue/composition-api':
optional: true
dependencies:
vue: 3.3.4
dev: false
/vue-docgen-api@4.56.4(vue@3.3.4): /vue-docgen-api@4.56.4(vue@3.3.4):
resolution: {integrity: sha512-Z59qNUYZNHMZL0QITNbqobGKJgmqyOs4OiAdzr1Ug7ys1gkFBGewiuwPURTsoM2zi4GWZWy2eW4B5FevwT7gpA==} resolution: {integrity: sha512-Z59qNUYZNHMZL0QITNbqobGKJgmqyOs4OiAdzr1Ug7ys1gkFBGewiuwPURTsoM2zi4GWZWy2eW4B5FevwT7gpA==}
dependencies: dependencies: