i18n(wo relations): translated snapshot names + explicit empty states

- WorksRelationManager Name column: getStateUsing(labor?->label()) so
  the row shows the labor's localized name (not the raw snapshot);
  fallback to stored snapshot when labor is missing.
- 4 explicit empty states with helper description + icon on Works,
  Parts, SubcontractJobs, Payments — replaces Filament's auto-generated
  'Не найдено X / Создать X для старта.'
- 4 CreateAction titles / modal headings for all four relation managers.
- Notification 'Piesa returnată în stoc' / 'Nimic de restituit' wrapped.
- +11 translation keys.

All 306 tests pass.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-07-26 10:59:47 +00:00
parent 9609295a9e
commit de2964c854
6 changed files with 57 additions and 13 deletions
@@ -87,7 +87,9 @@ class PartsRelationManager extends RelationManager
]), ]),
]) ])
->headerActions([ ->headerActions([
Actions\CreateAction::make(), Actions\CreateAction::make()
->label(__('Adaugă piesă'))
->modalHeading(__('Adaugă piesă în fișă')),
]) ])
->actions([ ->actions([
Actions\Action::make('smart_price') Actions\Action::make('smart_price')
@@ -154,12 +156,15 @@ class PartsRelationManager extends RelationManager
$r, (float) $data['qty'], $data['notes'] ?? null $r, (float) $data['qty'], $data['notes'] ?? null
); );
Notification::make() Notification::make()
->title($batch ? 'Piesa returnată în stoc' : 'Nimic de restituit') ->title($batch ? __('Piesa returnată în stoc') : __('Nimic de restituit'))
->{$batch ? 'success' : 'warning'}() ->{$batch ? 'success' : 'warning'}()
->send(); ->send();
}), }),
Actions\EditAction::make(), Actions\EditAction::make(),
Actions\DeleteAction::make(), Actions\DeleteAction::make(),
]); ])
->emptyStateHeading(__('Nicio piesă montată.'))
->emptyStateDescription(__('Adaugă piesele necesare din catalog. Stocul se rezervă automat, iar la marcarea „Montată" scade FIFO.'))
->emptyStateIcon('heroicon-o-cube');
} }
} }
@@ -49,7 +49,10 @@ class PaymentsRelationManager extends RelationManager
Tables\Columns\TextColumn::make('reference')->placeholder('—'), Tables\Columns\TextColumn::make('reference')->placeholder('—'),
]) ])
->headerActions([ ->headerActions([
Actions\CreateAction::make()->mutateFormDataUsing(function (array $data, RelationManager $livewire): array { Actions\CreateAction::make()
->label(__('Adaugă plată'))
->modalHeading(__('Adaugă plată la fișă'))
->mutateFormDataUsing(function (array $data, RelationManager $livewire): array {
$wo = $livewire->getOwnerRecord(); $wo = $livewire->getOwnerRecord();
$data['client_id'] = $wo->client_id; $data['client_id'] = $wo->client_id;
$data['user_id'] = auth()->id(); $data['user_id'] = auth()->id();
@@ -60,6 +63,9 @@ class PaymentsRelationManager extends RelationManager
Actions\EditAction::make(), Actions\EditAction::make(),
Actions\DeleteAction::make(), Actions\DeleteAction::make(),
]) ])
->emptyStateHeading(__('Nicio plată'))
->emptyStateDescription(__('Adaugă plățile parțiale sau totale primite pentru această fișă. Statusul plății se actualizează automat.'))
->emptyStateIcon('heroicon-o-banknotes')
->defaultSort('paid_at', 'desc'); ->defaultSort('paid_at', 'desc');
} }
} }
@@ -64,7 +64,14 @@ class SubcontractJobsRelationManager extends RelationManager
->badge() ->badge()
->colors(['warning' => ['sent', 'in_progress'], 'success' => ['done', 'returned'], 'danger' => ['cancelled']]), ->colors(['warning' => ['sent', 'in_progress'], 'success' => ['done', 'returned'], 'danger' => ['cancelled']]),
]) ])
->headerActions([Actions\CreateAction::make()]) ->headerActions([
->actions([Actions\EditAction::make(), Actions\DeleteAction::make()]); Actions\CreateAction::make()
->label(__('Adaugă lucrare terți'))
->modalHeading(__('Adaugă lucrare la subcontractor')),
])
->actions([Actions\EditAction::make(), Actions\DeleteAction::make()])
->emptyStateHeading(__('Nicio lucrare la terți'))
->emptyStateDescription(__('Adaugă lucrări trimise la ateliere externe (turbo, cutii, vopsitorie). Costul + markup intră automat în totalul fișei.'))
->emptyStateIcon('heroicon-o-arrow-top-right-on-square');
} }
} }
@@ -73,7 +73,8 @@ class WorksRelationManager extends RelationManager
return $table return $table
->recordTitleAttribute('name') ->recordTitleAttribute('name')
->columns([ ->columns([
Tables\Columns\TextColumn::make('name')->label(__('Manoperă'))->wrap(), Tables\Columns\TextColumn::make('name')->label(__('Manoperă'))->wrap()
->getStateUsing(fn ($record) => $record->labor?->label() ?: $record->name),
Tables\Columns\TextColumn::make('hours')->label(__('Ore'))->numeric(decimalPlaces: 2)->alignRight(), Tables\Columns\TextColumn::make('hours')->label(__('Ore'))->numeric(decimalPlaces: 2)->alignRight(),
Tables\Columns\TextColumn::make('price_per_hour')->label(__('Preț/h'))->money('MDL')->alignRight(), Tables\Columns\TextColumn::make('price_per_hour')->label(__('Preț/h'))->money('MDL')->alignRight(),
Tables\Columns\TextColumn::make('total') Tables\Columns\TextColumn::make('total')
@@ -117,6 +118,9 @@ class WorksRelationManager extends RelationManager
->actions([ ->actions([
Actions\EditAction::make(), Actions\EditAction::make(),
Actions\DeleteAction::make(), Actions\DeleteAction::make(),
]); ])
->emptyStateHeading(__('Nicio manoperă efectuată.'))
->emptyStateDescription(__('Adaugă manopere din catalog — piesele implicite se adaugă automat în tab-ul Piese.'))
->emptyStateIcon('heroicon-o-wrench');
} }
} }
+11
View File
@@ -107,6 +107,10 @@
"Adaugă furnizor": "Add supplier", "Adaugă furnizor": "Add supplier",
"Adaugă header": "Add header", "Adaugă header": "Add header",
"Adaugă imagine": "Add image", "Adaugă imagine": "Add image",
"Adaugă lucrare la subcontractor": "Add job to subcontractor",
"Adaugă lucrare terți": "Add subcontract job",
"Adaugă lucrări trimise la ateliere externe (turbo, cutii, vopsitorie). Costul + markup intră automat în totalul fișei.": "Add jobs sent to external workshops (turbo, gearboxes, paint). Cost + markup are auto-added to the order total.",
"Adaugă manopere din catalog — piesele implicite se adaugă automat în tab-ul Piese.": "Add labor from catalog — default parts auto-appear in the Parts tab.",
"Adaugă manopere și piese care se aplică împreună când selectezi acest șablon pe o fișă.": "Add labors and parts applied together when selecting this template on an order.", "Adaugă manopere și piese care se aplică împreună când selectezi acest șablon pe o fișă.": "Add labors and parts applied together when selecting this template on an order.",
"Adaugă manoperă": "Add labor", "Adaugă manoperă": "Add labor",
"Adaugă manoperă în fișă": "Add labor to order", "Adaugă manoperă în fișă": "Add labor to order",
@@ -115,10 +119,14 @@
"Adaugă notă": "Add note", "Adaugă notă": "Add note",
"Adaugă piese manual, sau folosește Achiziții ca să le adaugi prin recepție de la furnizor (cu prețuri și stoc auto). Procentaj poate seta automat prețul de vânzare.": "Adaugă piese manual, sau folosește Achiziții ca să le adaugi prin recepție de la furnizor (cu prețuri și stoc auto). Procentaj poate seta automat prețul de vânzare.", "Adaugă piese manual, sau folosește Achiziții ca să le adaugi prin recepție de la furnizor (cu prețuri și stoc auto). Procentaj poate seta automat prețul de vânzare.": "Adaugă piese manual, sau folosește Achiziții ca să le adaugi prin recepție de la furnizor (cu prețuri și stoc auto). Procentaj poate seta automat prețul de vânzare.",
"Adaugă piesele care se montează de obicei la această manoperă — se adaugă automat în fișă când selectezi manopera.": "Add parts usually installed with this labor — they are auto-added to the order when you select this labor.", "Adaugă piesele care se montează de obicei la această manoperă — se adaugă automat în fișă când selectezi manopera.": "Add parts usually installed with this labor — they are auto-added to the order when you select this labor.",
"Adaugă piesele necesare din catalog. Stocul se rezervă automat, iar la marcarea „Montată\" scade FIFO.": "Add the needed parts from catalog. Stock is auto-reserved; on \"Installed\" it deducts FIFO.",
"Adaugă piesă": "Add part", "Adaugă piesă": "Add part",
"Adaugă piesă implicită": "Add default part", "Adaugă piesă implicită": "Add default part",
"Adaugă piesă în catalog": "Add part to catalog", "Adaugă piesă în catalog": "Add part to catalog",
"Adaugă piesă în fișă": "Add part to order",
"Adaugă plată": "Add payment", "Adaugă plată": "Add payment",
"Adaugă plată la fișă": "Add payment to order",
"Adaugă plățile parțiale sau totale primite pentru această fișă. Statusul plății se actualizează automat.": "Add partial or full payments for this order. Payment status auto-updates.",
"Adaugă primul client SaaS folosind butonul „Adaugă companie\" — se va crea un tenant nou cu admin pe `<slug>.service.mir.md/app`.": "Adaugă primul client SaaS folosind butonul „Adaugă companie\" — se va crea un tenant nou cu admin pe `<slug>.service.mir.md/app`.", "Adaugă primul client SaaS folosind butonul „Adaugă companie\" — se va crea un tenant nou cu admin pe `<slug>.service.mir.md/app`.": "Adaugă primul client SaaS folosind butonul „Adaugă companie\" — se va crea un tenant nou cu admin pe `<slug>.service.mir.md/app`.",
"Adaugă primul tău client manual sau importă din CSV. Toate mașinile, fișele și plățile se vor lega automat de el.": "Adaugă primul tău client manual sau importă din CSV. Toate mașinile, fișele și plățile se vor lega automat de el.", "Adaugă primul tău client manual sau importă din CSV. Toate mașinile, fișele și plățile se vor lega automat de el.": "Adaugă primul tău client manual sau importă din CSV. Toate mașinile, fișele și plățile se vor lega automat de el.",
"Adaugă produs": "Add product", "Adaugă produs": "Add product",
@@ -1208,6 +1216,7 @@
"Nicio metodă de plată configurată. Contactează operatorul.": "No payment method configured. Contact operator.", "Nicio metodă de plată configurată. Contactează operatorul.": "No payment method configured. Contact operator.",
"Nicio piesă implicită": "No default parts", "Nicio piesă implicită": "No default parts",
"Nicio piesă montată.": "No parts installed.", "Nicio piesă montată.": "No parts installed.",
"Nicio plată": "No payments",
"Nicio plată în perioada selectată.": "No payments in selected period.", "Nicio plată în perioada selectată.": "No payments in selected period.",
"Nicio programare în această perioadă.": "No appointments in this period.", "Nicio programare în această perioadă.": "No appointments in this period.",
"Nicio programare în perioada selectată.": "No appointments in selected period.", "Nicio programare în perioada selectată.": "No appointments in selected period.",
@@ -1236,6 +1245,7 @@
"Niciun tenant încă": "No tenants yet", "Niciun tenant încă": "No tenants yet",
"Niciun token generat. Folosește butonul „Generează token": "No tokens generated. Use the \"Generate token\" button.", "Niciun token generat. Folosește butonul „Generează token": "No tokens generated. Use the \"Generate token\" button.",
"Niciun șablon": "No templates", "Niciun șablon": "No templates",
"Nimic de restituit": "Nothing to return",
"No": "No", "No": "No",
"No-show alert": "No-show alert", "No-show alert": "No-show alert",
"Noiembrie": "November", "Noiembrie": "November",
@@ -1417,6 +1427,7 @@
"Pickup": "Pickup", "Pickup": "Pickup",
"Pierdut": "Lost", "Pierdut": "Lost",
"Pierdute": "Missed", "Pierdute": "Missed",
"Piesa returnată în stoc": "Part returned to stock",
"Piese": "Parts", "Piese": "Parts",
"Piese (vânzare)": "Parts (sales)", "Piese (vânzare)": "Parts (sales)",
"Piese impl.": "Default parts", "Piese impl.": "Default parts",
+11
View File
@@ -107,6 +107,10 @@
"Adaugă furnizor": "Добавить поставщика", "Adaugă furnizor": "Добавить поставщика",
"Adaugă header": "Добавить заголовок", "Adaugă header": "Добавить заголовок",
"Adaugă imagine": "Добавить изображение", "Adaugă imagine": "Добавить изображение",
"Adaugă lucrare la subcontractor": "Добавить работу субподрядчику",
"Adaugă lucrare terți": "Добавить работу субподрядчика",
"Adaugă lucrări trimise la ateliere externe (turbo, cutii, vopsitorie). Costul + markup intră automat în totalul fișei.": "Добавьте работы, отправленные в сторонние мастерские (турбо, коробки, покраска). Стоимость + наценка автоматически входят в сумму наряда.",
"Adaugă manopere din catalog — piesele implicite se adaugă automat în tab-ul Piese.": "Добавьте работы из каталога — запчасти по умолчанию автоматически появятся в табе «Запчасти».",
"Adaugă manopere și piese care se aplică împreună când selectezi acest șablon pe o fișă.": "Добавьте работы и запчасти, которые применяются вместе при выборе этого шаблона в наряде.", "Adaugă manopere și piese care se aplică împreună când selectezi acest șablon pe o fișă.": "Добавьте работы и запчасти, которые применяются вместе при выборе этого шаблона в наряде.",
"Adaugă manoperă": "Добавить работу", "Adaugă manoperă": "Добавить работу",
"Adaugă manoperă în fișă": "Добавить работу в наряд", "Adaugă manoperă în fișă": "Добавить работу в наряд",
@@ -115,10 +119,14 @@
"Adaugă notă": "Добавить заметку", "Adaugă notă": "Добавить заметку",
"Adaugă piese manual, sau folosește Achiziții ca să le adaugi prin recepție de la furnizor (cu prețuri și stoc auto). Procentaj poate seta automat prețul de vânzare.": "Adaugă piese manual, sau folosește Achiziții ca să le adaugi prin recepție de la furnizor (cu prețuri și stoc auto). Procentaj poate seta automat prețul de vânzare.", "Adaugă piese manual, sau folosește Achiziții ca să le adaugi prin recepție de la furnizor (cu prețuri și stoc auto). Procentaj poate seta automat prețul de vânzare.": "Adaugă piese manual, sau folosește Achiziții ca să le adaugi prin recepție de la furnizor (cu prețuri și stoc auto). Procentaj poate seta automat prețul de vânzare.",
"Adaugă piesele care se montează de obicei la această manoperă — se adaugă automat în fișă când selectezi manopera.": "Добавьте запчасти, которые обычно устанавливаются в этой работе — они автоматически добавятся в наряд при выборе работы.", "Adaugă piesele care se montează de obicei la această manoperă — se adaugă automat în fișă când selectezi manopera.": "Добавьте запчасти, которые обычно устанавливаются в этой работе — они автоматически добавятся в наряд при выборе работы.",
"Adaugă piesele necesare din catalog. Stocul se rezervă automat, iar la marcarea „Montată\" scade FIFO.": "Добавьте нужные запчасти из каталога. Остаток резервируется автоматически, при отметке «Установлено» списывается по FIFO.",
"Adaugă piesă": "Добавить запчасть", "Adaugă piesă": "Добавить запчасть",
"Adaugă piesă implicită": "Добавить запчасть по умолчанию", "Adaugă piesă implicită": "Добавить запчасть по умолчанию",
"Adaugă piesă în catalog": "Добавить запчасть в каталог", "Adaugă piesă în catalog": "Добавить запчасть в каталог",
"Adaugă piesă în fișă": "Добавить запчасть в наряд",
"Adaugă plată": "Добавить платёж", "Adaugă plată": "Добавить платёж",
"Adaugă plată la fișă": "Добавить платёж к наряду",
"Adaugă plățile parțiale sau totale primite pentru această fișă. Statusul plății se actualizează automat.": "Добавьте частичные или полные платежи по этому наряду. Статус оплаты обновляется автоматически.",
"Adaugă primul client SaaS folosind butonul „Adaugă companie\" — se va crea un tenant nou cu admin pe `<slug>.service.mir.md/app`.": "Adaugă primul client SaaS folosind butonul „Adaugă companie\" — se va crea un tenant nou cu admin pe `<slug>.service.mir.md/app`.", "Adaugă primul client SaaS folosind butonul „Adaugă companie\" — se va crea un tenant nou cu admin pe `<slug>.service.mir.md/app`.": "Adaugă primul client SaaS folosind butonul „Adaugă companie\" — se va crea un tenant nou cu admin pe `<slug>.service.mir.md/app`.",
"Adaugă primul tău client manual sau importă din CSV. Toate mașinile, fișele și plățile se vor lega automat de el.": "Adaugă primul tău client manual sau importă din CSV. Toate mașinile, fișele și plățile se vor lega automat de el.", "Adaugă primul tău client manual sau importă din CSV. Toate mașinile, fișele și plățile se vor lega automat de el.": "Adaugă primul tău client manual sau importă din CSV. Toate mașinile, fișele și plățile se vor lega automat de el.",
"Adaugă produs": "Добавить товар", "Adaugă produs": "Добавить товар",
@@ -1208,6 +1216,7 @@
"Nicio metodă de plată configurată. Contactează operatorul.": "Способ оплаты не настроен. Свяжитесь с оператором.", "Nicio metodă de plată configurată. Contactează operatorul.": "Способ оплаты не настроен. Свяжитесь с оператором.",
"Nicio piesă implicită": "Нет запчастей по умолчанию", "Nicio piesă implicită": "Нет запчастей по умолчанию",
"Nicio piesă montată.": "Запчасти не установлены.", "Nicio piesă montată.": "Запчасти не установлены.",
"Nicio plată": "Нет платежей",
"Nicio plată în perioada selectată.": "Нет платежей за выбранный период.", "Nicio plată în perioada selectată.": "Нет платежей за выбранный период.",
"Nicio programare în această perioadă.": "Нет записей в этом периоде.", "Nicio programare în această perioadă.": "Нет записей в этом периоде.",
"Nicio programare în perioada selectată.": "Нет записей за выбранный период.", "Nicio programare în perioada selectată.": "Нет записей за выбранный период.",
@@ -1236,6 +1245,7 @@
"Niciun tenant încă": "Пока нет арендаторов", "Niciun tenant încă": "Пока нет арендаторов",
"Niciun token generat. Folosește butonul „Generează token": "Токены не созданы. Используйте кнопку «Создать токен».", "Niciun token generat. Folosește butonul „Generează token": "Токены не созданы. Используйте кнопку «Создать токен».",
"Niciun șablon": "Нет шаблонов", "Niciun șablon": "Нет шаблонов",
"Nimic de restituit": "Нечего возвращать",
"No": "Нет", "No": "Нет",
"No-show alert": "No-show предупр.", "No-show alert": "No-show предупр.",
"Noiembrie": "Ноябрь", "Noiembrie": "Ноябрь",
@@ -1417,6 +1427,7 @@
"Pickup": "Пикап", "Pickup": "Пикап",
"Pierdut": "Потерян", "Pierdut": "Потерян",
"Pierdute": "Пропущенные", "Pierdute": "Пропущенные",
"Piesa returnată în stoc": "Запчасть возвращена на склад",
"Piese": "Запчасти", "Piese": "Запчасти",
"Piese (vânzare)": "Запчасти (продажа)", "Piese (vânzare)": "Запчасти (продажа)",
"Piese impl.": "Запчасти", "Piese impl.": "Запчасти",