From abdc5fc06cb84feefad5a069e8dc962b235d1f6b Mon Sep 17 00:00:00 2001 From: Nathan Gray Date: Fri, 5 Feb 2016 18:17:47 +0000 Subject: [PATCH] Add minimum height for weeks - 1/2 hour must be at least 1 line high --- calendar/js/et2_widget_daycol.js | 97 +++++++++++++++++++++++------ calendar/js/et2_widget_timegrid.js | 49 +++++++++++---- calendar/templates/default/app.css | 7 +++ calendar/templates/pixelegg/app.css | 9 ++- 4 files changed, 129 insertions(+), 33 deletions(-) diff --git a/calendar/js/et2_widget_daycol.js b/calendar/js/et2_widget_daycol.js index 20bffd6969..1762c9e716 100644 --- a/calendar/js/et2_widget_daycol.js +++ b/calendar/js/et2_widget_daycol.js @@ -531,6 +531,23 @@ var et2_calendar_daycol = et2_valueWidget.extend([et2_IDetachedDOM, et2_IResizea /** * Apply styles for out-of-view and partially hidden events + * + * There are 3 different states or modes of display: + * + * - 'Normal' - When showing events positioned by time, the indicator is just + * a bar colored by the last category color. On hover it shows either the + * title of a single event or "x event(s)" if more than one are hidden. + * Clicking adjusts the current view to show the earliest / latest hidden + * event + * + * - Fixed - When showing events positioned by time but in a fixed-height + * week (not auto-sized to fit screen) the indicator is the same as sized. + * On hover it shows the titles of the hidden events, clicking changes + * the view to the selected day. + * + * - GridList - When showing just a list, the indicator shows "x event(s)", + * and on hover shows the category color, title & time. Clicking changes + * the view to the selected day, and opens the event for editing. */ _out_of_view: function() { @@ -591,8 +608,9 @@ var et2_calendar_daycol = et2_valueWidget.extend([et2_IDetachedDOM, et2_IResizea } // Reset event.title.css({'top':'','background-color':''}); - event.body.css('padding-top',''); + event.body.css({'padding-top':'','margin-top':''}); var hidden = isHidden.call(this,event.div); + var day = this; if(!hidden) { return; @@ -601,16 +619,19 @@ var et2_calendar_daycol = et2_valueWidget.extend([et2_IDetachedDOM, et2_IResizea // Bottom hidden is fine if(hidden.hidden === 'top' && !hidden.completely) { + var title_height = event.title.outerHeight(); event.title.css({ 'top': timegrid.scrolling.scrollTop() - event.div.position().top, 'background-color': 'transparent' }); - event.body.css('padding-top',timegrid.scrolling.scrollTop() - event.div.position().top); + event.body.css({ + 'padding-top': timegrid.scrolling.scrollTop() - event.div.position().top + title_height, + 'margin-top' : -title_height + }); } // Too many in gridlist view, show indicator else if (this.display_settings.granularity === 0 && hidden) { - var day = this; if($j('.hiddenEventAfter',this.div).length == 0) { this.event_wrapper.css('overflow','hidden'); @@ -625,7 +646,12 @@ var et2_calendar_daycol = et2_valueWidget.extend([et2_IDetachedDOM, et2_IResizea // Completely out of view, show indicator else if (hidden.completely) { - this._hidden_indicator(event, hidden.hidden == 'top'); + this._hidden_indicator(event, hidden.hidden == 'top', + timegrid.div.hasClass('calendar_calTimeGridFixed') ? function() { + app.calendar.update_state({view: 'day', date: day.date}); + return false; + } : false + ); } }, this, et2_calendar_event); }, @@ -642,24 +668,42 @@ var et2_calendar_daycol = et2_valueWidget.extend([et2_IDetachedDOM, et2_IResizea var indicator = ''; var day = this; var timegrid = this._parent; + var fixed_height = timegrid.div.hasClass('calendar_calTimeGridFixed'); if(top) { if($j('.hiddenEventBefore',this.header).length === 0) { indicator = $j('
') .appendTo(this.header) - .text(event.options.value.title) - .attr('data-hidden_count', 1) - .on('click', typeof onclick === 'function' ? onclick : function() { - $j('.calendar_calEvent',day.div).first()[0].scrollIntoView(); - return false; - }); + .attr('data-hidden_count', 1); + if(!fixed_height) + { + indicator + .text(event.options.value.title) + .on('click', typeof onclick === 'function' ? onclick : function() { + $j('.calendar_calEvent',day.div).first()[0].scrollIntoView(); + return false; + }); + } + else + { + indicator + .append("
"+event.options.value.title+"
"); + } } else { indicator = $j('.hiddenEventBefore',this.header); indicator.attr('data-hidden_count', parseInt(indicator.attr('data-hidden_count')) + 1); - indicator.text(day.egw().lang('%1 event(s) %2',indicator.attr('data-hidden_count'),'')); + + if (fixed_height) + { + indicator.append("
"+event.options.value.title+"
"); + } + else + { + indicator.text(day.egw().lang('%1 event(s) %2',indicator.attr('data-hidden_count'),'')); + } } } else @@ -675,14 +719,23 @@ var et2_calendar_daycol = et2_valueWidget.extend([et2_IDetachedDOM, et2_IResizea // Better re-run this to clean up day._out_of_view(); return false; - }) - .on('wheel', function(e) - { - // Avoid bubbling & triggering change in date span - e.stopPropagation(); - // IE? - e.cancelBubble; }); + if(fixed_height) + { + indicator + .on('mouseover', function() { + indicator.css({ + 'height': (indicator.attr('data-hidden_count')*1.2) + 'em', + 'margin-top': -(indicator.attr('data-hidden_count')*1.2) + 'em' + }); + }) + .on('mouseout', function() { + indicator.css({ + 'height': '', + 'margin-top': '' + }); + }); + } } var count = parseInt(indicator.attr('data-hidden_count')) + 1 indicator.attr('data-hidden_count', count); @@ -691,6 +744,10 @@ var et2_calendar_daycol = et2_valueWidget.extend([et2_IDetachedDOM, et2_IResizea indicator.append(event.div.clone()); indicator.attr('data-hidden_label', day.egw().lang('%1 event(s) %2',indicator.attr('data-hidden_count'),'')); } + else if (fixed_height) + { + indicator.append("
"+event.options.value.title+"
"); + } else { indicator.text(day.egw().lang('%1 event(s) %2',indicator.attr('data-hidden_count'),'')); @@ -702,8 +759,8 @@ var et2_calendar_daycol = et2_valueWidget.extend([et2_IDetachedDOM, et2_IResizea { // Avoid white, which is hard to see // Use border-bottom-color, Firefox doesn't give a value with border-color - var color = jQuery.Color(event.div.css('border-bottom-color')).toString() !== jQuery.Color('white').toString() ? - event.div.css('border-bottom-color') : event.div.css('background-color'); + var color = jQuery.Color(event.div.css('background-color')).toString() !== jQuery.Color('white').toString() ? + event.div.css('background-color') : event.div.css('border-bottom-color'); if(color !== 'rgba(0, 0, 0, 0)') { indicator.css('border-color', color); diff --git a/calendar/js/et2_widget_timegrid.js b/calendar/js/et2_widget_timegrid.js index 1247f9de57..45799c80bd 100644 --- a/calendar/js/et2_widget_timegrid.js +++ b/calendar/js/et2_widget_timegrid.js @@ -1706,11 +1706,14 @@ var et2_calendar_timegrid = et2_calendar_view.extend([et2_IDetachedDOM, et2_IRes // Set the max width to avoid animations screwing up the width this.div.css('max-width',$j(this.getInstanceManager().DOMContainer).width()); - // We expect the timegrid to be in a table with 0 or more other timegrids, - // 1 per row. We want each timegrid to be as large as possible, but space - // shared equally. Height can't be set to a percentage on the rows, because - // that doesn't work. - + /* + We expect the timegrid to be in a table with 0 or more other timegrids, + 1 per row. We want each timegrid to be as large as possible, but space + shared equally. Height can't be set to a percentage on the rows, because + that doesn't work. However, if the timegrid is too small (1/2 hour < 1 line + height), we change to showing only the working hours with no vertical + scrollbar. Each week gets as much space as it needs. + */ // How many rows? var rowCount = 0; this._parent.iterateOver(function(widget) { @@ -1718,7 +1721,7 @@ var et2_calendar_timegrid = et2_calendar_view.extend([et2_IDetachedDOM, et2_IRes },this, et2_calendar_timegrid); // Take the whole tab height - var height = Math.min($j(this.getInstanceManager().DOMContainer).height(),$j(this.getInstanceManager().DOMContainer).parent().innerHeight()); + var height = $j(this.getInstanceManager().DOMContainer).parent().innerHeight(); // Allow for toolbar height -= $j('#calendar-toolbar',this.div.parents('.egw_fw_ui_tab_content')).outerHeight(true); @@ -1728,13 +1731,35 @@ var et2_calendar_timegrid = et2_calendar_view.extend([et2_IDetachedDOM, et2_IRes // Allow for borders & padding this.options.height -= 2*((this.div.outerWidth(true) - this.div.innerWidth()) + parseInt(this.div.parent().css('padding-top'))); - // If too small, switch to list view automatically - // Set rather arbitrarily at 180 px. - if(this.options.granularity && rowCount > 1 && this.options.height < 180) + // Calculate how much space is needed, and + // if too small be bigger + var needed = ((this.day_end - this.day_start) / + (this.options.granularity / 60) * parseInt(this.div.css('line-height'))) + + this.gridHeader.outerHeight(); + var too_small = needed > this.options.height && this.options.granularity != 0; + + $j(this.getInstanceManager().DOMContainer) + .css({ + 'overflow-y': too_small ? 'auto' : 'hidden', + 'overflow-x': 'hidden', + 'height': too_small ? height : '100%' + }); + if(too_small) { - this._parent.iterateOver(function(widget) { - if(!widget.disabled) widget.set_granularity(0); - },this, et2_calendar_timegrid); + this.options.height = needed; + if(!this.div.hasClass('calendar_calTimeGridFixed')) + { + window.setTimeout(jQuery.proxy(function() { + this._parent.iterateOver(function(widget) { + if(!widget.disabled) widget.resize(); + },this, et2_calendar_timegrid); + },this),1); + } + this.div.addClass('calendar_calTimeGridFixed'); + } + else + { + this.div.removeClass('calendar_calTimeGridFixed'); } this.div.css('height', this.options.height); diff --git a/calendar/templates/default/app.css b/calendar/templates/default/app.css index 914a7b330e..3aa883cab9 100644 --- a/calendar/templates/default/app.css +++ b/calendar/templates/default/app.css @@ -237,6 +237,10 @@ e.g. the div with class calendar_calTimeGrid is generated by the timeGridWidget right: 0px; position: absolute; } +/* Timegrid that has hit a minimum size */ +.calendar_calTimeGridFixed .calendar_calTimeGridScroll { + overflow: hidden; +} /* Show the day headers for single week view only once. @@ -390,6 +394,9 @@ Hide subsequent headers in week view with non-consolidated owners height: 20px; background-color: white; } +.calendar_calTimeGridFixed .calendar_calDayCol .hiddenEventAfter:hover .calendar_calEvent { + position: relative; +} /* Days in a different month, but shown to fill out the week */ .calendar_calDayColHeader.calendar_differentMonth > * { diff --git a/calendar/templates/pixelegg/app.css b/calendar/templates/pixelegg/app.css index 0e2ff14104..7c561ee34d 100755 --- a/calendar/templates/pixelegg/app.css +++ b/calendar/templates/pixelegg/app.css @@ -11,7 +11,7 @@ * @package calendar * @version $Id$ */ -/* $Id: app.css 54927 2016-02-04 22:35:34Z nathangray $ */ +/* $Id: app.css 54928 2016-02-04 23:14:54Z nathangray $ */ /*Media print classes*/ @media print { .th td, @@ -250,6 +250,10 @@ e.g. the div with class calendar_calTimeGrid is generated by the timeGridWidget right: 0px; position: absolute; } +/* Timegrid that has hit a minimum size */ +.calendar_calTimeGridFixed .calendar_calTimeGridScroll { + overflow: hidden; +} /* Show the day headers for single week view only once. Hide subsequent headers in week view with non-consolidated owners @@ -402,6 +406,9 @@ Hide subsequent headers in week view with non-consolidated owners height: 20px; background-color: white; } +.calendar_calTimeGridFixed .calendar_calDayCol .hiddenEventAfter:hover .calendar_calEvent { + position: relative; +} /* Days in a different month, but shown to fill out the week */ .calendar_calDayColHeader.calendar_differentMonth > * { color: #6a6a6a;