-
Notifications
You must be signed in to change notification settings - Fork 2.1k
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
Fix deletion of selected files in trashbin #30993
Conversation
apps/files_trashbin/js/filelist.js
Outdated
/* | ||
The getSelectedFiles gives the file name as it is seen in UI. | ||
But the fact is filenames are storead as filename.dxxxxx. This | ||
change helps to extract exact filename. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
the filenames are stored like this because you can have multiple files in trashbin with the same name from different deletions. we need to use the suffixed name when talking to the server so I doubt that this approach can work correctly
Codecov Report
@@ Coverage Diff @@
## master #30993 +/- ##
=========================================
Coverage 62.91% 62.91%
Complexity 18424 18424
=========================================
Files 1156 1156
Lines 69184 69184
Branches 1260 1260
=========================================
Hits 43527 43527
Misses 25288 25288
Partials 369 369
Continue to review full report at Codecov.
|
apps/files_trashbin/js/filelist.js
Outdated
filesFromAttribute.push(trSelectedFiles[i].getAttribute('data-file')); | ||
} | ||
if (files !== filesFromAttribute) { | ||
files = filesFromAttribute; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@PVince81 This change gives the suffixed name i.e if the file name is a.txt
, then the data passed to server will be of the form a.txt.dxxxxxxx
. While testing with single and multiple files, I was able to see files getting deleted from trashbin. Also verified files getting deleted from files_trashbin/files
. Yes you are right, the issue was caused because suffixed filenames were not passed to the server.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I see, makes sense.
next up is adjusting unit tests. you can run them with |
Selected delete in trashbin works with this code (manual test). Selected restore does not work. I expect the same sort of code changes are needed for the code that runs when the "Restore" button is clicked. (also see recent comment in issue - #30942 (comment) ) |
I have updated the change for restore issue. Will be looking into the unit tests. |
@sharidas webUI tests for this are available. See the 2nd commit in #31024 The 2 new scenarios fail against current master, and pass when your code is included - good. Please include those tests in this PR. You will need to rebase this PR up to current master (to get the recent webUI test methods that are used). Then cherry-pick that commit c736a07 into this PR and push it up to GitHub. |
I realized that I can add the test commit myself to this PR, so I have done that. |
@PVince81 unit tests and webUI acceptance tests have been added here. |
apps/files_trashbin/js/filelist.js
Outdated
for (var i = 0; i < trSelectedFiles.length; i++) { | ||
filesFromAttribute.push(trSelectedFiles[i].getAttribute('data-file')); | ||
} | ||
if (files !== filesFromAttribute) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not sure this comparison is accurate as it might be comparing only the pointer reference and not the contents. Please use a clearer approach for this check.
apps/files_trashbin/js/filelist.js
Outdated
for (var i = 0; i < trSelectedFiles.length; i++) { | ||
filesFromAttribute.push(trSelectedFiles[i].getAttribute('data-file')); | ||
} | ||
if (files !== filesFromAttribute) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
duplicate code from above, please move to common method
@PVince81 I refactored that. And also, |
@phil-davis Even I was having same thought when asked to move the changes to common function. The |
apps/files_trashbin/js/filelist.js
Outdated
@@ -171,7 +186,7 @@ | |||
}; | |||
} | |||
else { | |||
files = _.pluck(this.getSelectedFiles(), 'name'); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Now that I understand this PR better, I'm a bit puzzled that the "name" attribute doesn't contain the combined name because the name displayed in the UI is supposed to be "displayName". Maybe that's another bug or regression.
An alternative and potentially better fix would be to adjust this class' elementToFile()
to add another attribute on the object containing the combined name.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I did acceptance and JS tests here, and just did a bit of refactoring of the JavaScript code because I thought it looked easy enough and would get this PR finished.
Now that there are classes and attributes and objects to be massaged, I will leave it to someone with real JavaScript coding skills :) @sharidas ?
At least there is a good set of JS unit tests and webUI acceptance tests, so you now easily know if a refactoring breaks some "important" behavior.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The name attribute does contain the compound name (tested on master):
and the "data-file" does contain the compound name, so I don't see the difference that the fix brings in regard to the name:
@sharidas was there something else ?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The problem happens when user select all and the unselect(s) from the list. In my case I tried select all.
-
The files I had in the trash were
a.txt
andb.txt
. Now I unselectedb.txt
. Next tried to deletea.txt
. Below is the screenshot where name has only a.txt:
-
Without selecting select all, and if I select specifically a file:
a.txt
the name becomes:
I guess @PVince81 the second option, right?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
hmm, then maybe the selection logic in "apps/files/js/filelist.js" has a general bug and we should rather fix it there instead of working it around in the trashbin list
this will need more debugging in the selection events
@@ -50,6 +50,29 @@ So that I can recover accidentally deleted files/folders in ownCloud | |||
But the file "data.zip" should not be listed in the files page on the webUI | |||
And the folder "simple-folder" should not be listed in the files page on the webUI | |||
|
|||
Scenario: Select all except for some trashbin files and restore them in a batch |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@phil-davis can you add a case where you delete two entries with the same name ?
basically create a folder "test", then deleted it, then another "test", delete it. they'd appear as two entries.
internally they have names with the timestamp appended (test.dXXXXXXX) but visually they look the same
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That will take more work. We have realized this before, but not yet done code to handle it in webUI tests. At the moment the webUI tests do things to file rows (on file page, favorites page, trashbin...) by finding the row with the matching displayed file name.
On favorites and trashbin you can have multiple files in the list with the same name. Currently we have not made code that lets you refer to "the second file called lorem.txt". And then it needs a way to say you want "the lorem.txt that came from folder f1", and that would look in the hover text on trashbin or favorites to see what the "real" location of the file is (which is something that users can do to distinguish which is the file they want to action).
That is not going to happen overnight. i raised issue #31038
Searched till 9.1.1 version. And this is broken in version 9.1.1. |
so version 9.1.0 was fine ? any changes ? git bisect will tell you |
Didn't bisected further. But I have my new finding as follows: |
Introducing "realname" is likely just a workaround for the real issue. |
/** | ||
* Event handler for when selecting/deselecting all files | ||
*/ | ||
_onClickSelectAll: function(e) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Override selectAll in trashbin. So The only difference between files/js/filelist.js and this filelist.js is from https://github.com/owncloud/core/pull/30993/files#diff-5016b1abbde02ec31bb639507f64d604R170 to https://github.com/owncloud/core/pull/30993/files#diff-5016b1abbde02ec31bb639507f64d604R176
i.e, addition of line:
this.files[i].name = this.files[i].name + '.d' +
Math.floor(this.files[i].mtime/1000);
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
looks better, need to find a way to prevent that much code duplication, could be done by introducing a new smaller method that can be overridden
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
seems we're getting closer and now I understand the actual problem better
apps/files_trashbin/js/filelist.js
Outdated
name of the files, i.e make the filenames real so that | ||
its appended with '.d' + mtime/1000 | ||
*/ | ||
this.files[i].name = this.files[i].name + '.d' + |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
not good as this would overwrite the existing data structure contents and will cause side effects
you need to make a copy of the file data, only replace the name there, not in the original array
/** | ||
* Event handler for when selecting/deselecting all files | ||
*/ | ||
_onClickSelectAll: function(e) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
looks better, need to find a way to prevent that much code duplication, could be done by introducing a new smaller method that can be overridden
09af122
to
4e6423b
Compare
apps/files_trashbin/js/filelist.js
Outdated
Any change to trashbinFiles will not have any change to this.files | ||
*/ | ||
var trashbinFiles = []; | ||
this.files.forEach((v, i) => { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do we have a better way to achieve a copy of this.file
update the name or does this look ok? Got this snippet while searching. This change does achieve the goal to not update this.files
.
apps/files/js/filelist.js
Outdated
@@ -704,15 +704,16 @@ | |||
/** | |||
* Event handler for when selecting/deselecting all files | |||
*/ | |||
_onClickSelectAll: function(e) { | |||
_onClickSelectAll: function(e, modifiedFiles) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Beware, the function is called from a jQuery event and I'm not sure whether the second param could have arbitrary values. Please double check.
Please update the JSDoc of the function
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Solution looks great, some small tweak, see comment :-)
apps/files/js/filelist.js
Outdated
* Check if there are no arbitrary keys that got into | ||
* modifiedFiles, which can cause irregular behaviours. | ||
*/ | ||
if (modifiedFiles && (modifiedFiles.length === this.files.length)) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Tried to verify at least the keys in modifiedFiles
are same as this.files
. Hope this check should be sufficient. If the keys are not same then immediate fall back to this.files
is made at https://github.com/owncloud/core/pull/30993/files#diff-dafefd9519924bec4efa9f5af4af8e68R729
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
comparing length doesn't guarantee that both arrays aren't the same and this approach looks like a hack
please find a more elegant way to solve this
The file selection process provides the result which has file name that doesn't match with the same in the filesystem. This is with reference to the trashbin. So lets say user tries to selectall, the value in this.files doesn't give the name which can be passed to the ajax request to delete or undelete for later actions. So the purpose of this change is to check if the selector is from trashbin, if so adjust the filename as filename + '.d' + mtime/1000. Signed-off-by: Sujith H <[email protected]>
Signed-off-by: Phil Davis <[email protected]>
Signed-off-by: Phil Davis <[email protected]>
Backport PR: #31700 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
👍
This thread has been automatically locked since there has not been any recent activity after it was closed. Please open a new issue for related bugs. |
When files were selected all, and later
selective files were opted for deletion,
the deletion was not happening. The reason
for this behaviour is filenames are passed
through ajax as seen in ui. Where as that
is not the case. This change helps to fix it.
Signed-off-by: Sujith H [email protected]
Description
The filenames passed in the ajax were the files seen in UI. But that is not the case with trashbin files. This change fixes the issue.
Related Issue
#30942
Motivation and Context
The filenames passed in the ajax were the files seen in UI. But that is not the case with trashbin files. This change fixes the issue.
How Has This Been Tested?
Screenshots (if appropriate):
Types of changes
Checklist: