From 67f378637c7465e22cddc6dc278c414ca4804a3e Mon Sep 17 00:00:00 2001 From: elizavetaRa Date: Thu, 16 Feb 2023 17:35:16 +0100 Subject: [PATCH 1/7] Configurable autosave for text editor --- .../enhancement-autosave-text-editor-changes | 5 +++++ packages/web-app-text-editor/src/App.vue | 20 ++++++++++++++++++- 2 files changed, 24 insertions(+), 1 deletion(-) create mode 100644 changelog/unreleased/enhancement-autosave-text-editor-changes diff --git a/changelog/unreleased/enhancement-autosave-text-editor-changes b/changelog/unreleased/enhancement-autosave-text-editor-changes new file mode 100644 index 00000000000..7e1d0cd0afa --- /dev/null +++ b/changelog/unreleased/enhancement-autosave-text-editor-changes @@ -0,0 +1,5 @@ +Enhancement: Autosave content changes in text editor + +We have added the configurable functionality to autosave content changes in text editor. + +https://github.com/owncloud/web/pull/8455 diff --git a/packages/web-app-text-editor/src/App.vue b/packages/web-app-text-editor/src/App.vue index 3caf76a999a..c4650e0b4f7 100644 --- a/packages/web-app-text-editor/src/App.vue +++ b/packages/web-app-text-editor/src/App.vue @@ -102,6 +102,7 @@ export default defineComponent({ const resource: Ref = ref() const store = useStore() const { $gettext, interpolate: $gettextInterpolate } = useGettext() + let autosaveInterval = ref(null) const errorPopup = (error) => { store.dispatch('showMessage', { @@ -111,6 +112,12 @@ export default defineComponent({ }) } + const autosavePopup = () => { + store.dispatch('showMessage', { + title: $gettext('File autosaved') + }) + } + const loadFileTask = useTask(function* () { resource.value = yield getFileInfo(currentFileContext, { davProperties: [DavProperty.FileId, DavProperty.Permissions, DavProperty.Name] @@ -194,7 +201,7 @@ export default defineComponent({ }) const isLoading = computed(() => { - return loadFileTask.isRunning || saveFileTask.isRunning + return loadFileTask.isRunning }) const showPreview = computed(() => { @@ -215,11 +222,22 @@ export default defineComponent({ document.addEventListener('keydown', handleSKey, false) // Ensure reload is not possible if there are changes window.addEventListener('beforeunload', handleUnload) + + // Autosave + const editorOptions = store.getters.configuration?.options?.editor + if (editorOptions?.autosaveEnabled && editorOptions?.autosaveInterval) { + autosaveInterval.value = setInterval(() => { + if (isDirty.value) { + save().then((r) => autosavePopup()) + } + }, editorOptions?.autosaveInterval) + } }) onBeforeUnmount(() => { window.removeEventListener('beforeunload', handleUnload) document.removeEventListener('keydown', handleSKey, false) + clearInterval(autosaveInterval) }) const save = async function () { From 1c956db39b324c8a8d6efac1585ac56407139e61 Mon Sep 17 00:00:00 2001 From: Elizaveta Ragozina Date: Thu, 16 Feb 2023 17:37:33 +0100 Subject: [PATCH 2/7] Add text editor autosave to getting-started.md --- docs/getting-started.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/docs/getting-started.md b/docs/getting-started.md index 2389952febd..f726074b578 100644 --- a/docs/getting-started.md +++ b/docs/getting-started.md @@ -65,6 +65,8 @@ hovers the row with his mouse. Defaults to `false`. - `option.routing` This accepts an object with the following fields to customize the routing behaviour: - `options.routing.idBased` Enable or disable fileIds being added to the URL. Defaults to `true` because otherwise e.g. spaces with name clashes can't be resolved correctly. Only disable this if you can guarantee server side that spaces of the same namespace can't have name clashes. - `options.upload.xhr.timeout` Specifies the timeout for XHR uploads in milliseconds. +- `options.editor.autosaveEnabled` Specifies if the autosave for the text editor is enabled. +- `options.editor.autosaveInterval` Specifies the time interval for the file editor autosave in milliseconds. ### Sentry From 845c2a4a69d76a15b31a6f082167240c7a00df35 Mon Sep 17 00:00:00 2001 From: Pascal Wengerter Date: Thu, 16 Feb 2023 22:56:19 +0100 Subject: [PATCH 3/7] Add default values for editor.autosave{Enabled,Interval}, update text-editor implementation --- packages/web-app-text-editor/src/App.vue | 13 ++++++------- packages/web-runtime/src/store/config.ts | 4 ++++ 2 files changed, 10 insertions(+), 7 deletions(-) diff --git a/packages/web-app-text-editor/src/App.vue b/packages/web-app-text-editor/src/App.vue index c4650e0b4f7..89df39a0ad0 100644 --- a/packages/web-app-text-editor/src/App.vue +++ b/packages/web-app-text-editor/src/App.vue @@ -102,7 +102,7 @@ export default defineComponent({ const resource: Ref = ref() const store = useStore() const { $gettext, interpolate: $gettextInterpolate } = useGettext() - let autosaveInterval = ref(null) + let autosaveIntervalId = null const errorPopup = (error) => { store.dispatch('showMessage', { @@ -223,21 +223,20 @@ export default defineComponent({ // Ensure reload is not possible if there are changes window.addEventListener('beforeunload', handleUnload) - // Autosave - const editorOptions = store.getters.configuration?.options?.editor - if (editorOptions?.autosaveEnabled && editorOptions?.autosaveInterval) { - autosaveInterval.value = setInterval(() => { + const editorOptions = store.getters.configuration.options.editor + if (editorOptions.autosaveEnabled) { + autosaveIntervalId = setInterval(() => { if (isDirty.value) { save().then((r) => autosavePopup()) } - }, editorOptions?.autosaveInterval) + }, editorOptions.autosaveInterval) } }) onBeforeUnmount(() => { window.removeEventListener('beforeunload', handleUnload) document.removeEventListener('keydown', handleSKey, false) - clearInterval(autosaveInterval) + clearInterval(autosaveIntervalId) }) const save = async function () { diff --git a/packages/web-runtime/src/store/config.ts b/packages/web-runtime/src/store/config.ts index a10e5fef248..0e6cba0e7b4 100644 --- a/packages/web-runtime/src/store/config.ts +++ b/packages/web-runtime/src/store/config.ts @@ -37,6 +37,10 @@ const state = { options: { contextHelpers: true, defaultExtension: 'files', + editor: { + autosaveEnabled: false, + autosaveInterval: 120000 + }, // ugly hack to still have notifications but don't have // them blocking UI elements in acceptance/E2E tests topCenterNotifications: false, From 9c0a712ebc087406f0252464b2b230f1443d5d0a Mon Sep 17 00:00:00 2001 From: Pascal Wengerter Date: Thu, 16 Feb 2023 22:56:54 +0100 Subject: [PATCH 4/7] Reuse editor.autosaveEnabled for DrawIo extension --- dev/docker/ocis.web.config.json | 1 - packages/web-app-draw-io/src/App.vue | 32 ++++++++++--------- .../src/composables/appDefaults/useAppMeta.ts | 1 - .../tests/unit/helpers/config.spec.ts | 1 - 4 files changed, 17 insertions(+), 18 deletions(-) diff --git a/dev/docker/ocis.web.config.json b/dev/docker/ocis.web.config.json index 42e1c4d8930..005a6038664 100644 --- a/dev/docker/ocis.web.config.json +++ b/dev/docker/ocis.web.config.json @@ -41,7 +41,6 @@ "path": "web-app-draw-io", "config": { "url": "https://embed.diagrams.net", - "autosave": false, "theme": "minimal" } } diff --git a/packages/web-app-draw-io/src/App.vue b/packages/web-app-draw-io/src/App.vue index 385324da898..30d0c57c245 100644 --- a/packages/web-app-draw-io/src/App.vue +++ b/packages/web-app-draw-io/src/App.vue @@ -14,21 +14,25 @@