Browse Source

Fix programme display for chrome

Integrate Piernov Pull request
Added missing deletion behavior
Fixed badge generation
Added intervention summary

Signed-off-by: tr4ck3ur <tr4ck3ur@style-python.fr>
tr4ck3ur 2 years ago
parent
commit
c058eb9245
4 changed files with 149 additions and 60 deletions
  1. 132 49
      jm2l/static/js/programme.js
  2. 1 1
      jm2l/templates/Participer.mako
  3. 2 2
      jm2l/templates/Salles/list.mako
  4. 14 8
      jm2l/views.py

+ 132 - 49
jm2l/static/js/programme.js

@@ -22,23 +22,23 @@ var Tasks = Array();
22 22
 d3.json("le-prog-json",
23 23
     function(error, json) {
24 24
         if (error) return console.warn(error);
25
-        var Keys = Object.keys(json["all"])
25
+        var Keys = Object.keys(json["all"]);
26 26
         // Build set of data in memory
27 27
         for (var k = 0; k < Keys.length; k++) {
28 28
             Salles[Keys[k]] = Array();
29 29
             Areas[Keys[k]] = Array();
30
-            Tasks[Keys[k]] = json["all"][Keys[k]]
30
+            Tasks[Keys[k]] = json["all"][Keys[k]];
31 31
             // Fix Json to make date objects
32 32
             Tasks[Keys[k]].forEach(function(d) {
33 33
                 d.startDate = new Date(d.startDate);
34 34
                 d.endDate = new Date(d.endDate);
35
-            })
35
+            });
36 36
 
37 37
             // Build the list of Salles and Areas
38 38
             Tasks[Keys[k]].forEach(function(d) {
39 39
                 Salles[Keys[k]].push( d.placeName );
40 40
                 Areas[Keys[k]].push( d.status );
41
-            } )
41
+            } );
42 42
             Salles[Keys[k]] = d3.set(Salles[Keys[k]]).values();
43 43
             Areas[Keys[k]] = d3.set(Areas[Keys[k]]).values();
44 44
             // Create Controls to Handle user selection
@@ -61,6 +61,10 @@ d3.json("le-prog-json",
61 61
                     .style("margin-left", "5px")
62 62
                     .text(TypeArea);
63 63
             });
64
+            
65
+			d3.select("#Schedule_SVG_"+Keys[k])
66
+                    .append("br");
67
+            
64 68
             // Create a dedicated SVG for it 
65 69
             svg = d3.select("#Schedule_SVG_"+Keys[k])
66 70
                 .append("svg")
@@ -69,7 +73,9 @@ d3.json("le-prog-json",
69 73
                 //.attr("height", height + margin.top + margin.bottom)
70 74
                 .attr("viewBox", "0 0 " + (width + margin.right + margin.left) + " " + (height + margin.top + margin.bottom) )
71 75
                 .attr("preserveAspectRatio", "xMidYMid meet");
72
-
76
+            // Add some gradient
77
+			header(svg);
78
+			// Create axis
73 79
             svg.append("g")
74 80
                 .attr("class", "xAxis axis");
75 81
              
@@ -84,6 +90,82 @@ d3.json("le-prog-json",
84 90
         }
85 91
 });
86 92
 
93
+function header(svg) {
94
+	defs = svg.append("svg:defs");
95
+	
96
+	conf = defs.append("svg:linearGradient")
97
+	    .attr("id", "BoxGradient-Conference")
98
+	    .attr("x1", "100%")
99
+	    .attr("y1", "0%")
100
+	    .attr("x2", "50%")
101
+	    .attr("y2", "100%")
102
+	    .attr("spreadMethod", "pad");
103
+
104
+	conf.append("svg:stop")
105
+	    .attr("offset", "0%")
106
+	    .attr("stop-color", "#EEE")
107
+	    .attr("stop-opacity", 0);
108
+	
109
+	conf.append("svg:stop")
110
+	    .attr("offset", "15%")
111
+	    .attr("stop-color", "#BDF86B")
112
+	    .attr("stop-opacity", .5);
113
+	    
114
+	atlier = defs.append("svg:linearGradient")
115
+	    .attr("id", "BoxGradient-Atelier")
116
+	    .attr("x1", "100%")
117
+	    .attr("y1", "0%")
118
+	    .attr("x2", "50%")
119
+	    .attr("y2", "100%")
120
+	    .attr("spreadMethod", "pad");
121
+
122
+	atlier.append("svg:stop")
123
+	    .attr("offset", "0%")
124
+	    .attr("stop-color", "#EEE")
125
+	    .attr("stop-opacity", 0);
126
+	
127
+	atlier.append("svg:stop")
128
+	    .attr("offset", "15%")
129
+	    .attr("stop-color", "#FF856E")
130
+	    .attr("stop-opacity", .5);	    
131
+
132
+	// append filter element
133
+	var filter = defs.append( 'filter' )
134
+	    .attr( 'id', 'dropshadow' ); /// !!! important - define id to reference it later
135
+	
136
+	// append gaussian blur to filter
137
+	filter.append( 'feGaussianBlur' )
138
+	      .attr( 'in', 'SourceAlpha' )
139
+	      .attr( 'stdDeviation', 3 ) // !!! important parameter - blur
140
+	      .attr( 'result', 'blur' );
141
+	
142
+	// append offset filter to result of gaussion blur filter
143
+	filter.append( 'feOffset' )
144
+	      .attr( 'in', 'blur' )
145
+	      .attr( 'dx', 2 ) // !!! important parameter - x-offset
146
+	      .attr( 'dy', 2 ) // !!! important parameter - y-offset
147
+	      .attr( 'result', 'offsetBlur' );
148
+
149
+	filter.append( 'feComponentTransfer' )
150
+		  .append( 'feFuncA' )
151
+		  .attr( "type", "linear" )
152
+		  .attr( "slope", "0.4" );
153
+	
154
+	// merge result with original image
155
+	var feMerge = filter.append( 'feMerge' );
156
+	
157
+	// first layer result of blur and offset
158
+	feMerge.append( 'feMergeNode' )
159
+	       .attr( 'in", "offsetBlur' );
160
+	
161
+	// original image on top
162
+	feMerge.append( 'feMergeNode' )
163
+	       .attr( 'in', 'SourceGraphic' );
164
+	// end filter stuff
165
+
166
+}
167
+
168
+
87 169
 var keyFunction = function(d) {
88 170
     return d.startDate + d.placeName + d.endDate;
89 171
 };
@@ -92,14 +174,14 @@ function HandleEvents(Ctrl) {
92 174
     d3.selectAll("input[name=OptTimetable-"+Ctrl+"]")
93 175
         .data(Areas[Ctrl])
94 176
         .on("change", function(TypeData) {
95
-            ArrayChoice = Array()
177
+            ArrayChoice = Array();
96 178
             checked = d3.selectAll("input[name=OptTimetable-"+Ctrl+"]")[0]
97 179
                 .forEach( function(v)
98 180
                     {
99 181
                     if (d3.select(v).node().checked)
100
-                        ArrayChoice.push(v.attributes['area'].value)
182
+                        ArrayChoice.push(v.attributes['area'].value);
101 183
                     }
102
-                )
184
+               );
103 185
             area_select = Array();
104 186
             selection = Tasks[Ctrl].filter(function(v) {
105 187
                 return ArrayChoice.indexOf(v.status)>=0;
@@ -154,53 +236,18 @@ function displayit(Set_of_Task, Set_of_Area, key) {
154 236
 
155 237
         var svg = d3.select("#TimeTable-"+key);
156 238
         
157
-        var chart = svg.select(".timetable")
158
-
159
-        var content = chart.selectAll("foreignObject")
160
-            .data(Set_of_Task, keyFunction);        
161
-
162
-        content.enter()
163
-            .insert("foreignObject",":first-child")
164
-            .append("xhtml:body")
165
-            .attr("class", "SvgBody")
166
-            .html(function(d) { 
167
-                return '<div class="EvtBox '+ taskStatus[d.status] +'"><a href="/event/'+ d.uid +
168
-                    '">' + d.desc + '</a></div>'
169
-                 })
170
-            .transition()
171
-            .duration(750);
172
-        
173
-        content.transition()
174
-            .duration(750)
175
-            .attr("x", function(d){ 
176
-                return xScale(d.placeName || "unk");
177
-                 })
178
-            .attr("y", function(d){ 
179
-                return yScale( d.startDate );
180
-                 })
181
-            .attr("width", function(d) { 
182
-                return xScale.rangeBand(); 
183
-            })
184
-            .attr("height", function(d) { 
185
-                return (yScale( d.endDate ) - yScale( d.startDate ));
186
-            });
187
-
188
-        content.exit()
189
-            .transition()
190
-            .duration(300)
191
-            .style("opacity", 1e-6)
192
-            .remove();
239
+        var chart = svg.select(".timetable");
193 240
 
194 241
         var rect = chart.selectAll("rect")
195 242
             .data(Set_of_Task, keyFunction);
196 243
         
197 244
         rect.enter()
198
-            .insert("rect",":first-child")
245
+            .insert("rect")
199 246
             .attr("rx", 5)
200 247
             .attr("ry", 5)
201
-            .attr("filter", "url(/img/shadow.svg#dropshadow)")
202
-            .attr("style", function(d){
203
-                return "fill:url(/img/shadow.svg#BoxGradient-"+ taskStatus[d.status] +")"
248
+            .attr("filter", "url(#dropshadow)")
249
+            .style("fill", function(d){
250
+            	return "url(#BoxGradient-"+ taskStatus[d.status] +")";
204 251
             })
205 252
             .attr("class", function(d){ 
206 253
                  if(taskStatus[d.status] == null)
@@ -208,7 +255,7 @@ function displayit(Set_of_Task, Set_of_Area, key) {
208 255
                  return taskStatus[d.status];
209 256
                 })
210 257
             .transition()
211
-            .duration(750)
258
+            .duration(750);
212 259
 
213 260
 
214 261
         rect.transition()
@@ -232,6 +279,42 @@ function displayit(Set_of_Task, Set_of_Area, key) {
232 279
             .style("opacity", 1e-6)
233 280
             .remove();
234 281
 
282
+        var content = chart.selectAll("foreignObject")
283
+            .data(Set_of_Task, keyFunction);        
284
+
285
+        content.enter()
286
+            .insert("foreignObject")
287
+            .append("xhtml:div")
288
+            .attr("class", "SvgBody")
289
+            .html(function(d) { 
290
+                return '<div class="EvtBox '+ taskStatus[d.status] +'"><a href="/event/'+ d.uid +
291
+                    '">' + d.desc + '</a></div>';
292
+                 })
293
+            .transition()
294
+            .duration(750);
295
+        
296
+        content.transition()
297
+            .duration(750)
298
+            .attr("x", function(d){ 
299
+                return xScale(d.placeName || "unk");
300
+                 })
301
+            .attr("y", function(d){ 
302
+                return yScale( d.startDate );
303
+                 })
304
+            .attr("width", function(d) { 
305
+                return xScale.rangeBand(); 
306
+            })
307
+            .attr("height", function(d) { 
308
+                return (yScale( d.endDate ) - yScale( d.startDate ));
309
+            });
310
+//            .attr("transform" ,"scale(1)");
311
+
312
+        content.exit()
313
+            .transition()
314
+            .duration(300)
315
+            .style("opacity", 1e-6)
316
+            .remove();
317
+
235 318
         svg.select(".yAxis")
236 319
             .attr("transform", "translate("+ margin.left +","+ margin.top +")")
237 320
             .transition()

+ 1 - 1
jm2l/templates/Participer.mako

@@ -55,7 +55,7 @@ DicForm ={
55 55
     } 
56 56
 %>
57 57
       <form action="/participer-l-evenement#inscription" method="post">
58
-        <h3 id="inscription" class="form-signin-heading">Je m'inscris</h3>
58
+        <h3 id="inscription">Je m'inscris</h3>
59 59
             <div class="container">
60 60
                 ${helpers.DisplayForm(form, DicForm)}
61 61
                 <div style="border:1px dashed #CCC;float:left;">

+ 2 - 2
jm2l/templates/Salles/list.mako

@@ -13,7 +13,7 @@ from slugify import slugify
13 13
 
14 14
 <div class="tabbable" id="main_tab">
15 15
     <ul class="nav nav-tabs" style="margin-bottom: 5px;">
16
-        % for Num, Entity in enumerate(sorted(DicSalle.keys(), key=lambda x:x.year_uid)):
16
+        % for Num, Entity in enumerate(sorted(DicSalle.keys(), key=lambda x:x.year_uid, reverse=True)):
17 17
         <li class="${["","active"][Num==0]}">
18 18
             <a href="#${Entity.year_uid}" id="Map_Pole_${Entity.year_uid}" data-toggle="tab">${Entity.year_uid}</a>
19 19
         </li>
@@ -22,7 +22,7 @@ from slugify import slugify
22 22
 
23 23
     <div class="tab-content" style="padding:0 10px">
24 24
 
25
-% for Num, Entity in enumerate(sorted(DicSalle.keys(), key=lambda x:x.year_uid)):
25
+% for Num, Entity in enumerate(sorted(DicSalle.keys(), key=lambda x:x.year_uid, reverse=True)):
26 26
         <div class="tab-pane fade ${["","active "][Num==0]} in" id="${Entity.year_uid}">
27 27
             <h4>${Entity.year_uid}</h4>
28 28
 <table class="table table-striped table-bordered table-hover">

+ 14 - 8
jm2l/views.py

@@ -11,8 +11,8 @@ from .forms import *
11 11
 # Database access imports
12 12
 from .models import *
13 13
 from .helpers import Orga_helpers
14
-from sqlalchemy import func, or_
15
-from os import path, makedirs
14
+from sqlalchemy import func, or_, text
15
+from os import path, makedirs, listdir
16 16
 # Usefull tools
17 17
 from slugify import slugify
18 18
 from icalendar import Calendar
@@ -140,7 +140,7 @@ def JSON_Progamme_Request(request):
140 140
         Events = DBSession.query(Event)\
141 141
                     .filter(Event.for_year == year)\
142 142
                     .filter(Event.event_type != 'Stand')\
143
-                    .filter("strftime('%d', start_time) = :dow").params(dow=Day.day)\
143
+                    .filter(text("strftime('%d', start_time) = :dow")).params(dow=Day.day)\
144 144
                     .order_by(Event.start_time)
145 145
                     
146 146
         ListEv = []
@@ -176,7 +176,7 @@ def JSON_TimeLine_Request(request):
176 176
         Events = DBSession.query(Event)\
177 177
                     .filter(Event.for_year == year)\
178 178
                     .filter(Event.event_type != 'Stand')\
179
-                    .filter("strftime('%d', start_time) = :dow").params(dow=Day.day)\
179
+                    .filter(text("strftime('%d', start_time) = :dow")).params(dow=Day.day)\
180 180
                     .order_by(Event.start_time)
181 181
                     
182 182
         #ListEv = []
@@ -192,10 +192,10 @@ def JSON_TimeLine_Request(request):
192 192
                     Container = ""
193 193
                 ListEv.append( {
194 194
                     #"uid":"%d/%d" % ( year, ev.uid ),
195
-                    "headline":ev.name,
195
+                    "headline":'<a href="/event/%s/%s">%s</a>' % (ev.for_year, ev.slug, ev.name),
196 196
                     "startDate":ev.start_time.strftime('%Y,%m,%d,%H,%M'),
197 197
                     "endDate":ev.end_time.strftime('%Y,%m,%d,%H,%M'),                
198
-                    "text":ev.Salle and (ev.Salle.name or "unk"),
198
+                    "text": ev.Salle and (ev.Salle.name or "unk"),
199 199
                     #"text":ev.description[:100],
200 200
                     "tags":ev.Salle and (ev.Salle.salle_id or "unk") ,
201 201
                     #"status":ev.event_type,
@@ -296,7 +296,13 @@ def index_page(request):
296 296
             raise HTTPNotFound()
297 297
     else:
298 298
         content = DBSession.query(JM2L_Year).filter(JM2L_Year.year_uid==CurrentYear).first().description
299
-    return {'year': CurrentYear, 'content':content, 'edition':u"9<sup>ème</sup>"}
299
+    TargetDir = "jm2l/static/img/%s/Photos" % (year or 2015)
300
+    TargetUrl = "/static/img/%s/Photos/" % (year or 2015)
301
+    if path.isdir(TargetDir):
302
+        ListPhotos =  map(lambda x: TargetUrl + x, listdir(TargetDir))
303
+    else:
304
+        ListPhotos = []
305
+    return {'year': CurrentYear, 'content':content, 'edition':u"9<sup>ème</sup>", 'ListPhotos': ListPhotos}
300 306
 
301 307
 @view_config(route_name='edit_index', renderer="jm2l:templates/Staff/EditIndex.mako")
302 308
 def edit_index(request):
@@ -1424,7 +1430,7 @@ def edit_event(request):
1424 1430
             form.duration.choices.append( (duration,u'Conférence    (%d min)' % duration) )
1425 1431
         if not form._fields.has_key("uid"):            
1426 1432
             form.duration.data=60
1427
-        SalleDispo = SalleDispo.filter(Salles.place_type.in_(['Conference', 'MAO']))
1433
+        SalleDispo = SalleDispo.filter(Salles.place_type.in_(['Conference', 'MAO', 'Atelier']))
1428 1434
     elif intervention=="Stand":
1429 1435
         form.duration.choices =[ 
1430 1436
             (8*60, u'Toute la journée'),