@@ -82,6 +82,7 @@ jQuery(document).ready(function () {
8282 jQuery ( element ) . addClass ( "selected" ) ;
8383
8484 showConstraintHints ( element ) ;
85+ showTimeSlotTypeIndicators ( element . dataset . type ) ;
8586
8687 let sessionInfoContainer = content . find ( ".scheduling-panel .session-info-container" ) ;
8788 sessionInfoContainer . html ( jQuery ( element ) . find ( ".session-info" ) . html ( ) ) ;
@@ -105,6 +106,7 @@ jQuery(document).ready(function () {
105106 else {
106107 sessions . removeClass ( "selected" ) ;
107108 showConstraintHints ( ) ;
109+ resetTimeSlotTypeIndicators ( ) ;
108110 content . find ( ".scheduling-panel .session-info-container" ) . html ( "" ) ;
109111 }
110112 }
@@ -203,6 +205,23 @@ jQuery(document).ready(function () {
203205 }
204206 }
205207
208+ /**
209+ * Remove timeslot classes indicating timeslot type disagreement
210+ */
211+ function resetTimeSlotTypeIndicators ( ) {
212+ timeslots . removeClass ( 'wrong-timeslot-type' ) ;
213+ }
214+
215+ /**
216+ * Add timeslot classes indicating timeslot type disagreement
217+ *
218+ * @param timeslot_type
219+ */
220+ function showTimeSlotTypeIndicators ( timeslot_type ) {
221+ timeslots . removeClass ( 'wrong-timeslot-type' ) ;
222+ timeslots . filter ( '[data-type!="' + timeslot_type + '"]' ) . addClass ( 'wrong-timeslot-type' ) ;
223+ }
224+
206225 /**
207226 * Should this timeslot be treated as a future timeslot?
208227 *
@@ -277,19 +296,42 @@ jQuery(document).ready(function () {
277296 return Boolean ( event . originalEvent . dataTransfer . getData ( dnd_mime_type ) ) ;
278297 }
279298
299+ /**
300+ * Get the session element being dragged
301+ *
302+ * @param event drag-related event
303+ */
304+ function getDraggedSession ( event ) {
305+ if ( ! isSessionDragEvent ( event ) ) {
306+ return null ;
307+ }
308+ const sessionId = event . originalEvent . dataTransfer . getData ( dnd_mime_type ) ;
309+ const sessionElements = sessions . filter ( "#" + sessionId ) ;
310+ if ( sessionElements . length > 0 ) {
311+ return sessionElements [ 0 ] ;
312+ }
313+ return null ;
314+ }
315+
280316 /**
281317 * Can a session be dropped in this element?
282318 *
283319 * Drop is allowed in drop-zones that are in unassigned-session or timeslot containers
284320 * not marked as 'past'.
285321 */
286- function sessionDropAllowed ( elt ) {
287- if ( ! officialSchedule ) {
288- return true ;
322+ function sessionDropAllowed ( dropElement , sessionElement ) {
323+ const relevant_parent = dropElement . closest ( '.timeslot, .unassigned-sessions' ) ;
324+ if ( ! relevant_parent || ! sessionElement ) {
325+ return false ;
326+ }
327+
328+ if ( officialSchedule && relevant_parent . classList . contains ( 'past' ) ) {
329+ return false ;
289330 }
290331
291- const relevant_parent = elt . closest ( '.timeslot, .unassigned-sessions' ) ;
292- return relevant_parent && ! ( relevant_parent . classList . contains ( 'past' ) ) ;
332+ return ! relevant_parent . dataset . type || (
333+ relevant_parent . dataset . type === sessionElement . dataset . type
334+ ) ;
293335 }
294336
295337 if ( ! content . find ( ".edit-grid" ) . hasClass ( "read-only" ) ) {
@@ -314,7 +356,7 @@ jQuery(document).ready(function () {
314356 // dropping
315357 let dropElements = content . find ( ".timeslot .drop-target,.unassigned-sessions .drop-target" ) ;
316358 dropElements . on ( 'dragenter' , function ( event ) {
317- if ( sessionDropAllowed ( this ) ) {
359+ if ( sessionDropAllowed ( this , getDraggedSession ( event ) ) ) {
318360 event . preventDefault ( ) ; // default action is signalling that this is not a valid target
319361 jQuery ( this ) . parent ( ) . addClass ( "dropping" ) ;
320362 }
@@ -324,46 +366,37 @@ jQuery(document).ready(function () {
324366 // we don't actually need this event, except we need to signal
325367 // that this is a valid drop target, by cancelling the default
326368 // action
327- if ( sessionDropAllowed ( this ) ) {
369+ if ( sessionDropAllowed ( this , getDraggedSession ( event ) ) ) {
328370 event . preventDefault ( ) ;
329371 }
330372 } ) ;
331373
332374 dropElements . on ( 'dragleave' , function ( event ) {
333375 // skip dragleave events if they are to children
334376 const leaving_child = event . originalEvent . currentTarget . contains ( event . originalEvent . relatedTarget ) ;
335- if ( ! leaving_child && sessionDropAllowed ( this ) ) {
377+ if ( ! leaving_child && sessionDropAllowed ( this , getDraggedSession ( event ) ) ) {
336378 jQuery ( this ) . parent ( ) . removeClass ( 'dropping' ) ;
337379 }
338380 } ) ;
339381
340382 dropElements . on ( 'drop' , function ( event ) {
341383 let dropElement = jQuery ( this ) ;
342384
343- if ( ! isSessionDragEvent ( event ) ) {
344- // event is result of something other than a session drag
345- dropElement . parent ( ) . removeClass ( "dropping" ) ;
346- return ;
347- }
348-
349- const sessionId = event . originalEvent . dataTransfer . getData ( dnd_mime_type ) ;
350- let sessionElement = sessions . filter ( "#" + sessionId ) ;
351- if ( sessionElement . length === 0 ) {
352- // drag event is not from a session we recognize
385+ const sessionElement = getDraggedSession ( event ) ;
386+ if ( ! sessionElement ) {
387+ // not drag event or not from a session we recognize
353388 dropElement . parent ( ) . removeClass ( "dropping" ) ;
354389 return ;
355390 }
356391
357- // We now know this is a drop of a recognized session
358-
359- if ( ! sessionDropAllowed ( this ) ) {
392+ if ( ! sessionDropAllowed ( this , sessionElement ) ) {
360393 dropElement . parent ( ) . removeClass ( "dropping" ) ; // just in case
361394 return ; // drop not allowed
362395 }
363396
364397 event . preventDefault ( ) ; // prevent opening as link
365398
366- let dragParent = sessionElement . parent ( ) ;
399+ let dragParent = jQuery ( sessionElement ) . parent ( ) ;
367400 if ( dragParent . is ( this ) ) {
368401 dropElement . parent ( ) . removeClass ( "dropping" ) ;
369402 return ;
@@ -400,7 +433,7 @@ jQuery(document).ready(function () {
400433 timeout : 5 * 1000 ,
401434 data : {
402435 action : "unassign" ,
403- session : sessionId . slice ( "session" . length )
436+ session : sessionElement . id . slice ( "session" . length )
404437 }
405438 } ) . fail ( failHandler ) . done ( done ) ;
406439 }
@@ -410,7 +443,7 @@ jQuery(document).ready(function () {
410443 method : "post" ,
411444 data : {
412445 action : "assign" ,
413- session : sessionId . slice ( "session" . length ) ,
446+ session : sessionElement . id . slice ( "session" . length ) ,
414447 timeslot : dropParent . attr ( "id" ) . slice ( "timeslot" . length )
415448 } ,
416449 timeout : 5 * 1000
@@ -673,7 +706,7 @@ jQuery(document).ready(function () {
673706 // toggling visible sessions by session parents
674707 let sessionParentInputs = content . find ( ".session-parent-toggles input" ) ;
675708
676- function setSessionHidden ( sess , hide ) {
709+ function setSessionHiddenParent ( sess , hide ) {
677710 sess . toggleClass ( 'hidden-parent' , hide ) ;
678711 sess . prop ( 'draggable' , ! hide ) ;
679712 }
@@ -684,13 +717,28 @@ jQuery(document).ready(function () {
684717 checked . push ( ".parent-" + this . value ) ;
685718 } ) ;
686719
687- setSessionHidden ( sessions . not ( ".untoggleable" ) . filter ( checked . join ( "," ) ) , false ) ;
688- setSessionHidden ( sessions . not ( ".untoggleable" ) . not ( checked . join ( "," ) ) , true ) ;
720+ setSessionHiddenParent ( sessions . not ( ".untoggleable-by-parent " ) . filter ( checked . join ( "," ) ) , false ) ;
721+ setSessionHiddenParent ( sessions . not ( ".untoggleable-by-parent " ) . not ( checked . join ( "," ) ) , true ) ;
689722 }
690723
691724 sessionParentInputs . on ( "click" , updateSessionParentToggling ) ;
692725 updateSessionParentToggling ( ) ;
693726
727+ // Toggling session purposes
728+ let sessionPurposeInputs = content . find ( '.session-purpose-toggles input' ) ;
729+ function updateSessionPurposeToggling ( ) {
730+ let checked = [ ] ;
731+ sessionPurposeInputs . filter ( ":checked" ) . each ( function ( ) {
732+ checked . push ( ".purpose-" + this . value ) ;
733+ } ) ;
734+
735+ sessions . filter ( checked . join ( "," ) ) . removeClass ( 'hidden-purpose' ) ;
736+ sessions . not ( checked . join ( "," ) ) . addClass ( 'hidden-purpose' ) ;
737+ }
738+
739+ sessionPurposeInputs . on ( "click" , updateSessionPurposeToggling ) ;
740+ updateSessionPurposeToggling ( ) ;
741+
694742 // toggling visible timeslots
695743 let timeslotGroupInputs = content . find ( "#timeslot-group-toggles-modal .modal-body input" ) ;
696744 function updateTimeslotGroupToggling ( ) {
0 commit comments