Commit 5b62745a authored by Jacob Priddy's avatar Jacob Priddy 👌

Add door groups management

parent a5126fcf
......@@ -8,16 +8,24 @@ use App\Http\Controllers\Controller;
use Illuminate\Http\RedirectResponse;
use Source\UseCases\Doors\GetDoor\GetDoorUseCase;
use Source\UseCases\Doors\GetDoors\GetDoorsUseCase;
use Source\UseCases\Groups\GetGroups\GetGroupsUseCase;
use Source\UseCases\Doors\CreateDoor\CreateDoorUseCase;
use Source\UseCases\Doors\DeleteDoor\DeleteDoorUseCase;
use Source\UseCases\Doors\UpdateDoor\UpdateDoorUseCase;
use Source\UseCases\Doors\CreateDoor\WebTokenGeneratePresenter;
use Source\UseCases\DoorGroup\GetDoorGroups\GetDoorGroupsUseCase;
use Source\UseCases\DoorGroup\AddDoorToGroup\AddDoorToGroupUseCase;
use Source\UseCases\Doors\GetDoor\APIPresenter as GetDoorPresenter;
use Source\UseCases\Doors\GenerateDoorToken\GenerateDoorTokenUseCase;
use Source\UseCases\Doors\GetDoors\WebPresenter as GetDoorsPresenter;
use Source\UseCases\Groups\GetGroups\WebPresenter as GroupsPresenter;
use Source\UseCases\Doors\CreateDoor\WebPresenter as CreateDoorPresenter;
use Source\UseCases\Doors\DeleteDoor\APIPresenter as DeleteDoorPresenter;
use Source\UseCases\Doors\UpdateDoor\APIPresenter as UpdateDoorPresenter;
use Source\UseCases\DoorGroup\RemoveDoorFromGroup\RemoveDoorFromGroupUseCase;
use Source\UseCases\DoorGroup\AddDoorToGroup\APIPresenter as DoorGroupPresenter;
use Source\UseCases\DoorGroup\GetDoorGroups\WebPresenter as DoorGroupsPresenter;
use Source\UseCases\DoorGroup\RemoveDoorFromGroup\APIPresenter as RemoveDoorGroupPresenter;
class DoorsController extends Controller
{
......@@ -139,4 +147,56 @@ class DoorsController extends Controller
{
return view('admin.entities.doorAccess', ['id' => $doorId]);
}
/**
* @param string $doorId
* @param \Source\UseCases\DoorGroup\GetDoorGroups\GetDoorGroupsUseCase $doorGroups
* @param \Source\UseCases\Groups\GetGroups\GetGroupsUseCase $groups
* @return \Illuminate\View\View
* @throws \Source\Exceptions\EntityNotFoundException
*/
public function groups(string $doorId, GetDoorGroupsUseCase $doorGroups, GetGroupsUseCase $groups): View
{
$groupsPresenter = new GroupsPresenter();
$groups->search(null, $groupsPresenter);
$presenter = new DoorGroupsPresenter();
$doorGroups->getGroupsForDoor($doorId, $presenter);
return view('admin.doorGroups', array_merge(
$presenter->getViewModel(),
$groupsPresenter->all('allGroups'),
['doorId' => $doorId],
));
}
/**
* @param string $doorId
* @param \Source\UseCases\DoorGroup\AddDoorToGroup\AddDoorToGroupUseCase $doorGroup
* @return \Illuminate\Http\RedirectResponse
* @throws \Illuminate\Validation\ValidationException
*/
public function addGroup(string $doorId, AddDoorToGroupUseCase $doorGroup): RedirectResponse
{
$this->validate($this->request, [
'group_id' => 'required|string',
]);
$presenter = new DoorGroupPresenter();
$doorGroup->addDoorToGroup([$doorId], [$this->request->input('group_id')], $presenter);
return redirect(route('web.admin.doors.groups', ['doorId' => $doorId]))->with($presenter->getViewModel());
}
public function removeGroup(string $doorId, string $groupId, RemoveDoorFromGroupUseCase $doorGroup): RedirectResponse
{
$presenter = new RemoveDoorGroupPresenter();
$doorGroup->removeDoorFromGroup([$doorId], [$groupId], $presenter);
return redirect(route('web.admin.doors.groups', ['doorId' => $doorId]))->with($presenter->getViewModel());
}
}
@extends('layouts.admin.tableData', [
'title' => 'Door Groups',
'route' => route('web.admin.doors.groups', ['doorId' => $doorId]),
'tableParams' => [
'headers' => $headers,
'paginatedData' => $groups,
'controls' => 'detachDoorGroup'
],
])
@section('controls')
<button class="btn btn-primary float-right" data-toggle="modal" data-target="#attachGroup">
Add Group
</button>
<div class="modal fade" id="attachGroup" tabindex="-1" role="dialog" aria-hidden="true">
<div class="modal-dialog" role="document">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title">Add group to door.</h5>
<button class="close" type="button" data-dismiss="modal" aria-label="Close">
<span aria-hidden="true">×</span>
</button>
</div>
<form method="POST" action="{{ route('web.admin.doors.addGroup', ['doorId' => $doorId]) }}">
@csrf
<div class="modal-body">
<label for="groupSelect">
Select group
</label>
<select class="form-control" name="group_id" id="groupSelect" required>
@foreach($allGroups as $group)
<option value="{{ $group['id'] }}">
{{ $group['title'] }}
</option>
@endforeach
</select>
</div>
<div class="modal-footer">
<button class="btn btn-secondary" type="button" data-dismiss="modal">Cancel</button>
<button class="btn btn-primary" type="submit">
Add Group
</button>
</div>
</form>
</div>
</div>
</div>
@endsection
@extends('layouts.admin')
@section('title', 'View ' . ucfirst($resource) )
@section('main-content')
@include('partials.message')
@include('partials.form-errors')
<div class="card shadow mb-4">
<div class="card-header py-3">
<div class="row">
<div class="col-6">
<h4 class="m-0 font-weight-bold text-primary float-left">{{ ucfirst($resource) }}</h4>
</div>
<div class="col-6">
@hasSection('index-controls')
@yield('index-controls')
@else
<a class="float-right btn btn-primary" href="{{ route('web.admin.' . $resource . '.create') }}">
New {{ ucfirst(\Illuminate\Support\Str::singular($resource)) }}
</a>
@endif
</div>
</div>
</div>
<div class="card-body">
<div class="table-responsive overflow-auto">
{{-- Search/filter options--}}
<form action="{{ route('web.admin.' . $resource . '.index') }}" method="GET">
<div class="form-row">
<div class="form-inline col-sm-12 col-md-6 col-xl-3 text-center">
@include('partials.perPage')
</div>
@yield('filters')
</div>
</form>
<hr>
<div class="ml-2">
@include('partials.table', $tableParams)
</div>
</div>
</div>
</div>
@extends('layouts.admin.tableData', [
'title' => ucfirst($resource),
'route' => route('web.admin.' . $resource . '.index'),
])
@section('controls')
@hasSection('index-controls')
@yield('index-controls')
@else
<a class="float-right btn btn-primary" href="{{ route('web.admin.' . $resource . '.create') }}">
New {{ ucfirst(\Illuminate\Support\Str::singular($resource)) }}
</a>
@endif
@endsection
@extends('layouts.admin')
@section('title', 'View ' . $title )
@section('main-content')
@include('partials.message')
@include('partials.form-errors')
<div class="card shadow mb-4">
<div class="card-header py-3">
<div class="row">
<div class="col-6">
<h4 class="m-0 font-weight-bold text-primary float-left">{{ $title }}</h4>
</div>
<div class="col-6">
@yield('controls')
</div>
</div>
</div>
<div class="card-body">
<div class="table-responsive overflow-auto">
{{-- Search/filter options--}}
<form action="{{ $route }}" method="GET">
<div class="form-row">
<div class="form-inline col-sm-12 col-md-6 col-xl-3 text-center">
@include('partials.perPage')
</div>
@hasSection('filters')
@yield('filters')
@else
<div class="col-sm-12 col-md-4 col-xl-2 text-center">
<input class="btn btn-primary" type="submit" value="Filter">
</div>
@endif
</div>
</form>
<hr>
<div class="ml-2">
@include('partials.table', $tableParams)
</div>
</div>
</div>
</div>
@endsection
<div class="d-flex flex-row">
<form action="{{ route('web.admin.doors.removeGroup', ['doorId' => $doorId, 'groupId' => $id]) }}" method="POST">
@csrf
@method('DELETE')
<button class="btn btn-danger" type="submit" data-toggle="tooltip" title="Detach door and group.">
<i class="fas fa-trash"></i>
</button>
</form>
</div>
<div class="d-flex flex-row">
<a class="btn btn-secondary" href="{{ route('web.admin.doors.groups', ['doorId' => $id]) }}" data-toggle="tooltip" title="Manage groups for the door.">
<i class="fas fa-object-group"></i>
</a>
<a class="btn btn-dark" href="{{ route('web.admin.doors.schedule', ['doorId' => $id]) }}" data-toggle="tooltip" title="View Open Mode Schedule">
<i class="fas fa-calendar-alt"></i>
</a>
......
......@@ -8,6 +8,18 @@
<div class="alert alert-info"> {{ request()->session()->get('message') }}</div>
@endif
@if(null !== request()->session()->get('messages'))
@foreach(request()->session()->get('messages') as $message)
<div class="alert alert-info"> {{ $message }}</div>
@endforeach
@endif
@if(null !== request()->session()->get('error'))
<div class="alert alert-danger"> {{ request()->session()->get('error') }}</div>
@endif
@if(null !== request()->session()->get('errors'))
@foreach(request()->session()->get('errors') as $error)
<div class="alert alert-danger"> {{ $error }}</div>
@endforeach
@endif
......@@ -71,6 +71,10 @@ Route::name('web.')->middleware(['auth:api'])->group(static function () {
Route::delete('/{doorId}', [DoorsController::class, 'destroy'])->name('destroy');
Route::get('/{doorId}', [DoorsController::class, 'schedule'])->name('schedule');
Route::post('/{doorId}/regenerate-token', [DoorsController::class, 'regenerateToken'])->name('regenerate');
Route::get('/{doorId}/groups', [DoorsController::class, 'groups'])->name('groups');
Route::post('/{doorId}/groups', [DoorsController::class, 'addGroup'])->name('addGroup');
Route::delete('/{doorId}/group/{groupId}', [DoorsController::class, 'removeGroup'])->name('removeGroup');
});
Route::name('users.')
......@@ -95,7 +99,6 @@ Route::name('web.')->middleware(['auth:api'])->group(static function () {
Route::delete('/{requestId}', [RequestsController::class, 'destroy'])->name('destroy');
});
Route::name('groups.')
->prefix('groups')
->middleware('can:' . Permissions::MANAGE_GROUPS)
......
<?php
namespace Source\UseCases\DoorGroup\GetDoorGroups;
use Source\Entities\Group;
use Source\Sanitize\Paginates;
use Source\UseCases\BasePresenter;
class WebPresenter extends BasePresenter implements Presenter
{
use Paginates;
protected array $groups = [];
/** @inheritDoc */
public function present(ResponseModel $responseModel): void
{
$this->groups = array_map(static function (Group $group) {
return [
'id' => $group->getId(),
'title' => $group->getTitle(),
'description' => $group->getDescription(),
];
}, $responseModel->getGroups());
}
/** @inheritDoc */
public function getViewModel(): array
{
return [
'groups' => $this->webPaginate($this->groups),
'headers' => [
'ID' => 'id',
'Title' => 'title',
'Description' => 'description',
],
];
}
}
......@@ -29,9 +29,9 @@ class RemoveDoorFromGroup implements RemoveDoorFromGroupUseCase
foreach ($doorIds as $doorId) {
try {
$this->repository->removeDoorFromGroup($doorId, $groupId);
$response->addMessage("Successfully added door $doorId to group $groupId");
$response->addMessage("Successfully detached door $doorId from group $groupId");
} catch (EntityNotFoundException $e) {
$response->addMessage("Could not add door $doorId to group $groupId. " . $e->getMessage());
$response->addMessage("Could not detach door $doorId from group $groupId. " . $e->getMessage());
}
}
}
......
......@@ -30,4 +30,13 @@ class WebPresenter extends BasePresenter implements Presenter
],
];
}
/**
* @param string $key
* @return array
*/
public function all(string $key = 'groups'): array
{
return [$key => $this->groups];
}
}
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment