Add a translation assistant to the panel
Each field's original sits beside the field to write, and a translation that fell behind shows what the original said when it was translated and what it says now, word by word. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -5,16 +5,9 @@ declare(strict_types=1);
|
||||
namespace App\Http\Controllers\Api\V1;
|
||||
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Models\Call;
|
||||
use App\Models\Page;
|
||||
use App\Models\Project;
|
||||
use App\Models\Service;
|
||||
use App\Support\AdminContent;
|
||||
use App\Support\ContentTypes;
|
||||
use App\Support\Health\Finding;
|
||||
use App\Support\Health\HealthReport;
|
||||
use App\Support\TranslationFreshness;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use App\Support\PendingTranslations;
|
||||
use Illuminate\Http\JsonResponse;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Validation\Rule;
|
||||
@@ -25,13 +18,6 @@ use Illuminate\Validation\Rule;
|
||||
*/
|
||||
class HealthController extends Controller
|
||||
{
|
||||
/**
|
||||
* The kinds of content written in several languages and checked for it.
|
||||
*
|
||||
* @var array<int, class-string<Model>>
|
||||
*/
|
||||
protected const TRANSLATED = [Page::class, Project::class, Service::class, Call::class];
|
||||
|
||||
/**
|
||||
* Every check the caller may see, problems first. A check behind a
|
||||
* permission they lack is left out, as on the panel.
|
||||
@@ -77,52 +63,18 @@ class HealthController extends Controller
|
||||
'published' => ['sometimes', 'boolean'],
|
||||
]);
|
||||
|
||||
$wanted = $request->input('locale');
|
||||
$items = collect();
|
||||
|
||||
foreach (self::TRANSLATED as $model) {
|
||||
$type = AdminContent::nameOf(new $model);
|
||||
|
||||
if ($request->filled('type') && $request->input('type') !== $type) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if ($request->user()->cannot('viewAny', $model)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$model::query()
|
||||
->when($request->boolean('published'), fn ($q) => $model === Call::class ? $q->open() : $q->published())
|
||||
->with('revisions')
|
||||
->get()
|
||||
->each(function (Model $record) use ($locales, $wanted, $type, $items): void {
|
||||
$missing = array_values(array_filter(
|
||||
$locales,
|
||||
fn (string $locale) => blank($record->getTranslation('title', $locale, false)),
|
||||
));
|
||||
|
||||
$stale = collect(TranslationFreshness::for($record))
|
||||
->map(fn ($since) => $since->toIso8601String())
|
||||
->all();
|
||||
|
||||
if ($wanted !== null) {
|
||||
$missing = array_values(array_intersect($missing, [$wanted]));
|
||||
$stale = array_intersect_key($stale, [$wanted => true]);
|
||||
}
|
||||
|
||||
if ($missing === [] && $stale === []) {
|
||||
return;
|
||||
}
|
||||
|
||||
$items->push([
|
||||
'type' => $type,
|
||||
'id' => $record->getKey(),
|
||||
'title' => ContentTypes::title($record),
|
||||
'missing' => $missing,
|
||||
'stale' => (object) $stale,
|
||||
]);
|
||||
});
|
||||
}
|
||||
$items = PendingTranslations::find(
|
||||
$request->user(),
|
||||
$request->input('locale'),
|
||||
$request->input('type'),
|
||||
$request->boolean('published'),
|
||||
)->map(fn (array $item) => [
|
||||
'type' => $item['type'],
|
||||
'id' => $item['id'],
|
||||
'title' => $item['title'],
|
||||
'missing' => $item['missing'],
|
||||
'stale' => (object) collect($item['stale'])->map(fn ($since) => $since->toIso8601String())->all(),
|
||||
]);
|
||||
|
||||
return response()->json(['data' => $items->values()]);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user