feat(i18n): wrap 1103 hardcoded UI strings across Filament with __()

- Convert static $modelLabel/$pluralModelLabel/$title to getter methods
- Wrap ->label()/->placeholder()/->helperText()/->description()/->title()/->body() args
- Wrap Section::make()/Fieldset::make()/Notification::make()->title() args
- Fix RelationManagers::getTitle() signature to match parent (Model, string)
- Fix Pages::getTitle() to instance method (BasePage::getTitle is non-static)
- Extend lang/ru.json + lang/en.json with 700+ common terms; identity fallback for the rest
- Remove duplicate getters in 5 resources that had manual getModelLabel already

All 306 tests pass. Missing translations fall back to the RO key so the UI never breaks.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-07-15 05:04:24 +00:00
parent 78ff8d4b43
commit f7fc69077b
83 changed files with 4212 additions and 1251 deletions
@@ -19,13 +19,18 @@ class PartsRelationManager extends RelationManager
{
protected static string $relationship = 'parts';
protected static ?string $title = 'Piese';
protected static ?string $title = null;
public static function getTitle(\Illuminate\Database\Eloquent\Model $ownerRecord, string $pageClass): string
{
return __('Piese');
}
public function form(Schema $schema): Schema
{
return $schema->components([
Forms\Components\Select::make('part_id')
->label('Din catalog (lasă gol pentru text liber)')
->label(__('Din catalog (lasă gol pentru text liber)'))
->options(fn () => Part::where('is_active', true)
->get()
->mapWithKeys(fn ($p) => [$p->id => "{$p->name} " . ($p->article ? "[{$p->article}] " : '') . "(stoc: {$p->qty})"])
@@ -43,20 +48,20 @@ class PartsRelationManager extends RelationManager
}
})
->columnSpanFull(),
Forms\Components\TextInput::make('name')->label('Denumire')->required()->columnSpanFull(),
Forms\Components\TextInput::make('article')->label('Cod articol')->maxLength(64),
Forms\Components\TextInput::make('name')->label(__('Denumire'))->required()->columnSpanFull(),
Forms\Components\TextInput::make('article')->label(__('Cod articol'))->maxLength(64),
Forms\Components\TextInput::make('brand')->maxLength(64),
Forms\Components\TextInput::make('qty')->label('Cantitate')->numeric()->default(1)->required(),
Forms\Components\TextInput::make('unit')->label('UM')->maxLength(16)->default('buc'),
Forms\Components\TextInput::make('buy_price')->label('Preț achiziție')->numeric()->default(0),
Forms\Components\TextInput::make('sell_price')->label('Preț vânzare')->numeric()->required(),
Forms\Components\TextInput::make('discount_pct')->label('Discount %')->numeric()->default(0),
Forms\Components\TextInput::make('qty')->label(__('Cantitate'))->numeric()->default(1)->required(),
Forms\Components\TextInput::make('unit')->label(__('UM'))->maxLength(16)->default('buc'),
Forms\Components\TextInput::make('buy_price')->label(__('Preț achiziție'))->numeric()->default(0),
Forms\Components\TextInput::make('sell_price')->label(__('Preț vânzare'))->numeric()->required(),
Forms\Components\TextInput::make('discount_pct')->label(__('Discount %'))->numeric()->default(0),
Forms\Components\Select::make('status')
->options(WorkOrderPart::STATUSES)
->default('needed')
->required()
->helperText('La trecere pe „Montată" se scade automat din stoc.'),
Forms\Components\Textarea::make('notes')->label('Observații')->columnSpanFull()->rows(2),
->helperText(__('La trecere pe „Montată" se scade automat din stoc.')),
Forms\Components\Textarea::make('notes')->label(__('Observații'))->columnSpanFull()->rows(2),
]);
}
@@ -65,11 +70,11 @@ class PartsRelationManager extends RelationManager
return $table
->recordTitleAttribute('name')
->columns([
Tables\Columns\TextColumn::make('name')->label('Piesă')->wrap(),
Tables\Columns\TextColumn::make('article')->label('Cod')->placeholder('—'),
Tables\Columns\TextColumn::make('name')->label(__('Piesă'))->wrap(),
Tables\Columns\TextColumn::make('article')->label(__('Cod'))->placeholder('—'),
Tables\Columns\TextColumn::make('brand')->placeholder('—'),
Tables\Columns\TextColumn::make('qty')->label('Cant.')->alignRight(),
Tables\Columns\TextColumn::make('sell_price')->label('Preț')->money('MDL')->alignRight(),
Tables\Columns\TextColumn::make('qty')->label(__('Cant.'))->alignRight(),
Tables\Columns\TextColumn::make('sell_price')->label(__('Preț'))->money('MDL')->alignRight(),
Tables\Columns\TextColumn::make('total')->money('MDL')->alignRight(),
Tables\Columns\TextColumn::make('status')
->formatStateUsing(fn ($s) => WorkOrderPart::STATUSES[$s] ?? $s)
@@ -86,11 +91,11 @@ class PartsRelationManager extends RelationManager
])
->actions([
Actions\Action::make('smart_price')
->label('Preț inteligent')
->label(__('Preț inteligent'))
->icon('heroicon-m-sparkles')
->color('primary')
->visible(fn (WorkOrderPart $r) => (bool) $r->part_id)
->modalHeading('Preț contextual')
->modalHeading(__('Preț contextual'))
->modalSubmitActionLabel('Aplică prețul')
->modalContent(function (WorkOrderPart $r) {
$wo = $r->workOrder;
@@ -112,7 +117,7 @@ class PartsRelationManager extends RelationManager
->success()->send();
}),
Actions\Action::make('issue_now')
->label('Eliberează')
->label(__('Eliberează'))
->icon('heroicon-m-arrow-up-on-square')
->color('warning')
->visible(fn (WorkOrderPart $r) => $r->part_id
@@ -128,7 +133,7 @@ class PartsRelationManager extends RelationManager
->success()->send();
}),
Actions\Action::make('return_part')
->label('Restituire')
->label(__('Restituire'))
->icon('heroicon-m-arrow-uturn-left')
->color('gray')
->visible(fn (WorkOrderPart $r) => $r->part_id
@@ -137,12 +142,12 @@ class PartsRelationManager extends RelationManager
->exists())
->schema([
Forms\Components\TextInput::make('qty')
->label('Cantitate restituită')
->label(__('Cantitate restituită'))
->numeric()
->required()
->minValue(0.001)
->default(fn (WorkOrderPart $r) => (float) $r->qty),
Forms\Components\Textarea::make('notes')->rows(2)->label('Observații'),
Forms\Components\Textarea::make('notes')->rows(2)->label(__('Observații')),
])
->action(function (WorkOrderPart $r, array $data) {
$batch = app(WarehouseService::class)->returnPart(