add fixed shift calendar headers and timelane
This commit is contained in:
parent
5299ca2103
commit
79ca2f1772
|
@ -19,6 +19,11 @@ class ShiftCalendarRenderer {
|
||||||
* Distance between two shifts in pixels
|
* Distance between two shifts in pixels
|
||||||
*/
|
*/
|
||||||
const MARGIN = 5;
|
const MARGIN = 5;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Seconds added to the start and end time
|
||||||
|
*/
|
||||||
|
const TIME_MARGIN = 1800;
|
||||||
|
|
||||||
private $lanes;
|
private $lanes;
|
||||||
|
|
||||||
|
@ -71,7 +76,7 @@ class ShiftCalendarRenderer {
|
||||||
}
|
}
|
||||||
// If all lanes for this room are busy, create a new lane and add shift to it
|
// If all lanes for this room are busy, create a new lane and add shift to it
|
||||||
if ($shift_added == false) {
|
if ($shift_added == false) {
|
||||||
$newLane = new ShiftCalendarLane("", $this->getFirstBlockStartTime(), $this->getBlocksPerSlot());
|
$newLane = new ShiftCalendarLane($header, $this->getFirstBlockStartTime(), $this->getBlocksPerSlot());
|
||||||
if (! $newLane->addShift($shift)) {
|
if (! $newLane->addShift($shift)) {
|
||||||
engelsystem_error("Unable to add shift to new lane.");
|
engelsystem_error("Unable to add shift to new lane.");
|
||||||
}
|
}
|
||||||
|
@ -170,7 +175,7 @@ class ShiftCalendarRenderer {
|
||||||
return div('tick day');
|
return div('tick day');
|
||||||
}
|
}
|
||||||
return div('tick day', [
|
return div('tick day', [
|
||||||
date('Y-m-d<b\r />H:i', $time)
|
date('m-d<b\r />H:i', $time)
|
||||||
]);
|
]);
|
||||||
} elseif ($time % (60 * 60) == 0) {
|
} elseif ($time % (60 * 60) == 0) {
|
||||||
if (! $label) {
|
if (! $label) {
|
||||||
|
@ -206,7 +211,7 @@ class ShiftCalendarRenderer {
|
||||||
$start_time = $shift['start'];
|
$start_time = $shift['start'];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return ShiftCalendarRenderer::SECONDS_PER_ROW * floor(($start_time - 60 * 60) / ShiftCalendarRenderer::SECONDS_PER_ROW);
|
return ShiftCalendarRenderer::SECONDS_PER_ROW * floor(($start_time - ShiftCalendarRenderer::TIME_MARGIN) / ShiftCalendarRenderer::SECONDS_PER_ROW);
|
||||||
}
|
}
|
||||||
|
|
||||||
private function calcLastBlockEndTime($shifts) {
|
private function calcLastBlockEndTime($shifts) {
|
||||||
|
@ -216,7 +221,7 @@ class ShiftCalendarRenderer {
|
||||||
$end_time = $shift['end'];
|
$end_time = $shift['end'];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return ShiftCalendarRenderer::SECONDS_PER_ROW * ceil(($end_time + 60 * 60) / ShiftCalendarRenderer::SECONDS_PER_ROW);
|
return ShiftCalendarRenderer::SECONDS_PER_ROW * ceil(($end_time + ShiftCalendarRenderer::TIME_MARGIN) / ShiftCalendarRenderer::SECONDS_PER_ROW);
|
||||||
}
|
}
|
||||||
|
|
||||||
private function calcBlocksPerSlot() {
|
private function calcBlocksPerSlot() {
|
||||||
|
|
|
@ -50,7 +50,7 @@ function Shift_view($shift, $shifttype, $room, $angeltypes_source, $user_shifts,
|
||||||
|
|
||||||
return page_with_title($shift['name'] . ' <small class="moment-countdown" data-timestamp="' . $shift['start'] . '">%c</small>', [
|
return page_with_title($shift['name'] . ' <small class="moment-countdown" data-timestamp="' . $shift['start'] . '">%c</small>', [
|
||||||
msg(),
|
msg(),
|
||||||
Shift_collides($shift, $user_shifts) ? info(_('This shift collides with one of your shifts.'), true) : '',
|
$shift_signup_state->getState() == ShiftSignupState::COLLIDES ? info(_('This shift collides with one of your shifts.'), true) : '',
|
||||||
$shift_signup_state->getState() == ShiftSignupState::SIGNED_UP ? info(_('You are signed up for this shift.'), true) : '',
|
$shift_signup_state->getState() == ShiftSignupState::SIGNED_UP ? info(_('You are signed up for this shift.'), true) : '',
|
||||||
($shift_admin || $admin_shifttypes || $admin_rooms) ? buttons([
|
($shift_admin || $admin_shifttypes || $admin_rooms) ? buttons([
|
||||||
$shift_admin ? button(shift_edit_link($shift), glyph('pencil') . _('edit')) : '',
|
$shift_admin ? button(shift_edit_link($shift), glyph('pencil') . _('edit')) : '',
|
||||||
|
|
|
@ -297,6 +297,20 @@ function User_view($user_source, $admin_user_privilege, $freeloader, $user_angel
|
||||||
|
|
||||||
return page_with_title('<span class="icon-icon_angel"></span> ' . htmlspecialchars($user_source['Nick']) . ' <small>' . $user_name . '</small>', [
|
return page_with_title('<span class="icon-icon_angel"></span> ' . htmlspecialchars($user_source['Nick']) . ' <small>' . $user_name . '</small>', [
|
||||||
msg(),
|
msg(),
|
||||||
|
div('row space-top', [
|
||||||
|
div('col-md-12', [
|
||||||
|
buttons([
|
||||||
|
$admin_user_privilege ? button(page_link_to('admin_user') . '&id=' . $user_source['UID'], glyph("edit") . _("edit")) : '',
|
||||||
|
$admin_user_privilege ? button(user_driver_license_edit_link($user_source), glyph("road") . _("driving license")) : '',
|
||||||
|
($admin_user_privilege && ! $user_source['Gekommen']) ? button(page_link_to('admin_arrive') . '&arrived=' . $user_source['UID'], _("arrived")) : '',
|
||||||
|
$admin_user_privilege ? button(page_link_to('users') . '&action=edit_vouchers&user_id=' . $user_source['UID'], glyph('cutlery') . _('Edit vouchers')) : '',
|
||||||
|
$its_me ? button(page_link_to('user_settings'), glyph('list-alt') . _("Settings")) : '',
|
||||||
|
$its_me ? button(page_link_to('ical') . '&key=' . $user_source['api_key'], glyph('calendar') . _("iCal Export")) : '',
|
||||||
|
$its_me ? button(page_link_to('shifts_json_export') . '&key=' . $user_source['api_key'], glyph('export') . _("JSON Export")) : '',
|
||||||
|
$its_me ? button(page_link_to('user_myshifts') . '&reset', glyph('repeat') . _('Reset API key')) : ''
|
||||||
|
])
|
||||||
|
])
|
||||||
|
]),
|
||||||
div('row', [
|
div('row', [
|
||||||
div('col-md-3', [
|
div('col-md-3', [
|
||||||
'<h1>',
|
'<h1>',
|
||||||
|
@ -322,20 +336,6 @@ function User_view($user_source, $admin_user_privilege, $freeloader, $user_angel
|
||||||
User_groups_render($user_groups)
|
User_groups_render($user_groups)
|
||||||
])
|
])
|
||||||
]),
|
]),
|
||||||
div('row space-top', [
|
|
||||||
div('col-md-12', [
|
|
||||||
buttons([
|
|
||||||
$admin_user_privilege ? button(page_link_to('admin_user') . '&id=' . $user_source['UID'], glyph("edit") . _("edit")) : '',
|
|
||||||
$admin_user_privilege ? button(user_driver_license_edit_link($user_source), glyph("road") . _("driving license")) : '',
|
|
||||||
($admin_user_privilege && ! $user_source['Gekommen']) ? button(page_link_to('admin_arrive') . '&arrived=' . $user_source['UID'], _("arrived")) : '',
|
|
||||||
$admin_user_privilege ? button(page_link_to('users') . '&action=edit_vouchers&user_id=' . $user_source['UID'], glyph('cutlery') . _('Edit vouchers')) : '',
|
|
||||||
$its_me ? button(page_link_to('user_settings'), glyph('list-alt') . _("Settings")) : '',
|
|
||||||
$its_me ? button(page_link_to('ical') . '&key=' . $user_source['api_key'], glyph('calendar') . _("iCal Export")) : '',
|
|
||||||
$its_me ? button(page_link_to('shifts_json_export') . '&key=' . $user_source['api_key'], glyph('export') . _("JSON Export")) : '',
|
|
||||||
$its_me ? button(page_link_to('user_myshifts') . '&reset', glyph('repeat') . _('Reset API key')) : ''
|
|
||||||
])
|
|
||||||
])
|
|
||||||
]),
|
|
||||||
($its_me || $admin_user_privilege) ? '<h2>' . _("Shifts") . '</h2>' : '',
|
($its_me || $admin_user_privilege) ? '<h2>' . _("Shifts") . '</h2>' : '',
|
||||||
($its_me || $admin_user_privilege) ? table([
|
($its_me || $admin_user_privilege) ? table([
|
||||||
'date' => _("Day"),
|
'date' => _("Day"),
|
||||||
|
|
|
@ -6757,12 +6757,14 @@ body {
|
||||||
}
|
}
|
||||||
.shift-calendar .lane {
|
.shift-calendar .lane {
|
||||||
background: #f9f9f9;
|
background: #f9f9f9;
|
||||||
min-width: 300px;
|
|
||||||
width: 300px;
|
|
||||||
flex-grow: 1;
|
flex-grow: 1;
|
||||||
|
min-width: 280px;
|
||||||
|
width: 280px;
|
||||||
|
flex-shrink: 1;
|
||||||
}
|
}
|
||||||
.shift-calendar .lane .header {
|
.shift-calendar .lane .header {
|
||||||
background: #ffffff;
|
background: #ffffff;
|
||||||
|
border-bottom: 1px solid #dddddd;
|
||||||
height: 30px;
|
height: 30px;
|
||||||
padding: 5px;
|
padding: 5px;
|
||||||
}
|
}
|
||||||
|
@ -6781,9 +6783,11 @@ body {
|
||||||
padding-left: 5px;
|
padding-left: 5px;
|
||||||
}
|
}
|
||||||
.shift-calendar .lane.time {
|
.shift-calendar .lane.time {
|
||||||
min-width: 100px;
|
border-right: 1px solid #dddddd;
|
||||||
width: 100px;
|
|
||||||
flex-grow: 0;
|
flex-grow: 0;
|
||||||
|
min-width: 50px;
|
||||||
|
width: 50px;
|
||||||
|
flex-shrink: 0;
|
||||||
}
|
}
|
||||||
.shift-calendar .shift {
|
.shift-calendar .shift {
|
||||||
margin: 0 5px 5px 0;
|
margin: 0 5px 5px 0;
|
||||||
|
|
|
@ -6780,12 +6780,14 @@ body {
|
||||||
}
|
}
|
||||||
.shift-calendar .lane {
|
.shift-calendar .lane {
|
||||||
background: #080808;
|
background: #080808;
|
||||||
min-width: 300px;
|
|
||||||
width: 300px;
|
|
||||||
flex-grow: 1;
|
flex-grow: 1;
|
||||||
|
min-width: 280px;
|
||||||
|
width: 280px;
|
||||||
|
flex-shrink: 1;
|
||||||
}
|
}
|
||||||
.shift-calendar .lane .header {
|
.shift-calendar .lane .header {
|
||||||
background: #222222;
|
background: #222222;
|
||||||
|
border-bottom: 1px solid #282828;
|
||||||
height: 30px;
|
height: 30px;
|
||||||
padding: 5px;
|
padding: 5px;
|
||||||
}
|
}
|
||||||
|
@ -6804,9 +6806,11 @@ body {
|
||||||
padding-left: 5px;
|
padding-left: 5px;
|
||||||
}
|
}
|
||||||
.shift-calendar .lane.time {
|
.shift-calendar .lane.time {
|
||||||
min-width: 100px;
|
border-right: 1px solid #282828;
|
||||||
width: 100px;
|
|
||||||
flex-grow: 0;
|
flex-grow: 0;
|
||||||
|
min-width: 50px;
|
||||||
|
width: 50px;
|
||||||
|
flex-shrink: 0;
|
||||||
}
|
}
|
||||||
.shift-calendar .shift {
|
.shift-calendar .shift {
|
||||||
margin: 0 5px 5px 0;
|
margin: 0 5px 5px 0;
|
||||||
|
|
|
@ -6757,12 +6757,14 @@ body {
|
||||||
}
|
}
|
||||||
.shift-calendar .lane {
|
.shift-calendar .lane {
|
||||||
background: #f9f9f9;
|
background: #f9f9f9;
|
||||||
min-width: 300px;
|
|
||||||
width: 300px;
|
|
||||||
flex-grow: 1;
|
flex-grow: 1;
|
||||||
|
min-width: 280px;
|
||||||
|
width: 280px;
|
||||||
|
flex-shrink: 1;
|
||||||
}
|
}
|
||||||
.shift-calendar .lane .header {
|
.shift-calendar .lane .header {
|
||||||
background: #ffffff;
|
background: #ffffff;
|
||||||
|
border-bottom: 1px solid #dddddd;
|
||||||
height: 30px;
|
height: 30px;
|
||||||
padding: 5px;
|
padding: 5px;
|
||||||
}
|
}
|
||||||
|
@ -6781,9 +6783,11 @@ body {
|
||||||
padding-left: 5px;
|
padding-left: 5px;
|
||||||
}
|
}
|
||||||
.shift-calendar .lane.time {
|
.shift-calendar .lane.time {
|
||||||
min-width: 100px;
|
border-right: 1px solid #dddddd;
|
||||||
width: 100px;
|
|
||||||
flex-grow: 0;
|
flex-grow: 0;
|
||||||
|
min-width: 50px;
|
||||||
|
width: 50px;
|
||||||
|
flex-shrink: 0;
|
||||||
}
|
}
|
||||||
.shift-calendar .shift {
|
.shift-calendar .shift {
|
||||||
margin: 0 5px 5px 0;
|
margin: 0 5px 5px 0;
|
||||||
|
|
|
@ -6766,12 +6766,14 @@ body {
|
||||||
}
|
}
|
||||||
.shift-calendar .lane {
|
.shift-calendar .lane {
|
||||||
background: #f9f9f9;
|
background: #f9f9f9;
|
||||||
min-width: 300px;
|
|
||||||
width: 300px;
|
|
||||||
flex-grow: 1;
|
flex-grow: 1;
|
||||||
|
min-width: 280px;
|
||||||
|
width: 280px;
|
||||||
|
flex-shrink: 1;
|
||||||
}
|
}
|
||||||
.shift-calendar .lane .header {
|
.shift-calendar .lane .header {
|
||||||
background: #ffffff;
|
background: #ffffff;
|
||||||
|
border-bottom: 1px solid #dddddd;
|
||||||
height: 30px;
|
height: 30px;
|
||||||
padding: 5px;
|
padding: 5px;
|
||||||
}
|
}
|
||||||
|
@ -6790,9 +6792,11 @@ body {
|
||||||
padding-left: 5px;
|
padding-left: 5px;
|
||||||
}
|
}
|
||||||
.shift-calendar .lane.time {
|
.shift-calendar .lane.time {
|
||||||
min-width: 100px;
|
border-right: 1px solid #dddddd;
|
||||||
width: 100px;
|
|
||||||
flex-grow: 0;
|
flex-grow: 0;
|
||||||
|
min-width: 50px;
|
||||||
|
width: 50px;
|
||||||
|
flex-shrink: 0;
|
||||||
}
|
}
|
||||||
.shift-calendar .shift {
|
.shift-calendar .shift {
|
||||||
margin: 0 5px 5px 0;
|
margin: 0 5px 5px 0;
|
||||||
|
|
|
@ -0,0 +1,30 @@
|
||||||
|
/**
|
||||||
|
* Enables the fixed headers and time lane for the shift-calendar.
|
||||||
|
*/
|
||||||
|
$(document).ready(
|
||||||
|
function() {
|
||||||
|
var time_lanes = $(".shift-calendar .time");
|
||||||
|
var headers = $(".shift-calendar .header");
|
||||||
|
var top_reference = $(".container-fluid .row");
|
||||||
|
var top = headers.offset().top;
|
||||||
|
var left = 15;
|
||||||
|
time_lanes.css({
|
||||||
|
"position" : "relative",
|
||||||
|
"z-index" : 1000
|
||||||
|
});
|
||||||
|
headers.css({
|
||||||
|
"position" : "relative",
|
||||||
|
"z-index" : 900
|
||||||
|
});
|
||||||
|
$(window).scroll(
|
||||||
|
function() {
|
||||||
|
time_lanes.css({
|
||||||
|
"left" : Math.max(0, $(window).scrollLeft() - left) + "px"
|
||||||
|
});
|
||||||
|
headers.css({
|
||||||
|
"top" : Math.max(0, $(window).scrollTop() - top
|
||||||
|
+ top_reference.offset().top)
|
||||||
|
+ "px"
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
|
@ -48,5 +48,6 @@
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
<script type="text/javascript" src="js/moment-countdown.js"></script>
|
<script type="text/javascript" src="js/moment-countdown.js"></script>
|
||||||
|
<script type="text/javascript" src="js/shift-calendar.js"></script>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|
|
@ -35,10 +35,6 @@ body {
|
||||||
}
|
}
|
||||||
|
|
||||||
.shift-calendar {
|
.shift-calendar {
|
||||||
display: flex;
|
|
||||||
flex-direction: row;
|
|
||||||
flex-wrap: nowrap;
|
|
||||||
align-itmes: stretch;
|
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: row;
|
flex-direction: row;
|
||||||
flex-wrap: nowrap;
|
flex-wrap: nowrap;
|
||||||
|
@ -48,12 +44,13 @@ body {
|
||||||
.lane {
|
.lane {
|
||||||
background: @table-bg-accent;
|
background: @table-bg-accent;
|
||||||
flex-grow: 1;
|
flex-grow: 1;
|
||||||
min-width: 300px;
|
min-width: 280px;
|
||||||
width: 300px;
|
width: 280px;
|
||||||
flex-grow: 1;
|
flex-shrink: 1;
|
||||||
|
|
||||||
.header {
|
.header {
|
||||||
background: @panel-bg;
|
background: @panel-bg;
|
||||||
|
border-bottom: 1px solid @table-border-color;
|
||||||
height: 30px;
|
height: 30px;
|
||||||
padding: 5px;
|
padding: 5px;
|
||||||
}
|
}
|
||||||
|
@ -77,10 +74,11 @@ body {
|
||||||
}
|
}
|
||||||
|
|
||||||
.lane.time {
|
.lane.time {
|
||||||
|
border-right: 1px solid @table-border-color;
|
||||||
flex-grow: 0;
|
flex-grow: 0;
|
||||||
min-width: 100px;
|
min-width: 50px;
|
||||||
width: 100px;
|
width: 50px;
|
||||||
flex-grow: 0;
|
flex-shrink: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
.shift {
|
.shift {
|
||||||
|
|
Loading…
Reference in New Issue