This commit is contained in:
Adrian Hopek 2022-02-02 10:37:16 +01:00
parent 3ebc391b83
commit 9a7ee2f5d3
5 changed files with 97 additions and 6 deletions

View File

@ -19,4 +19,38 @@ enum VacationRequestState: string
{
return __($this->value);
}
public static function pendingStates(): array
{
return [
self::CREATED,
self::WAITING_FOR_TECHNICAL,
self::WAITING_FOR_ADMINISTRATIVE,
self::ACCEPTED_BY_TECHNICAL,
self::ACCEPTED_BY_ADMINSTRATIVE,
];
}
public static function successStates(): array
{
return [self::APPROVED];
}
public static function failedStates(): array
{
return [
self::REJECTED,
self::CANCELED,
];
}
public static function filterByStatus(string $filter): array
{
return match ($filter) {
"pending" => VacationRequestState::pendingStates(),
"success" => VacationRequestState::successStates(),
"failed" => VacationRequestState::failedStates(),
default => VacationRequestState::cases(),
};
}
}

View File

@ -5,6 +5,7 @@ declare(strict_types=1);
namespace Toby\Eloquent\Models;
use Database\Factories\VacationRequestFactory;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
@ -54,6 +55,11 @@ class VacationRequest extends Model
$this->save();
}
public function scopeStates(Builder $query, array $states): Builder
{
return $query->whereIn("state", $states);
}
protected static function newFactory(): VacationRequestFactory
{
return VacationRequestFactory::new();

View File

@ -7,6 +7,7 @@ namespace Toby\Infrastructure\Http\Controllers;
use Illuminate\Http\RedirectResponse;
use Illuminate\Http\Request;
use Inertia\Response;
use Toby\Domain\Enums\VacationRequestState;
use Toby\Domain\Enums\VacationType;
use Toby\Domain\VacationRequestStateManager;
use Toby\Domain\Validation\VacationRequestValidator;
@ -19,16 +20,19 @@ class VacationRequestController extends Controller
{
public function index(Request $request): Response
{
$requests = $request->user()
$vacationRequests = $request->user()
->vacationRequests()
->latest()
->states(VacationRequestState::filterByStatus($request->query("status", "all")))
->paginate();
return inertia("VacationRequest/Index", [
"requests" => VacationRequestResource::collection($requests),
"requests" => VacationRequestResource::collection($vacationRequests),
"filters" => $request->only("status"),
]);
}
public function show(Request $request, VacationRequest $vacationRequest): Response
public function show(VacationRequest $vacationRequest): Response
{
return inertia("VacationRequest/Show", [
"request" => new VacationRequestResource($vacationRequest),

View File

@ -284,6 +284,7 @@ export default {
.transform(data => ({
...data,
employmentForm: data.employmentForm.value,
role: data.role.value,
}))
.put(`/users/${this.user.id}`)
},

View File

@ -17,6 +17,17 @@
</div>
</div>
<div class="overflow-x-auto xl:overflow-x-visible overflow-y-auto xl:overflow-y-visible">
<nav class="relative shadow flex divide-x divide-gray-200 border-t border-gray-200">
<InertiaLink
v-for="(status, index) in statuses"
:key="index"
:data="{ status: status.value }"
:class="[status.value === filters.status ? 'text-gray-900' : '', 'text-gray-500 hover:text-gray-700 group relative min-w-0 flex-1 overflow-hidden bg-white py-4 px-4 text-sm font-medium text-center hover:bg-gray-50 focus:z-10']"
>
<span>{{ status.name }}</span>
<span :class="[status.value === filters.status ? 'bg-blumilk-500' : 'bg-transparent', 'absolute inset-x-0 bottom-0 h-0.5']" />
</InertiaLink>
</nav>
<table class="min-w-full divide-y divide-gray-200">
<thead class="bg-gray-50">
<tr>
@ -56,6 +67,7 @@
>
Dni urlopu
</th>
<th scope="col" />
</tr>
</thead>
<tbody class="bg-white divide-y divide-gray-100">
@ -65,12 +77,12 @@
class="hover:bg-blumilk-25"
>
<td class="px-4 py-4 whitespace-nowrap text-sm text-gray-500">
<a
<InertiaLink
:href="`/vacation-requests/${request.id}`"
class="font-semibold text-blumilk-600 hover:text-blumilk-500 hover:underline"
>
{{ request.name }}
</a>
</InertiaLink>
</td>
<td class="px-4 py-4 whitespace-nowrap text-sm text-gray-500">
{{ request.type }}
@ -87,6 +99,11 @@
<td class="px-4 py-4 whitespace-nowrap text-sm text-gray-500">
X
</td>
<td class="px-4 py-4 whitespace-nowrap text-sm text-gray-500">
<InertiaLink :href="`/vacation-requests/${request.id}`">
<ChevronRightIcon class="block w-6 h-6 fill-gray-400" />
</InertiaLink>
</td>
</tr>
<tr
v-if="! requests.data.length"
@ -152,7 +169,7 @@
</template>
<script>
import {DotsVerticalIcon, PencilIcon, TrashIcon} from '@heroicons/vue/solid'
import {ChevronRightIcon, DotsVerticalIcon, PencilIcon, TrashIcon} from '@heroicons/vue/solid'
export default {
name: 'VacationRequestIndex',
@ -160,12 +177,41 @@ export default {
DotsVerticalIcon,
PencilIcon,
TrashIcon,
ChevronRightIcon,
},
props: {
requests: {
type: Object,
default: () => null,
},
filters: {
type: Object,
default: () => null,
},
},
setup() {
const statuses = [
{
name: 'Wszystkie',
value: 'all',
},
{
name: 'W trakcie',
value: 'pending',
},
{
name: 'Zatwierdzone',
value: 'success',
},
{
name: 'Odrzucone/anulowane',
value: 'failed',
},
]
return {
statuses,
}
},
}
</script>