Changeset 2905
- Timestamp:
- 05/19/10 17:17:25
- Files:
-
- trunk/deployment/webuser/webapp/resources/demoskins/themes/bedeworkTheme/css/bwScheduling.css (modified) (2 diffs)
- trunk/deployment/webuser/webapp/resources/demoskins/themes/bedeworkTheme/eventForm.xsl (modified) (2 diffs)
- trunk/deployment/webuser/webapp/resources/demoskins/themes/bedeworkTheme/head.xsl (modified) (2 diffs)
- trunk/deployment/webuser/webapp/resources/demoskins/themes/bedeworkTheme/javascript/bedeworkScheduling.js (modified) (18 diffs)
- trunk/deployment/webuser/webapp/resources/demoskins/themes/bedeworkTheme/javascript/freebusy-old.js (added)
- trunk/deployment/webuser/webapp/resources/demoskins/themes/bedeworkTheme/javascript/freebusy.js (modified) (2 diffs)
- trunk/deployment/webuser/webapp/resources/demoskins/themes/bedeworkTheme/navigation.xsl (modified) (6 diffs)
Legend:
- Unmodified
- Added
- Removed
- Modified
- Copied
- Moved
trunk/deployment/webuser/webapp/resources/demoskins/themes/bedeworkTheme/css/bwScheduling.css
r2903 r2905 5 5 #bwFreeBusyDisplay { 6 6 margin: 2em 2em 0 2em; 7 width: 80%;8 7 overflow: scroll; 9 8 } … … 172 171 margin-left: 1em; 173 172 } 174 173 #bwScheduleControls #bwFbOptionsMenu { 174 position: fixed; 175 display: none; 176 white-space: nowrap; 177 border: 1px solid #333; 178 background-color: #eee; 179 color: black; 180 padding: 0.5em; 181 margin: 0; 182 } trunk/deployment/webuser/webapp/resources/demoskins/themes/bedeworkTheme/eventForm.xsl
r2903 r2905 1502 1502 </td> 1503 1503 <td> 1504 <input type="button" id="bwSchedOptions" value="Options ▼"/> 1504 <input type="button" id="bwSchedOptions" onclick="bwGrid.showOptions();" value="Options ▼"/> 1505 <ul id="bwFbOptionsMenu"> 1506 <li>24 Hours</li> 1507 </ul> 1505 1508 </td> 1506 1509 <td class="dateLabel"> … … 1513 1516 </tr> 1514 1517 </table> 1515 <input type="button" id="getJson" onclick="bwGrid.requestFreeBusy('{$re sourcesRoot}/javascript/freebusy.js');" value="development: get freebusy"/>1518 <input type="button" id="getJson" onclick="bwGrid.requestFreeBusy('{$requestFreeBusy}');" value="development: get freebusy"/> 1516 1519 </div> 1517 1520 </div> trunk/deployment/webuser/webapp/resources/demoskins/themes/bedeworkTheme/head.xsl
r2904 r2905 172 172 <xsl:comment> 173 173 // initialize the free/busy grid - values taken directly from the xml 174 // send params: displayId, startRange, endRange, startDate, endDate, startHourRange, endHourRange, attendees, workday, zoom, browserResourcesRoot, fbUrl, organizerUri 175 // example: var bwGrid = new bwSchedulingGrid("bwFreeBusyDisplay","May 5, 2010","May 17, 2010","May 10, 2010 11:00:00","May 10, 2010 11:30:00",8,17,[{name:"Arlen Johnson",uid:"mailto:johnsa@rpi.edu",role:"CHAIR",status:"ACCEPTED",type:"person"}],true,100,"<xsl:value-of select="$resourcesRoot"/>","<xsl:value-of select="$requestFreeBusy"/>",""); 176 var bwGrid = new bwSchedulingGrid("bwFreeBusyDisplay","May 11, 2010","May 17, 2010","May 13, 2010 11:00:00","May 13, 2010 11:30:00",8,17,[{name:"Arlen Johnson",uid:"mailto:johnsa@mysite.edu",role:"CHAIR",status:"ACCEPTED",type:"person"},{name:"",uid:"mailto:douglm@mysite.edu",role:"REQ-PARTICIPANT",status:"NEEDS-ACTION",type:"person"}],true,100,"<xsl:value-of select="$resourcesRoot"/>","<xsl:value-of select="$resourcesRoot"/>/javascript/freebusy.js",""); 177 178 // send in some attendees - these will come from interaction with the form 179 // bwGrid.updateAttendee("Gary Schwartz", "mailto:schwag@mysite.edu", "OPT-PARTICIPANT", "DECLINED"); 180 181 // now initialize the grid 182 bwGrid.init(); 174 // send params: displayId, startRange, startHourRange, endHourRange, attendees, workday, zoom, browserResourcesRoot, fbUrl, organizerUri 175 // example: var bwGrid = new bwSchedulingGrid("bwFreeBusyDisplay","May 5, 2010",8,17,[{name:"Venerable Bede",uid:"vbede@mysite.edu",role:"CHAIR",status:"ACCEPTED",type:"person"}],true,100,"<xsl:value-of select="$resourcesRoot"/>","<xsl:value-of select="$requestFreeBusy"/>",""); 176 177 var bwGridSDate = new Date("<xsl:value-of select="/bedework/formElements/form/start/yearText/input/@value"/>/<xsl:value-of select="/bedework/formElements/form/start/month/select/option[@selected = 'selected']/@value"/>/<xsl:value-of select="/bedework/formElements/form/start/day/select/option[@selected = 'selected']/@value"/>"); 178 var bwGridAttees = new Array({name:"Arlen Johnson",uid:"johnsa@mysite.edu",role:"CHAIR",status:"ACCEPTED",type:"person"},{name:"",uid:"douglm@mysite.edu",role:"REQ-PARTICIPANT",status:"NEEDS-ACTION",type:"person"}); 179 var bwGrid = new bwSchedulingGrid("bwFreeBusyDisplay",bwGridSDate,8,17,bwGridAttees,true,100,"<xsl:value-of select="$resourcesRoot"/>","<xsl:value-of select="$requestFreeBusy"/>","johnsa@mysite.edu"); 180 181 // set the grid size 182 function bwGridSetSize() { 183 var fbWidth = $("#bwEventTab-Basic").width() - 52; 184 $("#bwFreeBusyDisplay").css("width", fbWidth + "px"); 185 }; 186 183 187 </xsl:comment> 184 188 </script> … … 231 235 focusElement('bwEventTitle'); 232 236 bwSetupDatePickers(); 233 bwGrid.display(); 237 bwGrid.init(); 238 bwGridSetSize(); 234 239 </xsl:when> 235 240 <xsl:when test="/bedework/page = 'editEvent'"> trunk/deployment/webuser/webapp/resources/demoskins/themes/bedeworkTheme/javascript/bedeworkScheduling.js
r2904 r2905 65 65 /* An attendee 66 66 * name: String - name of attendee, e.g. "Venerable Bede" 67 * uid: String - attendee's uid with mailto included, e.g. "mailto:vbede@example.com"67 * uid: String - attendee's uid, e.g. "vbede@example.com" 68 68 * role: String - Attendee role, e.g. CHAIR, REQ-PARTICIPANT, etc 69 69 * status: String - participation status (PARTSTAT) … … 118 118 this.end = ""; // will hold the UTC end value in milliseconds 119 119 120 if (this.type = "BUSY-TENTATIVE") {120 if (this.type == "BUSY-TENTATIVE") { 121 121 this.typeDisplay = bwFreeBusyDispTypeTentative; 122 122 } … … 132 132 var endMs; // end in milliseconds 133 133 if (this.value.indexOf("P") > -1) { 134 // freebusy value is of the form: 19971015T223000Z /PT6H30M134 // freebusy value is of the form: 19971015T223000Z\/PT6H30M 135 135 // extract the hours and minutes from the strings and cast as numbers 136 136 var durationHours = this.value.substring(this.value.lastIndexOf("T")+1,this.value.indexOf("H")); … … 144 144 endMs = this.start + duration; 145 145 } else { 146 // freebusy value is of the form: 19980314T233000Z /19980315T003000Z146 // freebusy value is of the form: 19980314T233000Z\/19980315T003000Z 147 147 // set the freebusy end date 148 148 var endDate = new Date(); 149 endDate.setUTCFullYear(this.value.substring(1 7,21),this.value.substring(21,23)-1,this.value.substring(23,25));150 endDate.setUTCHours(this.value.substring(2 6,28),this.value.substring(28,30),this.value.substring(30,32));149 endDate.setUTCFullYear(this.value.substring(18,22),this.value.substring(22,24)-1,this.value.substring(24,26)); 150 endDate.setUTCHours(this.value.substring(27,29),this.value.substring(29,31),this.value.substring(31,33)); 151 151 endMs = endDate.getTime(); 152 152 } … … 169 169 * displayId: ID of html block for display output 170 170 * startRange: js date string - start of date range for grid 171 * endRange: js date string - end of date range for grid 172 * startHoursRange: integer, 0-23 - hours of range start time (we'll use all minutes in an hour) 173 * endHoursRange: integer, 0-23 - hours of range end time (we'll use all minutes in an hour) 174 * startDate: js date string - start date/time for meeting 175 * endDate: date string - end date/time for meeting 171 * startHoursRange: integer, 0-23 - hours of range start time 172 * endHoursRange: integer, 0-23 - hours of range end time 176 173 * attendees: array - array of attendee objects; MUST include organizer on first instantiation 177 174 * workday: boolean - true to display workday hours only, false to display all 24 hours 178 175 * zoom: integer - scalar value for zooming the grid 179 176 * browserResourcesRoot: string - URL of browser resources (for displaying images, etc) 180 * fbUrl : string - URLfor making freebusy requests181 * organizerUri string - e.g. "someone@mysite.edu"177 * fbUrlPrefix: string - URL prefix for making freebusy requests 178 * organizerUri: string - e.g. "someone@mysite.edu" 182 179 */ 183 var bwSchedulingGrid = function(displayId, startRange, endRange, startDate, endDate, startHoursRange, endHoursRange, attendees, workday, zoom, browserResourcesRoot, fbUrl, organizerUri) {180 var bwSchedulingGrid = function(displayId, startRange, startHoursRange, endHoursRange, attendees, workday, zoom, browserResourcesRoot, fbUrlPrefix, organizerUri) { 184 181 this.displayId = displayId; 185 182 this.startRange = new Date(startRange); 186 this.endRange = new Date( endRange);183 this.endRange = new Date(startRange); 187 184 this.startHoursRange = startHoursRange; 188 185 this.endHoursRange = endHoursRange; 189 this.startDate = new Date(startDate);190 this.endDate = new Date(endDate);191 186 this.zoom = zoom; 192 187 this.workday = workday; 193 188 this.attendees = new Array(); // array of bwAttendee objects 194 189 this.resourcesRoot = browserResourcesRoot; 195 this.fbUrl = fbUrl;190 this.fbUrlPrefix = fbUrlPrefix; 196 191 this.organizer = organizerUri; 197 192 193 // format the endRange 194 this.endRange.addDays(5); 195 198 196 // 2D array of time and busy state for all attendees 199 197 // [millisecond value,true/false if busy] … … 225 223 var pickNextClicked = false; // false until the first time we click "pick next" - allows us to show the first free time window on first click 226 224 227 228 225 // initialize the grid 229 226 this.init = function() { 230 227 // initialize any incoming attendees on first load 231 // while iterating, build up the array of requests232 228 for (var i = 0; i < attendees.length; i++) { 233 var newAttendee = new bwAttendee(attendees[i].name, attendees[i].uid, attendees[i].role,attendees[i].status,attendees[i].type);229 var newAttendee = new bwAttendee(attendees[i].name, attendees[i].uid, attendees[i].role, attendees[i].status, attendees[i].type); 234 230 this.attendees.push(newAttendee); 235 231 } 236 232 237 233 // now go get the freebusy information for the attendees 238 if (this.attendees.length ) {239 this.requestFreeBusy( this.fbUrl);234 if (this.attendees.length > 0) { 235 this.requestFreeBusy(); 240 236 } 241 237 } … … 261 257 if (attendeeIsNew) { 262 258 this.attendees.push(newAttendee); 263 this.requestFreeBusy( this.fbUrl);259 this.requestFreeBusy(); 264 260 } 265 261 … … 268 264 this.removeAttendee = function(index) { 269 265 this.attendees.splice(index, 1); 270 this.requestFreeBusy(this.fbUrl); 271 } 272 273 this.requestFreeBusy = function(fburl) { 274 $.getJSON(fburl, function(fb) { 266 this.requestFreeBusy(); 267 } 268 269 this.requestFreeBusy = function() { 270 // set up the freebusy URL based on current parameters 271 // e.g. http://localhost:8080/ucal/event/requestFreeBusy.gdo?b=de&start=20100510T050000Z&end=20100517T050000Z&organizerUri=douglm@mysite.edu&attendeeUri=douglm@mysite.edu&attendeeUri=johnsa@mysite.edu 272 var fbUrlStart = "&start=" + this.startRange.getUTCFullYear() + this.startRange.getUTCMonthFull() + this.startRange.getUTCDateFull() + "T" + this.startRange.getUTCHoursFull() + this.startRange.getUTCMinutesFull() + "00Z"; 273 var fbUrlEnd = "&end=" + this.endRange.getUTCFullYear() + this.endRange.getUTCMonthFull() + this.endRange.getUTCDateFull() + "T" + this.endRange.getUTCHoursFull() + this.endRange.getUTCMinutesFull() + "00Z";; 274 var fbOrganizer = "&organizerUri=" + this.organizer; 275 var fbAttendees = ""; 276 for (var i=0; i < bwGrid.attendees.length; i++) { 277 fbAttendees += "&attendeeUri=" + bwGrid.attendees[i].uid; 278 } 279 var fbUrl = this.fbUrlPrefix + fbUrlStart + fbUrlEnd + fbOrganizer + fbAttendees; 280 281 $.getJSON(fbUrl, function(fb) { 275 282 for (var i=0; i < fb.microformats["schedule-response"].length; i++) { 276 283 var r = fb.microformats["schedule-response"][i]; // reference the current response 277 284 278 // find the attendee and pass in the freebusy object 285 // find the attendee and pass in the freebusy object if the attendee has any 279 286 for (var j=0; j < bwGrid.attendees.length; j++) { 280 if (bwGrid.attendees[j].uid == r["calendar-data"].attendee[0].value) { 281 bwGrid.attendees[j].updateFreeBusy(r["calendar-data"].freebusy); 287 if (bwGrid.attendees[j].uid == r["calendar-data"].attendee[0].value.substr(r["calendar-data"].attendee[0].value.lastIndexOf(":") + 1)) { 288 if (r["calendar-data"].freebusy) { 289 bwGrid.attendees[j].updateFreeBusy(r["calendar-data"].freebusy); 290 } 282 291 } 283 292 } 284 293 } 294 bwGrid.display(); 285 295 }); 286 this.display();287 296 } 288 297 … … 315 324 } 316 325 317 this.pickPrevious = function( gridObj) {326 this.pickPrevious = function() { 318 327 // clear highlighting 319 328 $("#bwScheduleTable .fbcell").removeClass("highlight"); … … 364 373 } 365 374 366 this.display = function() { 375 this.showOptions = function() { 376 $("#bwFbOptionsMenu").show("slow"); 377 } 378 379 this.display = function(width) { 367 380 try { 368 381 // number of days to display … … 384 397 fbDisplay.id = "bwScheduleTable"; 385 398 386 // generate the date row - includes top left empty corner 399 // create the add attendee html 400 var addAttendeeHtml = ''; 401 /*addAttendeeHtml += '<input type="text" name="uri" width="30" id="bwRaUri"/>'; 402 addAttendeeHtml += '<input type="button" value="add" />'; 403 addAttendeeHtml += '<br/>role:'; 404 addAttendeeHtml += '<select name="role">'; 405 addAttendeeHtml += '<option value="REQ-PARTICIPANT">required participant</option>'; 406 addAttendeeHtml += '<option value="OPT-PARTICIPANT">optional participant</option>'; 407 addAttendeeHtml += '<option value="CHAIR">chair</option>'; 408 addAttendeeHtml += '<option value="NON-PARTICIPANT">non-participant</option>'; 409 addAttendeeHtml += '</select>';*/ 410 411 // generate the date row - includes top left corner for "add attendee" 387 412 var fbDisplayDateRow = fbDisplay.insertRow(fbDisplay.rows.length); 388 $(fbDisplayDateRow).html('<td rowspan="2" colspan="4" class="corner"> </td><td class="fbBoundry"></td>');413 $(fbDisplayDateRow).html('<td rowspan="2" colspan="4" class="corner">' + addAttendeeHtml + '</td><td class="fbBoundry"></td>'); 389 414 for (var i=0; i < range; i++) { 390 415 var curDate = new Date(this.startRange); … … 439 464 for (var att = 0; att < this.attendees.length; att++) { 440 465 for (var m = 0; m < this.attendees[att].freebusy.length; m++) { 441 var tzoffset = -curDate.getTimezoneOffset() * 60000; // in milliseconds466 // keep for reference: var tzoffset = -curDate.getTimezoneOffset() * 60000; // in milliseconds 442 467 // adding the hourdivision increment in the calculation below is to correct for a bug 443 468 // in which the class was always offset by one table cell - should find cause 444 var curDateUTC = curDate.getTime() + tzoffset +(60 / this.hourDivision * 60000);469 var curDateUTC = curDate.getTime() + (60 / this.hourDivision * 60000); 445 470 if (this.attendees[att].freebusy[m].contains(curDateUTC) && this.attendees[att].selected) { 446 471 $(fbCell).addClass("busy"); … … 513 538 // output the attendee name or address (depending on which we have available) 514 539 // and add attendee functions 515 var attendeeAddress = curAttendee.uid .substr(curAttendee.uid.lastIndexOf(":") + 1);540 var attendeeAddress = curAttendee.uid; 516 541 var attendeeNameHtml = '<td class="name"><span class="bwAttendee" id="' + attendeeAddress + '">'; 517 542 if (curAttendee.name && curAttendee.name != "") { … … 542 567 for (var k = 0; k < this.hourDivision; k++) { 543 568 var fbCell = document.createElement("td"); 544 fbCell.id = curDate.getTime() + "-" + curAttendee.uid .substr(curAttendee.uid.lastIndexOf(":") + 1);569 fbCell.id = curDate.getTime() + "-" + curAttendee.uid; 545 570 $(fbCell).addClass("fbcell"); 546 571 $(fbCell).addClass(curDate.getTime().toString()); … … 549 574 } 550 575 for (var m = 0; m < curAttendee.freebusy.length; m++) { 551 var tzoffset = -curDate.getTimezoneOffset() * 60000; // in milliseconds576 // keep for reference: var tzoffset = -curDate.getTimezoneOffset() * 60000; // in milliseconds 552 577 // adding the hourdivision increment in the calculation below is to correct for a bug 553 578 // in which the class was always offset by one table cell - should find cause 554 var curDateUTC = curDate.getTime() + tzoffset +(60 / this.hourDivision * 60000);579 var curDateUTC = curDate.getTime() + (60 / this.hourDivision * 60000); 555 580 if (curAttendee.freebusy[m].contains(curDateUTC)) { 556 if (curAttendee.freebusy[m].typeDisplay .match("TENTATIVE")) {581 if (curAttendee.freebusy[m].typeDisplay == bwFreeBusyDispTypeTentative) { 557 582 $(fbCell).addClass("tentative"); 558 583 } else { … … 572 597 } 573 598 574 /* DEPRECATED - don't put in grid575 599 // generate the "add attendee" row 576 600 fbDisplayAddAttendeeRow = fbDisplay.insertRow(fbDisplay.rows.length); … … 607 631 } 608 632 $(fbDisplayAddAttendeeRow).append('<td class="dayBoundry"></td>'); 609 } */633 } 610 634 611 635 // generate a blank row at the end (this is just for visual padding) … … 834 858 } 835 859 860 /* UTC FORMATTERS */ 861 862 // return a formatted UTC month, prepended with zero if needed 863 Date.prototype.getUTCMonthFull = function() { 864 var monthFull = this.getUTCMonth() + 1; 865 if (monthFull < 10) { 866 return "0" + monthFull; 867 } 868 return monthFull; 869 } 870 // return a formatted UTC day date, prepended with zero if needed 871 Date.prototype.getUTCDateFull = function() { 872 var dateFull = this.getUTCDate(); 873 if (dateFull < 10) { 874 return "0" + dateFull; 875 } 876 return dateFull; 877 } 878 // return formatted UTC hours, prepended with zero if needed 879 Date.prototype.getUTCHoursFull = function() { 880 var hoursFull = this.getUTCHours(); 881 if (hoursFull < 10) { 882 return "0" + hoursFull; 883 } 884 return hoursFull; 885 } 886 // return formatted UTC minutes, prepended with zero if needed 887 Date.prototype.getUTCMinutesFull = function() { 888 var minutesFull = this.getUTCMinutes(); 889 if (minutesFull < 10) { 890 return "0" + minutesFull; 891 } 892 return minutesFull; 893 } 894 836 895 /* 837 896 * From RFC 5545 trunk/deployment/webuser/webapp/resources/demoskins/themes/bedeworkTheme/javascript/freebusy.js
r2904 r2905 34 34 "periods" : [ 35 35 { 36 "value" : "2010051 3T180000Z/PT2H"36 "value" : "20100519T080000Z\/PT2H" 37 37 }, 38 38 { 39 "value" : "20100514T120000Z/PT4H" 39 "value" : "20100520T120000Z\/PT4H" 40 }, 41 { 42 "value" : "20100521T140000Z\/PT1H" 40 43 } 41 44 ] … … 76 79 "periods" : [ 77 80 { 78 "value" : "2010051 2T180000Z/PT3H"81 "value" : "20100519T090000Z\/PT3H" 79 82 }, 80 83 { 81 "value" : "201005 14T140000Z/PT1H"84 "value" : "20100520T140000Z\/PT1H" 82 85 } 83 86 ] 84 } 87 }, 88 { 89 "fbtype" : { 90 "value" : "BUSY-TENTATIVE" 91 }, 92 "periods" : [ 93 { 94 "value" : "20100511T140000Z\/PT1H" 95 } 96 ] 97 } 85 98 ] 86 99 } trunk/deployment/webuser/webapp/resources/demoskins/themes/bedeworkTheme/navigation.xsl
r2896 r2905 197 197 198 198 <!-- show free / busy --> 199 <!-- DEPRECATED as of Bedework 3.7: the feature is left in place for backwards compatibility --> 200 <!-- 199 201 <xsl:choose> 200 202 <xsl:when test="/bedework/periodname!='Year'"> … … 216 218 </xsl:otherwise> 217 219 </xsl:choose> 220 --> 218 221 219 222 <!-- toggle list / calendar view --> … … 328 331 <xsl:copy-of select="$bwStr-Actn-AddEvent"/> 329 332 </a> 333 <!-- 330 334 <a href="{$event-initMeeting}&entityType=event&schedule=request&startdate={$dateTime}" title="schedule a meeting" onclick="javascript:changeClass('{$actionIconsId}','invisible')"> 331 335 <img src="{$resourcesRoot}/images/std-icalMeeting-icon-small.gif" width="12" height="16" border="0" alt="schedule meeting"/> … … 333 337 <xsl:copy-of select="$bwStr-Actn-ScheduleMeeting"/> 334 338 </a> 339 --> 335 340 <a href="{$initEvent}&entityType=task&startdate={$dateTime}" title="{$bwStr-Actn-AddTask}" onclick="javascript:changeClass('{$actionIconsId}','invisible')"> 336 341 <img src="{$resourcesRoot}/images/std-icalTask-icon-small.gif" width="12" height="16" border="0" alt="add task"/> … … 338 343 <xsl:copy-of select="$bwStr-Actn-AddTask"/> 339 344 </a> 345 <!-- 340 346 <a href="{$event-initMeeting}&entityType=task&schedule=request&startdate={$dateTime}" title="{$bwStr-Actn-ScheduleTask}" onclick="javascript:changeClass('{$actionIconsId}','invisible')"> 341 347 <img src="{$resourcesRoot}/images/std-icalSchTask-icon-small.gif" width="12" height="16" border="0" alt="schedule task"/> … … 348 354 <xsl:copy-of select="$bwStr-Actn-Upload"/> 349 355 </a> 356 --> 350 357 </div> 351 358 </xsl:template>
