Skip to content

Commit cf590f8

Browse files
committed
Add System Health Dashboard and Refactor Issues Metrics
1 parent 1835c9c commit cf590f8

File tree

7 files changed

+200
-51
lines changed

7 files changed

+200
-51
lines changed

app/Helpers/Api.php

+45
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
<?php
2+
3+
namespace App\Helpers;
4+
5+
use Symfony\Component\Process\Process;
6+
use GuzzleHttp\Client;
7+
8+
class Api
9+
{
10+
public static function getSentryUnreolvedIssues()
11+
{
12+
$organization = config('app.sentry_organization');
13+
$project = config('app.sentry_project');
14+
$token = config('app.sentry_token');
15+
16+
$client = new Client;
17+
try {
18+
$response = $client->request('GET', "https://sentry.io/api/0/projects/$organization/$project/issues/", [
19+
'headers' => [
20+
'Authorization' => "Bearer $token",
21+
],
22+
'query' => [
23+
'query' => 'is:unresolved',
24+
],
25+
]);
26+
return json_decode($response->getBody()->getContents(), true);
27+
} catch (\Exception $e) {
28+
return [];
29+
}
30+
}
31+
32+
public static function getComposerOutdatedPackages($flag = '--no-dev')
33+
{
34+
$composer = config('app.composer');
35+
$home = config('app.composer_home');
36+
$process = Process::fromShellCommandline("$composer outdated $flag -f json", base_path(), ['COMPOSER_HOME' => $home]);
37+
$process->run();
38+
$value = $process->getOutput();
39+
$data = json_decode($value, true);
40+
$process = Process::fromShellCommandline("$composer clear-cache", base_path(), ['COMPOSER_HOME' => $home]);
41+
$process->run();
42+
43+
return $data['installed'] ?? [];
44+
}
45+
}

app/Nova/Dashboards/Main.php

-16
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,6 @@
44

55
use App\Helpers\Helper;
66
use App\Helpers\Inspiring;
7-
use App\Helpers\Policy;
8-
use App\Nova\Metrics\Issues;
9-
use App\Nova\Metrics\ServerResource;
107
use Illuminate\Support\Facades\Auth;
118
use Illuminate\Support\Facades\Storage;
129
use Laravel\Nova\Dashboards\Main as Dashboard;
@@ -66,19 +63,6 @@ public function cards()
6663
->addItem(icon: 'calendar', title: 'Kalender Kegiatan', content: 'Fitur yang menampilkan kalender kegiatan,deadline dan tanggal penting lainnya. Selain itu juga mengirimkan reminder deadline kegiatan melalui Whatsapp (Aktualisasi Latsar Ilman Mimin Maulana)')
6764
->addItem(icon: 'document-chart-bar', title: 'Pengelolaan SAKIP', content: 'Fitur untuk pencatatan realisasi kinerja, kendala dan solusi, rencana dan pelaksanaan tindak lanjut dalam rangka pencapaian target kinerja.'),
6865
];
69-
if (Policy::make()->allowedFor('admin')->get()) {
70-
$cards[] = ServerResource::make()
71-
->width('1/2');
72-
73-
$cards[] = ServerResource::make('inode')
74-
->width('1/2');
75-
76-
$cards[] = Issues::make('outdated')
77-
->width('1/2');
78-
79-
$cards[] = Issues::make()
80-
->width('1/2');
81-
}
8266

8367
return $cards;
8468
}

app/Nova/Dashboards/SystemHealth.php

+45
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
<?php
2+
3+
namespace App\Nova\Dashboards;
4+
5+
use App\Helpers\Api;
6+
use App\Nova\Metrics\Issues;
7+
use App\Nova\Metrics\IssuesTable;
8+
use App\Nova\Metrics\OutdatedTable;
9+
use App\Nova\Metrics\ServerResource;
10+
use Laravel\Nova\Dashboard;
11+
use Laravelwebdev\Welcome\Welcome;
12+
13+
class SystemHealth extends Dashboard
14+
{
15+
/**
16+
* Get the cards for the dashboard.
17+
*
18+
* @return array<int, \Laravel\Nova\Card>
19+
*/
20+
public function cards(): array
21+
{
22+
$sentryIssues = Api::getSentryUnreolvedIssues();
23+
$outdatedPackages = Api::getComposerOutdatedPackages();
24+
25+
return [
26+
ServerResource::make(),
27+
ServerResource::make('inode'),
28+
Issues::make(count($sentryIssues)),
29+
Welcome::make()
30+
->title('Packages and Issues'),
31+
OutdatedTable::make($outdatedPackages)->width('1/2')
32+
->emptyText('All packages is up to date.'),
33+
IssuesTable::make($sentryIssues)->width('1/2')
34+
->emptyText('No issues found.'),
35+
];
36+
}
37+
38+
/**
39+
* Get the URI key for the dashboard.
40+
*/
41+
public function uriKey(): string
42+
{
43+
return 'system-health';
44+
}
45+
}

app/Nova/Metrics/Issues.php

+5-34
Original file line numberDiff line numberDiff line change
@@ -6,15 +6,17 @@
66
use Laravel\Nova\Http\Requests\NovaRequest;
77
use Laravel\Nova\Metrics\Value;
88
use Laravel\Nova\Metrics\ValueResult;
9-
use Symfony\Component\Process\Process;
109

1110
class Issues extends Value
1211
{
1312
private $type;
1413

15-
public function __construct($type = 'issues')
14+
private $value;
15+
16+
public function __construct($value, $type = 'issues')
1617
{
1718
$this->type = $type;
19+
$this->value = $value;
1820
}
1921

2022
public function name()
@@ -27,38 +29,7 @@ public function name()
2729
*/
2830
public function calculate(NovaRequest $request): ValueResult
2931
{
30-
if ($this->type === 'outdated') {
31-
$composer = config('app.composer');
32-
$home = config('app.composer_home');
33-
$devFlag = '--no-dev';
34-
$process = Process::fromShellCommandline("$composer outdated $devFlag -f json", base_path(), ['COMPOSER_HOME' => $home]);
35-
$process->run();
36-
$value = $process->getOutput();
37-
$data = json_decode($value, true);
38-
$count = count($data['installed'] ?? []);
39-
$process = Process::fromShellCommandline("$composer clear-cache", base_path(), ['COMPOSER_HOME' => $home]);
40-
$process->run();
41-
} else {
42-
//
43-
$organization = config('app.sentry_organization');
44-
$project = config('app.sentry_project');
45-
$token = config('app.sentry_token');
46-
47-
$client = new \GuzzleHttp\Client;
48-
$response = $client->request('GET', "https://sentry.io/api/0/projects/$organization/$project/issues/", [
49-
'headers' => [
50-
'Authorization' => "Bearer $token",
51-
],
52-
'query' => [
53-
'query' => 'is:unresolved',
54-
],
55-
]);
56-
57-
$data = json_decode($response->getBody()->getContents(), true);
58-
$count = count($data);
59-
}
60-
61-
return $this->result($count);
32+
return $this->result((float) $this->value);
6233
}
6334

6435
/**

app/Nova/Metrics/IssuesTable.php

+50
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
<?php
2+
3+
namespace App\Nova\Metrics;
4+
5+
use DateTimeInterface;
6+
use Laravel\Nova\Http\Requests\NovaRequest;
7+
use Laravel\Nova\Metrics\MetricTableRow;
8+
use Laravel\Nova\Metrics\Table;
9+
10+
class IssuesTable extends Table
11+
{
12+
private $data;
13+
14+
public function __construct($data = [])
15+
{
16+
$this->data = $data;
17+
}
18+
19+
public function name(): string
20+
{
21+
return 'Issues' . ' (' . count($this->data) . ')';
22+
}
23+
/**
24+
* Calculate the value of the metric.
25+
*
26+
* @return array<int, \Laravel\Nova\Metrics\MetricTableRow>
27+
*/
28+
public function calculate(NovaRequest $request): array
29+
{
30+
$rows = [];
31+
foreach ($this->data as $issue) {
32+
$rows[] = MetricTableRow::make()
33+
->icon($issue['level'] === 'error' ? 'x-circle' : 'exclamation-circle')
34+
->iconClass($issue['level'] === 'error' ? 'text-red-500' : 'text-yellow-500')
35+
->title(ucwords($issue['type']) . ' (' . $issue['count'] . ')')
36+
->subtitle($issue['title']);
37+
}
38+
return $rows;
39+
}
40+
41+
/**
42+
* Determine the amount of time the results of the metric should be cached.
43+
*/
44+
public function cacheFor(): DateTimeInterface|null
45+
{
46+
// return now()->addMinutes(5);
47+
48+
return null;
49+
}
50+
}

app/Nova/Metrics/OutdatedTable.php

+50
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
<?php
2+
3+
namespace App\Nova\Metrics;
4+
5+
use DateTimeInterface;
6+
use Laravel\Nova\Http\Requests\NovaRequest;
7+
use Laravel\Nova\Metrics\MetricTableRow;
8+
use Laravel\Nova\Metrics\Table;
9+
10+
class OutdatedTable extends Table
11+
{
12+
private $data;
13+
14+
public function __construct($data = [])
15+
{
16+
$this->data = $data;
17+
}
18+
19+
public function name(): string
20+
{
21+
return 'Outdated Packages' . ' (' . count($this->data) . ')';
22+
}
23+
/**
24+
* Calculate the value of the metric.
25+
*
26+
* @return array<int, \Laravel\Nova\Metrics\MetricTableRow>
27+
*/
28+
public function calculate(NovaRequest $request): array
29+
{
30+
$rows = [];
31+
foreach ($this->data as $package) {
32+
$rows[] = MetricTableRow::make()
33+
->icon('exclamation-circle')
34+
->iconClass('text-yellow-500')
35+
->title($package['name'])
36+
->subtitle('Installed: '.$package['version'].' | Latest: '.$package['latest']);
37+
}
38+
return $rows;
39+
}
40+
41+
/**
42+
* Determine the amount of time the results of the metric should be cached.
43+
*/
44+
public function cacheFor(): DateTimeInterface|null
45+
{
46+
// return now()->addMinutes(5);
47+
48+
return null;
49+
}
50+
}

app/Providers/NovaServiceProvider.php

+5-1
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
use App\Nova\DaftarReminder;
1313
use App\Nova\DaftarSp2d;
1414
use App\Nova\Dashboards\Main;
15+
use App\Nova\Dashboards\SystemHealth;
1516
use App\Nova\Dipa;
1617
use App\Nova\DokumentasiKegiatan;
1718
use App\Nova\DokumentasiLink;
@@ -268,7 +269,10 @@ protected function fortify(): void
268269
protected function dashboards()
269270
{
270271
return [
271-
new \App\Nova\Dashboards\Main,
272+
Main::make(),
273+
SystemHealth::make()->canSee(fn () => Policy::make()
274+
->allowedFor('admin')
275+
->get()),
272276
];
273277
}
274278

0 commit comments

Comments
 (0)