Recreated shift type admin backend
This commit is contained in:
parent
bf83e6a300
commit
0b165bc24c
|
@ -162,6 +162,18 @@ $route->addGroup(
|
|||
}
|
||||
);
|
||||
|
||||
// Shift types
|
||||
$route->addGroup(
|
||||
'/shifttypes',
|
||||
function (RouteCollector $route): void {
|
||||
$route->get('', 'Admin\\ShiftTypesController@index');
|
||||
$route->post('', 'Admin\\ShiftTypesController@delete');
|
||||
$route->get('/{shift_type_id:\d+}', 'Admin\\ShiftTypesController@view');
|
||||
$route->get('/edit[/{shift_type_id:\d+}]', 'Admin\\ShiftTypesController@edit');
|
||||
$route->post('/edit[/{shift_type_id:\d+}]', 'Admin\\ShiftTypesController@save');
|
||||
}
|
||||
);
|
||||
|
||||
// Questions
|
||||
$route->addGroup(
|
||||
'/questions',
|
||||
|
|
|
@ -1,163 +0,0 @@
|
|||
<?php
|
||||
|
||||
use Engelsystem\Models\Shifts\ShiftType;
|
||||
|
||||
/**
|
||||
* @param ShiftType $shifttype
|
||||
* @return string
|
||||
*/
|
||||
function shifttype_link(ShiftType $shifttype)
|
||||
{
|
||||
return url('/shifttypes', ['action' => 'view', 'shifttype_id' => $shifttype->id]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete a shifttype.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
function shifttype_delete_controller()
|
||||
{
|
||||
$request = request();
|
||||
if (!$request->has('shifttype_id')) {
|
||||
throw_redirect(url('/shifttypes'));
|
||||
}
|
||||
|
||||
$shifttype = ShiftType::findOrFail($request->input('shifttype_id'));
|
||||
if ($request->hasPostData('delete')) {
|
||||
engelsystem_log('Deleted shifttype ' . $shifttype->name);
|
||||
success(sprintf(__('Shifttype %s deleted.'), $shifttype->name));
|
||||
|
||||
$shifttype->delete();
|
||||
throw_redirect(url('/shifttypes'));
|
||||
}
|
||||
|
||||
return [
|
||||
sprintf(__('Delete shifttype %s'), $shifttype->name),
|
||||
ShiftType_delete_view($shifttype),
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Edit or create shift type.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
function shifttype_edit_controller()
|
||||
{
|
||||
$shifttype_id = null;
|
||||
$name = '';
|
||||
$description = '';
|
||||
|
||||
$request = request();
|
||||
|
||||
if ($request->has('shifttype_id')) {
|
||||
$shifttype = ShiftType::findOrFail($request->input('shifttype_id'));
|
||||
$shifttype_id = $shifttype->id;
|
||||
$name = $shifttype->name;
|
||||
$description = $shifttype->description;
|
||||
}
|
||||
|
||||
if ($request->hasPostData('submit')) {
|
||||
$valid = true;
|
||||
|
||||
if ($request->has('name') && $request->input('name') != '') {
|
||||
$name = strip_request_item('name');
|
||||
} else {
|
||||
$valid = false;
|
||||
error(__('Please enter a name.'));
|
||||
}
|
||||
|
||||
if ($request->has('description')) {
|
||||
$description = strip_request_item_nl('description');
|
||||
}
|
||||
|
||||
if ($valid) {
|
||||
$shiftType = ShiftType::findOrNew($shifttype_id);
|
||||
$shiftType->name = $name;
|
||||
$shiftType->description = $description;
|
||||
$shiftType->save();
|
||||
|
||||
if ($shifttype_id) {
|
||||
engelsystem_log('Updated shifttype ' . $name);
|
||||
success(__('Updated shifttype.'));
|
||||
} else {
|
||||
$shifttype_id = $shiftType->id;
|
||||
|
||||
engelsystem_log('Created shifttype ' . $name);
|
||||
success(__('Created shifttype.'));
|
||||
}
|
||||
|
||||
throw_redirect(url('/shifttypes', ['action' => 'view', 'shifttype_id' => $shifttype_id]));
|
||||
}
|
||||
}
|
||||
|
||||
return [
|
||||
shifttypes_title(),
|
||||
ShiftType_edit_view($name, $description, $shifttype_id),
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
function shifttype_controller()
|
||||
{
|
||||
$request = request();
|
||||
if (!$request->has('shifttype_id')) {
|
||||
throw_redirect(url('/shifttypes'));
|
||||
}
|
||||
$shifttype = ShiftType::findOrFail($request->input('shifttype_id'));
|
||||
|
||||
return [
|
||||
$shifttype->name,
|
||||
ShiftType_view($shifttype),
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* List all shift types.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
function shifttypes_list_controller()
|
||||
{
|
||||
$shifttypes = ShiftType::all()->sortBy('name', SORT_NATURAL | SORT_FLAG_CASE);
|
||||
|
||||
return [
|
||||
shifttypes_title(),
|
||||
ShiftTypes_list_view($shifttypes),
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Text for shift type related links.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
function shifttypes_title()
|
||||
{
|
||||
return __('Shifttypes');
|
||||
}
|
||||
|
||||
/**
|
||||
* Route shift type actions
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
function shifttypes_controller()
|
||||
{
|
||||
$request = request();
|
||||
$action = 'list';
|
||||
if ($request->has('action')) {
|
||||
$action = $request->input('action');
|
||||
}
|
||||
|
||||
return match ($action) {
|
||||
'view' => shifttype_controller(),
|
||||
'edit' => shifttype_edit_controller(),
|
||||
'delete' => shifttype_delete_controller(),
|
||||
'list' => shifttypes_list_controller(),
|
||||
default => shifttypes_list_controller(),
|
||||
};
|
||||
}
|
|
@ -31,7 +31,6 @@ $includeFiles = [
|
|||
__DIR__ . '/../includes/view/ShiftsFilterRenderer.php',
|
||||
__DIR__ . '/../includes/view/Shifts_view.php',
|
||||
__DIR__ . '/../includes/view/ShiftEntry_view.php',
|
||||
__DIR__ . '/../includes/view/ShiftTypes_view.php',
|
||||
__DIR__ . '/../includes/view/UserAngelTypes_view.php',
|
||||
__DIR__ . '/../includes/view/UserHintsRenderer.php',
|
||||
__DIR__ . '/../includes/view/User_view.php',
|
||||
|
@ -42,7 +41,6 @@ $includeFiles = [
|
|||
__DIR__ . '/../includes/controller/locations_controller.php',
|
||||
__DIR__ . '/../includes/controller/shift_entries_controller.php',
|
||||
__DIR__ . '/../includes/controller/shifts_controller.php',
|
||||
__DIR__ . '/../includes/controller/shifttypes_controller.php',
|
||||
__DIR__ . '/../includes/controller/users_controller.php',
|
||||
__DIR__ . '/../includes/controller/user_angeltypes_controller.php',
|
||||
|
||||
|
|
|
@ -328,7 +328,7 @@ function admin_shifts()
|
|||
. '<br>'
|
||||
. location_name_render(Location::find($shift['location_id'])),
|
||||
'title' =>
|
||||
ShiftType_name_render(ShiftType::find($shifttype_id))
|
||||
ShiftType::find($shifttype_id)->name
|
||||
. ($shift['title'] ? '<br />' . $shift['title'] : ''),
|
||||
'needed_angels' => '',
|
||||
];
|
||||
|
|
|
@ -83,7 +83,7 @@ function make_navigation()
|
|||
'users' => ['All Angels', 'admin_user'],
|
||||
'admin_free' => 'Free angels',
|
||||
'admin/questions' => ['Answer questions', 'question.edit'],
|
||||
'shifttypes' => 'Shifttypes',
|
||||
'admin/shifttypes' => ['shifttype.shifttypes', 'shifttypes'],
|
||||
'admin_shifts' => 'Create shifts',
|
||||
'admin/locations' => ['location.locations', 'admin_locations'],
|
||||
'admin_groups' => 'Grouprights',
|
||||
|
|
|
@ -1,140 +0,0 @@
|
|||
<?php
|
||||
|
||||
use Engelsystem\Models\Shifts\ShiftType;
|
||||
use Illuminate\Support\Collection;
|
||||
|
||||
/**
|
||||
* @param ShiftType $shifttype
|
||||
* @return string
|
||||
*/
|
||||
function ShiftType_name_render(ShiftType $shifttype)
|
||||
{
|
||||
if (auth()->can('shifttypes')) {
|
||||
return '<a href="' . shifttype_link($shifttype) . '">' . $shifttype->name . '</a>';
|
||||
}
|
||||
return $shifttype->name;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param ShiftType $shifttype
|
||||
* @return string
|
||||
*/
|
||||
function ShiftType_delete_view(ShiftType $shifttype)
|
||||
{
|
||||
return page_with_title(sprintf(__('Delete shifttype %s'), $shifttype->name), [
|
||||
info(sprintf(__('Do you want to delete shifttype %s?'), $shifttype->name), true),
|
||||
form([
|
||||
buttons([
|
||||
button(url('/shifttypes'), icon('x-lg') . __('form.cancel')),
|
||||
form_submit(
|
||||
'delete',
|
||||
icon('trash') . __('delete'),
|
||||
'btn-danger',
|
||||
false
|
||||
),
|
||||
]),
|
||||
]),
|
||||
], true);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $name
|
||||
* @param string $description
|
||||
* @param int $shifttype_id
|
||||
* @return string
|
||||
*/
|
||||
function ShiftType_edit_view($name, $description, $shifttype_id)
|
||||
{
|
||||
return page_with_title(
|
||||
$shifttype_id
|
||||
? (button(
|
||||
url('/shifttypes', ['action' => 'view', 'shifttype_id' => $shifttype_id]),
|
||||
icon('chevron-left'),
|
||||
'btn-sm'
|
||||
) . ' ' . __('Edit shifttype'))
|
||||
: (button(url('/shifttypes'), icon('chevron-left'), 'btn-sm') . ' ' . __('Create shifttype')),
|
||||
[
|
||||
msg(),
|
||||
buttons([
|
||||
button(url('/shifttypes'), shifttypes_title(), 'back'),
|
||||
]),
|
||||
form([
|
||||
form_text('name', __('general.name'), $name),
|
||||
form_textarea('description', __('general.description'), $description),
|
||||
form_info('', __('Please use markdown for the description.')),
|
||||
form_submit('submit', __('form.save')),
|
||||
]),
|
||||
],
|
||||
true
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param ShiftType $shifttype
|
||||
* @return string
|
||||
*/
|
||||
function ShiftType_view(ShiftType $shifttype)
|
||||
{
|
||||
$parsedown = new Parsedown();
|
||||
$title = $shifttype->name;
|
||||
$link = button(url('/shifttypes'), icon('chevron-left'), 'btn-sm');
|
||||
return page_with_title($link . ' ' . $title, [
|
||||
msg(),
|
||||
buttons([
|
||||
button(
|
||||
url('/shifttypes', ['action' => 'edit', 'shifttype_id' => $shifttype->id]),
|
||||
icon('pencil') . __('edit')
|
||||
),
|
||||
button(
|
||||
url('/shifttypes', ['action' => 'delete', 'shifttype_id' => $shifttype->id]),
|
||||
icon('trash') . __('delete'),
|
||||
),
|
||||
]),
|
||||
heading(__('general.description'), 2),
|
||||
$parsedown->parse($shifttype->description),
|
||||
], true);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param ShiftType[]|array[]|Collection $shifttypes
|
||||
* @return string
|
||||
*/
|
||||
function ShiftTypes_list_view($shifttypes)
|
||||
{
|
||||
foreach ($shifttypes as $shifttype) {
|
||||
$shifttype->name = '<a href="'
|
||||
. url('/shifttypes', ['action' => 'view', 'shifttype_id' => $shifttype->id])
|
||||
. '">'
|
||||
. $shifttype->name
|
||||
. '</a>';
|
||||
$shifttype->actions = table_buttons([
|
||||
button(
|
||||
url(
|
||||
'/shifttypes',
|
||||
['action' => 'edit', 'shifttype_id' => $shifttype->id]
|
||||
),
|
||||
icon('pencil') . __('edit'),
|
||||
'btn-sm'
|
||||
),
|
||||
button(
|
||||
url('/shifttypes', ['action' => 'delete', 'shifttype_id' => $shifttype->id]),
|
||||
icon('trash') . __('delete'),
|
||||
'btn-sm'
|
||||
),
|
||||
]);
|
||||
}
|
||||
|
||||
$link = button(url('/shifttypes', ['action' => 'edit']), icon('plus-lg'), 'add');
|
||||
return page_with_title(
|
||||
shifttypes_title() . ' ' . $link,
|
||||
[
|
||||
msg(),
|
||||
|
||||
table([
|
||||
'name' => __('general.name'),
|
||||
'actions' => '',
|
||||
], $shifttypes),
|
||||
],
|
||||
true,
|
||||
);
|
||||
}
|
|
@ -175,7 +175,7 @@ function Shift_view(
|
|||
$buttons = [
|
||||
$shift_admin ? button(shift_edit_link($shift), icon('pencil') . __('edit')) : '',
|
||||
$shift_admin ? button(shift_delete_link($shift), icon('trash') . __('delete')) : '',
|
||||
$admin_shifttypes ? button(shifttype_link($shifttype), $shifttype->name) : '',
|
||||
$admin_shifttypes ? button(url('/admin/shifttypes/' . $shifttype->id), $shifttype->name) : '',
|
||||
$admin_locations ? button(location_link($location), icon('pin-map-fill') . $location->name) : '',
|
||||
];
|
||||
}
|
||||
|
|
|
@ -272,6 +272,12 @@ msgstr "Ort erfolgreich bearbeitet."
|
|||
msgid "location.delete.success"
|
||||
msgstr "Ort erfolgreich gelöscht."
|
||||
|
||||
msgid "shifttype.edit.success"
|
||||
msgstr "Schichttyp erfolgreich bearbeitet."
|
||||
|
||||
msgid "shifttype.delete.success"
|
||||
msgstr "Schichttyp erfolgreich gelöscht."
|
||||
|
||||
msgid "validation.name.exists"
|
||||
msgstr "Der Name wird bereits verwendet."
|
||||
|
||||
|
|
|
@ -323,24 +323,6 @@ msgstr "Möchtest Du die Schicht %s von %s bis %s löschen?"
|
|||
msgid "Shift could not be found."
|
||||
msgstr "Schicht konnte nicht gefunden werden."
|
||||
|
||||
msgid "Shifttype %s deleted."
|
||||
msgstr "Schichttyp %s gelöscht."
|
||||
|
||||
msgid "Delete shifttype %s"
|
||||
msgstr "Lösche Schichttyp %s"
|
||||
|
||||
msgid "Please enter a name."
|
||||
msgstr "Gib bitte einen Namen an."
|
||||
|
||||
msgid "Updated shifttype."
|
||||
msgstr "Schichttyp geändert."
|
||||
|
||||
msgid "Created shifttype."
|
||||
msgstr "Schichttyp erstellt."
|
||||
|
||||
msgid "Shifttypes"
|
||||
msgstr "Schichttypen"
|
||||
|
||||
msgid "There is %d unconfirmed angeltype."
|
||||
msgid_plural "There are %d unconfirmed angeltypes."
|
||||
msgstr[0] "Es gibt %d nicht freigeschalteten Engeltypen!"
|
||||
|
@ -1127,15 +1109,6 @@ msgstr "Titel:"
|
|||
msgid "Type:"
|
||||
msgstr "Typ:"
|
||||
|
||||
msgid "Do you want to delete shifttype %s?"
|
||||
msgstr "Möchtest Du den Schichttypen %s löschen?"
|
||||
|
||||
msgid "Edit shifttype"
|
||||
msgstr "Schichttyp bearbeiten"
|
||||
|
||||
msgid "Create shifttype"
|
||||
msgstr "Schichttyp erstellen"
|
||||
|
||||
msgid "Location"
|
||||
msgstr "Ort"
|
||||
|
||||
|
@ -1960,6 +1933,18 @@ msgstr "Ort bearbeiten"
|
|||
msgid "location.delete.title"
|
||||
msgstr "Ort \"%s\" löschen"
|
||||
|
||||
msgid "shifttype.shifttypes"
|
||||
msgstr "Schichttypen"
|
||||
|
||||
msgid "shifttype.edit.title"
|
||||
msgstr "Schichttyp bearbeiten"
|
||||
|
||||
msgid "shifttype.create.title"
|
||||
msgstr "Schichttyp erstellen"
|
||||
|
||||
msgid "shifttype.delete.title"
|
||||
msgstr "Schichttyp \"%s\" löschen"
|
||||
|
||||
msgid "event.day"
|
||||
msgstr "Tag %1$d"
|
||||
|
||||
|
|
|
@ -271,6 +271,12 @@ msgstr "Location edited successfully."
|
|||
msgid "location.delete.success"
|
||||
msgstr "Location successfully deleted."
|
||||
|
||||
msgid "shifttype.edit.success"
|
||||
msgstr "Shift type edited successfully."
|
||||
|
||||
msgid "shifttype.delete.success"
|
||||
msgstr "Shift type successfully deleted."
|
||||
|
||||
msgid "validation.name.exists"
|
||||
msgstr "The name is already used."
|
||||
|
||||
|
|
|
@ -616,6 +616,18 @@ msgstr "Edit location"
|
|||
msgid "location.delete.title"
|
||||
msgstr "Delete location \"%s\""
|
||||
|
||||
msgid "shifttype.shifttypes"
|
||||
msgstr "Shift types"
|
||||
|
||||
msgid "shifttype.edit.title"
|
||||
msgstr "Edit shift type"
|
||||
|
||||
msgid "shifttype.create.title"
|
||||
msgstr "Create shift type"
|
||||
|
||||
msgid "shifttype.delete.title"
|
||||
msgstr "Delete shift type \"%s\""
|
||||
|
||||
msgid "event.day"
|
||||
msgstr "Day %1$d"
|
||||
|
||||
|
|
|
@ -0,0 +1,38 @@
|
|||
{% extends 'admin/shifttypes/index.twig' %}
|
||||
{% import 'macros/base.twig' as m %}
|
||||
{% import 'macros/form.twig' as f %}
|
||||
|
||||
{% block title %}{{ shifttype ? __('shifttype.edit.title') : __('shifttype.create.title') }}{% endblock %}
|
||||
|
||||
{% block row_content %}
|
||||
<form method="post">
|
||||
{{ csrf() }}
|
||||
{{ f.hidden('id', shifttype ? shifttype.id : '') }}
|
||||
|
||||
<div class="row">
|
||||
<div class="col-lg-6">
|
||||
{{ f.input('name', __('general.name'), {
|
||||
'required': true,
|
||||
'required_icon': true,
|
||||
'value': f.formData('shifttype', shifttype ? shifttype.name : ''),
|
||||
}) }}
|
||||
|
||||
{{ f.textarea('description', __('general.description'), {
|
||||
'value': f.formData('description', shifttype ? shifttype.description : ''),
|
||||
'rows': 5,
|
||||
'info': __('form.markdown')
|
||||
}) }}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-md-12">
|
||||
<div class="btn-group">
|
||||
{{ f.submit(__('form.save'), {'icon_left': 'save'}) }}
|
||||
{% if shifttype %}
|
||||
{{ f.delete(__('form.delete'), {'confirm_title': __('shifttype.delete.title', [shifttype.name|e])}) }}
|
||||
{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</form>
|
||||
{% endblock %}
|
|
@ -0,0 +1,66 @@
|
|||
{% extends 'layouts/app.twig' %}
|
||||
{% import 'macros/base.twig' as m %}
|
||||
{% import 'macros/form.twig' as f %}
|
||||
|
||||
{% block title %}{{ __('shifttype.shifttypes') }}{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
<div class="container">
|
||||
<h1>
|
||||
{% if not is_index|default(false) %}
|
||||
{{ m.button(m.icon('chevron-left'), url('/admin/shifttypes'), 'secondary', 'sm') }}
|
||||
{% endif %}
|
||||
|
||||
{{ block('title') }}
|
||||
|
||||
{% if is_index|default(false) %}
|
||||
{{ m.button(m.icon('plus-lg'), url('/admin/shifttypes/edit'), 'secondary') }}
|
||||
{% endif %}
|
||||
</h1>
|
||||
|
||||
{% include 'layouts/parts/messages.twig' %}
|
||||
|
||||
<div class="row">
|
||||
|
||||
{% block row_content %}
|
||||
<div class="col-md-12">
|
||||
<div class="table-responsive">
|
||||
<table class="table table-striped">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>{{ __('general.name') }}</th>
|
||||
<th></th>
|
||||
</tr>
|
||||
</thead>
|
||||
|
||||
<tbody>
|
||||
{% for shifttype in shifttypes %}
|
||||
<tr>
|
||||
<td>
|
||||
<a href="{{ url('/admin/shifttypes/' ~ shifttype.id) }}">{{ shifttype.name }}</a>
|
||||
</td>
|
||||
|
||||
<td>
|
||||
<div class="d-flex ms-auto">
|
||||
|
||||
{{ m.button(m.icon('pencil'), url('admin/shifttypes/edit/' ~ shifttype.id), null, 'sm', __('form.edit')) }}
|
||||
|
||||
<form method="post" class="ps-1">
|
||||
{{ csrf() }}
|
||||
{{ f.hidden('id', shifttype.id) }}
|
||||
{{ f.delete(null, {'size': 'sm', 'confirm_title': __('shifttype.delete.title', [shifttype.name|e])}) }}
|
||||
</form>
|
||||
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
{% endblock %}
|
||||
|
||||
</div>
|
||||
</div>
|
||||
{% endblock %}
|
|
@ -0,0 +1,11 @@
|
|||
{% extends 'admin/shifttypes/index.twig' %}
|
||||
{% import 'macros/base.twig' as m %}
|
||||
{% import 'macros/form.twig' as f %}
|
||||
|
||||
{% block title %}{{ shifttype.name }}{% endblock %}
|
||||
|
||||
{% block row_content %}
|
||||
<div class="col-md-12">
|
||||
{{ shifttype.description|md }}
|
||||
</div>
|
||||
{% endblock %}
|
|
@ -0,0 +1,141 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Engelsystem\Controllers\Admin;
|
||||
|
||||
use Engelsystem\Controllers\BaseController;
|
||||
use Engelsystem\Controllers\HasUserNotifications;
|
||||
use Engelsystem\Http\Exceptions\ValidationException;
|
||||
use Engelsystem\Http\Redirector;
|
||||
use Engelsystem\Http\Request;
|
||||
use Engelsystem\Http\Response;
|
||||
use Engelsystem\Http\Validation\Validator;
|
||||
use Engelsystem\Models\Shifts\ShiftType;
|
||||
use Psr\Log\LoggerInterface;
|
||||
|
||||
class ShiftTypesController extends BaseController
|
||||
{
|
||||
use HasUserNotifications;
|
||||
|
||||
/** @var array<string> */
|
||||
protected array $permissions = [
|
||||
'shifttypes',
|
||||
];
|
||||
|
||||
public function __construct(
|
||||
protected LoggerInterface $log,
|
||||
protected ShiftType $shiftType,
|
||||
protected Redirector $redirect,
|
||||
protected Response $response
|
||||
) {
|
||||
}
|
||||
|
||||
public function index(): Response
|
||||
{
|
||||
$shiftTypes = $this->shiftType
|
||||
->get()
|
||||
->sortBy('name', SORT_NATURAL | SORT_FLAG_CASE);
|
||||
|
||||
return $this->response->withView(
|
||||
'admin/shifttypes/index',
|
||||
['shifttypes' => $shiftTypes, 'is_index' => true]
|
||||
);
|
||||
}
|
||||
|
||||
public function edit(Request $request): Response
|
||||
{
|
||||
$shiftTypeId = (int) $request->getAttribute('shift_type_id');
|
||||
|
||||
$shiftType = $this->shiftType->find($shiftTypeId);
|
||||
|
||||
return $this->response->withView(
|
||||
'admin/shifttypes/edit',
|
||||
['shifttype' => $shiftType]
|
||||
);
|
||||
}
|
||||
|
||||
public function view(Request $request): Response
|
||||
{
|
||||
$shiftTypeId = (int) $request->getAttribute('shift_type_id');
|
||||
$shiftType = $this->shiftType->findOrFail($shiftTypeId);
|
||||
|
||||
return $this->response->withView(
|
||||
'admin/shifttypes/view',
|
||||
['shifttype' => $shiftType]
|
||||
);
|
||||
}
|
||||
|
||||
public function save(Request $request): Response
|
||||
{
|
||||
$shiftTypeId = (int) $request->getAttribute('shift_type_id');
|
||||
|
||||
/** @var ShiftType $shiftType */
|
||||
$shiftType = $this->shiftType->findOrNew($shiftTypeId);
|
||||
|
||||
if ($request->request->has('delete')) {
|
||||
return $this->delete($request);
|
||||
}
|
||||
|
||||
$data = $this->validate(
|
||||
$request,
|
||||
[
|
||||
'name' => 'required',
|
||||
'description' => 'required|optional',
|
||||
]
|
||||
);
|
||||
|
||||
if (ShiftType::whereName($data['name'])->where('id', '!=', $shiftType->id)->exists()) {
|
||||
throw new ValidationException((new Validator())->addErrors(['name' => ['validation.name.exists']]));
|
||||
}
|
||||
|
||||
$shiftType->name = $data['name'];
|
||||
$shiftType->description = $data['description'];
|
||||
|
||||
$shiftType->save();
|
||||
|
||||
$this->log->info(
|
||||
'Updated shift type "{name}": {description}',
|
||||
[
|
||||
'name' => $shiftType->name,
|
||||
'description' => $shiftType->description,
|
||||
]
|
||||
);
|
||||
|
||||
$this->addNotification('shifttype.edit.success');
|
||||
|
||||
return $this->redirect->to('/admin/shifttypes');
|
||||
}
|
||||
|
||||
public function delete(Request $request): Response
|
||||
{
|
||||
$data = $this->validate($request, [
|
||||
'id' => 'required|int',
|
||||
'delete' => 'checked',
|
||||
]);
|
||||
|
||||
$shiftType = $this->shiftType->findOrFail($data['id']);
|
||||
|
||||
$shifts = $shiftType->shifts;
|
||||
foreach ($shifts as $shift) {
|
||||
foreach ($shift->shiftEntries as $entry) {
|
||||
event('shift.entry.deleting', [
|
||||
'user' => $entry->user,
|
||||
'start' => $shift->start,
|
||||
'end' => $shift->end,
|
||||
'name' => $shift->shiftType->name,
|
||||
'title' => $shift->title,
|
||||
'type' => $entry->angelType->name,
|
||||
'location' => $shift->location,
|
||||
'freeloaded' => $entry->freeloaded,
|
||||
]);
|
||||
}
|
||||
}
|
||||
$shiftType->delete();
|
||||
|
||||
$this->log->info('Deleted shift type {name}', ['name' => $shiftType->name]);
|
||||
$this->addNotification('shifttype.delete.success');
|
||||
|
||||
return $this->redirect->to('/admin/shifttypes');
|
||||
}
|
||||
}
|
|
@ -88,9 +88,6 @@ class LegacyMiddleware implements MiddlewareInterface
|
|||
return users_controller();
|
||||
case 'user_angeltypes':
|
||||
return user_angeltypes_controller();
|
||||
case 'shifttypes':
|
||||
list($title, $content) = shifttypes_controller();
|
||||
return [$title, $content];
|
||||
case 'admin_event_config':
|
||||
list($title, $content) = event_config_edit_controller();
|
||||
return [$title, $content];
|
||||
|
|
|
@ -0,0 +1,223 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Engelsystem\Test\Unit\Controllers\Admin;
|
||||
|
||||
use Engelsystem\Controllers\Admin\ShiftTypesController;
|
||||
use Engelsystem\Events\EventDispatcher;
|
||||
use Engelsystem\Helpers\Carbon;
|
||||
use Engelsystem\Http\Exceptions\ValidationException;
|
||||
use Engelsystem\Http\Redirector;
|
||||
use Engelsystem\Http\Request;
|
||||
use Engelsystem\Http\Validation\Validator;
|
||||
use Engelsystem\Models\Shifts\ShiftEntry;
|
||||
use Engelsystem\Models\Shifts\ShiftType;
|
||||
use Engelsystem\Models\Shifts\Shift;
|
||||
use Engelsystem\Models\User\User;
|
||||
use Engelsystem\Test\Unit\Controllers\ControllerTest;
|
||||
use PHPUnit\Framework\MockObject\MockObject;
|
||||
|
||||
class ShiftTypeControllerTest extends ControllerTest
|
||||
{
|
||||
protected Redirector|MockObject $redirect;
|
||||
|
||||
/**
|
||||
* @covers \Engelsystem\Controllers\Admin\ShiftTypesController::__construct
|
||||
* @covers \Engelsystem\Controllers\Admin\ShiftTypesController::index
|
||||
*/
|
||||
public function testIndex(): void
|
||||
{
|
||||
/** @var ShiftTypesController $controller */
|
||||
$controller = $this->app->make(ShiftTypesController::class);
|
||||
ShiftType::factory(5)->create();
|
||||
|
||||
$this->response->expects($this->once())
|
||||
->method('withView')
|
||||
->willReturnCallback(function (string $view, array $data) {
|
||||
$this->assertEquals('admin/shifttypes/index', $view);
|
||||
$this->assertTrue($data['is_index'] ?? false);
|
||||
$this->assertCount(5, $data['shifttypes'] ?? []);
|
||||
return $this->response;
|
||||
});
|
||||
|
||||
$controller->index();
|
||||
}
|
||||
|
||||
/**
|
||||
* @covers \Engelsystem\Controllers\Admin\ShiftTypesController::view
|
||||
*/
|
||||
public function testView(): void
|
||||
{
|
||||
/** @var ShiftTypesController $controller */
|
||||
$controller = $this->app->make(ShiftTypesController::class);
|
||||
$shiftType = ShiftType::factory()->create();
|
||||
|
||||
$this->response->expects($this->once())
|
||||
->method('withView')
|
||||
->willReturnCallback(function (string $view, array $data) use ($shiftType) {
|
||||
$this->assertEquals('admin/shifttypes/view', $view);
|
||||
$this->assertArrayHasKey('shifttype', $data);
|
||||
$this->assertEquals($shiftType->id, $data['shifttype']['id']);
|
||||
return $this->response;
|
||||
});
|
||||
|
||||
$controller->view(new Request([], [], ['shift_type_id' => $shiftType->id]));
|
||||
}
|
||||
|
||||
/**
|
||||
* @covers \Engelsystem\Controllers\Admin\ShiftTypesController::edit
|
||||
*/
|
||||
public function testEdit(): void
|
||||
{
|
||||
/** @var ShiftTypesController $controller */
|
||||
$controller = $this->app->make(ShiftTypesController::class);
|
||||
/** @var ShiftType $shifttype */
|
||||
$shifttype = ShiftType::factory()->create();
|
||||
|
||||
$this->response->expects($this->once())
|
||||
->method('withView')
|
||||
->willReturnCallback(function (string $view, array $data) use ($shifttype) {
|
||||
$this->assertEquals('admin/shifttypes/edit', $view);
|
||||
$this->assertEquals($shifttype->id, $data['shifttype']?->id);
|
||||
$this->assertNotEmpty($data['shifttype']?->name);
|
||||
$this->assertNotEmpty($data['shifttype']?->description);
|
||||
return $this->response;
|
||||
});
|
||||
|
||||
$this->request = $this->request->withAttribute('shift_type_id', 1);
|
||||
|
||||
$controller->edit($this->request);
|
||||
}
|
||||
|
||||
/**
|
||||
* @covers \Engelsystem\Controllers\Admin\ShiftTypesController::edit
|
||||
*/
|
||||
public function testEditNew(): void
|
||||
{
|
||||
/** @var ShiftTypesController $controller */
|
||||
$controller = $this->app->make(ShiftTypesController::class);
|
||||
|
||||
$this->response->expects($this->once())
|
||||
->method('withView')
|
||||
->willReturnCallback(function (string $view, array $data) {
|
||||
$this->assertEquals('admin/shifttypes/edit', $view);
|
||||
$this->assertArrayHasKey('shifttype', $data);
|
||||
$this->assertNull($data['shifttype']);
|
||||
return $this->response;
|
||||
});
|
||||
|
||||
$controller->edit($this->request);
|
||||
}
|
||||
|
||||
/**
|
||||
* @covers \Engelsystem\Controllers\Admin\ShiftTypesController::save
|
||||
*/
|
||||
public function testSave(): void
|
||||
{
|
||||
/** @var ShiftTypesController $controller */
|
||||
$controller = $this->app->make(ShiftTypesController::class);
|
||||
$controller->setValidator(new Validator());
|
||||
|
||||
$this->setExpects($this->redirect, 'to', ['/admin/shifttypes']);
|
||||
|
||||
$this->request = $this->request->withParsedBody([
|
||||
'name' => 'Test shift type',
|
||||
'description' => 'Something',
|
||||
]);
|
||||
|
||||
$controller->save($this->request);
|
||||
|
||||
$this->assertTrue($this->log->hasInfoThatContains('Updated shift type'));
|
||||
$this->assertHasNotification('shifttype.edit.success');
|
||||
$this->assertCount(1, ShiftType::whereName('Test shift type')->get());
|
||||
}
|
||||
|
||||
/**
|
||||
* @covers \Engelsystem\Controllers\Admin\ShiftTypesController::save
|
||||
*/
|
||||
public function testSaveUniqueName(): void
|
||||
{
|
||||
/** @var ShiftTypesController $controller */
|
||||
$controller = $this->app->make(ShiftTypesController::class);
|
||||
$controller->setValidator(new Validator());
|
||||
ShiftType::factory()->create(['name' => 'Test shift type']);
|
||||
|
||||
$this->request = $this->request->withParsedBody([
|
||||
'name' => 'Test shift type',
|
||||
]);
|
||||
|
||||
$this->expectException(ValidationException::class);
|
||||
$controller->save($this->request);
|
||||
}
|
||||
|
||||
/**
|
||||
* @covers \Engelsystem\Controllers\Admin\ShiftTypesController::save
|
||||
* @covers \Engelsystem\Controllers\Admin\ShiftTypesController::delete
|
||||
*/
|
||||
public function testSaveDelete(): void
|
||||
{
|
||||
/** @var ShiftTypesController $controller */
|
||||
$controller = $this->app->make(ShiftTypesController::class);
|
||||
$controller->setValidator(new Validator());
|
||||
/** @var ShiftType $shifttype */
|
||||
$shifttype = ShiftType::factory()->create();
|
||||
|
||||
$this->request = $this->request->withParsedBody([
|
||||
'id' => '1',
|
||||
'delete' => '1',
|
||||
]);
|
||||
|
||||
$controller->save($this->request);
|
||||
$this->assertEmpty(ShiftType::find($shifttype->id));
|
||||
}
|
||||
|
||||
/**
|
||||
* @covers \Engelsystem\Controllers\Admin\ShiftTypesController::delete
|
||||
*/
|
||||
public function testDelete(): void
|
||||
{
|
||||
/** @var EventDispatcher|MockObject $dispatcher */
|
||||
$dispatcher = $this->createMock(EventDispatcher::class);
|
||||
$this->app->instance('events.dispatcher', $dispatcher);
|
||||
/** @var ShiftTypesController $controller */
|
||||
$controller = $this->app->make(ShiftTypesController::class);
|
||||
$controller->setValidator(new Validator());
|
||||
/** @var ShiftType $shifttype */
|
||||
$shifttype = ShiftType::factory()->create();
|
||||
/** @var Shift $shift */
|
||||
$shift = Shift::factory()->create(['shift_type_id' => $shifttype->id, 'start' => Carbon::create()->subHour()]);
|
||||
/** @var User $user */
|
||||
$user = User::factory()->create(['name' => 'foo', 'email' => 'lorem@ipsum']);
|
||||
/** @var ShiftEntry $shiftEntry */
|
||||
ShiftEntry::factory()->create(['shift_id' => $shift->id, 'user_id' => $user->id]);
|
||||
|
||||
$this->setExpects($this->redirect, 'to', ['/admin/shifttypes'], $this->response);
|
||||
|
||||
$dispatcher->expects($this->once())
|
||||
->method('dispatch')
|
||||
->willReturnCallback(function (string $event, array $data) use ($shifttype, $user) {
|
||||
$this->assertEquals('shift.entry.deleting', $event);
|
||||
$this->assertEquals($shifttype->name, $data['name']);
|
||||
$this->assertEquals($user->id, $data['user']->id);
|
||||
|
||||
return [];
|
||||
});
|
||||
|
||||
$this->request = $this->request->withParsedBody(['id' => 1, 'delete' => '1']);
|
||||
|
||||
$controller->delete($this->request);
|
||||
|
||||
$this->assertNull(ShiftType::find($shifttype->id));
|
||||
$this->assertTrue($this->log->hasInfoThatContains('Deleted shift type'));
|
||||
$this->assertHasNotification('shifttype.delete.success');
|
||||
}
|
||||
|
||||
public function setUp(): void
|
||||
{
|
||||
parent::setUp();
|
||||
|
||||
$this->redirect = $this->createMock(Redirector::class);
|
||||
$this->app->instance(Redirector::class, $this->redirect);
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue