Repository: mozilla/pontoon

Issue:
Add an option to link to multiple strings
*This issue was created automatically by a [script](https://github.com/mathjazz/bugzilla2github/).*
## [Bug 1324933](https://bugzilla.mozilla.org/show_bug.cgi?id=1324933)
Bug Reporter: @tomer
CC:   @gaby2300, @ItielMaN, @mathjazz
Blocker for:  [Bug 1390931](https://bugzilla.mozilla.org/show_bug.cgi?id=1390931)

In dxr.mozilla.org I can select multiple lines in a file and than have a link that will show these lines highlighted. I'd suggest having a similar feature in pontoon, so we could send a team member a link that contains multiple strings, instead of one of the following workarounds:

* Sending one string per link
* Sending link to a search results or a resource, and asking them to look on the second string, the third from the bottom, etc. 

I'd like to have a link similar to this one: 
https://pontoon.mozilla.org/he/firefox-aurora/all-resources/?string=75295,75296 
… Which will show me both strings in the list.


As for the UI for creating such lists, I guess having control-click to toggle multiple selections will be enough; this is an advanced feature after all. ☺


Discussion:

Resolving patch:
diff --git a/pontoon/projects/management/commands/send_review_notifications.py b/pontoon/projects/management/commands/send_review_notifications.py
--- a/pontoon/projects/management/commands/send_review_notifications.py
+++ b/pontoon/projects/management/commands/send_review_notifications.py
@@ -1,6 +1,5 @@
 from collections import defaultdict
 from datetime import timedelta
-from urllib.parse import urlencode
 
 from django.core.management.base import BaseCommand
 from django.db.models import Q
@@ -13,7 +12,7 @@
 class Command(BaseCommand):
     help = "Notify translators about their newly reviewed suggestions"
 
-    def get_description(self, author, notifyData):
+    def get_description(self, notifyData):
         desc = "Your suggestions have been reviewed:\n<ul>"
 
         for (locale, project), (approved, rejected) in notifyData.items():
@@ -25,11 +24,8 @@ def get_description(self, author, notifyData):
                     "resource": "all-resources",
                 },
             )
-            url += "?" + urlencode({"author": author.email})
-            if len(approved) == 1 and len(rejected) == 0:
-                url += "&" + urlencode({"string": approved[0]})
-            elif len(approved) == 0 and len(rejected) == 1:
-                url += "&" + urlencode({"string": rejected[0]})
+            list = map(str, approved + rejected)
+            url += "?list=" + ",".join(list)
 
             # Filter out rejections where the author's own suggestion replaced the previous
             rejected = [x for x in rejected if x not in approved]
@@ -73,7 +69,7 @@ def handle(self, *args, **options):
                 data[author][(locale, project)][1].append(suggestion.entity.pk)
 
         for author, notifyData in data.items():
-            desc = self.get_description(author, notifyData)
+            desc = self.get_description(notifyData)
             notify.send(
                 sender=author,
                 recipient=author,


Test patch:
diff --git a/translate/src/context/location.test.js b/translate/src/context/location.test.js
--- a/translate/src/context/location.test.js
+++ b/translate/src/context/location.test.js
@@ -19,7 +19,7 @@ describe('LocationProvider', () => {
     });
   });
 
-  it('correctly parses the query string', () => {
+  it('correctly parses a query string', () => {
     const history = {
       location: {
         pathname: '/kg/waterwolf/path/',
@@ -36,4 +36,23 @@ describe('LocationProvider', () => {
       status: 'missing,warnings',
     });
   });
+
+  it('correctly parses a query string with a list', () => {
+    const history = {
+      location: {
+        pathname: '/kg/waterwolf/path/',
+        search: '?status=missing,warnings&list=13,42,99&string=42',
+      },
+    };
+    const wrapper = shallow(<LocationProvider history={history} />);
+
+    expect(wrapper.prop('value')).toMatchObject({
+      locale: 'kg',
+      project: 'waterwolf',
+      resource: 'path',
+      entity: 42,
+      list: [13, 42, 99],
+      status: null,
+    });
+  });
 });
diff --git a/translate/src/modules/search/components/SearchBox.test.js b/translate/src/modules/search/components/SearchBox.test.js
--- a/translate/src/modules/search/components/SearchBox.test.js
+++ b/translate/src/modules/search/components/SearchBox.test.js
@@ -233,6 +233,7 @@ describe('<SearchBoxBase>', () => {
         tag: 'browser',
         time: '111111111111-111111111111',
         entity: 0,
+        list: null,
       }),
     ).toBeTruthy();
   });