Repository: wagtail/wagtail

Issue:
Respect already selected collection when adding new documents or images
### Is your proposal related to a problem?

Documents and Images list views allows filtering by Collection. Choosing a collection and clicking on "Add a document" opens a new view, where first (Root) collection is selected. This causes confusion to some users and makes them make mistakes where the document would be uploaded.



### Describe the solution you'd like

It would be great if a button to add new documents would transfer currently selected collection id as parameter to multiple add view.  This way current user would upload files to already choosen collection, which looks like right thing to do, especially if there are more then few collections.

![wagtail-current-collection-in-add-view](https://user-images.githubusercontent.com/13813/117170977-c2e94a80-adca-11eb-8216-1d083e1682c4.png)


### Describe alternatives you've considered

Did not found any other alternative for this.

### Additional context

This should be pretty easy to implement, in few steps:

1. [AddView](https://github.com/wagtail/wagtail/blob/main/wagtail/admin/views/generic/multiple_upload.py#L160) would accept optional query parameter `collection_id` and pass it to template, which would select current collection.
2. [document index template](https://github.com/wagtail/wagtail/blob/main/wagtail/documents/templates/wagtaildocs/documents/index.html) already has `current_collection`, so the only change required here would be to pass it to `wagtaildocs:add_multiple` url
3. change in second step would be made in [image index template](https://github.com/wagtail/wagtail/blob/main/wagtail/images/templates/wagtailimages/images/index.html)

If there are no objections for this, I can prepare pull request.


Discussion:
A nice additional touch here would be to have `AddView` and `EditView` both pick up the `collection_id` from the URL and redirect back to a collection-filtered listing once the item is saved.
I'm working on it

Resolving patch:
diff --git a/wagtail/admin/views/generic/multiple_upload.py b/wagtail/admin/views/generic/multiple_upload.py
--- a/wagtail/admin/views/generic/multiple_upload.py
+++ b/wagtail/admin/views/generic/multiple_upload.py
@@ -171,6 +171,7 @@ def get_context_data(self, **kwargs):
         # actual rendering of forms will happen on AJAX POST rather than here
         upload_form_class = self.get_upload_form_class()
         self.form = upload_form_class(user=self.request.user)
+        selected_collection_id = self.request.GET.get("collection_id")
 
         collections = self.permission_policy.collections_user_has_permission_for(
             self.request.user, "add"
@@ -184,6 +185,7 @@ def get_context_data(self, **kwargs):
                 "help_text": self.form.fields["file"].help_text,
                 "collections": collections,
                 "form_media": self.form.media,
+                "selected_collection_id": selected_collection_id,
             }
         )
 


Test patch:
diff --git a/wagtail/documents/tests/test_admin_views.py b/wagtail/documents/tests/test_admin_views.py
--- a/wagtail/documents/tests/test_admin_views.py
+++ b/wagtail/documents/tests/test_admin_views.py
@@ -132,6 +132,19 @@ def test_index_with_collection(self):
             ["Root", "Evil plans", "Good plans"],
         )
 
+    def test_index_with_collection_filtered(self):
+        root_collection = Collection.get_first_root_node()
+        travel_plans = root_collection.add_child(name="Travel plans")
+
+        self.make_docs()
+
+        response = self.get({"collection_id": travel_plans.pk})
+        # should append the correct params to the add document button
+        url = reverse("wagtaildocs:add_multiple")
+        self.assertContains(
+            response, f'<a href="{url}?collection_id={travel_plans.pk}"'
+        )
+
     def test_collection_nesting(self):
         root_collection = Collection.get_first_root_node()
         evil_plans = root_collection.add_child(name="Evil plans")
@@ -819,10 +832,21 @@ def test_add_with_collections(self):
         self.assertEqual(response.status_code, 200)
         self.assertTemplateUsed(response, "wagtaildocs/multiple/add.html")
 
-        # collection chooser should exisst
+        # collection chooser should exist
         self.assertContains(response, "id_adddocument_collection")
         self.assertContains(response, "Evil plans")
 
+    def test_add_with_selected_collection(self):
+        root_collection = Collection.get_first_root_node()
+        collection = root_collection.add_child(name="Evil plans")
+
+        response = self.client.get(
+            reverse("wagtaildocs:add_multiple") + f"?collection_id={collection.pk}"
+        )
+        self.assertEqual(response.status_code, 200)
+        # collection chooser should have selected collection passed with parameter
+        self.assertContains(response, f'<option value="{collection.pk}" selected>')
+
     def test_add_post(self):
         """
         This tests that a POST request to the add view saves the document and returns an edit form
diff --git a/wagtail/images/tests/test_admin_views.py b/wagtail/images/tests/test_admin_views.py
--- a/wagtail/images/tests/test_admin_views.py
+++ b/wagtail/images/tests/test_admin_views.py
@@ -106,6 +106,13 @@ def test_collection_query_search(self):
         for i in range(0, 10, 2):
             self.assertIn("Baker %i" % i, response_body)
 
+        # should append the correct params to the add images button
+        url = reverse("wagtailimages:add_multiple")
+        self.assertContains(
+            response,
+            f'<a href="{url}?q=Baker&amp;collection_id={child_collection[0].pk}"',
+        )
+
     def test_pagination(self):
         pages = ["0", "1", "-1", "9999", "Not a page"]
         for page in pages:
@@ -612,6 +619,19 @@ def test_add_with_collections(self):
         image = images.first()
         self.assertEqual(image.collection, evil_plans_collection)
 
+    def test_add_with_selected_collection(self):
+
+        root_collection = Collection.get_first_root_node()
+        collection = root_collection.add_child(name="Travel pics")
+
+        response = self.client.get(
+            reverse("wagtailimages:add_multiple") + f"?collection_id={collection.pk}"
+        )
+        self.assertEqual(response.status_code, 200)
+
+        # collection chooser should have selected collection passed with parameter
+        self.assertContains(response, f'option value="{collection.pk}" selected')
+
     @override_settings(WAGTAILIMAGES_IMAGE_MODEL="tests.CustomImage")
     def test_unique_together_validation_error(self):
         root_collection = Collection.get_first_root_node()