diff --git a/themes/vocabulary_theme/templates/issue_finder.html b/themes/vocabulary_theme/templates/issue_finder.html index b5861c078..fdf625d2b 100644 --- a/themes/vocabulary_theme/templates/issue_finder.html +++ b/themes/vocabulary_theme/templates/issue_finder.html @@ -39,9 +39,4 @@

{{ this.title }}

- {% endblock %} diff --git a/webpack/js/components.js b/webpack/js/components.js index a0a0a925f..4fac8f5f8 100644 --- a/webpack/js/components.js +++ b/webpack/js/components.js @@ -1,4 +1,5 @@ import VueSelect from 'vue-select'; +import {Octokit} from '@octokit/rest'; import {hydrateAppWithData} from "./hydration"; @@ -40,7 +41,7 @@ export const IssueCard = {

{{ issue.repo }}#{{ issue.number }} @@ -70,8 +71,7 @@ export const IssueCard = { }, computed: { dateCreated() { - const dateCreated = new Date(this.issue.createdAt * 1000) - const [dateComponent,] = dateCreated.toISOString().split("T") + const [dateComponent,] = this.issue.created_at.split("T") return dateComponent } } @@ -84,6 +84,20 @@ export const App = {

+ + +
+

*Not all issues have skills marked on them, especially if they are @@ -144,6 +159,10 @@ export const App = { data() { return { options: { + aims: [ + {name: 'Contributing code', code: 'contribute'}, + {name: 'Triaging issues', code: 'triage'} + ], skills: [], experiences: [ {name: 'Yes, it is', code: 'beginner'}, @@ -151,11 +170,13 @@ export const App = { ] }, filters: { + aim: 'contribute', skills: [], experience: 'experienced' }, categories: {}, - issues: [] + issues: [], + octokit: null } }, computed: { @@ -165,7 +186,13 @@ export const App = { * @returns {array} the array of filtered issues */ filteredIssues() { - return window.issues.filter(issue => { + return this.issues.filter(issue => { + // If aim is to triage issues + if (this.filters.aim === 'triage') { + // Show all issues as they all have the label "🚦 status: awaiting triage" + return true + } + // Check experience match if (this.filters.experience === 'beginner' && !issue.labels.includes('good first issue')) { return false @@ -173,18 +200,47 @@ export const App = { // Check skill set match const joinedLabels = issue.labels.join(',') - if (this.filters.skills.length && !this.filters.skills.some(skill => joinedLabels.includes(skill))) { - return false - } - - return true + return !(this.filters.skills.length && !this.filters.skills.some(skill => joinedLabels.includes(skill))); }).sort((a, b) => b.createdAt - a.createdAt) } }, + watch: { + 'filters.aim' (to, from) { + if (to !== from) { + this.loadIssues() + } + } + }, + methods: { + loadIssues () { + const q = ['org:creativecommons', 'is:open', 'is:issue'] + if (this.filters.aim === 'contribute') { + q.push('label:"help wanted"') + } else if (this.filters.aim === 'triage') { + q.push('label:"🚦 status: awaiting triage"') + } + this.octokit.search.issuesAndPullRequests({ + q: q.join(' '), + per_page: 100, + sort: 'updated' + }).then(res => { + this.issues = res.data.items + this.issues.forEach(issue => { + issue.labels = issue.labels.map(label => label.name) + + const repoUrl = issue.repository_url + issue.repo = repoUrl.slice(repoUrl.lastIndexOf('/') + 1) + }) + }) + } + }, mounted() { const BASE_URL = 'https://raw.githubusercontent.com/creativecommons/ccos-scripts/master/normalize_repos' const FILE_URL = name => `${BASE_URL}/${name}.json` + this.octokit = new Octokit() + this.loadIssues() + Promise .all([ fetch(FILE_URL('skills')) diff --git a/webpack/js/hydration.js b/webpack/js/hydration.js index c3b8828ab..a42da9f5d 100644 --- a/webpack/js/hydration.js +++ b/webpack/js/hydration.js @@ -1,10 +1,13 @@ export const hydrateAppWithData = (skills, labels) => { - skills = Array.from( // Convert back into an array - new Set( // Remove duplicates - Object.values(skills) - .flat() // Combine all skills - .map(skill => skill.split('/')[0]) // Keep only the prefix - ) + skills = Array.from( + new Set( // Remove duplicates + Object.values(skills).flat() // Combine all skills + ) + ) + const top_level_skills = Array.from( + new Set( // Remove duplicates + skills.map(skill => skill.split('/')[0]) // Keep only the prefix + ) ) const categories = {} @@ -35,5 +38,5 @@ export const hydrateAppWithData = (skills, labels) => { categories[name] = 'skill' }) - return [skills, categories] + return [top_level_skills, categories] } diff --git a/webpack/package-lock.json b/webpack/package-lock.json index 5876d11dd..d7169fcb8 100644 --- a/webpack/package-lock.json +++ b/webpack/package-lock.json @@ -286,6 +286,132 @@ "integrity": "sha512-+s+5BdfjiYl0Um5+GaAkXIJdRJQCEn3G7lXmWgOm60dc8mc9bx2wh1I1zZBRW0rUbUXKzvm4kk0gYNYT9xzj4w==", "dev": true }, + "@octokit/auth-token": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/@octokit/auth-token/-/auth-token-2.4.2.tgz", + "integrity": "sha512-jE/lE/IKIz2v1+/P0u4fJqv0kYwXOTujKemJMFr6FeopsxlIK3+wKDCJGnysg81XID5TgZQbIfuJ5J0lnTiuyQ==", + "requires": { + "@octokit/types": "^5.0.0" + } + }, + "@octokit/core": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/@octokit/core/-/core-3.1.2.tgz", + "integrity": "sha512-AInOFULmwOa7+NFi9F8DlDkm5qtZVmDQayi7TUgChE3yeIGPq0Y+6cAEXPexQ3Ea+uZy66hKEazR7DJyU+4wfw==", + "requires": { + "@octokit/auth-token": "^2.4.0", + "@octokit/graphql": "^4.3.1", + "@octokit/request": "^5.4.0", + "@octokit/types": "^5.0.0", + "before-after-hook": "^2.1.0", + "universal-user-agent": "^6.0.0" + } + }, + "@octokit/endpoint": { + "version": "6.0.8", + "resolved": "https://registry.npmjs.org/@octokit/endpoint/-/endpoint-6.0.8.tgz", + "integrity": "sha512-MuRrgv+bM4Q+e9uEvxAB/Kf+Sj0O2JAOBA131uo1o6lgdq1iS8ejKwtqHgdfY91V3rN9R/hdGKFiQYMzVzVBEQ==", + "requires": { + "@octokit/types": "^5.0.0", + "is-plain-object": "^5.0.0", + "universal-user-agent": "^6.0.0" + }, + "dependencies": { + "is-plain-object": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-5.0.0.tgz", + "integrity": "sha512-VRSzKkbMm5jMDoKLbltAkFQ5Qr7VDiTFGXxYFXXowVj387GeGNOCsOH6Msy00SGZ3Fp84b1Naa1psqgcCIEP5Q==" + } + } + }, + "@octokit/graphql": { + "version": "4.5.6", + "resolved": "https://registry.npmjs.org/@octokit/graphql/-/graphql-4.5.6.tgz", + "integrity": "sha512-Rry+unqKTa3svswT2ZAuqenpLrzJd+JTv89LTeVa5UM/5OX8o4KTkPL7/1ABq4f/ZkELb0XEK/2IEoYwykcLXg==", + "requires": { + "@octokit/request": "^5.3.0", + "@octokit/types": "^5.0.0", + "universal-user-agent": "^6.0.0" + } + }, + "@octokit/plugin-paginate-rest": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/@octokit/plugin-paginate-rest/-/plugin-paginate-rest-2.4.0.tgz", + "integrity": "sha512-YT6Klz3LLH6/nNgi0pheJnUmTFW4kVnxGft+v8Itc41IIcjl7y1C8TatmKQBbCSuTSNFXO5pCENnqg6sjwpJhg==", + "requires": { + "@octokit/types": "^5.5.0" + } + }, + "@octokit/plugin-request-log": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@octokit/plugin-request-log/-/plugin-request-log-1.0.0.tgz", + "integrity": "sha512-ywoxP68aOT3zHCLgWZgwUJatiENeHE7xJzYjfz8WI0goynp96wETBF+d95b8g/uL4QmS6owPVlaxiz3wyMAzcw==" + }, + "@octokit/plugin-rest-endpoint-methods": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/@octokit/plugin-rest-endpoint-methods/-/plugin-rest-endpoint-methods-4.2.0.tgz", + "integrity": "sha512-1/qn1q1C1hGz6W/iEDm9DoyNoG/xdFDt78E3eZ5hHeUfJTLJgyAMdj9chL/cNBHjcjd+FH5aO1x0VCqR2RE0mw==", + "requires": { + "@octokit/types": "^5.5.0", + "deprecation": "^2.3.1" + } + }, + "@octokit/request": { + "version": "5.4.9", + "resolved": "https://registry.npmjs.org/@octokit/request/-/request-5.4.9.tgz", + "integrity": "sha512-CzwVvRyimIM1h2n9pLVYfTDmX9m+KHSgCpqPsY8F1NdEK8IaWqXhSBXsdjOBFZSpEcxNEeg4p0UO9cQ8EnOCLA==", + "requires": { + "@octokit/endpoint": "^6.0.1", + "@octokit/request-error": "^2.0.0", + "@octokit/types": "^5.0.0", + "deprecation": "^2.0.0", + "is-plain-object": "^5.0.0", + "node-fetch": "^2.6.1", + "once": "^1.4.0", + "universal-user-agent": "^6.0.0" + }, + "dependencies": { + "is-plain-object": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-5.0.0.tgz", + "integrity": "sha512-VRSzKkbMm5jMDoKLbltAkFQ5Qr7VDiTFGXxYFXXowVj387GeGNOCsOH6Msy00SGZ3Fp84b1Naa1psqgcCIEP5Q==" + } + } + }, + "@octokit/request-error": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/@octokit/request-error/-/request-error-2.0.2.tgz", + "integrity": "sha512-2BrmnvVSV1MXQvEkrb9zwzP0wXFNbPJij922kYBTLIlIafukrGOb+ABBT2+c6wZiuyWDH1K1zmjGQ0toN/wMWw==", + "requires": { + "@octokit/types": "^5.0.1", + "deprecation": "^2.0.0", + "once": "^1.4.0" + } + }, + "@octokit/rest": { + "version": "18.0.6", + "resolved": "https://registry.npmjs.org/@octokit/rest/-/rest-18.0.6.tgz", + "integrity": "sha512-ES4lZBKPJMX/yUoQjAZiyFjei9pJ4lTTfb9k7OtYoUzKPDLl/M8jiHqt6qeSauyU4eZGLw0sgP1WiQl9FYeM5w==", + "requires": { + "@octokit/core": "^3.0.0", + "@octokit/plugin-paginate-rest": "^2.2.0", + "@octokit/plugin-request-log": "^1.0.0", + "@octokit/plugin-rest-endpoint-methods": "4.2.0" + } + }, + "@octokit/types": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/@octokit/types/-/types-5.5.0.tgz", + "integrity": "sha512-UZ1pErDue6bZNjYOotCNveTXArOMZQFG6hKJfOnGnulVCMcVVi7YIIuuR4WfBhjo7zgpmzn/BkPDnUXtNx+PcQ==", + "requires": { + "@types/node": ">= 8" + } + }, + "@types/node": { + "version": "14.11.8", + "resolved": "https://registry.npmjs.org/@types/node/-/node-14.11.8.tgz", + "integrity": "sha512-KPcKqKm5UKDkaYPTuXSx8wEP7vE9GnuaXIZKijwRYcePpZFDVuy2a57LarFKiORbHOuTOOwYzxVxcUzsh2P2Pw==" + }, "@webassemblyjs/ast": { "version": "1.9.0", "resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.9.0.tgz", @@ -945,6 +1071,11 @@ "tweetnacl": "^0.14.3" } }, + "before-after-hook": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/before-after-hook/-/before-after-hook-2.1.0.tgz", + "integrity": "sha512-IWIbu7pMqyw3EAJHzzHbWa85b6oud/yfKYg5rqB5hNE8CeMi3nX+2C2sj0HswfblST86hpVEOAb9x34NZd6P7A==" + }, "big.js": { "version": "5.2.2", "resolved": "https://registry.npmjs.org/big.js/-/big.js-5.2.2.tgz", @@ -1741,6 +1872,11 @@ "integrity": "sha1-hMbhWbgZBP3KWaDvRM2HDTElD5o=", "dev": true }, + "deprecation": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/deprecation/-/deprecation-2.3.1.tgz", + "integrity": "sha512-xmHIy4F3scKVwMsQ4WnVaS8bHOx0DmVwRywosKhaILI0ywMDWPtBSku2HNxRvF7jtwDRsoEwYQSfbxj8b7RlJQ==" + }, "des.js": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/des.js/-/des.js-1.0.1.tgz", @@ -3946,6 +4082,11 @@ "integrity": "sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==", "dev": true }, + "node-fetch": { + "version": "2.6.1", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.1.tgz", + "integrity": "sha512-V4aYg89jEoVRxRb2fJdAg8FHvI7cEyYdVAh94HH0UIK8oJxUfkjlDQN9RbMx+bEjP7+ggMiFRprSti032Oipxw==" + }, "node-gyp": { "version": "3.8.0", "resolved": "https://registry.npmjs.org/node-gyp/-/node-gyp-3.8.0.tgz", @@ -4187,7 +4328,6 @@ "version": "1.4.0", "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", - "dev": true, "requires": { "wrappy": "1" } @@ -5796,6 +5936,11 @@ "imurmurhash": "^0.1.4" } }, + "universal-user-agent": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/universal-user-agent/-/universal-user-agent-6.0.0.tgz", + "integrity": "sha512-isyNax3wXoKaulPDZWHQqbmIx1k2tb9fb3GGDBRxCscfYV2Ch7WxPArBsFEG8s/safwXTT7H4QGhaIkTp9447w==" + }, "unset-value": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/unset-value/-/unset-value-1.0.0.tgz", @@ -6358,8 +6503,7 @@ "wrappy": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", - "dev": true + "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=" }, "xtend": { "version": "4.0.2", diff --git a/webpack/package.json b/webpack/package.json index 5c966af35..5204f1bfc 100644 --- a/webpack/package.json +++ b/webpack/package.json @@ -26,6 +26,7 @@ "webpack-cli": "^3.3.11" }, "dependencies": { + "@octokit/rest": "^18.0.6", "vue": "^2.6.12", "vue-select": "^3.10.8" },