Skip to content

Commit 27eda43

Browse files
authored
Add date filters to tech report (#1218)
* Add date filters to tech report * Linting
1 parent 5b22330 commit 27eda43

File tree

10 files changed

+139
-9
lines changed

10 files changed

+139
-9
lines changed

package-lock.json

Lines changed: 11 additions & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

server/routes.py

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
11
import re
2+
from datetime import datetime
3+
24

35
from flask import abort, jsonify, redirect, request, send_from_directory
46
from urllib.parse import urlsplit, urlunsplit, parse_qsl, urlencode
@@ -10,6 +12,7 @@
1012
from . import talisman
1113
from . import techreport as tech_report_util
1214
from . import url_for
15+
from .dates import get_dates
1316

1417

1518
def safe_int(value, default=1):
@@ -145,6 +148,17 @@ def techreportlanding(page_id):
145148

146149
last_page = request.args.get("last_page") or False
147150

151+
all_dates = [
152+
{
153+
"value": d.replace("_", "-"),
154+
"display": datetime.strptime(d, "%Y_%m_%d").strftime("%b %Y"),
155+
}
156+
for d in get_dates()
157+
]
158+
159+
requested_start = request.args.get("start") or ""
160+
requested_end = request.args.get("end") or ""
161+
148162
filters = {
149163
"geo": requested_geo,
150164
"rank": requested_rank,
@@ -154,6 +168,8 @@ def techreportlanding(page_id):
154168
"last_page": last_page,
155169
"selected": selected_techs,
156170
"rows": selected_rows,
171+
"start": requested_start,
172+
"end": requested_end,
157173
}
158174
params = {
159175
"geo": requested_geo.replace(" ", "+"),
@@ -171,6 +187,7 @@ def techreportlanding(page_id):
171187
tech_report_page=active_tech_report,
172188
custom_navigation=True,
173189
reports=all_reports,
190+
all_dates=all_dates,
174191
)
175192

176193

@@ -209,11 +226,25 @@ def techreport():
209226
requested_geo = request.args.get("geo") or "ALL"
210227
requested_rank = request.args.get("rank") or "ALL"
211228
requested_category = request.args.get("category") or "ALL"
229+
230+
all_dates = [
231+
{
232+
"value": d.replace("_", "-"),
233+
"display": datetime.strptime(d, "%Y_%m_%d").strftime("%b %Y"),
234+
}
235+
for d in get_dates()
236+
]
237+
238+
requested_start = request.args.get("start") or ""
239+
requested_end = request.args.get("end") or ""
240+
212241
filters = {
213242
"geo": requested_geo,
214243
"rank": requested_rank,
215244
"app": requested_technologies,
216245
"category": requested_category,
246+
"start": requested_start,
247+
"end": requested_end,
217248
}
218249
params = {
219250
"geo": requested_geo.replace(" ", "+"),
@@ -242,6 +273,7 @@ def techreport():
242273
tech_report_page=active_tech_report,
243274
custom_navigation=True,
244275
reports=all_reports,
276+
all_dates=all_dates,
245277
)
246278

247279

server/tests/routes_test.py

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -278,6 +278,29 @@ def test_tech_report_invalid_page(client):
278278
assert response.status_code == 404
279279

280280

281+
def test_tech_report_drilldown_with_dates(client):
282+
response = client.get(
283+
"/reports/techreport/tech?tech=WordPress&geo=ALL&rank=ALL&start=2024-01-01&end=2024-03-01"
284+
)
285+
data = response.get_data(as_text=True)
286+
assert response.status_code == 200
287+
assert 'value="2024-01-01" selected' in data
288+
assert 'value="2024-03-01" selected' in data
289+
assert 'value="2025-01-01" selected' not in data
290+
291+
292+
def test_tech_report_comparison_with_dates(client):
293+
response = client.get(
294+
"/reports/techreport/tech?tech=jQuery%2CWordPress&geo=ALL&rank=ALL&start=2024-01-01&end=2024-03-01"
295+
)
296+
assert response.status_code == 200
297+
data = response.get_data(as_text=True)
298+
assert response.status_code == 200
299+
assert 'value="2024-01-01" selected' in data
300+
assert 'value="2024-03-01" selected' in data
301+
assert 'value="2025-01-01" selected' not in data
302+
303+
281304
def test_well_known_atproto_did(client):
282305
response = client.get("/.well-known/atproto-did")
283306
assert response.status_code == 200

src/js/components/filters.js

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,8 @@ class Filters {
4848
const geo = document.getElementsByName('geo')[0].value;
4949
const rank = document.getElementsByName('rank')[0].value;
5050
const categories = document.getElementsByName('categories')[0]?.value;
51+
const startDate = document.getElementsByName('startDate')[0]?.value;
52+
const endDate = document.getElementsByName('endDate')[0]?.value;
5153

5254
/* Create a string of technologies */
5355
let technologies = [];
@@ -75,6 +77,16 @@ class Filters {
7577
url.searchParams.append('category', categories);
7678
}
7779

80+
url.searchParams.delete('start');
81+
if (startDate) {
82+
url.searchParams.append('start', startDate);
83+
}
84+
85+
url.searchParams.delete('end');
86+
if (endDate) {
87+
url.searchParams.append('end', endDate);
88+
}
89+
7890
// Reset to page 1 when filters change
7991
url.searchParams.delete('page');
8092
url.searchParams.append('page', '1');

src/js/techreport/index.js

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -241,13 +241,21 @@ class TechReport {
241241

242242
const geo = this.filters.geo.replaceAll(" ", "%20");
243243
const rank = this.filters.rank.replaceAll(" ", "%20");
244+
const start = this.filters.start;
245+
const end = this.filters.end;
244246

245247
let allResults = {};
246248
let techInfo = {};
247249
technologies.forEach(tech => allResults[tech] = []);
248250

249251
Promise.all(apis.map(api => {
250-
const url = `${Constants.apiBase}/${api.endpoint}?technology=${technology}&geo=${geo}&rank=${rank}`;
252+
let url = `${Constants.apiBase}/${api.endpoint}?technology=${technology}&geo=${geo}&rank=${rank}`;
253+
if (start) {
254+
url += `&start=${start}`;
255+
}
256+
if (end) {
257+
url += `&end=${end}`;
258+
}
251259

252260
return fetch(url)
253261
.then(result => result.json())

src/js/techreport/tableLinked.js

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,8 @@ class TableLinked {
5454
const filters = new URLSearchParams(window.location.search);
5555
const geo = filters.get('geo') || 'ALL';
5656
const rank = filters.get('rank') || 'ALL';
57+
const start = filters.get('start') || '';
58+
const end = filters.get('end') || '';
5759

5860
// sort data
5961
const sortEndpoint = component.dataset.sortEndpoint;
@@ -117,7 +119,7 @@ class TableLinked {
117119

118120
const formattedApp = DataUtils.formatAppName(app);
119121
const link = document.createElement('a');
120-
link.setAttribute('href', `/reports/techreport/tech?tech=${app}&geo=${geo}&rank=${rank}`);
122+
link.setAttribute('href', `/reports/techreport/tech?tech=${app}&geo=${geo}&rank=${rank}${start ? '&start=' + start : ''}${end ? '&end=' + end : ''}`);
121123
link.innerText = formattedApp;
122124
wrapper.append(link);
123125
cell.append(wrapper);

static/css/techreport/techreport.css

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -613,24 +613,23 @@ nav {
613613
color: var(--color-text-darker);
614614
}
615615

616-
/* Page filters: Geo and rank */
617-
#page-filters .lens {
616+
#page-filters :is(.lens, .date-range) {
618617
margin-bottom: 1.5rem;
619618
margin-right: 0;
620619
margin-top: 1.5rem;
621620
border-bottom: 1px solid var(--color-separator);
622621
padding-bottom: 2rem;
623622
}
624623

625-
#page-filters .lens label,
624+
#page-filters :is(.lens, .date-range) label,
626625
.breakdown label {
627626
color: var(--color-text);
628627
font-size: 0.875rem;
629628
font-weight: 600;
630629
width: 100%;
631630
}
632631

633-
#page-filters .lens .select-label select {
632+
#page-filters :is(.lens, .date-range) .select-label select {
634633
color: var(--color-text-darker);
635634
font-size: 0.9rem;
636635
width: 100%;
@@ -645,7 +644,7 @@ nav {
645644
border: none;
646645
}
647646

648-
#page-filters .lens .select-label:not(:last-of-type) {
647+
#page-filters :is(.lens, .date-range) .select-label:not(:last-of-type) {
649648
margin-bottom: 2rem;
650649
}
651650

templates/report/report.html

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -92,7 +92,7 @@ <h1>
9292
</div>
9393

9494
<div class="col-sm-4 col-xs-12">
95-
<label for="endDate" title="Optional">
95+
<label for="endDate">
9696
End Date
9797
</label>
9898

templates/techreport/templates/filters.html

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,48 @@
5050
</div>
5151
</div>
5252
</fieldset>
53+
<fieldset class="date-range">
54+
<legend class="sr-only">Date range</legend>
55+
<div class="default-dropdown-group">
56+
<label for="startDate">Start Date</label>
57+
<div class="default-dropdown-wrapper">
58+
<select name="startDate" id="startDate" class="default-dropdown" disabled>
59+
<option value=""></option>
60+
{% for d in all_dates %}
61+
{% if d.value==tech_report_page.filters.start %}
62+
<option value="{{ d.value }}" selected>
63+
{{ d.display }}
64+
</option>
65+
{% else %}
66+
<option value="{{ d.value }}">
67+
{{ d.display }}
68+
</option>
69+
{% endif %}
70+
{% endfor %}
71+
</select>
72+
</div>
73+
</div>
74+
75+
<div class="default-dropdown-group">
76+
<label for="endDate">End Date</label>
77+
<div class="default-dropdown-wrapper">
78+
<select name="endDate" id="endDate" class="default-dropdown" disabled>
79+
<option value=""></option>
80+
{% for d in all_dates %}
81+
{% if d.value==tech_report_page.filters.end %}
82+
<option value="{{ d.value }}" selected>
83+
{{ d.display }}
84+
</option>
85+
{% else %}
86+
<option value="{{ d.value }}">
87+
{{ d.display }}
88+
</option>
89+
{% endif %}
90+
{% endfor %}
91+
</select>
92+
</div>
93+
</div>
94+
</fieldset>
5395
</div>
5496
<button type="submit" id="submit-form" class="main-btn">Update</button>
5597
{% include "techreport/components/filter_meta.html" %}

tools/test/test_status_codes.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,8 @@ const test_status_codes = async () => {
6767
await test_status_code('/reports/techreport/landing', 200);
6868
await test_status_code('/reports/techreport/drilldown', 200);
6969
await test_status_code('/reports/techreport/comparison', 200);
70+
await test_status_code('/reports/techreport/tech?tech=WordPress&geo=ALL&rank=ALL&start=2024-01-01&end=2024-03-01', 200);
71+
await test_status_code('/reports/techreport/tech?tech=jQuery%2CWordPress&geo=ALL&rank=ALL&start=2024-01-01&end=2024-03-01', 200);
7072

7173
// Test non-sitemap pages
7274
await test_status_code('/sitemap.xml', 200);

0 commit comments

Comments
 (0)