You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

226 lines
13 KiB

5 months ago
5 months ago
5 months ago
5 months ago
5 months ago
5 months ago
5 months ago
1 month ago
5 months ago
5 months ago
1 month ago
5 months ago
5 months ago
  1. {% extends 'base.html.twig' %}
  2. {% import 'macro.html.twig' as macro %}
  3. {% block breadcrumb %}
  4. <li class="breadcrumb-item"><a href="{{ path('app_project') }}">Projets</a></li>
  5. <li class="breadcrumb-item"><a href="{{ path('app_project_show', {'slug': project.slug}) }}">{{ project.name }}</a></li>
  6. <li class="breadcrumb-item"><a href="{{ path('app_task_show', {'slug': task.slug}) }}">{{ task.name }}</a></li>
  7. {% endblock %}
  8. {% block page_title %}
  9. {% include 'partials/_task-title.html.twig' %}
  10. {% endblock %}
  11. {% block page_content %}
  12. <div class="row">
  13. <div class="col mb-3">
  14. <div class="btn-toolbar" role="toolbar">
  15. <div class="btn-group me-2">
  16. <a href="{{ path('app_project_show', {'slug': project.slug}) }}" class="btn btn-secondary" title="Revenir au projet">
  17. <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-house" viewBox="0 0 16 16">
  18. <path d="M8.707 1.5a1 1 0 0 0-1.414 0L.646 8.146a.5.5 0 0 0 .708.708L2 8.207V13.5A1.5 1.5 0 0 0 3.5 15h9a1.5 1.5 0 0 0 1.5-1.5V8.207l.646.647a.5.5 0 0 0 .708-.708L13 5.793V2.5a.5.5 0 0 0-.5-.5h-1a.5.5 0 0 0-.5.5v1.293zM13 7.207V13.5a.5.5 0 0 1-.5.5h-9a.5.5 0 0 1-.5-.5V7.207l5-5z"/>
  19. </svg>
  20. Projet
  21. </a>
  22. </div>
  23. {% if is_granted('IS_AUTHENTICATED_FULLY') %}
  24. {% if app.user is same as(task.createdBy) %}
  25. <div class="btn-group me-2">
  26. <a href="{{ path('app_task_update', {'slug': task.slug}) }}" class="btn btn-secondary" title="Modifier la tâche">
  27. <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-pencil" viewBox="0 0 16 16">
  28. <path d="M12.146.146a.5.5 0 0 1 .708 0l3 3a.5.5 0 0 1 0 .708l-10 10a.5.5 0 0 1-.168.11l-5 2a.5.5 0 0 1-.65-.65l2-5a.5.5 0 0 1 .11-.168zM11.207 2.5 13.5 4.793 14.793 3.5 12.5 1.207zm1.586 3L10.5 3.207 4 9.707V10h.5a.5.5 0 0 1 .5.5v.5h.5a.5.5 0 0 1 .5.5v.5h.293zm-9.761 5.175-.106.106-1.528 3.821 3.821-1.528.106-.106A.5.5 0 0 1 5 12.5V12h-.5a.5.5 0 0 1-.5-.5V11h-.5a.5.5 0 0 1-.468-.325"/>
  29. </svg>
  30. Modifier
  31. </a>
  32. <a href="{{ path('app_task_remove', {'slug': task.slug}) }}" target="_blank" class="btn btn-secondary" title="Supprimer la tâche">
  33. <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-trash" viewBox="0 0 16 16">
  34. <path d="M5.5 5.5A.5.5 0 0 1 6 6v6a.5.5 0 0 1-1 0V6a.5.5 0 0 1 .5-.5m2.5 0a.5.5 0 0 1 .5.5v6a.5.5 0 0 1-1 0V6a.5.5 0 0 1 .5-.5m3 .5a.5.5 0 0 0-1 0v6a.5.5 0 0 0 1 0z"/>
  35. <path d="M14.5 3a1 1 0 0 1-1 1H13v9a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V4h-.5a1 1 0 0 1-1-1V2a1 1 0 0 1 1-1H6a1 1 0 0 1 1-1h2a1 1 0 0 1 1 1h3.5a1 1 0 0 1 1 1zM4.118 4 4 4.059V13a1 1 0 0 0 1 1h6a1 1 0 0 0 1-1V4.059L11.882 4zM2.5 3h11V2h-11z"/>
  36. </svg>
  37. Supprimer
  38. </a>
  39. </div>
  40. {% endif %}
  41. <div class="btn-group me-2">
  42. {% for transition in workflow_transitions(task) %}
  43. {% if not workflow_metadata(task, 'locking', task.status) or app.user is same as(task.lockedBy) %}
  44. <a href="{{ path(workflow_metadata(task, 'route', transition), {'slug': task.slug}) }}" class="btn btn-secondary" title="{{ workflow_metadata(task, 'title', transition) }}">
  45. {% if transition.name == 'start' %}
  46. <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-play-fill" viewBox="0 0 16 16">
  47. <path d="m11.596 8.697-6.363 3.692c-.54.313-1.233-.066-1.233-.697V4.308c0-.63.692-1.01 1.233-.696l6.363 3.692a.802.802 0 0 1 0 1.393"/>
  48. </svg>
  49. {% elseif transition.name == 'finish' %}
  50. <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-stop-fill" viewBox="0 0 16 16">
  51. <path d="M5 3.5h6A1.5 1.5 0 0 1 12.5 5v6a1.5 1.5 0 0 1-1.5 1.5H5A1.5 1.5 0 0 1 3.5 11V5A1.5 1.5 0 0 1 5 3.5"/>
  52. </svg>
  53. {% elseif transition.name == 'cancel' %}
  54. <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-skip-backward-fill" viewBox="0 0 16 16">
  55. <path d="M.5 3.5A.5.5 0 0 0 0 4v8a.5.5 0 0 0 1 0V8.753l6.267 3.636c.54.313 1.233-.066 1.233-.697v-2.94l6.267 3.636c.54.314 1.233-.065 1.233-.696V4.308c0-.63-.693-1.01-1.233-.696L8.5 7.248v-2.94c0-.63-.692-1.01-1.233-.696L1 7.248V4a.5.5 0 0 0-.5-.5"/>
  56. </svg>
  57. {% elseif transition.name == 'reset' %}
  58. <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-skip-backward-fill" viewBox="0 0 16 16">
  59. <path d="M.5 3.5A.5.5 0 0 0 0 4v8a.5.5 0 0 0 1 0V8.753l6.267 3.636c.54.313 1.233-.066 1.233-.697v-2.94l6.267 3.636c.54.314 1.233-.065 1.233-.696V4.308c0-.63-.693-1.01-1.233-.696L8.5 7.248v-2.94c0-.63-.692-1.01-1.233-.696L1 7.248V4a.5.5 0 0 0-.5-.5"/>
  60. </svg>
  61. {% endif %}
  62. {{ workflow_metadata(task, 'short', transition) }}
  63. </a>
  64. {% endif %}
  65. {% endfor %}
  66. </div>
  67. {% if workflow_metadata(task, 'locking', task.status) and app.user is same as(task.lockedBy) %}
  68. <div class="btn-group me-2">
  69. <div class="btn-group">
  70. <button class="btn btn-secondary dropdown-toggle" type="button" data-bs-toggle="dropdown" aria-expanded="false" title="Télécharger la tâche">
  71. <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-download" viewBox="0 0 16 16">
  72. <path d="M.5 9.9a.5.5 0 0 1 .5.5v2.5a1 1 0 0 0 1 1h12a1 1 0 0 0 1-1v-2.5a.5.5 0 0 1 1 0v2.5a2 2 0 0 1-2 2H2a2 2 0 0 1-2-2v-2.5a.5.5 0 0 1 .5-.5"/>
  73. <path d="M7.646 11.854a.5.5 0 0 0 .708 0l3-3a.5.5 0 0 0-.708-.708L8.5 10.293V1.5a.5.5 0 0 0-1 0v8.793L5.354 8.146a.5.5 0 1 0-.708.708z"/>
  74. </svg>
  75. Télécharger
  76. </button>
  77. <ul class="dropdown-menu">
  78. <li><a class="dropdown-item" href="{{ path('app_task_geojson', {'slug': task.slug}) }}">.geojson</a></li>
  79. <li><a class="dropdown-item" href="{{ path('app_task_gpx', {'slug': task.slug}) }}">.gpx</a></li>
  80. </ul>
  81. </div>
  82. <button
  83. class="btn btn-secondary"
  84. type="button"
  85. data-controller="josm"
  86. data-action="click->josm#remoteControl"
  87. data-josm-commands-value="{{ josmCommands|escape('html_attr') }}"
  88. title="Télécommande JOSM"
  89. >
  90. <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-broadcast" viewBox="0 0 16 16">
  91. <path d="M3.05 3.05a7 7 0 0 0 0 9.9.5.5 0 0 1-.707.707 8 8 0 0 1 0-11.314.5.5 0 0 1 .707.707m2.122 2.122a4 4 0 0 0 0 5.656.5.5 0 1 1-.708.708 5 5 0 0 1 0-7.072.5.5 0 0 1 .708.708m5.656-.708a.5.5 0 0 1 .708 0 5 5 0 0 1 0 7.072.5.5 0 1 1-.708-.708 4 4 0 0 0 0-5.656.5.5 0 0 1 0-.708m2.122-2.12a.5.5 0 0 1 .707 0 8 8 0 0 1 0 11.313.5.5 0 0 1-.707-.707 7 7 0 0 0 0-9.9.5.5 0 0 1 0-.707zM10 8a2 2 0 1 1-4 0 2 2 0 0 1 4 0"/>
  92. </svg>
  93. JOSM
  94. </button>
  95. </div>
  96. {% endif %}
  97. {% endif %}
  98. {% if randomTask %}
  99. <div class="btn-group me-2">
  100. <a href="{{ path('app_task_show', {'slug': randomTask.slug}) }}" class="btn btn-secondary" title="Piocher une tâche">
  101. <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-shuffle" viewBox="0 0 16 16">
  102. <path fill-rule="evenodd" d="M0 3.5A.5.5 0 0 1 .5 3H1c2.202 0 3.827 1.24 4.874 2.418.49.552.865 1.102 1.126 1.532.26-.43.636-.98 1.126-1.532C9.173 4.24 10.798 3 13 3v1c-1.798 0-3.173 1.01-4.126 2.082A9.6 9.6 0 0 0 7.556 8a9.6 9.6 0 0 0 1.317 1.918C9.828 10.99 11.204 12 13 12v1c-2.202 0-3.827-1.24-4.874-2.418A10.6 10.6 0 0 1 7 9.05c-.26.43-.636.98-1.126 1.532C4.827 11.76 3.202 13 1 13H.5a.5.5 0 0 1 0-1H1c1.798 0 3.173-1.01 4.126-2.082A9.6 9.6 0 0 0 6.444 8a9.6 9.6 0 0 0-1.317-1.918C4.172 5.01 2.796 4 1 4H.5a.5.5 0 0 1-.5-.5"/>
  103. <path d="M13 5.466V1.534a.25.25 0 0 1 .41-.192l2.36 1.966c.12.1.12.284 0 .384l-2.36 1.966a.25.25 0 0 1-.41-.192m0 9v-3.932a.25.25 0 0 1 .41-.192l2.36 1.966c.12.1.12.284 0 .384l-2.36 1.966a.25.25 0 0 1-.41-.192"/>
  104. </svg>
  105. Piocher
  106. </a>
  107. </div>
  108. {% endif %}
  109. </div>
  110. </div>
  111. </div>
  112. <div class="row">
  113. <div class="col mb-3">
  114. <p class="text-muted">
  115. {% include 'partials/_task-metadata.html.twig' %}
  116. {% include 'partials/_task-locking.html.twig' %}
  117. </p>
  118. </div>
  119. </div>
  120. {% if task.description is not empty %}
  121. <h2 class="mb-3">Description</h2>
  122. <div class="row">
  123. <div class="col mb-3 lead">{{ task.description|markdown_to_html }}</div>
  124. </div>
  125. {% endif %}
  126. {% if task.status == 'doing' %}
  127. <div class="row">
  128. <div class="col mb-3">
  129. <table class="table table-bordered table-sm">
  130. <tbody>
  131. <tr>
  132. <th scope="row">Commentaire</th>
  133. <td>
  134. {{ macro.clipboard(sourceGenerator.generate(task)) }}
  135. </td>
  136. </tr>
  137. <tr>
  138. <th scope="row">Source</th>
  139. <td>
  140. {{ macro.clipboard(project.source) }}
  141. </td>
  142. </tr>
  143. </tbody>
  144. </table>
  145. </div>
  146. </div>
  147. {% endif %}
  148. {% if task.status == 'done' and task.changesetsResult is not empty %}
  149. <div class="row">
  150. <div class="col mb-3">
  151. <div class="accordion" id="changsetsAccordion">
  152. {% set changesets = task.changesetsResult|json_decode %}
  153. {% for changeset in changesets %}
  154. {% set collapseId = 'collapse' ~ loop.index %}
  155. <div class="accordion-item">
  156. <h2 class="accordion-header">
  157. <button class="accordion-button collapsed" type="button" data-bs-toggle="collapse" data-bs-target="{{ '#' ~ collapseId }}" aria-expanded="false" aria-controls="{{ collapseId }}">
  158. {{ 'Groupe de modifications ' ~ changeset.id }}
  159. </button>
  160. </h2>
  161. <div id="{{ collapseId }}" class="accordion-collapse collapse" data-bs-parent="#changesetsAccordion">
  162. <div class="accordion-body">
  163. <p> Voir sur <a href="{{ 'https://www.openstreetmap.org/changeset/' ~ changeset.id }}" target="_blank">OSM</a> ou <a href="{{ 'https://osmcha.org/changesets/' ~ changeset.id }}" target="_blank">OSMCha</a></p>
  164. <table class="table table-bordered table-sm">
  165. <tbody>
  166. {% for key, value in changeset %}
  167. <tr>
  168. <th scope="row">{{ key }}</th>
  169. <td>{{ value }}</td>
  170. </tr>
  171. {% endfor %}
  172. </tbody>
  173. </table>
  174. </div>
  175. </div>
  176. </div>
  177. {% endfor %}
  178. </div>
  179. </div>
  180. </div>
  181. {% endif %}
  182. <h2 class="mb-3">Carte</h2>
  183. <div class="row">
  184. <div class="col mb-3">
  185. {{ macro.map(task, task.project.overpassResult) }}
  186. </div>
  187. </div>
  188. {% if task.comments is not empty %}
  189. <details>
  190. <summary class="mb-3"><h2 class="d-inline">Commentaires <span class="badge text-bg-secondary">{{ task.comments|length }}</span></h2></summary>
  191. {% endif %}
  192. {% if task.comments is not empty %}
  193. <div class="row">
  194. <div class="col mb-3">
  195. {% for comment in task.comments %}
  196. <blockquote class="blockquote">
  197. {{ comment.content|markdown_to_html }}
  198. </blockquote>
  199. <figcaption class="blockquote-footer">
  200. {% include 'partials/_comment-metadata.html.twig' %}
  201. </figcaption>
  202. {% endfor %}
  203. </div>
  204. </div>
  205. {% endif %}
  206. {% if task.comments is not empty %}
  207. </details>
  208. {% endif %}
  209. {% if is_granted('IS_AUTHENTICATED_FULLY') %}
  210. <div class="row">
  211. <div class="col mb-3">
  212. {{ form(commentForm) }}
  213. </div>
  214. </div>
  215. {% endif %}
  216. {% endblock %}