summaryrefslogtreecommitdiff
path: root/script.js
blob: b10c6c7bc14afecce34b8d8f7b25ffd12d0f9bbb (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
const tbody = document.getElementById('tbody');

function newEl(tagname, content) {
	const cell = document.createElement(tagname);
	if (content instanceof Node)
		cell.appendChild(content);
	else
		cell.textContent = content;
	return cell;
}

const updateUrl = debounce(params => {
	if (Object.keys(params).length == 0)
		window.history.pushState({}, '', '/');
	else
		window.history.pushState({}, '', '?' + new URLSearchParams(params).toString());
}, 500);

function display(proposals) {
	const params = {};
	if (nameInput.value) {
		proposals = proposals.filter(p => (p.name || p.page_title).toLowerCase().includes(nameInput.value.toLowerCase()));
		params.q = nameInput.value;
	}

	if (authorsInput.value) {
		// The first letter of MediaWiki usernames is case-insensitive.
		const firstChar = authorsInput.value.charAt(0);
		const rest = authorsInput.value.slice(1);
		const lowercase = firstChar.toLowerCase() + rest;
		const uppercase = firstChar.toUpperCase() + rest;
		proposals = proposals.filter(p => p.authors && (p.authors.includes(lowercase) || p.authors.includes(uppercase)));
		params.author = authorsInput.value;
	}

	updateUrl(params);

	tbody.innerHTML = '';
	proposals.forEach(proposal => {
		const row = document.createElement('tr');

		const statusCell = newEl('td', proposal.status);
		statusCell.className = 'status-' + proposal.status;
		row.appendChild(statusCell);

		let date = '???';
		if (proposal.status == 'voting' || proposal.status == 'approved' || proposal.status == 'rejected') {
			date = proposal.vote_start;
		} else if (proposal.status == 'proposed') {
			date = proposal.rfc_start;
		} else {
			date = proposal.draft_start;
		}
		row.appendChild(newEl('td', date));

		const link = newEl('a', proposal.name || proposal.page_title);
		link.href = 'https://wiki.openstreetmap.org/wiki/' + proposal.page_title.replaceAll(' ', '_');
		row.appendChild(newEl('td', link));
		row.appendChild(newEl('td', proposal.authors));

		tbody.appendChild(row);
	});
}

const nameInput = document.getElementById('name');
const authorsInput = document.getElementById('authors');

function debounce(callback, wait) {
	let timeoutId = null;
	return (...args) => {
		window.clearTimeout(timeoutId);
		timeoutId = window.setTimeout(() => {
			callback.apply(null, args);
		}, wait);
	};
}

(async function() {
	const proposals = await (await fetch('proposals.json')).json();

	const params = new URLSearchParams(location.search);
	nameInput.value = params.get('q');
	authorsInput.value = params.get('author');

	display(proposals);

	nameInput.addEventListener('input', debounce(e => {
		display(proposals);
	}, 100));
	authorsInput.addEventListener('input', debounce(e => {
		display(proposals);
	}, 100));
})();