1
1
import VueSelect from 'vue-select' ;
2
2
3
- import { octokit } from './octokit' ;
4
-
5
3
export const IssueLabel = {
6
4
template : `
7
5
<span class="gh-label" :class="className">
@@ -27,24 +25,34 @@ export const IssueLabel = {
27
25
* @returns {string } the name of the class to apply to the label
28
26
*/
29
27
className ( ) {
30
- return window . className [ this . name ] || 'miscellaneous'
28
+ return window . categories [ this . name ] || 'miscellaneous'
31
29
}
32
30
}
33
31
}
34
32
35
33
export const IssueCard = {
36
34
template : `
37
35
<div class="card entry-post vertical margin-top-normal padding-normal">
38
- <h4 class="card-title b-header margin-bottom-small">{{ issue.title }}</h4>
39
- <a :href="issue.html_url" class="button is-text tiny site-link" target="_blank">
40
- <span class="has-color-forest-green">
41
- {{ issue.repository.name }}#{{ issue.number }}
42
- </span>
43
- <i class="icon external-link has-color-forest-green"></i>
44
- </a>
36
+ <h4 class="card-title b-header margin-bottom-small">
37
+ {{ issue.title }}
38
+ </h4>
39
+ <p class="is-size-6">
40
+ <a
41
+ :href="issue.html_url"
42
+ target="_blank">
43
+ <span class="has-color-forest-green">
44
+ {{ issue.repo }}#{{ issue.number }}
45
+ </span>
46
+ <i
47
+ class="icon external-link has-color-forest-green is-size-7"
48
+ :style="{ verticalAlign: 'top' }">
49
+ </i>
50
+ </a>
51
+ opened on {{ dateCreated }}.
52
+ </p>
45
53
<div class="labels margin-top-small">
46
54
<IssueLabel
47
- v-for="(name, index) in issue.labelNames "
55
+ v-for="(name, index) in issue.labels "
48
56
:key="index"
49
57
:name="name"/>
50
58
</div>
@@ -57,6 +65,12 @@ export const IssueCard = {
57
65
type : Object ,
58
66
required : true
59
67
} ,
68
+ } ,
69
+ computed : {
70
+ dateCreated ( ) {
71
+ const dateCreated = new Date ( this . issue . createdAt * 1000 )
72
+ return dateCreated . toLocaleDateString ( )
73
+ }
60
74
}
61
75
}
62
76
@@ -68,7 +82,7 @@ export const App = {
68
82
<div class="column is-one-quarter">
69
83
<form id="filters">
70
84
<label for="skills">
71
- <strong>Skill set</strong><br>
85
+ <strong>Skill set</strong><br/ >
72
86
Choose up to three skills that you would like to see issues for.
73
87
</label>
74
88
<VueSelect
@@ -82,7 +96,7 @@ export const App = {
82
96
multiple/>
83
97
<br/>
84
98
<label for="experience">
85
- <strong>Experience</strong><br>
99
+ <strong>Experience</strong><br/ >
86
100
Is this your first time contributing to CC?
87
101
</label>
88
102
<VueSelect
@@ -96,10 +110,10 @@ export const App = {
96
110
</form>
97
111
</div>
98
112
<div class="column">
99
- <template v-if="issues .length">
100
- <issue-card
101
- v-for="issue in filteredIssues"
102
- :key="issue.id "
113
+ <template v-if="filteredIssues .length">
114
+ <IssueCard
115
+ v-for="( issue, index) in filteredIssues"
116
+ :key="index "
103
117
:issue="issue"/>
104
118
</template>
105
119
<p
@@ -117,7 +131,7 @@ export const App = {
117
131
data ( ) {
118
132
return {
119
133
options : {
120
- skills : window . skillSet ,
134
+ skills : window . skills ,
121
135
experiences : [
122
136
{ name : 'Yes, it is' , code : 'beginner' } ,
123
137
{ name : 'No, it isn\'t' , code : 'experienced' }
@@ -137,51 +151,20 @@ export const App = {
137
151
* @returns {array } the array of filtered issues
138
152
*/
139
153
filteredIssues ( ) {
140
- return this . issues . filter ( issue => {
141
- const joinedLabels = issue . labelNames . join ( ',' )
142
- if ( this . filters . skills . length && ! this . filters . skills . some ( skill => joinedLabels . includes ( skill ) ) ) {
154
+ return window . issues . filter ( issue => {
155
+ // Check experience match
156
+ if ( this . filters . experience === 'beginner' && ! issue . labels . includes ( 'good first issue' ) ) {
143
157
return false
144
158
}
145
- if ( this . filters . experience === 'beginner' && ! joinedLabels . includes ( 'good first issue' ) ) {
159
+
160
+ // Check skill set match
161
+ const joinedLabels = issue . labels . join ( ',' )
162
+ if ( this . filters . skills . length && ! this . filters . skills . some ( skill => joinedLabels . includes ( skill ) ) ) {
146
163
return false
147
164
}
165
+
148
166
return true
149
- } )
167
+ } ) . sort ( ( a , b ) => b . createdAt - a . createdAt )
150
168
}
151
- } ,
152
- methods : {
153
- /**
154
- * Run the search based on the data submitted via the form and load all
155
- * results into the `issues` attribute. Can be reused for a future
156
- * 'Load More' button.
157
- *
158
- * @param {number } page - the page of results to fetch
159
- */
160
- search ( page = 1 ) {
161
- octokit
162
- . issues
163
- . listForOrg ( {
164
- org : 'creativecommons' ,
165
- state : 'open' ,
166
- filter : 'all' ,
167
- labels : 'help wanted' ,
168
- sort : 'created' ,
169
- direction : 'desc' ,
170
- per_page : 100 ,
171
- page
172
- } )
173
- . then ( response => response . data )
174
- . then ( issueLists => {
175
- const issues = issueLists . flat ( )
176
- issues . forEach ( issue => {
177
- issue . labelNames = issue . labels . map ( label => label . name )
178
- } )
179
- this . issues = issues
180
- } )
181
- . catch ( err => console . error ( err ) )
182
- }
183
- } ,
184
- mounted ( ) {
185
- this . search ( )
186
169
}
187
170
}
0 commit comments