diff --git a/includes/controller/public_dashboard_controller.php b/includes/controller/public_dashboard_controller.php index 531ad61b..88003207 100644 --- a/includes/controller/public_dashboard_controller.php +++ b/includes/controller/public_dashboard_controller.php @@ -1,6 +1,7 @@ get('filtered') && auth()->user()) { + $filter = new ShiftsFilter(); + $filter->sessionImport(session()->get('shifts-filter')); + } + $stats = [ - 'needed-3-hours' => stats_angels_needed_three_hours(), - 'needed-night' => stats_angels_needed_for_nightshifts(), - 'angels-working' => stats_currently_working(), - 'hours-to-work' => stats_hours_to_work() + 'needed-3-hours' => stats_angels_needed_three_hours($filter), + 'needed-night' => stats_angels_needed_for_nightshifts($filter), + 'angels-working' => stats_currently_working($filter), + 'hours-to-work' => stats_hours_to_work($filter) ]; - $free_shifts_source = Shifts_free(time(), time() + 12 * 60 * 60); + $free_shifts_source = Shifts_free(time(), time() + 12 * 60 * 60, $filter); $free_shifts = []; foreach ($free_shifts_source as $shift) { - $free_shift = public_dashboard_controller_free_shift($shift); + $free_shift = public_dashboard_controller_free_shift($shift, $filter); if (count($free_shift['needed_angels']) > 0) { $free_shifts[] = $free_shift; } @@ -34,10 +41,12 @@ function public_dashboard_controller() /** * Gathers information for free shifts to display. * - * @param array $shift + * @param array $shift + * @param ShiftsFilter|null $filter + * * @return array */ -function public_dashboard_controller_free_shift($shift) +function public_dashboard_controller_free_shift($shift, ShiftsFilter $filter = null) { $shifttype = ShiftType($shift['shifttype_id']); $room = Room::find($shift['RID']); @@ -61,7 +70,7 @@ function public_dashboard_controller_free_shift($shift) $free_shift['style'] = 'danger'; } - $free_shift['needed_angels'] = public_dashboard_needed_angels($shift['NeedAngels']); + $free_shift['needed_angels'] = public_dashboard_needed_angels($shift['NeedAngels'], $filter); return $free_shift; } @@ -69,15 +78,17 @@ function public_dashboard_controller_free_shift($shift) /** * Gathers information for needed angels on dashboard * - * @param array $needed_angels + * @param array $needed_angels + * @param ShiftsFilter|null $filter + * * @return array */ -function public_dashboard_needed_angels($needed_angels) +function public_dashboard_needed_angels($needed_angels, ShiftsFilter $filter = null) { $result = []; foreach ($needed_angels as $needed_angel) { $need = $needed_angel['count'] - $needed_angel['taken']; - if ($need > 0) { + if ($need > 0 && (!$filter || in_array($needed_angel['TID'], $filter->getTypes()))) { $angeltype = AngelType($needed_angel['TID']); if ($angeltype['show_on_dashboard']) { $result[] = [ @@ -93,9 +104,11 @@ function public_dashboard_needed_angels($needed_angels) /** * Returns url to public dashboard * + * @param array $parameters + * * @return string */ -function public_dashboard_link() +function public_dashboard_link(array $parameters = []): string { - return page_link_to('public-dashboard'); + return page_link_to('public-dashboard', $parameters); } diff --git a/includes/model/Shifts_model.php b/includes/model/Shifts_model.php index 796f0024..107430c0 100644 --- a/includes/model/Shifts_model.php +++ b/includes/model/Shifts_model.php @@ -34,21 +34,24 @@ function Shifts_by_angeltype($angeltype) /** * Returns every shift with needed angels in the given time range. * - * @param int $start timestamp - * @param int $end timestamp + * @param int $start timestamp + * @param int $end timestamp + * @param ShiftsFilter|null $filter + * * @return array */ -function Shifts_free($start, $end) +function Shifts_free($start, $end, ShiftsFilter $filter = null) { - $shifts = Db::select(" + $shifts = Db::select(' SELECT * FROM ( SELECT * FROM `Shifts` LEFT JOIN schedule_shift AS s on Shifts.SID = s.shift_id WHERE (`end` > ? AND `start` < ?) - AND (SELECT SUM(`count`) FROM `NeededAngelTypes` WHERE `NeededAngelTypes`.`shift_id`=`Shifts`.`SID`) - > (SELECT COUNT(*) FROM `ShiftEntry` WHERE `ShiftEntry`.`SID`=`Shifts`.`SID` AND `freeloaded`=0) + AND (SELECT SUM(`count`) FROM `NeededAngelTypes` WHERE `NeededAngelTypes`.`shift_id`=`Shifts`.`SID`' . ($filter ? ' AND NeededAngelTypes.angel_type_id IN (' . implode(',', $filter->getTypes()) . ')' : '') . ') + > (SELECT COUNT(*) FROM `ShiftEntry` WHERE `ShiftEntry`.`SID`=`Shifts`.`SID` AND `freeloaded`=0' . ($filter ? ' AND ShiftEntry.TID IN (' . implode(',', $filter->getTypes()) . ')' : '') . ') AND s.shift_id IS NULL + ' . ($filter ? 'AND Shifts.RID IN (' . implode(',', $filter->getRooms()) . ')' : '') . ' UNION @@ -56,12 +59,13 @@ function Shifts_free($start, $end) FROM `Shifts` LEFT JOIN schedule_shift AS s on Shifts.SID = s.shift_id WHERE (`end` > ? AND `start` < ?) - AND (SELECT SUM(`count`) FROM `NeededAngelTypes` WHERE `NeededAngelTypes`.`room_id`=`Shifts`.`RID`) - > (SELECT COUNT(*) FROM `ShiftEntry` WHERE `ShiftEntry`.`SID`=`Shifts`.`SID` AND `freeloaded`=0) + AND (SELECT SUM(`count`) FROM `NeededAngelTypes` WHERE `NeededAngelTypes`.`room_id`=`Shifts`.`RID`' . ($filter ? ' AND NeededAngelTypes.angel_type_id IN (' . implode(',', $filter->getTypes()) . ')' : '') . ') + > (SELECT COUNT(*) FROM `ShiftEntry` WHERE `ShiftEntry`.`SID`=`Shifts`.`SID` AND `freeloaded`=0' . ($filter ? ' AND ShiftEntry.TID IN (' . implode(',', $filter->getTypes()) . ')' : '') . ') AND NOT s.shift_id IS NULL + ' . ($filter ? 'AND Shifts.RID IN (' . implode(',', $filter->getRooms()) . ')' : '') . ' ) AS `tmp` ORDER BY `tmp`.`start` - ", [ + ', [ $start, $end, $start, diff --git a/includes/model/Stats.php b/includes/model/Stats.php index 29550694..f595e328 100644 --- a/includes/model/Stats.php +++ b/includes/model/Stats.php @@ -1,78 +1,83 @@ getTypes()) . ')' : '') . ' + )) AS `count` FROM `Shifts` - WHERE (`end` >= ? AND `start` <= ?)", [ - time(), - time() - ]); - - if (empty($result['count'])) { - return '-'; - } + WHERE (`end` >= UNIX_TIMESTAMP() AND `start` <= UNIX_TIMESTAMP()) + '. ($filter ? 'AND Shifts.RID IN (' . implode(',', $filter->getRooms()) . ')' : '') + ); - return $result['count']; + return $result['count'] ?: '-'; } /** * Return the number of hours still to work. * + * @param ShiftsFilter|null $filter + * * @return int|string */ -function stats_hours_to_work() +function stats_hours_to_work(ShiftsFilter $filter = null) { - $result = Db::selectOne(" + $result = Db::selectOne( + ' SELECT ROUND(SUM(`count`)) AS `count` FROM ( SELECT - (SELECT SUM(`count`) FROM `NeededAngelTypes` WHERE `NeededAngelTypes`.`shift_id`=`Shifts`.`SID`) + (SELECT SUM(`count`) FROM `NeededAngelTypes` WHERE `NeededAngelTypes`.`shift_id`=`Shifts`.`SID`' . ($filter ? ' AND NeededAngelTypes.angel_type_id IN (' . implode(',', $filter->getTypes()) . ')' : '') . ') * (`Shifts`.`end` - `Shifts`.`start`)/3600 AS `count` FROM `Shifts` LEFT JOIN schedule_shift AS s on Shifts.SID = s.shift_id - WHERE `end` >= ? + WHERE `end` >= UNIX_TIMESTAMP() AND s.shift_id IS NULL + '. ($filter ? 'AND Shifts.RID IN (' . implode(',', $filter->getRooms()) . ')' : '') . ' UNION ALL SELECT - (SELECT SUM(`count`) FROM `NeededAngelTypes` WHERE `NeededAngelTypes`.`room_id`=`Shifts`.`RID`) + (SELECT SUM(`count`) FROM `NeededAngelTypes` WHERE `NeededAngelTypes`.`room_id`=`Shifts`.`RID`' . ($filter ? ' AND NeededAngelTypes.angel_type_id IN (' . implode(',', $filter->getTypes()) . ')' : '') . ') * (`Shifts`.`end` - `Shifts`.`start`)/3600 AS `count` FROM `Shifts` LEFT JOIN schedule_shift AS s on Shifts.SID = s.shift_id - WHERE `end` >= ? + WHERE `end` >= UNIX_TIMESTAMP() AND NOT s.shift_id IS NULL + '. ($filter ? 'AND Shifts.RID IN (' . implode(',', $filter->getRooms()) . ')' : '') . ' ) AS `tmp` - ", [ - time(), - time() - ]); - if (empty($result['count'])) { - return '-'; - } - return $result['count']; + ' + ); + + return $result['count'] ?: '-'; } /** * Returns the number of needed angels in the next 3 hours * + * @param ShiftsFilter|null $filter + * * @return int|string */ -function stats_angels_needed_three_hours() +function stats_angels_needed_three_hours(ShiftsFilter $filter = null) { - $now = time(); - $in3hours = $now + 3 * 60 * 60; - $result = Db::selectOne(" + $in3hours = time() + 3 * 60 * 60; + $result = Db::selectOne(' SELECT SUM(`count`) AS `count` FROM ( SELECT GREATEST(0, @@ -82,19 +87,22 @@ function stats_angels_needed_three_hours() JOIN `AngelTypes` ON `AngelTypes`.`id`=`NeededAngelTypes`.`angel_type_id` WHERE `AngelTypes`.`show_on_dashboard`=TRUE AND `NeededAngelTypes`.`shift_id`=`Shifts`.`SID` + ' . ($filter ? 'AND NeededAngelTypes.angel_type_id IN (' . implode(',', $filter->getTypes()) . ')' : '') . ' ) - ( SELECT COUNT(*) FROM `ShiftEntry` JOIN `AngelTypes` ON `AngelTypes`.`id`=`ShiftEntry`.`TID` WHERE `AngelTypes`.`show_on_dashboard`=TRUE AND `ShiftEntry`.`SID`=`Shifts`.`SID` AND `freeloaded`=0 + ' . ($filter ? 'AND ShiftEntry.TID IN (' . implode(',', $filter->getTypes()) . ')' : '') . ' ) ) AS `count` FROM `Shifts` LEFT JOIN schedule_shift AS s on Shifts.SID = s.shift_id - WHERE `end` > ? AND `start` < ? + WHERE `end` > UNIX_TIMESTAMP() AND `start` < ? AND s.shift_id IS NULL + '. ($filter ? 'AND Shifts.RID IN (' . implode(',', $filter->getRooms()) . ')' : '') . ' UNION ALL @@ -106,37 +114,38 @@ function stats_angels_needed_three_hours() JOIN `AngelTypes` ON `AngelTypes`.`id`=`NeededAngelTypes`.`angel_type_id` WHERE `AngelTypes`.`show_on_dashboard`=TRUE AND `NeededAngelTypes`.`room_id`=`Shifts`.`RID` + ' . ($filter ? 'AND NeededAngelTypes.angel_type_id IN (' . implode(',', $filter->getTypes()) . ')' : '') . ' ) - ( SELECT COUNT(*) FROM `ShiftEntry` JOIN `AngelTypes` ON `AngelTypes`.`id`=`ShiftEntry`.`TID` WHERE `AngelTypes`.`show_on_dashboard`=TRUE AND `ShiftEntry`.`SID`=`Shifts`.`SID` AND `freeloaded`=0 + ' . ($filter ? 'AND ShiftEntry.TID IN (' . implode(',', $filter->getTypes()) . ')' : '') . ' ) ) AS `count` FROM `Shifts` LEFT JOIN schedule_shift AS s on Shifts.SID = s.shift_id - WHERE `end` > ? AND `start` < ? + WHERE `end` > UNIX_TIMESTAMP() AND `start` < ? AND NOT s.shift_id IS NULL - ) AS `tmp`", [ - $now, + '. ($filter ? 'AND Shifts.RID IN (' . implode(',', $filter->getRooms()) . ')' : '') . ' + ) AS `tmp`', [ $in3hours, - $now, $in3hours ]); - if (empty($result['count'])) { - return '-'; - } - return $result['count']; + + return $result['count'] ?: '-'; } /** * Returns the number of needed angels for nightshifts (see config) * + * @param ShiftsFilter|null $filter + * * @return int|string */ -function stats_angels_needed_for_nightshifts() +function stats_angels_needed_for_nightshifts(ShiftsFilter $filter = null) { $nightShiftsConfig = config('night_shifts'); $nightStartTime = $nightShiftsConfig['start']; @@ -147,7 +156,7 @@ function stats_angels_needed_for_nightshifts() date('Y-m-d', time() + 12 * 60 * 60) . ' ' . $nightStartTime . ':00' ); $night_end = $night_start + ($nightEndTime - $nightStartTime) * 60 * 60; - $result = Db::selectOne(" + $result = Db::selectOne(' SELECT SUM(`count`) AS `count` FROM ( SELECT GREATEST(0, @@ -157,12 +166,14 @@ function stats_angels_needed_for_nightshifts() JOIN `AngelTypes` ON `AngelTypes`.`id`=`NeededAngelTypes`.`angel_type_id` WHERE `AngelTypes`.`show_on_dashboard`=TRUE AND `NeededAngelTypes`.`shift_id`=`Shifts`.`SID` + ' . ($filter ? 'AND NeededAngelTypes.angel_type_id IN (' . implode(',', $filter->getTypes()) . ')' : '') . ' ) - ( SELECT COUNT(*) FROM `ShiftEntry` JOIN `AngelTypes` ON `AngelTypes`.`id`=`ShiftEntry`.`TID` WHERE `AngelTypes`.`show_on_dashboard`=TRUE AND `ShiftEntry`.`SID`=`Shifts`.`SID` AND `freeloaded`=0 + ' . ($filter ? 'AND ShiftEntry.TID IN (' . implode(',', $filter->getTypes()) . ')' : '') . ' ) ) AS `count` @@ -170,6 +181,7 @@ function stats_angels_needed_for_nightshifts() LEFT JOIN schedule_shift AS s on Shifts.SID = s.shift_id WHERE `end` > ? AND `start` < ? AND s.shift_id IS NULL + '. ($filter ? 'AND Shifts.RID IN (' . implode(',', $filter->getRooms()) . ')' : '') . ' UNION ALL @@ -181,12 +193,14 @@ function stats_angels_needed_for_nightshifts() JOIN `AngelTypes` ON `AngelTypes`.`id`=`NeededAngelTypes`.`angel_type_id` WHERE `AngelTypes`.`show_on_dashboard`=TRUE AND `NeededAngelTypes`.`room_id`=`Shifts`.`RID` + ' . ($filter ? 'AND AngelTypes.id IN (' . implode(',', $filter->getTypes()) . ')' : '') . ' ) - ( SELECT COUNT(*) FROM `ShiftEntry` JOIN `AngelTypes` ON `AngelTypes`.`id`=`ShiftEntry`.`TID` WHERE `AngelTypes`.`show_on_dashboard`=TRUE AND `ShiftEntry`.`SID`=`Shifts`.`SID` AND `freeloaded`=0 + ' . ($filter ? 'AND ShiftEntry.TID IN (' . implode(',', $filter->getTypes()) . ')' : '') . ' ) ) AS `count` @@ -194,14 +208,13 @@ function stats_angels_needed_for_nightshifts() LEFT JOIN schedule_shift AS s on Shifts.SID = s.shift_id WHERE `end` > ? AND `start` < ? AND NOT s.shift_id IS NULL - ) AS `tmp`", [ + '. ($filter ? 'AND Shifts.RID IN (' . implode(',', $filter->getRooms()) . ')' : '') . ' + ) AS `tmp`', [ $night_start, $night_end, $night_start, $night_end ]); - if (empty($result['count'])) { - return '-'; - } - return $result['count']; + + return $result['count'] ?: '-'; } diff --git a/includes/view/PublicDashboard_view.php b/includes/view/PublicDashboard_view.php index baab2f8a..33cf375d 100644 --- a/includes/view/PublicDashboard_view.php +++ b/includes/view/PublicDashboard_view.php @@ -31,6 +31,7 @@ function public_dashboard_view($stats, $free_shifts) ]); } + $isFiltered = request()->get('filtered'); return page([ div('public-dashboard', [ div('first', [ @@ -41,21 +42,26 @@ function public_dashboard_view($stats, $free_shifts) '' ], 'statistics'), $needed_angels ], 'public-dashboard'), - div('first col-md-12 text-center', [ - buttons([ - button_js(' - $(\'#navbar-collapse-1,#footer,#fullscreen-button\').remove(); - $(\'.navbar-brand\').append(\' ' . __('Public Dashboard') . '\'); - ', glyph('fullscreen') . __('Fullscreen')) - ]) - ], 'fullscreen-button') + div('first col-md-12 text-center', [buttons([ + button_js( + ' + $(\'#navbar-collapse-1,.navbar-nav,.navbar-toggle,#footer,#fullscreen-button\').remove(); + $(\'.navbar-brand\').append(\' ' . __('Public Dashboard') . '\'); + ', + glyph('fullscreen') . __('Fullscreen') + ), + auth()->user() ? button( + public_dashboard_link($isFiltered ? [] : ['filtered' => 1]), + glyph('filter') . ($isFiltered ? __('All') : __('Filtered')) + ) : '' + ])], 'fullscreen-button'), ]); } diff --git a/resources/lang/de_DE/default.po b/resources/lang/de_DE/default.po index 3b470cc0..ec3e3f66 100644 --- a/resources/lang/de_DE/default.po +++ b/resources/lang/de_DE/default.po @@ -2157,6 +2157,9 @@ msgstr "Noch zu schaffende Stunden" msgid "Fullscreen" msgstr "Vollbild" +msgid "Filtered" +msgstr "Filtern" + #: includes/view/Questions_view.php:28 msgid "Open questions" msgstr "Offene Fragen"