forked from creativecommons/ccos-website-source
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathissue-finder.js
180 lines (156 loc) · 6.06 KB
/
issue-finder.js
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
import { Octokit } from "@octokit/rest"; // GitHub API
import yaml from "js-yaml"; // Parse YAML files into JS objects
// Wait for the DOM to fully load before running the script
document.addEventListener("DOMContentLoaded", function () {
// HTML element references
const issuesContainer = document.getElementById("issues-container");
const aimDropdown = document.getElementById("aim");
const skillsDropdown = document.getElementById("skills");
const experienceDropdown = document.getElementById("experience");
const skillFiltersDiv = document.getElementById("skill-filters");
// Base URL for fetching YAML data
const BASE_YAML_URL =
"https://raw.githubusercontent.com/creativecommons/ccos-scripts/main/ccos/norm";
const getYamlFileUrl = (fileName) => `${BASE_YAML_URL}/${fileName}.yml`;
// Initial state for issues and filters
let issuesList = []; //
const userFilters = {
aim: "contribute", // Default to "Contribute"
skills: [], // Default to "No preferences"
experience: "experienced", // Default to "Experienced"
};
// Fetch and load filter data (skills and labels)
async function fetchFilterData() {
try {
const [skillsYaml, labelsYaml] = await Promise.all([
fetch(getYamlFileUrl("skills")).then((res) => res.text()),
fetch(getYamlFileUrl("labels")).then((res) => res.text()),
]);
const skills = yaml.safeLoad(skillsYaml);
populateSkillsDropdown(Object.values(skills).flat()); // Populate skills dropdown
} catch (error) {
console.error("Error loading filters:", error);
}
}
function populateSkillsDropdown(skills) {
// Process skills to remove duplicates
const uniqueSkills = Array.from(new Set(Object.values(skills).flat())); // Flatten and remove duplicates
const topLevelSkills = Array.from(
new Set(uniqueSkills.map((skill) => skill.split("/")[0]))
); // Extract prefixes
// Populate skills dropdown
const skillsDropdown = document.getElementById("skills");
skillsDropdown.innerHTML = ""; // Clear existing options
const noPreferenceOption = document.createElement("option");
noPreferenceOption.value = ""; // Empty value for no preference
noPreferenceOption.textContent = "No preferences";
skillsDropdown.appendChild(noPreferenceOption);
// Add each top-level skill to the dropdown
topLevelSkills.forEach((skill) => {
const optionElement = document.createElement("option");
optionElement.value = skill.toLowerCase();
optionElement.textContent = skill;
skillsDropdown.appendChild(optionElement);
});
}
// Build GitHub search query based on user-selected filters
function loadIssues() {
const query = ["org:creativecommons", "is:open", "is:issue"];
if (userFilters.aim === "contribute") query.push('label:"help wanted"');
if (userFilters.aim === "triage")
query.push('label:"🚦 status: awaiting triage"');
if (userFilters.aim === "label")
query.push('label:"🏷 status: label work required"');
return query.join(" ");
}
// Fetch and display GitHub issues based on filters
async function fetchAndDisplayIssues() {
try {
const octokit = new Octokit();
const query = loadIssues();
const response = await octokit.search.issuesAndPullRequests({
q: query,
per_page: 100,
sort: "created",
order: "desc",
});
// Extract needed data from issues
issuesList = response.data.items.map((issue) => ({
...issue,
labels: issue.labels.map((label) => label.name),
repo: issue.repository_url.split("/").pop(),
}));
displayFilteredIssues(); // Display filtered issues
} catch (error) {
console.error("Error loading GitHub issues:", error);
}
}
// function to display filtered issues
function displayFilteredIssues() {
issuesContainer.innerHTML = ""; // Clear any existing issues
const filteredIssues = issuesList.filter((issue) => {
if (userFilters.aim !== "contribute") return true;
// Show only "good first issues" for beginners
if (
userFilters.experience === "beginner" &&
!issue.labels.includes("good first issue")
)
return false;
// Check if issue matches selected skills
if (
userFilters.skills.length &&
!userFilters.skills.some((skill) =>
issue.labels.includes(`💪 skill: ${skill}`)
)
)
return false;
return true; // Show issue if it meets all criteria
});
// Show "No results" message if no issues match
if (filteredIssues.length === 0) {
issuesContainer.innerHTML = "<p>No results.</p>";
return;
}
// Create an issue card for each filtered issue
filteredIssues.forEach((issue) => {
const issueCard = document.createElement("div");
issueCard.className = "issue-card";
issueCard.innerHTML = `
<h4>${issue.title}</h4>
<p>
<a href="${issue.html_url}" target="_blank">
<span>${issue.repo}#${issue.number}</span>
</a>
opened on ${issue.created_at.split("T")[0]}.
</p>
<div class="labels">
${issue.labels
.map((label) => `<span class="label">${label}</span>`)
.join("")}
</div>
`;
issuesContainer.appendChild(issueCard);
});
}
// Update filters and reload issues when the user changes selections
aimDropdown.addEventListener("change", (event) => {
userFilters.aim = event.target.value;
skillFiltersDiv.style.display =
userFilters.aim === "contribute" ? "block" : "none";
fetchAndDisplayIssues();
});
skillsDropdown.addEventListener("change", (event) => {
const selectedSkills = Array.from(event.target.selectedOptions).map(
(option) => option.value
);
userFilters.skills = selectedSkills.includes("") ? [] : selectedSkills;
displayFilteredIssues();
});
experienceDropdown.addEventListener("change", (event) => {
userFilters.experience = event.target.value;
displayFilteredIssues();
});
// Load filters and issues when the page loads
fetchFilterData();
fetchAndDisplayIssues();
});