omassot 6 gadi atpakaļ
vecāks
revīzija
2d6dcab6ae

+ 4 - 1
main/static/css/custom.css

@@ -172,7 +172,10 @@ select[multiple] option {
 	justify-content: space-around;
 }
 
-
+.messages {
+	text-align: center;
+	list-style: none;
+}
 
 /* Main Header */
 

+ 55 - 1
main/static/js/custom.js

@@ -261,5 +261,59 @@ $(document).ready( function () {
 		
 	});
 	
-	
+	$("#sprint-end .story_close").click(function(event) {
+		event.preventDefault();
+		var story_tr = $(this).closest('tr');
+		var story_id = story_tr.data('id');
+		
+        $.ajax({
+            type: "POST",
+            url: "/stories/close/" + story_id + "/",
+            data: '{story_id:' + story_id + '}',
+            contentType: "application/json; charset=utf-8",
+            dataType: "json",
+            beforeSend: function(xhr, settings) {
+                if (!csrfSafeMethod(settings.type) && !this.crossDomain) {
+                    xhr.setRequestHeader("X-CSRFToken", csrftoken);
+                }
+            },
+            success: function (response) {
+            	story_tr.find('.btn-cell').html('<a class="button special icon fa-check tool-btn already-checked"></a>');
+            	story_tr.find('.btn-cell-2').html('<a class="button special icon fa-mail-forward tool-btn disabled"></a>');
+            },
+            failure: function (response) {
+                alert(response.responseText);
+            },
+            error: function (response) {
+                alert(response.responseText);
+            }
+        });
+	});
+
+	$("#sprint-end .story_reaffect").click(function(event) {
+		event.preventDefault();
+		var story_tr = $(this).closest('tr');
+		var story_id = story_tr.data('id');
+		
+        $.ajax({
+            type: "POST",
+            url: "/stories/reaffect/" + story_id + "/",
+            success: function (response) {
+            	story_tr.find('.btn-cell').html('<a class="button special icon fa-check tool-btn disabled"></a>');
+            	story_tr.find('.btn-cell-2').html('<a class="button special icon fa-mail-forward tool-btn already-checked"></a>');
+            },
+            failure: function (response) {
+                alert(response.responseText);
+            },
+            error: function (response) {
+                alert(response.responseText);
+            }
+        });
+	});
+
+	$("#sprint-end .retro-section input").click(function (event) {
+		if (confirm('Le sprint courant va être marqué comme terminé, continuer?')) {
+			return true;
+		}
+	});
 });

+ 8 - 0
main/templates/_layout.html

@@ -136,6 +136,14 @@
 		
 		<section id="main">
 			<div class="inner">
+			{% if messages %}
+			<ul class="messages">
+			    {% for message in messages %}
+			    <li{% if message.tags %} class="{{ message.tags }}"{% endif %}>{{ message }}</li>
+			    {% endfor %}
+			</ul>
+			{% endif %}
+			
 			{% block main %}
 			
 			{% endblock %}

+ 4 - 91
main/templates/sprint_end.html

@@ -19,6 +19,7 @@
 		</div>
 	</header>
 	
+	<div id="sprint-end">
 	{% if not next_sprint %}
 		<p class="error">Le sprint suivant n'existe pas!</p>
 	{% else %}
@@ -27,7 +28,7 @@
 		<table>
 		{% for story in sprint.stories.all|dictsort:"id" %}
 			<tr data-id="{{ story.id }}">
-				<td class="btn-cell">
+				<td class="btn-cell" width="1%">
 					{% if story.closed %}
 					<a href="" class="story_close button special icon fa-check tool-btn already-checked"></a>
 					{% elif next_sprint in story.sprints.all %}
@@ -36,7 +37,7 @@
 					<a href="" class="story_close button special icon fa-check tool-btn" title="Clôre"></a>
 					{% endif %}
 				</td>
-				<td class="btn-cell-2">
+				<td class="btn-cell-2" width="1%">
 					{% if story.closed %}
 					<a class="button special icon fa-mail-forward tool-btn disabled"></a>
 					{% elif next_sprint in story.sprints.all %}
@@ -63,95 +64,7 @@
 	    		<input type="submit" value="Enregistrer et clôre le sprint">
 	    	</div>
 		</form>
