feat(block1): variety detail + edit screen with reactive lots
Tapping an inventory item now opens its detail (the /variety/:id route was a
placeholder). Read + edit one variety end-to-end:
- Detail view: photo, category, "also known as" names, notes and lots, driven
by a reactive VarietyDetailCubit.
- Edit core fields (label/category/notes, LWW) via a bottom sheet.
- Add a lot (harvest year + quantity) — the list refreshes reactively.
- Soft-delete (tombstone) with a confirm dialog.
Repository:
- watchVariety(id): merges Drift table-change streams (variety, lots, names,
attachments) via StreamGroup and reloads the full detail on any change, so a
lot added to a *different* table still refreshes the view.
- updateVariety (LWW), addLot, softDeleteVariety.
i18n: detail/edit/addLot strings (ES/EN); switched slang to {param} braces
interpolation (translator- and Weblate-friendly).
Tests: repository (reactive watchVariety, update, soft-delete) and widget tests
(render, edit updates title, add-lot appears, delete shows not-found). Full
suite green: 23 passing, 1 skipped (SQLCipher-only encryption guard).
This commit is contained in:
parent
040f15a898
commit
7ff4e38a15
15 changed files with 1093 additions and 18 deletions
|
|
@ -40,8 +40,12 @@ class TranslationsEs extends Translations with BaseTranslations<AppLocale, Trans
|
|||
|
||||
// Translations
|
||||
@override late final _Translations$app$es app = _Translations$app$es._(_root);
|
||||
@override late final _Translations$common$es common = _Translations$common$es._(_root);
|
||||
@override late final _Translations$inventory$es inventory = _Translations$inventory$es._(_root);
|
||||
@override late final _Translations$quickAdd$es quickAdd = _Translations$quickAdd$es._(_root);
|
||||
@override late final _Translations$detail$es detail = _Translations$detail$es._(_root);
|
||||
@override late final _Translations$editVariety$es editVariety = _Translations$editVariety$es._(_root);
|
||||
@override late final _Translations$addLot$es addLot = _Translations$addLot$es._(_root);
|
||||
@override late final _Translations$quantityKind$es quantityKind = _Translations$quantityKind$es._(_root);
|
||||
}
|
||||
|
||||
|
|
@ -55,6 +59,19 @@ class _Translations$app$es extends Translations$app$en {
|
|||
@override String get title => 'Tanemaki';
|
||||
}
|
||||
|
||||
// Path: common
|
||||
class _Translations$common$es extends Translations$common$en {
|
||||
_Translations$common$es._(TranslationsEs root) : this._root = root, super.internal(root);
|
||||
|
||||
final TranslationsEs _root; // ignore: unused_field
|
||||
|
||||
// Translations
|
||||
@override String get save => 'Guardar';
|
||||
@override String get cancel => 'Cancelar';
|
||||
@override String get delete => 'Eliminar';
|
||||
@override String get edit => 'Editar';
|
||||
}
|
||||
|
||||
// Path: inventory
|
||||
class _Translations$inventory$es extends Translations$inventory$en {
|
||||
_Translations$inventory$es._(TranslationsEs root) : this._root = root, super.internal(root);
|
||||
|
|
@ -85,6 +102,49 @@ class _Translations$quickAdd$es extends Translations$quickAdd$en {
|
|||
@override String get cancel => 'Cancelar';
|
||||
}
|
||||
|
||||
// Path: detail
|
||||
class _Translations$detail$es extends Translations$detail$en {
|
||||
_Translations$detail$es._(TranslationsEs root) : this._root = root, super.internal(root);
|
||||
|
||||
final TranslationsEs _root; // ignore: unused_field
|
||||
|
||||
// Translations
|
||||
@override String get notFound => 'Esta semilla ya no está aquí.';
|
||||
@override String get lots => 'Lotes';
|
||||
@override String get noLots => 'Aún no hay lotes.';
|
||||
@override String get names => 'También conocida como';
|
||||
@override String get notes => 'Notas';
|
||||
@override String get addLot => 'Añadir lote';
|
||||
@override String get deleteConfirm => '¿Eliminar esta semilla?';
|
||||
@override String year({required Object year}) => 'Año ${year}';
|
||||
@override String get noYear => 'Año desconocido';
|
||||
}
|
||||
|
||||
// Path: editVariety
|
||||
class _Translations$editVariety$es extends Translations$editVariety$en {
|
||||
_Translations$editVariety$es._(TranslationsEs root) : this._root = root, super.internal(root);
|
||||
|
||||
final TranslationsEs _root; // ignore: unused_field
|
||||
|
||||
// Translations
|
||||
@override String get title => 'Editar semilla';
|
||||
@override String get name => 'Nombre';
|
||||
@override String get category => 'Categoría';
|
||||
@override String get notes => 'Notas';
|
||||
}
|
||||
|
||||
// Path: addLot
|
||||
class _Translations$addLot$es extends Translations$addLot$en {
|
||||
_Translations$addLot$es._(TranslationsEs root) : this._root = root, super.internal(root);
|
||||
|
||||
final TranslationsEs _root; // ignore: unused_field
|
||||
|
||||
// Translations
|
||||
@override String get title => 'Añadir lote';
|
||||
@override String get year => 'Año de cosecha';
|
||||
@override String get quantity => 'Cantidad';
|
||||
}
|
||||
|
||||
// Path: quantityKind
|
||||
class _Translations$quantityKind$es extends Translations$quantityKind$en {
|
||||
_Translations$quantityKind$es._(TranslationsEs root) : this._root = root, super.internal(root);
|
||||
|
|
@ -121,6 +181,10 @@ extension on TranslationsEs {
|
|||
dynamic _flatMapFunction(String path) {
|
||||
return switch (path) {
|
||||
'app.title' => 'Tanemaki',
|
||||
'common.save' => 'Guardar',
|
||||
'common.cancel' => 'Cancelar',
|
||||
'common.delete' => 'Eliminar',
|
||||
'common.edit' => 'Editar',
|
||||
'inventory.title' => 'Inventario',
|
||||
'inventory.searchHint' => 'Buscar semillas',
|
||||
'inventory.empty' => 'Aún no hay semillas. Toca + para añadir la primera.',
|
||||
|
|
@ -133,6 +197,22 @@ extension on TranslationsEs {
|
|||
'quickAdd.more' => 'Añadir más…',
|
||||
'quickAdd.save' => 'Guardar',
|
||||
'quickAdd.cancel' => 'Cancelar',
|
||||
'detail.notFound' => 'Esta semilla ya no está aquí.',
|
||||
'detail.lots' => 'Lotes',
|
||||
'detail.noLots' => 'Aún no hay lotes.',
|
||||
'detail.names' => 'También conocida como',
|
||||
'detail.notes' => 'Notas',
|
||||
'detail.addLot' => 'Añadir lote',
|
||||
'detail.deleteConfirm' => '¿Eliminar esta semilla?',
|
||||
'detail.year' => ({required Object year}) => 'Año ${year}',
|
||||
'detail.noYear' => 'Año desconocido',
|
||||
'editVariety.title' => 'Editar semilla',
|
||||
'editVariety.name' => 'Nombre',
|
||||
'editVariety.category' => 'Categoría',
|
||||
'editVariety.notes' => 'Notas',
|
||||
'addLot.title' => 'Añadir lote',
|
||||
'addLot.year' => 'Año de cosecha',
|
||||
'addLot.quantity' => 'Cantidad',
|
||||
'quantityKind.aFew' => 'unas pocas',
|
||||
'quantityKind.some' => 'algunas',
|
||||
'quantityKind.plenty' => 'muchas',
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue