Merge remote-tracking branch 'origin/next' into api-sensitive-data-scrubber

This commit is contained in:
Andras Bacsai
2026-06-04 15:27:32 +02:00
16 changed files with 1071 additions and 142 deletions
@@ -4,6 +4,7 @@ namespace App\Console\Commands\Generate;
use Illuminate\Console\Command;
use Illuminate\Support\Arr;
use Illuminate\Support\Facades\Process;
use Symfony\Component\Yaml\Yaml;
class Services extends Command
@@ -77,6 +78,7 @@ class Services extends Command
'category' => $data->get('category'),
'logo' => $data->get('logo', 'svgs/default.webp'),
'minversion' => $data->get('minversion', '0.0.0'),
'template_last_updated_at' => $this->templateLastUpdatedAt($file),
];
if ($port = $data->get('port')) {
@@ -99,6 +101,26 @@ class Services extends Command
return $payload;
}
private function templateLastUpdatedAt(string $file): ?string
{
$process = Process::path(base_path())->run([
'git',
'log',
'-1',
'--format=%cI',
'--',
"templates/compose/{$file}",
]);
if ($process->failed()) {
return null;
}
$timestamp = trim($process->output());
return $timestamp === '' ? null : $timestamp;
}
private function generateServiceTemplatesWithFqdn(): void
{
$serviceTemplatesWithFqdn = collect(array_merge(
@@ -155,6 +177,7 @@ class Services extends Command
'category' => $data->get('category'),
'logo' => $data->get('logo', 'svgs/default.webp'),
'minversion' => $data->get('minversion', '0.0.0'),
'template_last_updated_at' => $this->templateLastUpdatedAt($file),
];
if ($port = $data->get('port')) {
@@ -232,6 +255,7 @@ class Services extends Command
'category' => $data->get('category'),
'logo' => $data->get('logo', 'svgs/default.webp'),
'minversion' => $data->get('minversion', '0.0.0'),
'template_last_updated_at' => $this->templateLastUpdatedAt($file),
];
if ($port = $data->get('port')) {
+8
View File
@@ -1053,6 +1053,7 @@ class GlobalSearch extends Component
'quickcommand' => '(type: new postgresql)',
'type' => 'postgresql',
'category' => 'Databases',
'logo' => 'svgs/postgresql.svg',
'resourceType' => 'database',
]);
@@ -1062,6 +1063,7 @@ class GlobalSearch extends Component
'quickcommand' => '(type: new mysql)',
'type' => 'mysql',
'category' => 'Databases',
'logo' => 'svgs/mysql.svg',
'resourceType' => 'database',
]);
@@ -1071,6 +1073,7 @@ class GlobalSearch extends Component
'quickcommand' => '(type: new mariadb)',
'type' => 'mariadb',
'category' => 'Databases',
'logo' => 'svgs/mariadb.svg',
'resourceType' => 'database',
]);
@@ -1080,6 +1083,7 @@ class GlobalSearch extends Component
'quickcommand' => '(type: new redis)',
'type' => 'redis',
'category' => 'Databases',
'logo' => 'svgs/redis.svg',
'resourceType' => 'database',
]);
@@ -1089,6 +1093,7 @@ class GlobalSearch extends Component
'quickcommand' => '(type: new keydb)',
'type' => 'keydb',
'category' => 'Databases',
'logo' => 'svgs/keydb.svg',
'resourceType' => 'database',
]);
@@ -1098,6 +1103,7 @@ class GlobalSearch extends Component
'quickcommand' => '(type: new dragonfly)',
'type' => 'dragonfly',
'category' => 'Databases',
'logo' => 'svgs/dragonfly.svg',
'resourceType' => 'database',
]);
@@ -1107,6 +1113,7 @@ class GlobalSearch extends Component
'quickcommand' => '(type: new mongodb)',
'type' => 'mongodb',
'category' => 'Databases',
'logo' => 'svgs/mongodb.svg',
'resourceType' => 'database',
]);
@@ -1116,6 +1123,7 @@ class GlobalSearch extends Component
'quickcommand' => '(type: new clickhouse)',
'type' => 'clickhouse',
'category' => 'Databases',
'logo' => 'svgs/clickhouse-icon.svg',
'resourceType' => 'database',
]);
}
+24 -13
View File
@@ -6,7 +6,6 @@ use App\Models\Project;
use App\Models\Server;
use Carbon\CarbonImmutable;
use Illuminate\Support\Collection;
use Illuminate\Support\Facades\Cache;
use Livewire\Component;
class Select extends Component
@@ -107,7 +106,7 @@ class Select extends Component
public function loadServices()
{
$services = get_service_templates();
$templateLastUpdatedMap = $this->serviceTemplateLastUpdatedMap($services->keys());
$templateLastUpdatedMap = $this->serviceTemplateLastUpdatedMap($services);
$services = collect($services)->map(function ($service, $key) use ($templateLastUpdatedMap) {
$default_logo = 'images/default.webp';
@@ -279,19 +278,31 @@ class Select extends Component
return $this->formatLastModified($this->serviceTemplatesPath());
}
private function serviceTemplateLastUpdatedMap(Collection $serviceNames): array
private function serviceTemplateLastUpdatedMap(Collection $services): array
{
$bundleMtime = file_exists($this->serviceTemplatesPath()) ? filemtime($this->serviceTemplatesPath()) : 0;
return $services
->mapWithKeys(fn ($service, $serviceName) => [
(string) $serviceName => $this->serviceTemplateLastUpdatedFromPayload($service)
?? $this->serviceTemplateLastUpdated((string) $serviceName),
])
->all();
}
return Cache::remember(
"service-template-last-updated-map:{$bundleMtime}",
now()->addDay(),
fn () => $serviceNames
->mapWithKeys(fn ($serviceName) => [
(string) $serviceName => $this->serviceTemplateLastUpdated((string) $serviceName),
])
->all()
);
private function serviceTemplateLastUpdatedFromPayload(mixed $service): ?string
{
$timestamp = data_get($service, 'template_last_updated_at');
if (! is_string($timestamp) || $timestamp === '') {
return null;
}
try {
return CarbonImmutable::parse($timestamp)
->timezone(config('app.timezone'))
->format('M j, Y H:i');
} catch (\Throwable) {
return null;
}
}
private function serviceTemplateLastUpdated(string $serviceName): ?string