-		
-		<script>
-			function csrfSafeMethod(method) {
-			    // these HTTP methods do not require CSRF protection
-			    return (/^(GET|HEAD|OPTIONS|TRACE)$/.test(method));
-			}
-			function getCookie(name) {
-			    var cookieValue = null;
-			    if (document.cookie && document.cookie !== '') {
-			        var cookies = document.cookie.split(';');
-			        for (var i = 0; i < cookies.length; i++) {
-			            var cookie = jQuery.trim(cookies[i]);
-			            // Does this cookie string begin with the name we want?
-			            if (cookie.substring(0, name.length + 1) === (name + '=')) {
-			                cookieValue = decodeURIComponent(cookie.substring(name.length + 1));
-			                break;
-			            }
-			        }
-			    }
-			    return cookieValue;
-			}
-			var csrftoken = getCookie('csrftoken');
-		
-			$(".story_close").click(function(event) {
-				event.preventDefault();
-				var story_tr = $(this).closest('tr');
-				var story_id = story_tr.data('id');
-				
-	            $.ajax({
-	                type: "POST",
-	                url: "/stories/close/" + story_id + "/",
-	                data: '{story_id:' + story_id + '}',
-	                contentType: "application/json; charset=utf-8",
-	                dataType: "json",
-	                beforeSend: function(xhr, settings) {
-	                    if (!csrfSafeMethod(settings.type) && !this.crossDomain) {
-	                        xhr.setRequestHeader("X-CSRFToken", csrftoken);
-	                    }
-	                },
-	                success: function (response) {
-	                	story_tr.find('.btn-cell').html('<a class="button special icon fa-check tool-btn already-checked"></a>');
-	                	story_tr.find('.btn-cell-2').html('<a class="button special icon fa-mail-forward tool-btn disabled"></a>');
-	                },
-	                failure: function (response) {
-	                    alert(response.responseText);
-	                },
-	                error: function (response) {
-	                    alert(response.responseText);
-	                }
-	            });
-			});
-		
-			$(".story_reaffect").click(function(event) {
-				event.preventDefault();
-				var story_tr = $(this).closest('tr');
-				var story_id = story_tr.data('id');
-				
-	            $.ajax({
-	                type: "POST",
-	                url: "/stories/reaffect/" + story_id + "/",
-	                data: '{story_id:' + story_id + '}',
-	                contentType: "application/json; charset=utf-8",
-	                dataType: "json",
-	                beforeSend: function(xhr, settings) {
-	                    if (!csrfSafeMethod(settings.type) && !this.crossDomain) {
-	                        xhr.setRequestHeader("X-CSRFToken", csrftoken);
-	                    }
-	                },
-	                success: function (response) {
-	                	story_tr.find('.btn-cell').html('<a class="button special icon fa-check tool-btn disabled"></a>');
-	                	story_tr.find('.btn-cell-2').html('<a class="button special icon fa-mail-forward tool-btn already-checked"></a>');
-	                },
-	                failure: function (response) {
-	                    alert(response.responseText);
-	                },
-	                error: function (response) {
-	                    alert(response.responseText);
-	                }
-	            });
-			});
-	
-			$(".retro-section input").click(function (event) {
-				if (confirm('Le sprint courant va être marqué comme terminé, continuer?')) {
-					return true;
-				}
-			});
-			
-		</script>
-
+	</div>
 	{% endif %}
 
 {% endblock %}

+ 5 - 2
main/views.py

@@ -2,6 +2,7 @@ from datetime import datetime, timedelta
 import json
 import uuid
 
+from django.contrib import messages
 from django.contrib.auth import logout, login, update_session_auth_hash
 from django.contrib.auth.decorators import login_required
 from django.contrib.auth.forms import PasswordChangeForm
@@ -110,6 +111,10 @@ def sprint_end(request):
     current_sprint = Sprint.current()
     next_sprint = Sprint.next()
     
+    if not current_sprint:
+        messages.error(request, 'Aucun sprint en cours')
+        return redirect("index")
+    
     if not next_sprint:
         return redirect("sprint_new")
     
@@ -495,8 +500,6 @@ def notify_sprint_end(sprint, next_sprint, ended_by):
     notify.send(ended_by, recipient=User.objects.all(), action_object = sprint, verb=f"Fin du <a href='{target_url}'>{sprint}</a>")
     notify.send(ended_by, recipient=User.objects.all(), action_object = sprint, verb=f"Démarrage du <a href='{target_url}'>{next_sprint}</a>")
 
-
-
 @login_required
 def md_upload_file(request):
     if request.method == 'POST' and request.is_ajax():