Skip to content

Commit 57340b8

Browse files
authored
feat(37): improved admin panel (#4312)
1 parent a69b0b3 commit 57340b8

649 files changed

Lines changed: 51108 additions & 47480 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

app/Actions/InstallUpdate/CheckUpdate.php

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,4 +66,24 @@ public function getCode(): UpdateStatus
6666
}
6767
// @codeCoverageIgnoreEnd
6868
}
69+
70+
/**
71+
* Return the latest known release version from the remote update feed.
72+
*
73+
* @codeCoverageIgnore
74+
*/
75+
public function getLatestVersion(): ?string
76+
{
77+
return $this->file_version->remote_version?->toString();
78+
}
79+
80+
/**
81+
* Return the current installed file version.
82+
*
83+
* @codeCoverageIgnore
84+
*/
85+
public function getCurrentVersion(): string
86+
{
87+
return $this->file_version->getVersion()->toString();
88+
}
6989
}

app/DTO/AdminStatsOverview.php

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
<?php
2+
3+
/**
4+
* SPDX-License-Identifier: MIT
5+
* Copyright (c) 2017-2018 Tobias Reich
6+
* Copyright (c) 2018-2026 LycheeOrg.
7+
*/
8+
9+
namespace App\DTO;
10+
11+
/**
12+
* Immutable value object returned by AdminStatsService.
13+
*/
14+
class AdminStatsOverview
15+
{
16+
public function __construct(
17+
public readonly int $photos_count,
18+
public readonly int $albums_count,
19+
public readonly int $users_count,
20+
public readonly int $storage_bytes,
21+
public readonly int $queued_jobs,
22+
public readonly int $failed_jobs_24h,
23+
public readonly ?string $last_successful_job_at,
24+
public readonly string $cached_at,
25+
/** @var string[] */
26+
public readonly array $errors,
27+
) {
28+
}
29+
}
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
<?php
2+
3+
/**
4+
* SPDX-License-Identifier: MIT
5+
* Copyright (c) 2017-2018 Tobias Reich
6+
* Copyright (c) 2018-2026 LycheeOrg.
7+
*/
8+
9+
namespace App\Http\Controllers\Admin;
10+
11+
use App\Http\Requests\Admin\AdminStatsRequest;
12+
use App\Http\Resources\Models\AdminStatsResource;
13+
use App\Services\AdminStatsService;
14+
use Illuminate\Routing\Controller;
15+
16+
class AdminDashboardController extends Controller
17+
{
18+
public function __construct(private AdminStatsService $service)
19+
{
20+
}
21+
22+
public function stats(AdminStatsRequest $request): AdminStatsResource
23+
{
24+
$force = $request->boolean('force');
25+
$overview = $this->service->getOverview($force);
26+
27+
return AdminStatsResource::fromOverview($overview);
28+
}
29+
}
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
<?php
2+
3+
/**
4+
* SPDX-License-Identifier: MIT
5+
* Copyright (c) 2017-2018 Tobias Reich
6+
* Copyright (c) 2018-2026 LycheeOrg.
7+
*/
8+
9+
namespace App\Http\Controllers\Admin;
10+
11+
use App\Actions\InstallUpdate\CheckUpdate;
12+
use App\Assets\Features;
13+
use App\Http\Requests\Admin\AdminUpdateStatusRequest;
14+
use App\Http\Resources\Models\AdminUpdateStatusResource;
15+
use Illuminate\Routing\Controller;
16+
17+
class AdminUpdateStatusController extends Controller
18+
{
19+
public function __construct(private CheckUpdate $check_update)
20+
{
21+
}
22+
23+
/**
24+
* Return update status information for the current installation.
25+
*/
26+
public function show(AdminUpdateStatusRequest $_request): AdminUpdateStatusResource
27+
{
28+
if (Features::inactive('update-check')) {
29+
return AdminUpdateStatusResource::disabled();
30+
}
31+
32+
$update_status = $this->check_update->getCode();
33+
34+
return AdminUpdateStatusResource::fromUpdateStatus(
35+
$update_status,
36+
$this->check_update->getCurrentVersion(),
37+
$this->check_update->getLatestVersion(),
38+
);
39+
}
40+
}
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
<?php
2+
3+
/**
4+
* SPDX-License-Identifier: MIT
5+
* Copyright (c) 2017-2018 Tobias Reich
6+
* Copyright (c) 2018-2026 LycheeOrg.
7+
*/
8+
9+
namespace App\Http\Requests\Admin;
10+
11+
use App\Http\Requests\BaseApiRequest;
12+
use App\Models\Configs;
13+
use App\Policies\SettingsPolicy;
14+
use Illuminate\Support\Facades\Gate;
15+
16+
class AdminStatsRequest extends BaseApiRequest
17+
{
18+
public function authorize(): bool
19+
{
20+
return Gate::check(SettingsPolicy::CAN_EDIT, [Configs::class]);
21+
}
22+
23+
public function rules(): array
24+
{
25+
return [
26+
'force' => 'sometimes|boolean',
27+
];
28+
}
29+
30+
protected function processValidatedValues(array $values, array $files): void
31+
{
32+
}
33+
}
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
<?php
2+
3+
/**
4+
* SPDX-License-Identifier: MIT
5+
* Copyright (c) 2017-2018 Tobias Reich
6+
* Copyright (c) 2018-2026 LycheeOrg.
7+
*/
8+
9+
namespace App\Http\Requests\Admin;
10+
11+
use App\Http\Requests\AbstractEmptyRequest;
12+
use App\Models\Configs;
13+
use App\Policies\SettingsPolicy;
14+
use Illuminate\Support\Facades\Gate;
15+
16+
class AdminUpdateStatusRequest extends AbstractEmptyRequest
17+
{
18+
public function authorize(): bool
19+
{
20+
return Gate::check(SettingsPolicy::CAN_EDIT, [Configs::class]);
21+
}
22+
}

