diff --git a/app/js/query.js b/app/js/query.js index 4fa3e0d..04452a0 100644 --- a/app/js/query.js +++ b/app/js/query.js @@ -19,6 +19,18 @@ const ANONYMOUS = { ONLY: 'only' }; +const COMMENTED = { + INCLUDE: 'include', + HIDE: 'hide', + ONLY: 'only' +}; + +const AREA = { + GLOBAL: 'global', + VIEW: 'view', + CUSTOM: 'custom' +} + const SORT = { CREATED_AT: 'created_at', UPDATED_AT: 'updated_at' @@ -33,25 +45,29 @@ const ORDER = { // Values which are null by default are not included, because they are removed in a different step. const DEFAULTS = { UI: { - 'apply-bbox': false, limit: 50, status: STATUS.OPEN, anonymous: ANONYMOUS.INCLUDE, + commented: COMMENTED.INCLUDE, // Specific frontend values which are not send to the API but transformed to another value before sort: `${SORT.CREATED_AT}:${ORDER.DESCENDING}`, - uncommented: false + area: AREA.GLOBAL }, API: { - 'apply-bbox': false, limit: 50, status: STATUS.ALL, anonymous: ANONYMOUS.INCLUDE, + commented: COMMENTED.INCLUDE, // Specific API values which are not used for the permalink sort_by: SORT.UPDATED_AT, // eslint-disable-line camelcase order: ORDER.DESCENDING } }; +const NOT_MODIFIABLE_BY_USER = [ + 'bbox', 'polygon', 'sort_by', 'order' +]; + export default class Query { /** * Constructor for a new query @@ -73,8 +89,11 @@ export default class Query { id: 'bbox', handler: this.bbox }, { - id: 'apply-bbox', - handler: this.applyBBox + id: 'polygon', + handler: this.polygon + }, { + id: 'area', + handler: this.area }, { id: 'limit', handler: this.limit @@ -97,9 +116,8 @@ export default class Query { permalink: 'before', handler: this.before }, { - id: 'only-uncommented', - permalink: 'uncommented', - handler: this.uncommented + id: 'commented', + handler: this.commented }, { id: 'sort', handler: this.sort @@ -192,10 +210,37 @@ export default class Query { return this; } + /** + * Search only in the given polygon + * + * @function + * @param {String} polygon + * @returns {Query} + */ + polygon(polygon) { + this.data.polygon = polygon; + return this; + } + + /** + * Whether the search should return notes globally, in the current view or a custom area + * + * @function + * @param {AREA} area + * @returns {Query} + */ + area(area) { + this.data.area = area; + return this; + } + + + /** * Whether the search should only return notes in the current bounding box * * @function + * @deprecated * @param {Boolean} enabled * @returns {Query} */ @@ -293,6 +338,7 @@ export default class Query { * Filter notes by the amount of comments * * @function + * @deprecated * @param {Number} comments * @returns {Query} */ @@ -305,6 +351,7 @@ export default class Query { * Whether to include only uncommented notes * * @function + * @deprecated * @param {Boolean} uncommented * @returns {Query} */ @@ -314,6 +361,18 @@ export default class Query { return this; } + /** + * Whether commented notes should be included, hidden or displayed as only results + * + * @function + * @param {COMMENTED} commented + * @returns {Query} + */ + commented(commented) { + this.data.commented = commented; + return this; + } + /** * Sort notes by their creation date or the date of the last update in the given order * @@ -342,8 +401,13 @@ export default class Query { // that are necessary for the construction of the URL const data = Object.assign({}, this.data); - // Do not use the bounding box if the user wants to do a global search - data['apply-bbox'] ? null : delete data.bbox; // eslint-disable-line no-unused-expressions + // Do not use the bounding box/polygon if the user does not want to do the respective search + if (data.area !== AREA.VIEW) { + delete data.bbox; + } + if (data.area !== AREA.CUSTOM) { + delete data.polygon; + } if (data.before !== null) { // Increment the actual date by a single day, to simulate a closed interval [from, to] @@ -356,8 +420,8 @@ export default class Query { } // Remove unused properties that are already set by another value - delete data.uncommented; delete data.sort; + delete data.area; url.search = Request.encodeQueryData(Util.clean(data, DEFAULTS.API)); return url.toString(); @@ -378,11 +442,15 @@ export default class Query { map: `${this.map.zoom()}/${this.map.center().lat}/${this.map.center().lng}`, }, this.data); - // Do not use the bounding box if the user wants to do a global search - data['apply-bbox'] ? null : delete data.bbox; // eslint-disable-line no-unused-expressions + // Do not use the bounding box/polygon if the user does not want to do the respective search + if (data.area !== AREA.VIEW) { + delete data.bbox; + } + if (data.area !== AREA.CUSTOM) { + delete data.polygon; + } // Remove unused properties that are already set by another value - delete data.comments; delete data.sort_by; delete data.order; @@ -412,7 +480,7 @@ export default class Query { // Find all values that are not default values or null and can be changed by the user directly via the user interface const nonDefaults = Object.entries(Util.clean(this.data, DEFAULTS.UI)) .reduce((a, [key, value]) => - ((value == null || key == 'bbox' || key == 'comments' || key == 'sort_by' || key == 'order') + ((value == null || NOT_MODIFIABLE_BY_USER.includes(key)) ? a : (a[key] = value, a)), {}); const amountOfNonDefaults = Object.keys(nonDefaults).length; diff --git a/app/locales/de.json b/app/locales/de.json index 536d07b..e29d490 100644 --- a/app/locales/de.json +++ b/app/locales/de.json @@ -56,7 +56,9 @@ "to": "Bis", "sort": "Sortieren nach", "status": "Status", - "anonymous": "Anonyme Notizen" + "anonymous": "Anonyme Notizen", + "area": "Suchgebiet", + "commented": "Kommentierte Notizen" }, "description": { "share": "Kopiere diesen Link um die aktuelle Abfrage zu teilen:", @@ -78,8 +80,6 @@ } }, "query": "Ein Wort oder ein Satz, der in der Notiz enthalten ist", - "applyBoundingBox": "Nur in der aktuellen Ansicht suchen", - "onlyUncommented": "Nur unkommentierte Notizen anzeigen", "status": { "all": "Alle", "open": "Offen", @@ -92,7 +92,17 @@ }, "statistics": "%s Notizen gefunden", "from": "Ein Datum (UTC) als untere Grenze", - "to": "Ein Datum (UTC) als obere Grenze" + "to": "Ein Datum (UTC) als obere Grenze", + "area": { + "global": "Weltweit", + "view": "Aktuelle Ansicht", + "custom": "Bestimmter Bereich" + }, + "commented": { + "include": "Anzeigen", + "hide": "Verstecken", + "only": "Ausschließlich" + } }, "settings": { "choose": "Wähle eine Option", diff --git a/app/locales/en.json b/app/locales/en.json index ba4ca07..5a0a7c9 100644 --- a/app/locales/en.json +++ b/app/locales/en.json @@ -56,7 +56,9 @@ "to": "To", "sort": "Sort by", "status": "Status", - "anonymous": "Anonymous notes" + "anonymous": "Anonymous notes", + "area": "Search area", + "commented": "Commented notes" }, "description": { "share": "Copy this link to share the current query:", @@ -78,8 +80,6 @@ } }, "query": "A word or phrase mentioned in the note", - "applyBoundingBox": "Search only in current view", - "onlyUncommented": "Show only uncommented notes", "status": { "all": "All", "open": "Open", @@ -92,7 +92,17 @@ }, "statistics": "Found %s notes", "from": "A date (UTC) as lower limit", - "to": "A date (UTC) as upper limit" + "to": "A date (UTC) as upper limit", + "area": { + "global": "Global", + "view": "Current view", + "custom": "Custom area" + }, + "commented": { + "include": "Include", + "hide": "Hide", + "only": "Only" + } }, "settings": { "choose": "Choose an option", diff --git a/app/templates/includes/nav.hbs b/app/templates/includes/nav.hbs index 55984ab..a23271d 100644 --- a/app/templates/includes/nav.hbs +++ b/app/templates/includes/nav.hbs @@ -73,19 +73,27 @@ + +
+ + +
+
- + + + + + +
- + + + + + +