contrib/nitrpg: clean stats display in panels
[nit.git] / contrib / nitrpg / src / templates / panels.nit
1 # This file is part of NIT ( http://www.nitlanguage.org ).
2 #
3 # Copyright 2014-2015 Alexandre Terrasa <alexandre@moz-code.org>
4 #
5 # Licensed under the Apache License, Version 2.0 (the "License");
6 # you may not use this file except in compliance with the License.
7 # You may obtain a copy of the License at
8 #
9 # http://www.apache.org/licenses/LICENSE-2.0
10 #
11 # Unless required by applicable law or agreed to in writing, software
12 # distributed under the License is distributed on an "AS IS" BASIS,
13 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 # See the License for the specific language governing permissions and
15 # limitations under the License.
16
17 # Panels templates for `nitpg`.
18 module panels
19
20 import templates_base
21
22 # A panel can be displayed in a html page.
23 #
24 # This display a Bootstrap panel.
25 class Panel
26 super Template
27
28 redef fun rendering do
29 add """<div class="panel panel-default">
30 <div class="panel-heading">
31 <h3 class="panel-title">"""
32 render_title
33 add """ </h3>
34 </div>
35 <div class="panel-body">"""
36 render_body
37 add """</div>
38 </div>"""
39 end
40
41 # Render the panel title.
42 # Betweem `<h4>` tags.
43 fun render_title do end
44
45 # Render the panel body.
46 fun render_body do end
47 end
48
49 # A panel that contain only a table as body.
50 class TablePanel
51 super Panel
52
53 redef fun rendering do
54 add """<div class="panel panel-default">
55 <div class="panel-heading">
56 <h3 class="panel-title">"""
57 render_title
58 add """
59 </h3>
60 </div>"""
61 render_body
62 add """</div>"""
63 end
64 end
65
66 # Display an error message within a panel.
67 class ErrorPanel
68 super Panel
69
70 redef fun rendering do
71 add """
72 <div class="panel panel-danger">
73 <div class="panel-heading">
74 <h3 class="panel-title">"""
75 render_title
76 add """
77 </h3>
78 </div>
79 <div class="panel-body">"""
80 render_body
81 add """
82 </div>
83 </div>
84 """
85 end
86
87 # The error message to display as panel body.
88 var msg: String
89
90 redef fun render_title do
91 add "<span class=\"glyphicon glyphicon-warning-sign\"></span>&nbsp;&nbsp;"
92 add "Error"
93 end
94
95 redef fun render_body do
96 add msg.html_escape
97 end
98
99 end
100
101 # A panel that display repo statistics.
102 class GameStatusPanel
103 super Panel
104
105 # Repo to display.
106 var game: Game
107
108 redef fun render_title do
109 add "<span class=\"glyphicon glyphicon-home\"></span>&nbsp;&nbsp;"
110 add "<a href=\"{game.url}\">{game.name}</a>"
111 end
112
113 redef fun render_body do
114 add "<strong class=\"text-success\">{game.load_players.length}</strong>"
115 add " <a href=\"{game.url}/players\">players</a><br><br>"
116 add "<strong class=\"text-success\">{game.stats["pulls"]}</strong> pull requests"
117 add " (<strong>{game.stats["pulls_open"]}</strong> open)<br>"
118 add "<strong class=\"text-success\">{game.stats["issues"]}</strong> issues"
119 add " (<strong>{game.stats["issues_open"]}</strong> open)<br>"
120 add "<strong class=\"text-success\">{game.stats["commits"]}</strong> commits"
121 end
122 end
123
124 # Player status panel.
125 class PlayerStatusPanel
126 super Panel
127
128 # Game instance.
129 var game: Game
130
131 # Target player.
132 var player: Player
133
134 redef fun render_title do
135 add "<a href=\"{player.url}\">"
136 add " <img class=\"img-circle\" style=\"width: 30px\""
137 add " src=\"{player.user.avatar_url}\" alt=\"{player.name}\">"
138 add "</a>&nbsp;&nbsp;"
139 add "<a href=\"{player.url}\">{player.name}</a>"
140 end
141
142 redef fun render_body do
143 var ranking = game.player_ranking
144 # TODO player.rank
145 add "<p class=\"lead\">ranked "
146 add " <span class=\"text-success\"># {ranking[player.name]}</span></p>"
147 add "<strong class=\"text-success\">{player.nitcoins}</strong> nitcoins<br><br>"
148 add "<strong>{player.stats["pulls"]}</strong> pull requests<br>"
149 add "<strong>{player.stats["issues"]}</strong> issues<br>"
150 add "<strong>{player.stats["commits"]}</strong> commits"
151
152 end
153 end
154
155 # A panel that display a list of player in a repo.
156 class ShortListPlayersPanel
157 super Panel
158
159 # Game instance.
160 var game: Game
161
162 redef fun render_title do
163 add "<span class=\"glyphicon glyphicon-user\"></span>&nbsp;&nbsp;"
164 add "<a href=\"{game.url}/players\">Players</a>"
165 end
166
167 redef fun render_body do
168 var players = game.load_players.values.to_a
169 if players.is_empty then
170 add "<em>No player yet...</em>"
171 return
172 end
173 (new PlayerCoinComparator).sort(players)
174 for player in players do
175 add "<a href=\"{player.url}\">"
176 add player.name
177 add "</a>&nbsp;({player.nitcoins})<br>"
178 end
179 end
180 end
181
182 # A panel that display a list of player in a repo.
183 class ListPlayersPanel
184 super TablePanel
185
186 # Game instance.
187 var game: Game
188
189 redef fun render_title do
190 add "<span class=\"glyphicon glyphicon-user\"></span>&nbsp;&nbsp;"
191 add "<a href=\"{game.url}/players\">Players</a>"
192 end
193
194 redef fun render_body do
195 var players = game.load_players.values.to_a
196 (new PlayerCoinComparator).sort(players)
197 if players.is_empty then
198 add "<div class=\"panel-body\">"
199 add "<em>No player yet...</em>"
200 add "</div>"
201 return
202 end
203 add """<table class="table table-striped table-hover">
204 <tr>
205 <th>#</th>
206 <th>Player</th>
207 <th>Nitcoins</th>
208 </tr>"""
209 var rank = 1
210 for player in players do
211 add "<tr>"
212 add " <td>{rank}</td>"
213 add " <td><a href=\"{player.url}\">{player.name}</a></td>"
214 add " <td>{player.nitcoins}</td>"
215 add "</tr>"
216 rank += 1
217 end
218 add "</table>"
219 end
220 end
221
222 # A panel that display the podium.
223 class PodiumPanel
224 super Panel
225
226 # Game instance.
227 var game: Game
228
229 redef fun render_title do
230 add "<span class=\"glyphicon glyphicon-stats\"></span>&nbsp;&nbsp;Hall of fame"
231 end
232
233 redef fun render_body do
234 var players = game.load_players.values.to_a
235 (new PlayerCoinComparator).sort(players)
236 if players.is_empty then
237 add "<em>No players yet...</em>"
238 return
239 end
240 add """
241 <div class="container-fluid">
242 <div id="podium" class="row row-sm-height">"""
243 var max = players.first.nitcoins
244 var orders = [3, 1, 0, 2, 4]
245 for order in orders do
246 if order >= players.length then continue
247 var player = players[order]
248 var size = 0
249 if max > 0 then size = player.nitcoins * 300 / max
250 add """
251 <div class="col-xs-2 col-xs-height col-xs-offset-{{{order}}} col-bottom"
252 style="text-align: center;">
253 <p>
254 <a href="{{{player.url}}}">
255 <img class="img-circle" style="width: 80px"
256 src="{{{player.user.avatar_url}}}" alt="{{{player.name}}}">
257 </a>
258 </p>
259 <p><a href="{{{player.url}}}">{{{player.name}}}</a></p>
260 <p>{{{player.nitcoins}}}</p>
261 <div class=" progress-bar-warning progress-bar-striped"
262 style="height: {{{size}}}px;"></div>
263 </div>"""
264 end
265 add """
266 </div>
267 </div>"""
268 end
269 end
270
271 # A `Panel` that displays the list of PR to review for a `Player`.
272 class PlayerReviewsPanel
273 super Panel
274
275 # Repo to display.
276 var game: Game
277
278 # Player to display customized list for.
279 var player: Player
280
281 redef fun render_title do
282 add "<span class=\"glyphicon glyphicon-check\"></span>&nbsp;&nbsp;"
283 add "Review pull requests to gain nitcoins!"
284 end
285
286 redef fun render_body do
287 var q = "is:open label:need_review sort:updated-asc " +
288 "-involves:{player.name}"
289
290 var issues = game.repo.search_issues(q)
291 if issues.is_empty then
292 add "<em>No pull request to review yet...</em>"
293 return
294 end
295 for issue in issues do
296 add """<div class="media">
297 <a class="media-left" href="{{{player.url}}}">
298 <img class=\"img-circle\" style="width:50px"
299 src="{{{issue.user.avatar_url}}}" alt="{{{issue.user.login}}}">
300 </a>
301 <div class="media-body">
302 <h4 class="media-heading">
303 <a href="{{{issue.html_url}}}">#{{{issue.number}}} {{{issue.title}}}</a></h4>
304 <span class="text-muted">opened by </span>
305 <a href="{{{player.url}}}">{{{issue.user.login}}}</a>
306 </div>
307 </div>"""
308 end
309 end
310 end