add shift calendar to angeltype view
This commit is contained in:
parent
d8476f244d
commit
928e707015
|
@ -1,5 +1,7 @@
|
||||||
<?php
|
<?php
|
||||||
|
|
||||||
|
use Engelsystem\ShiftsFilter;
|
||||||
|
use Engelsystem\ShiftsFilterRenderer;
|
||||||
/**
|
/**
|
||||||
* Text for Angeltype related links.
|
* Text for Angeltype related links.
|
||||||
*
|
*
|
||||||
|
@ -182,6 +184,14 @@ function angeltype_controller()
|
||||||
$user_angeltype = UserAngelType_by_User_and_AngelType($user, $angeltype);
|
$user_angeltype = UserAngelType_by_User_and_AngelType($user, $angeltype);
|
||||||
$user_driver_license = UserDriverLicense($user['UID']);
|
$user_driver_license = UserDriverLicense($user['UID']);
|
||||||
$members = Users_by_angeltype($angeltype);
|
$members = Users_by_angeltype($angeltype);
|
||||||
|
|
||||||
|
$days = angeltype_controller_shiftsFilterDays($angeltype);
|
||||||
|
$shiftsFilter = angeltype_controller_shiftsFilter($angeltype, $days);
|
||||||
|
|
||||||
|
$shiftsFilterRenderer = new ShiftsFilterRenderer($shiftsFilter);
|
||||||
|
$shiftsFilterRenderer->enableDaySelection($days);
|
||||||
|
|
||||||
|
$shiftCalendarRenderer = shiftCalendarRendererByShiftFilter($shiftsFilter);
|
||||||
|
|
||||||
return [
|
return [
|
||||||
sprintf(_('Team %s'), $angeltype['name']),
|
sprintf(_('Team %s'), $angeltype['name']),
|
||||||
|
@ -193,11 +203,60 @@ function angeltype_controller()
|
||||||
in_array('admin_angel_types', $privileges),
|
in_array('admin_angel_types', $privileges),
|
||||||
$user_angeltype['supporter'],
|
$user_angeltype['supporter'],
|
||||||
$user_driver_license,
|
$user_driver_license,
|
||||||
$user
|
$user,
|
||||||
|
$shiftsFilterRenderer,
|
||||||
|
$shiftCalendarRenderer
|
||||||
)
|
)
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* On which days do shifts for this angeltype occur? Needed for shiftCalendar.
|
||||||
|
*
|
||||||
|
* @param Angeltype $angeltype
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
function angeltype_controller_shiftsFilterDays($angeltype) {
|
||||||
|
$all_shifts = Shifts_by_angeltype($angeltype);
|
||||||
|
$days = [];
|
||||||
|
foreach ($all_shifts as $shift) {
|
||||||
|
$day = date('Y-m-d', $shift['start']);
|
||||||
|
if (!in_array($day, $days)) {
|
||||||
|
$days[] = $day;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return $days;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets up the shift filter for the angeltype.
|
||||||
|
*
|
||||||
|
* @param Angeltype $angeltype
|
||||||
|
* @param array $days
|
||||||
|
* @return ShiftsFilter
|
||||||
|
*/
|
||||||
|
function angeltype_controller_shiftsFilter($angeltype, $days) {
|
||||||
|
global $privileges;
|
||||||
|
|
||||||
|
$request = request();
|
||||||
|
$shiftsFilter = new ShiftsFilter(
|
||||||
|
in_array('user_shifts_admin', $privileges),
|
||||||
|
Room_ids(),
|
||||||
|
[$angeltype['id']]
|
||||||
|
);
|
||||||
|
$selected_day = date('Y-m-d');
|
||||||
|
if (!empty($days)) {
|
||||||
|
$selected_day = $days[0];
|
||||||
|
}
|
||||||
|
if ($request->has('shifts_filter_day')) {
|
||||||
|
$selected_day = $request->input('shifts_filter_day');
|
||||||
|
}
|
||||||
|
$shiftsFilter->setStartTime(parse_date('Y-m-d H:i', $selected_day . ' 00:00'));
|
||||||
|
$shiftsFilter->setEndTime(parse_date('Y-m-d H:i', $selected_day . ' 23:59'));
|
||||||
|
|
||||||
|
return $shiftsFilter;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* View a list of all angeltypes.
|
* View a list of all angeltypes.
|
||||||
*
|
*
|
||||||
|
|
|
@ -13,6 +13,17 @@ function Rooms($show_all = false)
|
||||||
return DB::select('SELECT * FROM `Room`' . ($show_all ? '' : ' WHERE `show`=\'Y\'') . ' ORDER BY `Name`');
|
return DB::select('SELECT * FROM `Room`' . ($show_all ? '' : ' WHERE `show`=\'Y\'') . ' ORDER BY `Name`');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns Room id array
|
||||||
|
*
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
function Room_ids()
|
||||||
|
{
|
||||||
|
$result = DB::select('SELECT `RID` FROM `Room`');
|
||||||
|
return select_array($result, 'RID', 'RID');
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Delete a room
|
* Delete a room
|
||||||
*
|
*
|
||||||
|
|
|
@ -4,6 +4,29 @@ use Engelsystem\Database\DB;
|
||||||
use Engelsystem\ShiftsFilter;
|
use Engelsystem\ShiftsFilter;
|
||||||
use Engelsystem\ShiftSignupState;
|
use Engelsystem\ShiftSignupState;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param array $angeltype
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
function Shifts_by_angeltype($angeltype) {
|
||||||
|
return DB::select('
|
||||||
|
SELECT DISTINCT `Shifts`.* FROM `Shifts`
|
||||||
|
JOIN `NeededAngelTypes` ON `NeededAngelTypes`.`shift_id` = `Shifts`.`SID`
|
||||||
|
WHERE `NeededAngelTypes`.`angel_type_id` = ?
|
||||||
|
AND `NeededAngelTypes`.`count` > 0
|
||||||
|
AND `Shifts`.`PSID` IS NULL
|
||||||
|
|
||||||
|
UNION
|
||||||
|
|
||||||
|
SELECT DISTINCT `Shifts`.* FROM `Shifts`
|
||||||
|
JOIN `NeededAngelTypes` ON `NeededAngelTypes`.`room_id` = `Shifts`.`RID`
|
||||||
|
WHERE `NeededAngelTypes`.`angel_type_id` = ?
|
||||||
|
AND `NeededAngelTypes`.`count` > 0
|
||||||
|
AND NOT `Shifts`.`PSID` IS NULL
|
||||||
|
', [$angeltype['id'], $angeltype['id']]);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param array $room
|
* @param array $room
|
||||||
* @return array
|
* @return array
|
||||||
|
@ -24,7 +47,7 @@ function Shifts_by_ShiftsFilter(ShiftsFilter $shiftsFilter)
|
||||||
FROM `Shifts`
|
FROM `Shifts`
|
||||||
JOIN `Room` USING (`RID`)
|
JOIN `Room` USING (`RID`)
|
||||||
JOIN `ShiftTypes` ON `ShiftTypes`.`id` = `Shifts`.`shifttype_id`
|
JOIN `ShiftTypes` ON `ShiftTypes`.`id` = `Shifts`.`shifttype_id`
|
||||||
JOIN `NeededAngelTypes` ON `NeededAngelTypes`.`shift_id`=`Shifts`.`SID`
|
JOIN `NeededAngelTypes` ON `NeededAngelTypes`.`shift_id` = `Shifts`.`SID`
|
||||||
WHERE `Shifts`.`RID` IN (' . implode(',', $shiftsFilter->getRooms()) . ')
|
WHERE `Shifts`.`RID` IN (' . implode(',', $shiftsFilter->getRooms()) . ')
|
||||||
AND `start` BETWEEN ? AND ?
|
AND `start` BETWEEN ? AND ?
|
||||||
AND `NeededAngelTypes`.`angel_type_id` IN (' . implode(',', $shiftsFilter->getTypes()) . ')
|
AND `NeededAngelTypes`.`angel_type_id` IN (' . implode(',', $shiftsFilter->getTypes()) . ')
|
||||||
|
|
|
@ -1,5 +1,31 @@
|
||||||
<?php
|
<?php
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Renders tabs from the array. Array key is tab name, array value is tab content.
|
||||||
|
*
|
||||||
|
* @param array $tabs
|
||||||
|
* @return string HTML
|
||||||
|
*/
|
||||||
|
function tabs($tabs)
|
||||||
|
{
|
||||||
|
$tab_header = [];
|
||||||
|
$tab_content = [];
|
||||||
|
foreach($tabs as $header => $content) {
|
||||||
|
$class = '';
|
||||||
|
if(count($tab_header) == 0) {
|
||||||
|
$class = 'active';
|
||||||
|
}
|
||||||
|
$tab_header[] = '<li role="presentation" class="' . $class . '">
|
||||||
|
<a href="#' . $header . '" aria-controls="' . $header . '" role="tab" data-toggle="tab">'
|
||||||
|
. $header . '</a></li>';
|
||||||
|
$tab_content[] = '<div role="tabpanel" class="tab-pane ' . $class . '" id="' . $header . '">' . $content . '</div>';
|
||||||
|
}
|
||||||
|
return div('', [
|
||||||
|
'<ul class="nav nav-tabs" role="tablist">' . join($tab_header) . '</ul>',
|
||||||
|
'<div class="tab-content">' . join($tab_content) . '</div>'
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Display muted (grey) text.
|
* Display muted (grey) text.
|
||||||
*
|
*
|
||||||
|
|
|
@ -1,5 +1,7 @@
|
||||||
<?php
|
<?php
|
||||||
|
|
||||||
|
use Engelsystem\ShiftsFilterRenderer;
|
||||||
|
use Engelsystem\ShiftCalendarRenderer;
|
||||||
/**
|
/**
|
||||||
* AngelTypes
|
* AngelTypes
|
||||||
*/
|
*/
|
||||||
|
@ -320,36 +322,86 @@ function AngelType_view(
|
||||||
$admin_angeltypes,
|
$admin_angeltypes,
|
||||||
$supporter,
|
$supporter,
|
||||||
$user_driver_license,
|
$user_driver_license,
|
||||||
$user
|
$user,
|
||||||
|
ShiftsFilterRenderer $shiftsFilterRenderer,
|
||||||
|
ShiftCalendarRenderer $shiftCalendarRenderer
|
||||||
) {
|
) {
|
||||||
$page = [
|
return page_with_title(sprintf(_('Team %s'), $angeltype['name']), [
|
||||||
AngelType_view_buttons($angeltype, $user_angeltype, $admin_angeltypes, $supporter, $user_driver_license, $user),
|
AngelType_view_buttons($angeltype, $user_angeltype, $admin_angeltypes, $supporter, $user_driver_license, $user),
|
||||||
msg()
|
msg(),
|
||||||
];
|
tabs([
|
||||||
|
_('Info') => AngelType_view_info(
|
||||||
|
$angeltype,
|
||||||
|
$members,
|
||||||
|
$admin_user_angeltypes,
|
||||||
|
$admin_angeltypes,
|
||||||
|
$supporter
|
||||||
|
),
|
||||||
|
_('Shifts') => AngelType_view_shifts(
|
||||||
|
$angeltype,
|
||||||
|
$shiftsFilterRenderer,
|
||||||
|
$shiftCalendarRenderer
|
||||||
|
)
|
||||||
|
])
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param Angeltype $angeltype
|
||||||
|
* @param ShiftsFilterRenderer $shiftsFilterRenderer
|
||||||
|
* @param ShiftCalendarRenderer $shiftCalendarRenderer
|
||||||
|
* @return string HTML
|
||||||
|
*/
|
||||||
|
function AngelType_view_shifts($angeltype, $shiftsFilterRenderer, $shiftCalendarRenderer)
|
||||||
|
{
|
||||||
|
$shifts = $shiftsFilterRenderer->render(page_link_to('angeltypes', [
|
||||||
|
'action' => 'view',
|
||||||
|
'angeltype_id' => $angeltype['id']
|
||||||
|
]));
|
||||||
|
$shifts .= $shiftCalendarRenderer->render();
|
||||||
|
|
||||||
|
return div('first', $shifts);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param Angeltype $angeltype
|
||||||
|
* @param array $members
|
||||||
|
* @param bool $admin_user_angeltypes
|
||||||
|
* @param bool $admin_angeltypes
|
||||||
|
* @param bool $supporter
|
||||||
|
* @return string HTML
|
||||||
|
*/
|
||||||
|
function AngelType_view_info(
|
||||||
|
$angeltype,
|
||||||
|
$members,
|
||||||
|
$admin_user_angeltypes,
|
||||||
|
$admin_angeltypes,
|
||||||
|
$supporter
|
||||||
|
) {
|
||||||
|
$info = [];
|
||||||
if(AngelType_has_contact_info($angeltype)) {
|
if(AngelType_has_contact_info($angeltype)) {
|
||||||
$page[] = AngelTypes_render_contact_info($angeltype);
|
$info[] = AngelTypes_render_contact_info($angeltype);
|
||||||
}
|
}
|
||||||
|
|
||||||
$page[] = '<h3>' . _('Description') . '</h3>';
|
$info[] = '<h3>' . _('Description') . '</h3>';
|
||||||
$parsedown = new Parsedown();
|
$parsedown = new Parsedown();
|
||||||
if ($angeltype['description'] != '') {
|
if ($angeltype['description'] != '') {
|
||||||
$page[] = '<div class="well">' . $parsedown->parse($angeltype['description']) . '</div>';
|
$info[] = '<div class="well">' . $parsedown->parse($angeltype['description']) . '</div>';
|
||||||
}
|
}
|
||||||
|
|
||||||
list($supporters, $members_confirmed, $members_unconfirmed) = AngelType_view_members(
|
list($supporters, $members_confirmed, $members_unconfirmed) = AngelType_view_members(
|
||||||
$angeltype,
|
$angeltype,
|
||||||
$members,
|
$members,
|
||||||
$admin_user_angeltypes,
|
$admin_user_angeltypes,
|
||||||
$admin_angeltypes
|
$admin_angeltypes
|
||||||
);
|
);
|
||||||
$table_headers = AngelType_view_table_headers($angeltype, $supporter, $admin_angeltypes);
|
$table_headers = AngelType_view_table_headers($angeltype, $supporter, $admin_angeltypes);
|
||||||
|
|
||||||
if (count($supporters) > 0) {
|
if (count($supporters) > 0) {
|
||||||
$page[] = '<h3>' . _('supporters') . '</h3>';
|
$info[] = '<h3>' . _('supporters') . '</h3>';
|
||||||
$page[] = table($table_headers, $supporters);
|
$info[] = table($table_headers, $supporters);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (count($members_confirmed) > 0) {
|
if (count($members_confirmed) > 0) {
|
||||||
$members_confirmed[] = [
|
$members_confirmed[] = [
|
||||||
'Nick' => _('Sum'),
|
'Nick' => _('Sum'),
|
||||||
|
@ -357,7 +409,7 @@ function AngelType_view(
|
||||||
'actions' => ''
|
'actions' => ''
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
if (count($members_unconfirmed) > 0) {
|
if (count($members_unconfirmed) > 0) {
|
||||||
$members_unconfirmed[] = [
|
$members_unconfirmed[] = [
|
||||||
'Nick' => _('Sum'),
|
'Nick' => _('Sum'),
|
||||||
|
@ -365,40 +417,40 @@ function AngelType_view(
|
||||||
'actions' => ''
|
'actions' => ''
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
$page[] = '<h3>' . _('Members') . '</h3>';
|
$info[] = '<h3>' . _('Members') . '</h3>';
|
||||||
if ($admin_user_angeltypes) {
|
if ($admin_user_angeltypes) {
|
||||||
$page[] = buttons([
|
$info[] = buttons([
|
||||||
button(
|
button(
|
||||||
page_link_to(
|
page_link_to(
|
||||||
'user_angeltypes',
|
'user_angeltypes',
|
||||||
['action' => 'add', 'angeltype_id' => $angeltype['id']]
|
['action' => 'add', 'angeltype_id' => $angeltype['id']]
|
||||||
),
|
),
|
||||||
_('Add'),
|
_('Add'),
|
||||||
'add'
|
'add'
|
||||||
)
|
)
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
$page[] = table($table_headers, $members_confirmed);
|
$info[] = table($table_headers, $members_confirmed);
|
||||||
|
|
||||||
if ($admin_user_angeltypes && $angeltype['restricted'] && count($members_unconfirmed) > 0) {
|
if ($admin_user_angeltypes && $angeltype['restricted'] && count($members_unconfirmed) > 0) {
|
||||||
$page[] = '<h3>' . _('Unconfirmed') . '</h3>';
|
$info[] = '<h3>' . _('Unconfirmed') . '</h3>';
|
||||||
$page[] = buttons([
|
$info[] = buttons([
|
||||||
button(
|
button(
|
||||||
page_link_to('user_angeltypes', ['action' => 'confirm_all', 'angeltype_id' => $angeltype['id']]),
|
page_link_to('user_angeltypes', ['action' => 'confirm_all', 'angeltype_id' => $angeltype['id']]),
|
||||||
_('confirm all'),
|
_('confirm all'),
|
||||||
'ok'
|
'ok'
|
||||||
),
|
),
|
||||||
button(
|
button(
|
||||||
page_link_to('user_angeltypes', ['action' => 'delete_all', 'angeltype_id' => $angeltype['id']]),
|
page_link_to('user_angeltypes', ['action' => 'delete_all', 'angeltype_id' => $angeltype['id']]),
|
||||||
_('deny all'),
|
_('deny all'),
|
||||||
'cancel'
|
'cancel'
|
||||||
)
|
)
|
||||||
]);
|
]);
|
||||||
$page[] = table($table_headers, $members_unconfirmed);
|
$info[] = table($table_headers, $members_unconfirmed);
|
||||||
}
|
}
|
||||||
|
|
||||||
return page_with_title(sprintf(_('Team %s'), $angeltype['name']), $page);
|
return join($info);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -407,7 +459,8 @@ function AngelType_view(
|
||||||
* @param Anteltype $angeltype
|
* @param Anteltype $angeltype
|
||||||
* @return string HTML
|
* @return string HTML
|
||||||
*/
|
*/
|
||||||
function AngelTypes_render_contact_info($angeltype) {
|
function AngelTypes_render_contact_info($angeltype)
|
||||||
|
{
|
||||||
return heading(_('Contact'), 3) . description([
|
return heading(_('Contact'), 3) . description([
|
||||||
_('Name') => $angeltype['contact_name'],
|
_('Name') => $angeltype['contact_name'],
|
||||||
_('DECT') => $angeltype['contact_dect'],
|
_('DECT') => $angeltype['contact_dect'],
|
||||||
|
|
|
@ -19,7 +19,10 @@ function Room_view($room, ShiftsFilterRenderer $shiftsFilterRenderer, ShiftCalen
|
||||||
}
|
}
|
||||||
|
|
||||||
return page_with_title(glyph('map-marker') . $room['Name'], [
|
return page_with_title(glyph('map-marker') . $room['Name'], [
|
||||||
$shiftsFilterRenderer->render($room),
|
$shiftsFilterRenderer->render(page_link_to('rooms', [
|
||||||
|
'action' => 'view',
|
||||||
|
'room_id' => $room['RID']
|
||||||
|
])),
|
||||||
$assignNotice,
|
$assignNotice,
|
||||||
$shiftCalendarRenderer->render()
|
$shiftCalendarRenderer->render()
|
||||||
]);
|
]);
|
||||||
|
|
|
@ -143,7 +143,7 @@ class ShiftCalendarRenderer
|
||||||
public function render()
|
public function render()
|
||||||
{
|
{
|
||||||
if (count($this->lanes) == 0) {
|
if (count($this->lanes) == 0) {
|
||||||
return '';
|
return info(_('No shifts found.'), true);
|
||||||
}
|
}
|
||||||
return div('shift-calendar', [
|
return div('shift-calendar', [
|
||||||
$this->renderTimeLane(),
|
$this->renderTimeLane(),
|
||||||
|
|
|
@ -39,21 +39,17 @@ class ShiftsFilterRenderer
|
||||||
/**
|
/**
|
||||||
* Renders the filter.
|
* Renders the filter.
|
||||||
*
|
*
|
||||||
* @param array $room
|
* @param string $page_link Link pointing to the actual page.
|
||||||
* @return string Generated HTML
|
* @return string Generated HTML
|
||||||
*/
|
*/
|
||||||
public function render($room)
|
public function render($page_link)
|
||||||
{
|
{
|
||||||
$toolbar = [];
|
$toolbar = [];
|
||||||
if ($this->daySelectionEnabled && !empty($this->days)) {
|
if ($this->daySelectionEnabled && !empty($this->days)) {
|
||||||
$selected_day = date('Y-m-d', $this->shiftsFilter->getStartTime());
|
$selected_day = date('Y-m-d', $this->shiftsFilter->getStartTime());
|
||||||
$day_dropdown_items = [];
|
$day_dropdown_items = [];
|
||||||
foreach ($this->days as $day) {
|
foreach ($this->days as $day) {
|
||||||
$link = page_link_to('rooms', [
|
$link = $page_link . '&shifts_filter_day=' . $day;
|
||||||
'action' => 'view',
|
|
||||||
'room_id' => $room['RID'],
|
|
||||||
'shifts_filter_day' => $day,
|
|
||||||
]);
|
|
||||||
$day_dropdown_items[] = toolbar_item_link($link, '', $day);
|
$day_dropdown_items[] = toolbar_item_link($link, '', $day);
|
||||||
}
|
}
|
||||||
$toolbar[] = toolbar_dropdown('', $selected_day, $day_dropdown_items, 'active');
|
$toolbar[] = toolbar_dropdown('', $selected_day, $day_dropdown_items, 'active');
|
||||||
|
|
Binary file not shown.
File diff suppressed because it is too large
Load Diff
|
@ -6,8 +6,6 @@ $(document).ready(function () {
|
||||||
var timeLanes = $(".shift-calendar .time");
|
var timeLanes = $(".shift-calendar .time");
|
||||||
var headers = $(".shift-calendar .header");
|
var headers = $(".shift-calendar .header");
|
||||||
var topReference = $(".container-fluid .row");
|
var topReference = $(".container-fluid .row");
|
||||||
var top = headers.offset().top;
|
|
||||||
var left = 15;
|
|
||||||
timeLanes.css({
|
timeLanes.css({
|
||||||
"position": "relative",
|
"position": "relative",
|
||||||
"z-index": 999
|
"z-index": 999
|
||||||
|
@ -18,6 +16,8 @@ $(document).ready(function () {
|
||||||
});
|
});
|
||||||
$(window).scroll(
|
$(window).scroll(
|
||||||
function () {
|
function () {
|
||||||
|
var top = headers.parent().offset().top;
|
||||||
|
var left = 15;
|
||||||
timeLanes.css({
|
timeLanes.css({
|
||||||
"left": Math.max(0, $(window).scrollLeft() - left) + "px"
|
"left": Math.max(0, $(window).scrollLeft() - left) + "px"
|
||||||
});
|
});
|
||||||
|
|
Loading…
Reference in New Issue