Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feat/read only setting #4902

Draft
wants to merge 8 commits into
base: main
Choose a base branch
from
Draft

Conversation

benthie
Copy link

@benthie benthie commented Oct 26, 2023

πŸ“ Summary

Hi everybody,

So far the following is implemented:

  • A global setting open_read_only_enabled has been added, which can be toggled in the same way as workspace_available via command line. Thus, the original functionality remains untouched.
  • With open_read_only_enabled=true text/markdown files are opened in read-only mode by default and an edit button is shown next to the "Show Outline" button. Clicking on the button makes the file editable, the edit button is replaced by a "Save document" button and the formatting menu bar is shown as in normal mode beneath the button.

While playing around with that new mode, we figured it would be useful to have a possibility to prevent the file from being auto-saved on exit if the user changed the file. Instead, we thought of showing a confirmation dialog in case of unsaved changes asking whether the user wants to save them.
I tried to add such a dialog to the Editor.vue component, but as far as as I understand it, the editor is destroyed by the parent Viewer component and in the editor's beforeDestroy life hook, where the auto-save is performed, I am not able to launch a modal that waits for the user input, because the remaining life hooks are executed immediately after beforeDestroy.
The ImageEditor.vue component of the Viewer app does exactly this, but it uses the FilerobotImageEditor which can be provided with an onClose callback.
Is there any other way we could achieve the same functionality?

I am new to web development and I know that many of the changes I propose here can be improved. I happy about your feedback.

πŸ–ΌοΈ Screenshots

Read-only

read-only-mode-01

Editable

read-only-mode-02

🚧 TODO

  • Menu bar appearance in rich workspaces
  • Menu bar appearance in text files
  • SCSS / layout for mobile devices

🏁 Checklist

  • Code is properly formatted (npm run lint / npm run stylelint / composer run cs:check)
  • Sign-off message is added to all commits
  • Tests (unit, integration and/or end-to-end) passing and the changes are covered with tests
  • Documentation (README or documentation) has been updated or is not required

@juliushaertl
Copy link
Member

Thanks a lot for your contribution. Implementation wise I only had a first quick look, but this seems reasonable.

I'd be ok having a setting for this if it is covered by a e2e test that verifies it doesn't break, however would also like some confirmation from @nextcloud/designers on this especially given the previous discussion in #3923 which didn't have a common conclusion yet on that topic.

Copy link
Member

@jancborchardt jancborchardt left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I’m quite unsure if this is a good idea – this is not something that desktop apps for text or office do, and neither Google Docs, Notion or others, at least by default.

If we do this (which as said I’m leaning against), then there is some feedback for this pull request:

  • In view-only mode, the "checkmark" save button is also shown, floating in mid-air. This would need to be removed
  • In edit mode, the "Save" button already exists as the "checkmark" save button on the right. The "Save document" button with the floppy disk icon (outdated, should not be used) is not necessary, also as it introduces another vertical bar

@benthie
Copy link
Author

benthie commented Nov 10, 2023

Hi @juliushaertl and @jancborchardt,

thank you for your feedback.

Before we put further effort into this PR and try to implement the final parts, we would like to make sure that there exists the chance it will actually get accepted eventually.

We understand that some of you are not convinced by the feature, because comparable editors handle things differently. And adding a new feature always entails maintenance work.

When looking at the votes of the currently open tickets, however, this feature is among the top 10 voted tickets with a handful of people that would be happy to see it coming. And the way it is implemented now, Text will not become an editor that handles things differently compared to other text apps / editors, because the feature is kind of hidden and must be enabled first.

@rvjr
Copy link

rvjr commented Nov 11, 2023

I think if everything is fixed and tests are ok this could be a very helpful addition. And because it's optional now it should not disturb anyone expecting to always edit files directly. At least to me it seemed in #3923 that there might be quite a few other people liking the more explicit editing behaviour. But indeed it depends on @jancborchardt first, before it makes sense to polish everything for a merge...

@benthie
Copy link
Author

benthie commented Nov 27, 2023

Hi @juliushaertl and @jancborchardt, this is a friendly ping. Is there any progress in deciding whether the feature might get accepted?

@benthie
Copy link
Author

benthie commented Nov 28, 2023

I’m quite unsure if this is a good idea – this is not something that desktop apps for text or office do, and neither Google Docs, Notion or others, at least by default.

Desktop apps for text or office usually do not to automatically save the document in the background, but instead the user is notified upon closing the document that there are some unsaved changes, offering the possibility to prevent unwanted changes. Web based editors like text, Google Docs and Notion, however, do automatically save and in all of them that is desired behavior (which of course makes sense) and cannot be disabled as far as I know.

@juliushaertl
Copy link
Member

cc @nimishavijay As Jan is currently out of office :)

Copy link
Member

@jancborchardt jancborchardt left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@benthie sorry for the late reply! :) I would be fine with this feature, as long as the config.php setting (open_read_only_enabled as far as I understand?) is false by default. And considering my design feedback from above comment #4902 (review)

