Skip to content

Commit e7ad282

Browse files
authored
Merge pull request #53 from mihaisolomon/feature/timesheet-dashboard
Feature/timesheet dashboard
2 parents 753e3a7 + 261e795 commit e7ad282

6 files changed

Lines changed: 178 additions & 41 deletions

File tree

app/Filament/Pages/TimesheetDashboard.php

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44

55
use App\Filament\Widgets\Timesheet\ActivitiesReport;
66
use App\Filament\Widgets\Timesheet\MonthlyReport;
7+
use App\Filament\Widgets\Timesheet\WeeklyReport;
78
use Filament\Pages\Page;
89

910
class TimesheetDashboard extends Page
@@ -35,7 +36,8 @@ protected function getWidgets(): array
3536
{
3637
return [
3738
MonthlyReport::class,
38-
ActivitiesReport::class
39+
ActivitiesReport::class,
40+
WeeklyReport::class
3941
];
4042
}
4143
}

app/Filament/Widgets/Timesheet/MonthlyReport.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,7 @@ protected function filter(User $user, array $params)
7777
DB::raw("YEAR(created_at)=" . (is_null($params['year']) ? Carbon::now()->format('Y') : $params['year']))
7878
)
7979
->where('user_id', $user->id)
80-
->groupBy(DB::raw("DATE_FORMAT (created_at, '%m')"))
80+
->groupBy(DB::raw("DATE_FORMAT(created_at,'%m')"))
8181
->get();
8282
}
8383

Lines changed: 101 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,101 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace App\Filament\Widgets\Timesheet;
6+
7+
use App\Models\TicketHour;
8+
use App\Models\User;
9+
use Carbon\Carbon;
10+
use Carbon\CarbonPeriod;
11+
use Filament\Widgets\BarChartWidget;
12+
use Illuminate\Database\Eloquent\Collection;
13+
use Illuminate\Support\Facades\DB;
14+
15+
class WeeklyReport extends BarChartWidget
16+
{
17+
protected int|string|array $columnSpan = [
18+
'sm' => 1,
19+
'md' => 6,
20+
'lg' => 3
21+
];
22+
23+
protected function getData(): array
24+
{
25+
$now = Carbon::now();
26+
27+
$weekStartDate = $now->startOfWeek()->format('Y-m-d');
28+
$weekEndDate = $now->endOfWeek()->format('Y-m-d');
29+
30+
$collection = $this->filter(auth()->user(), [
31+
'year' => null,
32+
'weekStartDate' => $weekStartDate,
33+
'weekEndDate' => $weekEndDate
34+
]);
35+
36+
$dates = $this->buildDatesRange($weekStartDate, $weekEndDate);
37+
38+
$datasets = $this->buildRapport($collection, $dates);
39+
40+
return [
41+
'datasets' => [
42+
[
43+
'label' => __('Weekly time logged'),
44+
'data' => $datasets,
45+
'backgroundColor' => [
46+
'rgba(54, 162, 235, .6)'
47+
],
48+
'borderColor' => [
49+
'rgba(54, 162, 235, .8)'
50+
],
51+
],
52+
],
53+
'labels' => $dates,
54+
];
55+
}
56+
57+
protected function buildRapport(Collection $collection, array $dates): array
58+
{
59+
$template = $this->createReportTemplate($dates);
60+
foreach ($collection as $item) {
61+
$template[$item->day]['value'] = $item->value;
62+
}
63+
return collect($template)->pluck('value')->toArray();
64+
}
65+
66+
protected function filter(User $user, array $params)
67+
{
68+
return TicketHour::select([
69+
DB::raw("DATE_FORMAT(created_at,'%Y-%m-%d') as day"),
70+
DB::raw('SUM(value) as value'),
71+
])
72+
->whereBetween('created_at', [$params['weekStartDate'], $params['weekEndDate']])
73+
->whereRaw(
74+
DB::raw("YEAR(created_at)=" . (is_null($params['year']) ? Carbon::now()->format('Y') : $params['year']))
75+
)
76+
->where('user_id', $user->id)
77+
->groupBy(DB::raw("DATE_FORMAT(created_at,'%Y-%m-%d')"))
78+
->get();
79+
}
80+
81+
protected function buildDatesRange($weekStartDate, $weekEndDate): array
82+
{
83+
$period = CarbonPeriod::create($weekStartDate, $weekEndDate);
84+
85+
$dates = [];
86+
foreach ($period as $item) {
87+
$dates[] = $item->format('Y-m-d');
88+
}
89+
90+
return $dates;
91+
}
92+
93+
protected function createReportTemplate(array $dates): array
94+
{
95+
$template = [];
96+
foreach ($dates as $date) {
97+
$template[$date]['value'] = 0;
98+
}
99+
return $template;
100+
}
101+
}
Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace App\Http\Livewire\Timesheet;
6+
7+
use App\Models\Ticket;
8+
use Filament\Tables;
9+
use Filament\Tables\Concerns\InteractsWithTable;
10+
use Filament\Tables\Contracts\HasTable;
11+
use Illuminate\Database\Eloquent\Builder;
12+
use Illuminate\Database\Eloquent\Model;
13+
use Livewire\Component;
14+
15+
class TimeLogged extends Component implements HasTable
16+
{
17+
use InteractsWithTable;
18+
19+
public Ticket $ticket;
20+
21+
protected function getFormModel(): Model|string|null
22+
{
23+
return $this->ticket;
24+
}
25+
26+
protected function getTableQuery(): Builder
27+
{
28+
return $this->ticket->hours()->getQuery();
29+
}
30+
31+
protected function getTableColumns(): array
32+
{
33+
return [
34+
Tables\Columns\TextColumn::make('user.name')
35+
->label(__('Owner'))
36+
->sortable()
37+
->formatStateUsing(fn($record) => view('components.user-avatar', ['user' => $record->user]))
38+
->searchable(),
39+
40+
Tables\Columns\TextColumn::make('value')
41+
->label(__('Hours'))
42+
->sortable()
43+
->searchable(),
44+
Tables\Columns\TextColumn::make('comment')
45+
->label(__('Comment'))
46+
->limit(50)
47+
->sortable()
48+
->searchable(),
49+
50+
Tables\Columns\TextColumn::make('activity.name')
51+
->label(__('Activity'))
52+
->sortable(),
53+
54+
Tables\Columns\TextColumn::make('ticket.name')
55+
->label(__('Ticket'))
56+
->sortable(),
57+
58+
Tables\Columns\TextColumn::make('created_at')
59+
->label(__('Created at'))
60+
->dateTime()
61+
->sortable()
62+
->searchable(),
63+
];
64+
}
65+
}

resources/views/filament/resources/tickets/view.blade.php

Lines changed: 1 addition & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -323,45 +323,7 @@ class="text-danger-500 text-xs hover:text-danger-600 hover:underline">
323323
</div>
324324
@endif
325325
@if($tab === 'time')
326-
<div class="w-full flex flex-col pt-5">
327-
@if($record->hours->count())
328-
@foreach($record->hours->sortByDesc('created_at') as $item)
329-
<div class="w-full flex flex-col gap-2
330-
@if(!$loop->last) pb-5 mb-5 border-b border-gray-200 @endif">
331-
<span class="flex items-center gap-1 text-gray-500 text-sm">
332-
<span class="font-medium flex items-center gap-1">
333-
<x-user-avatar :user="$item->user"/>
334-
{{ $item->user->name }}
335-
</span>
336-
<span class="text-gray-400 px-2">|</span>
337-
{{ $item->created_at->format('Y-m-d g:i A') }}
338-
({{ $item->created_at->diffForHumans() }})
339-
</span>
340-
<div class="w-full flex items-center gap-1">
341-
<span class="text-gray-400">{{ __('Logged:') }}</span>
342-
<span class="text-primary-500 font-medium">
343-
{{ $item->forHumans }}
344-
</span>
345-
</div>
346-
<div class="w-full flex items-center gap-1">
347-
<span class="text-gray-400">{{ __('Activity:') }}</span>
348-
<span class="text-primary-500 font-medium">
349-
{{ $item->activity ? $item->activity->name : '-' }}
350-
</span>
351-
</div>
352-
@if($item->comment)
353-
<div class="w-full">
354-
{!! nl2br(e($item->comment)) !!}
355-
</div>
356-
@endif
357-
</div>
358-
@endforeach
359-
@else
360-
<span class="text-gray-400 text-sm font-medium">
361-
{{ __('No time logged yet!') }}
362-
</span>
363-
@endif
364-
</div>
326+
<livewire:timesheet.time-logged :ticket="$record" />
365327
@endif
366328
@if($tab === 'attachments')
367329
<livewire:ticket.attachments :ticket="$record" />
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
<div class="w-full flex flex-col gap-5">
2+
<div class="w-full flex flex-col gap-1 pt-3">
3+
<div class="w-full">
4+
{{ $this->table }}
5+
</div>
6+
</div>
7+
</div>

0 commit comments

Comments
 (0)