app/Http/Resources/GalleryConfigs/InitConfig.php

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -147,6 +147,8 @@ class InitConfig extends Data
147147
public AlbumHeaderSize $album_header_size;
148148
public bool $is_album_header_landing_title_enabled;
149149

150+
public bool $use_admin_dashboard;
151+
150152
public function __construct()
151153
{
152154
// Debug mode
@@ -251,6 +253,7 @@ public function __construct()
251253
$this->is_album_enhanced_display_enabled = request()->configs()->getValueAsBool('album_enhanced_display_enabled');
252254
$this->album_header_size = request()->configs()->getValueAsEnum('album_header_size', AlbumHeaderSize::class);
253255
$this->is_album_header_landing_title_enabled = request()->configs()->getValueAsBool('album_header_landing_title_enabled');
256+
$this->use_admin_dashboard = request()->configs()->getValueAsBool('use_admin_dashboard');
254257

255258
$this->set_supporter_properties();
256259
}
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
<?php
2+
3+
/**
4+
* SPDX-License-Identifier: MIT
5+
* Copyright (c) 2017-2018 Tobias Reich
6+
* Copyright (c) 2018-2026 LycheeOrg.
7+
*/
8+
9+
namespace App\Http\Resources\Models;
10+
11+
use App\DTO\AdminStatsOverview;
12+
use Spatie\LaravelData\Data;
13+
use Spatie\TypeScriptTransformer\Attributes\TypeScript;
14+
15+
#[TypeScript()]
16+
class AdminStatsResource extends Data
17+
{
18+
public int $photos_count;
19+
public int $albums_count;
20+
public int $users_count;
21+
public int $storage_bytes;
22+
public int $queued_jobs;
23+
public int $failed_jobs_24h;
24+
public ?string $last_successful_job_at;
25+
public string $cached_at;
26+
/** @var string[] */
27+
public array $errors;
28+
29+
public static function fromOverview(AdminStatsOverview $o): self
30+
{
31+
$resource = new self();
32+
$resource->photos_count = $o->photos_count;
33+
$resource->albums_count = $o->albums_count;
34+
$resource->users_count = $o->users_count;
35+
$resource->storage_bytes = $o->storage_bytes;
36+
$resource->queued_jobs = $o->queued_jobs;
37+
$resource->failed_jobs_24h = $o->failed_jobs_24h;
38+
$resource->last_successful_job_at = $o->last_successful_job_at;
39+
$resource->cached_at = $o->cached_at;
40+
$resource->errors = $o->errors;
41+
42+
return $resource;
43+
}
44+
}
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
<?php
2+
3+
/**
4+
* SPDX-License-Identifier: MIT
5+
* Copyright (c) 2017-2018 Tobias Reich
6+
* Copyright (c) 2018-2026 LycheeOrg.
7+
*/
8+
9+
namespace App\Http\Resources\Models;
10+
11+
use App\Enum\UpdateStatus;
12+
use Spatie\LaravelData\Data;
13+
use Spatie\TypeScriptTransformer\Attributes\TypeScript;
14+
15+
#[TypeScript()]
16+
class AdminUpdateStatusResource extends Data
17+
{
18+
public function __construct(
19+
public bool $enabled,
20+
public ?int $update_status,
21+
public bool $has_update,
22+
public ?string $current_version,
23+
public ?string $latest_version,
24+
) {
25+
}
26+
27+
public static function disabled(): self
28+
{
29+
return new self(
30+
enabled: false,
31+
update_status: null,
32+
has_update: false,
33+
current_version: null,
34+
latest_version: null,
35+
);
36+
}
37+
38+
public static function fromUpdateStatus(UpdateStatus $update_status, string $current_version, string $latest_version): self
39+
{
40+
return new self(
41+
enabled: true,
42+
update_status: $update_status->value,
43+
has_update: $update_status === UpdateStatus::NOT_UP_TO_DATE,
44+
current_version: $current_version,
45+
latest_version: $latest_version,
46+
);
47+
}
48+
}

app/Metadata/Cache/RouteCacheManager.php

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -132,6 +132,8 @@ public function __construct()
132132
'api/v2/Users::count' => new RouteCacheConfig(tag: CacheTag::USERS, user_dependant: true),
133133
'api/v2/Version' => false,
134134
'api/v2/ChangeLogs' => false,
135+
'api/v2/Admin/Stats' => false,
136+
'api/v2/Admin/UpdateStatus' => false,
135137

136138
'api/v2/Import' => new RouteCacheConfig(tag: CacheTag::SETTINGS, user_dependant: true),
137139
'api/v2/Import::browse' => false, // This will return a different result each time depending on the directory requested.

0 commit comments

Comments
 (0)