_render_repo.html 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391
  1. {% from "_projectstring.html" import projectstring, projecticon %}
  2. {% macro searchbox(select) %}
  3. <form action="{{url_for('ui_ns.search')}}" id="headerSearch">
  4. <select name="type" style="display:none;">
  5. <option value="projects"{% if select=='projects' %} selected {% endif %}>{{projectstring(plural=True)}}</option>
  6. <option value="projects_forks"{% if select=='projects_forks' %} selected {% endif %}>{{projectstring(plural=True)}} &amp; Forks</option>
  7. <option value="user"{% if select=='users' %} selected {% endif %}>Users</option>
  8. <option value="groups"{% if select=='groups' %} selected {% endif %}>Groups</option>
  9. </select>
  10. {% if select == 'projects' %}
  11. <input type="hidden" name="direct" readonly value="1">
  12. {% endif %}
  13. <input type="text" name="term" id="term" placeholder="{%
  14. if select=='projects' %}Search {{projectstring(plural=True)}}{%
  15. elif select=='users' %} Search Users {%
  16. elif select=='groups'%} Search Groups{%
  17. endif %}" class="form-control" title="Search" />
  18. <input type="submit" style="display:none;" value="Search" class="btn btn-primary" />
  19. </form>
  20. {% endmacro%}
  21. {% macro render_row(items) -%}
  22. {% for repo in items %}
  23. {% set url = url_for('ui_ns.view_repo',
  24. username=repo.user.username if repo.is_fork else None,
  25. repo=repo.name, namespace=repo.namespace) %}
  26. <div class="col-lg-4 col-md-6">
  27. <div class="border mb-4">
  28. <div class="d-flex p-2">
  29. {% if repo.avatar_email %}
  30. <img src="{{ repo.avatar_email | avatar_url }}" width=60 height=60 />
  31. {% else %}
  32. <div><span class="fa {{projecticon()}} fa-4x text-muted"></span></div>
  33. {% endif %}
  34. <div class="pl-3">
  35. <a href="{{ url }}">
  36. <div>
  37. <strong>
  38. {{ repo.namespace + '/' if repo.namespace }}{{ repo.name }}
  39. </strong>
  40. {% if repo.private %}
  41. <span title="Private {{projectstring()}}" class="text-danger fa fa-fw fa-lock"></span>
  42. {% endif %}
  43. </div>
  44. </a>
  45. <div title="{{ repo.description }}" data-toggle="tooltip">
  46. <small>
  47. {% if repo.description %}{{ repo.description }}{% else %}
  48. <span class="text-muted">no description<span>{% endif %}
  49. </small>
  50. </div>
  51. </div>
  52. </div>
  53. <div class="bg-light border-top">
  54. <span class="pl-2">
  55. <small>created {{repo.date_created|humanize}}</small>
  56. </span>
  57. <div style="text-align:right;" class="pr-2 text-muted float-right">
  58. <span title="Forks" data-toggle="tooltip">
  59. <i class="fa fa-code-fork"></i>
  60. {{repo.forks|count}}
  61. </span>
  62. </div>
  63. </div>
  64. </div>
  65. </div>
  66. {% else %}
  67. <p>No {{projectstring(plural=True)}} found</p>
  68. {% endfor %}
  69. {%- endmacro %}
  70. {% macro pagination_link(pagetitle, page, total) -%}
  71. {% set prev_page = request.url | combine_url(
  72. page=page-1, pagetitle=pagetitle, **kwargs) %}
  73. {% set next_page = request.url | combine_url(
  74. page=page+1, pagetitle=pagetitle, **kwargs) %}
  75. <aside>
  76. <nav class="text-center">
  77. <ul class="pagination">
  78. <li class="page-item {% if page <= 1%} disabled {% endif %}">
  79. <a href="{{ prev_page }}" class="page-link">
  80. <span aria-hidden="true">&laquo;</span>
  81. <span class="sr-only">Newer</span>
  82. </a>
  83. </li>
  84. <li class="page-item disabled"><a class="page-link" href="#" tabindex="-1">page {{ page }} of {{ total }}</a></li>
  85. <li class="page-item {% if page >= total %}disabled{%endif%}">
  86. <a href="{{ next_page }}" class="page-link">
  87. <span aria-hidden="true">&raquo;</span>
  88. <span class="sr-only">Older</span>
  89. </a>
  90. </li>
  91. </ul>
  92. </nav>
  93. </aside>
  94. {%- endmacro %}
  95. {% macro render_repos(
  96. list, total, pagetitle, page, title, count, id,
  97. username=None, hide=True, sorting=None, select='projects') %}
  98. <div class="row mb-3" id="{{ id }}">
  99. <div class="col align-self-center">
  100. <h3 class="m-0 font-weight-bold">{{
  101. title
  102. }} <span class="badge badge-secondary">{{ count }}</span>
  103. {%- if username -%}
  104. <a href="{{ url_for('ui_ns.new_project') }}">
  105. <button type="button" class="btn btn-success float-right">
  106. New {{projectstring()}}
  107. </button>
  108. </a>
  109. {%- endif -%}
  110. </h3>
  111. </div>
  112. <div class="col-auto form-inline">
  113. {{searchbox(select)}}
  114. <button type="button" class="btn btn-outline-primary dropdown-toggle ml-2" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
  115. Sort
  116. </button>
  117. <div class="dropdown-menu dropdown-menu-right">
  118. <a class="dropdown-item" href="{{
  119. url_for('ui_ns.browse_projects') }}">
  120. {% if not sorting or sorting == 'name'%}
  121. <span class="fa fa-check"></span>
  122. {%endif%}
  123. Name
  124. </a>
  125. <a class="dropdown-item" href="{{
  126. url_for('ui_ns.browse_projects', sorting='latest') }}">
  127. {% if sorting == 'latest'%}
  128. <span class="fa fa-check"></span>
  129. {%endif%}
  130. Recent First
  131. </a>
  132. <a class="dropdown-item" href="{{
  133. url_for('ui_ns.browse_projects', sorting='oldest') }}">
  134. {% if sorting == 'oldest'%}
  135. <span class="fa fa-check"></span>
  136. {%endif%}
  137. Oldest First
  138. </a>
  139. </div>
  140. </div>
  141. </div>
  142. <div class="row">
  143. {{ render_row(list) }}
  144. </div>
  145. {% if total and total > 1 %}
  146. {{ pagination_link(pagetitle, page, total, sorting=sorting) }}
  147. {% endif %}
  148. {% endmacro %}
  149. {% macro render_user_repos(
  150. list, total, pagetitle, page, title, count, id, username=None, hide=True) %}
  151. <div class="card" id="{{ id }}">
  152. <div class="card-header">
  153. {{ title }} <span class="badge badge-secondary">{{ count }}</span>
  154. </div>
  155. {% if total and total > 1 %}
  156. {{ pagination_link(pagetitle, page, total) }}
  157. {% endif %}
  158. <div class="card-block">
  159. {% for repo in list %}
  160. <a class="project_link logo_link" href="{{
  161. url_for(
  162. 'ui_ns.view_repo',
  163. repo=repo.name,
  164. username=repo.user.username if repo.is_fork else None,
  165. namespace=repo.namespace)
  166. }}">
  167. <div>
  168. <strong>
  169. {{ repo.namespace + '/' if repo.namespace }}{{ repo.name }}
  170. </strong>
  171. </div>
  172. </a>
  173. {% else %}
  174. <p>No {{projectstring(plural=True)}} found</p>
  175. {% endfor %}
  176. </div>
  177. {% if total and total > 1 %}
  178. {{ pagination_link(pagetitle, page, total) }}
  179. {% endif %}
  180. </div>
  181. {% endmacro %}
  182. {% macro repos_switch(all=True, hide=True) %}
  183. <aside class="show_parts">
  184. <div class="container">
  185. <strong>
  186. {% if all %}My repos:{% else %}Repos:{% endif %}
  187. </strong>
  188. <label class="switch">
  189. <input type="checkbox" class="switch-input"
  190. name="{% if all %}my{% endif %}repos"
  191. {%- if (
  192. (all and 'myrepos' in config.get('SHOW_PROJECTS_INDEX', []))
  193. or
  194. (not all and 'repos' not in config.get('SHOW_PROJECTS_INDEX', []))
  195. )
  196. or not hide %} checked {% endif %}/>
  197. <span class="switch-label" data-on="On" data-off="Off"></span>
  198. <span class="switch-handle"></span>
  199. </label>
  200. <strong>Forks:</strong>
  201. <label class="switch">
  202. <input type="checkbox" class="switch-input"
  203. name="{% if all %}my{% endif %}forks" {%
  204. if 'myforks' in config.get('SHOW_PROJECTS_INDEX', []) or not hide
  205. %} checked {% endif %}/>
  206. <span class="switch-label" data-on="On" data-off="Off"></span>
  207. <span class="switch-handle"></span>
  208. </label>
  209. {% if all %}
  210. <strong>All repos:</strong>
  211. <label class="switch">
  212. <input type="checkbox" class="switch-input"
  213. name="repos" id="allrepos" {%
  214. if 'repos' in config.get('SHOW_PROJECTS_INDEX', []) or not hide
  215. %} checked {% endif %}/>
  216. <span class="switch-label" data-on="On" data-off="Off"></span>
  217. <span class="switch-handle"></span>
  218. </label>
  219. {% endif %}
  220. </div>
  221. </aside>
  222. {% endmacro %}
  223. {% macro render_repos_as_card(list, total, name, pagetitle, page, total_page) %}
  224. {% if total_page and total_page > 1 %}
  225. {{ pagination_link(pagetitle, page, total_page) }}
  226. {% endif %}
  227. <div class="card mb-3">
  228. <div class="card-header">
  229. {{name}} <span class="badge badge-secondary">{{total}}</span>
  230. </div>
  231. {% if list %}
  232. <div class="list-group">
  233. {% for repo in list %}
  234. {% set url = url_for('ui_ns.view_repo',
  235. repo=repo.name,
  236. username=repo.user.username if repo.is_fork else None,
  237. namespace=repo.namespace) %}
  238. <div class="list-group-item">
  239. <div class="media">
  240. {% if repo.avatar_email %}
  241. <img class="align-self-center text-center mr-3"
  242. src="{{ repo.avatar_email | avatar_url }}"
  243. width=60 height=60 />
  244. {% elif repo.is_fork %}
  245. <div class="align-self-center text-center" style="width:60px">
  246. <span class="fa fa-code-fork fa-4x text-muted" ></span>
  247. </div>
  248. {% else %}
  249. <div class="align-self-center text-center mr-3" style="width:60px">
  250. <span class="fa {{projecticon()}} fa-4x text-muted" ></span>
  251. </div>
  252. {% endif %}
  253. <div class="media-body align-self-center">
  254. <a class="font-weight-bold" href="{{ url }}">{{ repo.fullname }}</a>
  255. <div title="{{ repo.description }}" data-toggle="tooltip" class="repo_descripton">
  256. <small>
  257. {% if repo.description %}
  258. {{ repo.description }}
  259. {% else %}
  260. <span class="text-muted">no description<span>
  261. {% endif %}
  262. </small>
  263. </div>
  264. </div>
  265. </div>
  266. </div>
  267. {% endfor %}
  268. </div>
  269. {% else %}
  270. <div class="card-block">
  271. <p>No {{projectstring(plural=True)}} found</p>
  272. </div>
  273. {% endif %}
  274. </div>
  275. {% if total_page and total_page > 1 %}
  276. {{ pagination_link(pagetitle, page, total_page) }}
  277. {% endif %}
  278. {% endmacro %}
  279. {% macro render_activity_graph(username, _class="") %}
  280. <script type="text/javascript"src="{{
  281. url_for('static', filename='vendor/jquery/jquery.min.js') }}?version={{ g.version}}"></script>
  282. <script type="text/javascript" src="{{
  283. url_for('static', filename='vendor/d3/d3.v3.min.js') }}"></script>
  284. <script type="text/javascript" src="{{
  285. url_for('static', filename='vendor/jstimezonedetect/jstz.min.js') }}?version={{ g.version}}"></script>
  286. <script type="text/javascript" src="{{
  287. url_for('static', filename='vendor/cal-heatmap/cal-heatmap.min.js') }}?version={{ g.version}}"></script>
  288. <link rel="stylesheet" href="{{
  289. url_for('static', filename='vendor/cal-heatmap/cal-heatmap.css') }}?version={{ g.version}}" />
  290. <div class="mb-2 {{_class}}" id="user_graph">
  291. <div class="p-0">
  292. <div id="cal-heatmap">
  293. </div>
  294. <div id="user-activity" class="hidden">
  295. <div class="list-group" id="user-activity-body">
  296. <div class="list-group-item bg-light font-weight-bold">
  297. <span id="user-activity-title"></span>
  298. <span class="float-right">
  299. <button class="btn btn-outline-secondary border-0 btn-sm" id="hide_activity">
  300. <span class="fa fa-times" data-toggle="tooltip"
  301. title="Hide activity info" aria-hidden="true">
  302. </span>
  303. </button>
  304. </span>
  305. </div>
  306. </div>
  307. </div>
  308. </div>
  309. <script type="text/javascript">
  310. function padStr(i) {
  311. return (i < 10) ? "0" + i : "" + i;
  312. }
  313. $('#hide_activity').click(function(){
  314. $('#user-activity').hide();
  315. });
  316. var cal = new CalHeatMap();
  317. var tz = jstz.determine().name();
  318. cal.init({
  319. cellSize: 9,
  320. domain: "month",
  321. subDomain: "day",
  322. domainLabelFormat: "%b",
  323. displayLegend: false,
  324. legend: [0, 1, 5, 10, 15, 20],
  325. legendColors: {
  326. min: "#efefef",
  327. max: "#204a87",
  328. empty: "#efefef"
  329. },
  330. start: new Date(new Date().setMonth(new Date().getMonth() - 11)),
  331. data: "{{ url_for(
  332. 'api_ns.api_view_user_activity_stats',
  333. username=username, format='timestamp') }}" + '&tz=' + tz,
  334. dataType: "json",
  335. highlight: "now",
  336. onClick: function(date, nb) {
  337. date = date.getFullYear() + '-' + padStr(date.getMonth() + 1)
  338. + '-' + padStr(date.getDate());
  339. $.ajax({
  340. type: 'GET',
  341. url: "{{ url_for(
  342. 'api_ns.api_view_user_activity_date',
  343. username=username, date='') }}" + date + '?grouped=1&tz=' + tz,
  344. contentType: "application/json",
  345. dataType: 'json',
  346. success: function(data) {
  347. $('.activity-item').remove();
  348. $('#user-activity-title').text(data.activities.length+' actions on ' + date);
  349. $('#user-activity').show();
  350. if (data.activities.length > 0){
  351. for (var i=0; i<data.activities.length; i++){
  352. var d = data.activities[i];
  353. $('#user-activity-body').append(
  354. '<div class="list-group-item activity-item">'
  355. + d.description_mk
  356. + '</div>'
  357. );
  358. }
  359. }
  360. else {
  361. $('#user-activity-body').append(
  362. '<div class="list-group-item activity-item">No activity recorded on that day</div>'
  363. );
  364. }
  365. }
  366. });
  367. }
  368. });
  369. </script>
  370. </div>
  371. {% endmacro%}