-
-
Notifications
You must be signed in to change notification settings - Fork 2
Expand file tree
/
Copy pathroadmap.js
More file actions
213 lines (170 loc) · 8.24 KB
/
Copy pathroadmap.js
File metadata and controls
213 lines (170 loc) · 8.24 KB
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
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
function applyLabelStyle(labelEl, color) {
labelEl.style.backgroundColor = `#${color}`;
const r = Number.parseInt(color.substring(0, 2), 16);
const g = Number.parseInt(color.substring(2, 4), 16);
const b = Number.parseInt(color.substring(4, 6), 16);
const brightness = (r * 299 + g * 587 + b * 114) / 1000;
labelEl.style.color = brightness > 125 ? '#000' : '#fff';
}
document.addEventListener('DOMContentLoaded', function() {
const issuesList = document.getElementById('issues-container');
const issueModal = new bootstrap.Modal(document.getElementById('issueModal'));
const issueModalBody = document.getElementById('issueModalBody');
const issueModalLabel = document.getElementById('issueModalLabel');
const viewOnGithubBtn = document.getElementById('viewOnGithub');
// GitHub API endpoint for your repository's issues
const apiUrl = 'https://api.github.com/repos/LizardByte/roadmap/issues?state=open&labels=planned&per_page=100';
fetch(apiUrl)
.then(response => {
if (!response.ok) {
throw new Error('Network response was not ok');
}
return response.json();
})
.then(issues => {
if (issues.length === 0) {
issuesList.innerHTML = '<p>No roadmap items found.</p>';
return;
}
// Clear loading message
issuesList.innerHTML = '';
issues.forEach(issue => {
const issueCol = document.createElement('div');
issueCol.className = 'col-lg-4 mb-5';
const issueEl = document.createElement('div');
issueEl.className = 'card h-100 shadow border-0 rounded-0';
issueEl.style.cursor = 'pointer';
// Store issue data for modal
issueEl.dataset.issue = JSON.stringify(issue);
// Click event to show modal
issueEl.addEventListener('click', function() {
const issueData = JSON.parse(this.dataset.issue);
displayIssueInModal(issueData);
});
const cardBody = document.createElement('div');
cardBody.className = 'card-body p-4 rounded-0';
// Issue title
const titleEl = document.createElement('h5');
titleEl.className = 'card-title mb-3 fw-bolder crowdin-ignore';
const titleText = document.createElement('span');
titleText.textContent = issue.title;
titleText.className = 'text-decoration-none';
titleEl.appendChild(titleText);
// Issue metadata
const metaEl = document.createElement('div');
metaEl.className = 'd-flex justify-content-between mb-2 small';
// Issue number
const numberEl = document.createElement('span');
numberEl.className = 'badge bg-secondary crowdin-ignore';
numberEl.textContent = `#${issue.number}`;
// Issue date
const dateEl = document.createElement('span');
dateEl.className = 'crowdin-ignore';
const createdDate = new Date(issue.created_at);
dateEl.textContent = createdDate.toLocaleDateString();
metaEl.appendChild(numberEl);
metaEl.appendChild(dateEl);
// Labels
const labelsEl = document.createElement('div');
labelsEl.className = 'd-flex flex-wrap gap-1 mb-2';
// Sort labels alphabetically by name
const sortedLabels = [...issue.labels].sort((a, b) =>
a.name.toLowerCase().localeCompare(b.name.toLowerCase())
);
sortedLabels.forEach(label => {
const labelEl = document.createElement('span');
labelEl.className = 'badge crowdin-ignore';
labelEl.textContent = label.name;
applyLabelStyle(labelEl, label.color);
labelsEl.appendChild(labelEl);
});
// Add all elements to the card body
cardBody.appendChild(titleEl);
cardBody.appendChild(metaEl);
cardBody.appendChild(labelsEl);
issueEl.appendChild(cardBody);
issueCol.appendChild(issueEl);
issuesList.appendChild(issueCol);
});
})
.catch(error => {
issuesList.innerHTML = `<p class="text-danger">Error loading roadmap items: ${error.message}</p>`;
});
// Function to display issue in modal
function displayIssueInModal(issue) {
// Set modal title
issueModalLabel.textContent = `${issue.title} (#${issue.number})`;
// Set GitHub link
viewOnGithubBtn.href = issue.html_url;
// Create modal content
let modalContent = document.createElement('div');
// Issue metadata
const metaEl = document.createElement('div');
metaEl.className = 'd-flex justify-content-between mb-3';
// Issue created date
const createdEl = document.createElement('span');
const createdLabel = document.createElement('strong');
createdLabel.textContent = 'Created:';
createdEl.appendChild(createdLabel);
createdEl.appendChild(document.createTextNode(' '));
const createdValue = document.createElement('span');
createdValue.className = 'crowdin-ignore';
const createdDate = new Date(issue.created_at);
createdValue.textContent = createdDate.toLocaleDateString();
createdEl.appendChild(createdValue);
// Issue author
const authorEl = document.createElement('span');
const authorLabel = document.createElement('strong');
authorLabel.textContent = 'By:';
authorEl.appendChild(authorLabel);
authorEl.appendChild(document.createTextNode(' '));
const authorValue = document.createElement('span');
authorValue.className = 'crowdin-ignore';
authorValue.textContent = issue.user.login;
authorEl.appendChild(authorValue);
metaEl.appendChild(createdEl);
metaEl.appendChild(authorEl);
modalContent.appendChild(metaEl);
// Labels
if (issue.labels && issue.labels.length > 0) {
const labelsContainer = document.createElement('div');
labelsContainer.className = 'mb-3';
const labelsTitle = document.createElement('strong');
labelsTitle.textContent = 'Labels:';
labelsContainer.appendChild(labelsTitle);
const labelsEl = document.createElement('div');
labelsEl.className = 'd-flex flex-wrap gap-1 mt-1';
issue.labels.forEach(label => {
const labelEl = document.createElement('span');
labelEl.className = 'badge crowdin-ignore';
labelEl.textContent = label.name;
applyLabelStyle(labelEl, label.color);
labelsEl.appendChild(labelEl);
});
labelsContainer.appendChild(labelsEl);
modalContent.appendChild(labelsContainer);
}
// Issue body
const bodyContainer = document.createElement('div');
bodyContainer.className = 'mt-3 p-3 rounded-0';
if (issue.body) {
// Create a container with crowdin-ignore class for the entire rendered content
const markdownContainer = document.createElement('div');
markdownContainer.className = 'crowdin-ignore';
// Use Marked to parse the markdown
markdownContainer.innerHTML = marked.parse(issue.body);
// Add the rendered content to the body container
bodyContainer.appendChild(markdownContainer);
} else {
const noContentMsg = document.createElement('div');
noContentMsg.textContent = 'No description provided.';
bodyContainer.appendChild(noContentMsg);
}
modalContent.appendChild(bodyContainer);
// Set modal content
issueModalBody.innerHTML = '';
issueModalBody.appendChild(modalContent);
// Show modal
issueModal.show();
}
});