@juliushaertl
Copy link
Member

All right, in order to get this merged I'd definitely require proper tests that cover this feature. I'd suggest to write a cypress e2e test that could make use of the "testing" app in server to set the app value, then load a file and check the new UI parts.

<!-- Rich Menu -->
<template v-else>
<div v-if="openReadOnlyEnabled" class="text-editor--editable-bar-save">
<EditableBarSave />
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

UI wise I would prefer to not have an extra menu line but rather integrate this into the existing menu bar This could be passed into a slot of the Menubar component

@@ -457,9 +478,11 @@ export default {
onOpened({ document, session }) {
this.currentSession = session
this.document = document
this.readOnly = document.readOnly
this.documentReadOnly = document.readOnly
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not a fan of having a copy of the state, can we just use document.readOnly instead in places where this is used?

@@ -457,9 +478,11 @@ export default {
onOpened({ document, session }) {
this.currentSession = session
this.document = document
this.readOnly = document.readOnly
this.documentReadOnly = document.readOnly
this.editable = !this.documentReadOnly && !this.openReadOnlyEnabled
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe call this editMode to be a bit more clear what this value is about?

@@ -65,6 +67,22 @@ export const ReadonlyEntries = [{
},
}]

export const EditEntries = [{
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we can just directly hardcode those into the bar components and reduce the complexity a bit here.

@benthie
Copy link
Author

benthie commented Feb 14, 2024

Hi everybody, I finally have the time to get started working on the requested changes/tests.

Right now I cannot get the cypress e2e tests running. What I do is running the following in the terminal of the devcontainer:

export CYPRESS_baseUrl='http://localhost/index.php'
make test-cypress

which produces this output:

devcontainer@41419b791cd8:/var/www/html/apps-extra/text$ make test-cypress
cd cypress && ./runLocal.sh run
Server is up at http://localhost/index.php

DevTools listening on ws://127.0.0.1:40191/devtools/browser/4d5972cd-f295-4529-8837-f34ab3156995
[32423:0214/143519.296721:ERROR:object_proxy.cc(590)] Failed to call method: org.freedesktop.portal.Settings.Read: object_path= /org/freedesktop/portal/desktop: unknown error type: 
Missing baseUrl in compilerOptions. tsconfig-paths will be skipped
Building undefined undefined 

Your configFile threw an error from: /var/www/html/apps-extra/text/cypress.config.js

The error was thrown while executing your e2e.setupNodeEvents() function:

TypeError [ERR_INVALID_ARG_TYPE]: The "path" argument must be of type string. Received undefined
    at new NodeError (node:internal/errors:387:5)
    at validateString (node:internal/validators:162:11)
    at Object.join (node:path:1172:7)
    at Object.<anonymous> (/var/www/html/apps-extra/text/node_modules/@nextcloud/webpack-vue-config/webpack.config.js:48:20)
    at Module._compile (node:internal/modules/cjs/loader:1198:14)
    at Object.S (/var/www/html/apps-extra/text/node_modules/tsx/dist/cjs/index.cjs:1:1292)
    at Module.load (node:internal/modules/cjs/loader:1076:32)
    at Function.Module._load (node:internal/modules/cjs/loader:911:12)
    at Module.require (node:internal/modules/cjs/loader:1100:19)
    at require (node:internal/modules/cjs/helpers:119:18)
    at Object.<anonymous> (/var/www/html/apps-extra/text/node_modules/@nextcloud/webpack-vue-config/index.js:23:18)
    at Module._compile (node:internal/modules/cjs/loader:1198:14)
    at Object.S (/var/www/html/apps-extra/text/node_modules/tsx/dist/cjs/index.cjs:1:1292)
    at Module.load (node:internal/modules/cjs/loader:1076:32)
    at Function.Module._load (node:internal/modules/cjs/loader:911:12)
    at Module.require (node:internal/modules/cjs/loader:1100:19)
    at require (node:internal/modules/cjs/helpers:119:18)
    at setupNodeEvents (/var/www/html/apps-extra/text/cypress.config.js:24:27)
    at /home/devcontainer/.cache/Cypress/13.6.3/Cypress/resources/app/node_modules/@packages/server/lib/plugins/child/run_plugins.js:122:14
    at tryCatcher (/home/devcontainer/.cache/Cypress/13.6.3/Cypress/resources/app/node_modules/bluebird/js/release/util.js:16:23)
    at Function.Promise.attempt.Promise.try (/home/devcontainer/.cache/Cypress/13.6.3/Cypress/resources/app/node_modules/bluebird/js/release/method.js:39:29)
    at RunPlugins.load (/home/devcontainer/.cache/Cypress/13.6.3/Cypress/resources/app/node_modules/@packages/server/lib/plugins/child/run_plugins.js:119:9)
    at RunPlugins.runSetupNodeEvents (/home/devcontainer/.cache/Cypress/13.6.3/Cypress/resources/app/node_modules/@packages/server/lib/plugins/child/run_plugins.js:59:17)
    at EventEmitter.<anonymous> (/home/devcontainer/.cache/Cypress/13.6.3/Cypress/resources/app/node_modules/@packages/server/lib/plugins/child/run_require_async_child.js:185:22)
    at EventEmitter.emit (node:events:513:28)
    at EventEmitter.emit (node:domain:489:12)
    at process.<anonymous> (/home/devcontainer/.cache/Cypress/13.6.3/Cypress/resources/app/node_modules/@packages/server/lib/plugins/util.js:33:22)
    at process.emit (node:events:513:28)
./runLocal.sh: line 12: docker-compose: command not found
make: *** [Makefile:32: test-cypress] Error 1

If I do not set the CYPRESS_baseUrl environment variable, it just tells me that it cannot find docker-compose.

devcontainer@41419b791cd8:/var/www/html/apps-extra/text$ make test-cypress
cd cypress && ./runLocal.sh run
No server reached at http://localhost:8081/index.php - starting containers.
./runLocal.sh: line 28: docker-compose: command not found

I looked for information in this section of the readme, but it only says that the user must be in the docker group.

Is there anything I am missing or doing wrong?

@juliushaertl
Copy link
Member

I think running within the dev container is currently not really working. If you can run it outside of the container you could just use your existing URL of your development environment and start cypress with CYPRESS_baseUrl=https://nextcloud.local/index.php npx cypress open

Hope this helps

Signed-off-by: Benjamin Thiemann <benjamin.thiemann@optonic.com>
Signed-off-by: Benjamin Thiemann <benjamin.thiemann@optonic.com>
Signed-off-by: Benjamin Thiemann <benjamin.thiemann@optonic.com>
Signed-off-by: Benjamin Thiemann <benjamin.thiemann@optonic.com>
Signed-off-by: Benjamin Thiemann <benjamin.thiemann@optonic.com>
Signed-off-by: Benjamin Thiemann <benjamin.thiemann@optonic.com>
@benthie
Copy link
Author

benthie commented Feb 26, 2024

I think running within the dev container is currently not really working. If you can run it outside of the container you could just use your existing URL of your development environment and start cypress with CYPRESS_baseUrl=https://nextcloud.local/index.php npx cypress open

Hope this helps

Hi @juliushaertl,

that helped indeed, thanks. I've written the e2e tests, but currently the tests with open_read_only_enabled=1 are failing on Chrome, although the feature works fine when I test it manually in Chrome. Both Firefox and Electron are passing all tests. It seems that it crashes when the tests try to change from read-only to edit mode. Do you have any ideas on how to fix that?

If you prefer the commits squashed or with another commit message style, just let me know and I will adapt it.

Signed-off-by: Julius HΓ€rtl <jus@bitgrid.net>
@juliushaertl
Copy link
Member

Pushed a small commit that hopefully makes them pass on CI.

I had one chrome crash as well when trying locally but not reproducible anymore later on, so for that I have no real clue for now. However would not consider that a blocker once it passes on CI as some chromium or cypress bug could also be the case there.

Signed-off-by: Julius HΓ€rtl <jus@bitgrid.net>
@benthie
Copy link
Author

benthie commented Mar 11, 2024

Hi @juliushaertl, did the tests pass as expected? And is there anything left for me to do?

@rvjr
Copy link

rvjr commented Mar 25, 2024

@juliushaertl, @benthie can we get this closer to merge? I would be really happy to have this on our NC instance...

@rvjr
Copy link

rvjr commented Apr 12, 2024

@juliushaertl I talked to @benthie and according to him all tests pass locally for him; how can we make them pass on CI as well?

@max-nextcloud
Copy link
Collaborator

@rvjr @benthie First of all thanks a lot for your contribution! ❀️

I'm looking into ci issues right now and trying to make it run more robustly. I will also take a look at the failures here and check if they relate to your changes or are flaky tests for other reasons. I'll let you know if I run into anything you'd need to fix.

Copy link
Contributor

Hello there,
Thank you so much for taking the time and effort to create a pull request to our Nextcloud project.

We hope that the review process is going smooth and is helpful for you. We want to ensure your pull request is reviewed to your satisfaction. If you have a moment, our community management team would very much appreciate your feedback on your experience with this PR review process.

Your feedback is valuable to us as we continuously strive to improve our community developer experience. Please take a moment to complete our short survey by clicking on the following link: https://cloud.nextcloud.com/apps/forms/s/i9Ago4EQRZ7TWxjfmeEpPkf6

Thank you for contributing to Nextcloud and we hope to hear from you soon!

@rvjr
Copy link

rvjr commented May 11, 2024

@max-nextcloud any updates here? Can we do anything to help?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Add a setting to open files read-only by default
5 participants