Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,14 @@

All notable changes to this project will be documented in this file.

## [3.14.1] - 2026-01-26

### Changed

- **Variant Filter Logic** - Recipe variants are now shown by default with an option to hide them (previously hidden by default)
- Renamed filter from "Show Canonical Recipes" to "Hide Variants" for better clarity
- Users see all recipes including variants unless they explicitly enable the hide filter

## [3.14.0] - 2026-01-25

### Added
Expand Down
6 changes: 3 additions & 3 deletions app/Livewire/Web/Concerns/WithFilterShareTrait.php
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
* @property string $search
* @property string $sortBy
* @property bool $filterHasPdf
* @property bool $filterShowCanonical
* @property bool $filterHideVariants
* @property array<int> $excludedAllergenIds
* @property array<int> $ingredientIds
* @property string $ingredientMatchMode
Expand Down Expand Up @@ -167,8 +167,8 @@ protected function collectBooleanFilters(array &$filters): void
$filters['has_pdf'] = true;
}

if ($this->filterShowCanonical) {
$filters['show_canonical'] = true;
if ($this->filterHideVariants) {
$filters['hide_variants'] = true;
}

$filters['ingredient_match'] = $this->ingredientMatchMode;
Expand Down
14 changes: 7 additions & 7 deletions app/Livewire/Web/Recipes/RecipeIndex.php
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ class RecipeIndex extends AbstractComponent

public bool $filterHasPdf = false;

public bool $filterShowCanonical = false;
public bool $filterHideVariants = false;

/** @var array<int> */
public array $excludedAllergenIds = [];
Expand Down Expand Up @@ -92,7 +92,7 @@ public function mount(?Menu $menu = null): void
$this->selectedMenuWeek = $this->menu?->year_week;
$this->viewMode = session('view_mode', ViewModeEnum::Grid->value);
$this->filterHasPdf = session($this->filterSessionKey('has_pdf'), false);
$this->filterShowCanonical = session($this->filterSessionKey('show_canonical'), false);
$this->filterHideVariants = session($this->filterSessionKey('hide_variants'), false);
$this->excludedAllergenIds = session($this->filterSessionKey('excluded_allergens'), []);
$this->ingredientIds = session($this->filterSessionKey('ingredients'), []);
$this->ingredientMatchMode = session($this->filterSessionKey('ingredient_match'), IngredientMatchModeEnum::Any->value);
Expand Down Expand Up @@ -281,7 +281,7 @@ protected function getSessionMapping(): array
{
return [
'filterHasPdf' => 'has_pdf',
'filterShowCanonical' => 'show_canonical',
'filterHideVariants' => 'hide_variants',
'excludedAllergenIds' => 'excluded_allergens',
'ingredientIds' => 'ingredients',
'ingredientMatchMode' => 'ingredient_match',
Expand All @@ -308,7 +308,7 @@ public function activeFilterCount(): int
$count++;
}

if ($this->filterShowCanonical) {
if ($this->filterHideVariants) {
$count++;
}

Expand Down Expand Up @@ -387,7 +387,7 @@ public function isTagActive(int $tagId): bool
public function clearFilters(): void
{
$this->filterHasPdf = false;
$this->filterShowCanonical = false;
$this->filterHideVariants = false;
$this->excludedAllergenIds = [];
$this->ingredientIds = [];
$this->ingredientMatchMode = IngredientMatchModeEnum::Any->value;
Expand All @@ -402,7 +402,7 @@ public function clearFilters(): void

session()->forget([
$this->filterSessionKey('has_pdf'),
$this->filterSessionKey('show_canonical'),
$this->filterSessionKey('hide_variants'),
$this->filterSessionKey('excluded_allergens'),
$this->filterSessionKey('ingredients'),
$this->filterSessionKey('ingredient_match'),
Expand Down Expand Up @@ -432,7 +432,7 @@ public function recipes(): LengthAwarePaginator
->when($menuRecipeIds !== [], fn (Builder $query) => $query->whereIn('id', $menuRecipeIds))
->when($this->search !== '', fn (Builder $query): Builder => $this->applySearchFilter($query))
->when($this->filterHasPdf, fn (Builder $query) => $query->where('has_pdf', true))
->when(! $this->filterShowCanonical, fn (Builder $query) => $query->where('variant', false))
->when($this->filterHideVariants, fn (Builder $query) => $query->where('variant', false))
->when($this->excludedAllergenIds !== [], fn (Builder $query) => $query->whereDoesntHave(
'allergens',
fn (Builder $allergenQuery) => $allergenQuery->whereIn('allergens.id', $this->excludedAllergenIds)
Expand Down
2 changes: 1 addition & 1 deletion app/Livewire/Web/Recipes/RecipeRandom.php
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ public function randomRecipes(): Collection
return Recipe::where('country_id', $this->countryId)
->when($this->search !== '', fn (Builder $query): Builder => $this->applySearchFilter($query))
->when($this->filterHasPdf, fn (Builder $query) => $query->where('has_pdf', true))
->unless($this->filterShowCanonical, fn (Builder $query) => $query->where('variant', false))
->when($this->filterHideVariants, fn (Builder $query) => $query->where('variant', false))
->when($this->excludedAllergenIds !== [], fn (Builder $query) => $query->whereDoesntHave(
'allergens',
fn (Builder $allergenQuery) => $allergenQuery->whereIn('allergens.id', $this->excludedAllergenIds)
Expand Down
2 changes: 1 addition & 1 deletion lang/da.json
Original file line number Diff line number Diff line change
Expand Up @@ -144,7 +144,7 @@
"Not Found": "Ikke fundet",
"Oldest first": "Ældste først",
"Only the owner can share this list.": "Kun ejeren kan dele denne liste.",
"Show Canonical Recipes": "Vis også opskriftsvarianter",
"Hide Variants": "Skjul varianter",
"Only with PDF": "Kun med PDF",
"Optional description for your list": "Valgfri beskrivelse til din liste",
"Page Expired": "Siden er udløbet",
Expand Down
2 changes: 1 addition & 1 deletion lang/de.json
Original file line number Diff line number Diff line change
Expand Up @@ -144,7 +144,7 @@
"Nutrition": "Nährwerte",
"Oldest first": "Älteste zuerst",
"Only the owner can share this list.": "Nur der Eigentümer kann diese Liste teilen.",
"Show Canonical Recipes": "Auch Rezeptvarianten anzeigen",
"Hide Variants": "Rezeptvarianten ausblenden",
"Only with PDF": "Nur mit PDF",
"Optional description for your list": "Optionale Beschreibung für deine Liste",
"Page Expired": "Seite abgelaufen",
Expand Down
2 changes: 1 addition & 1 deletion lang/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -143,7 +143,7 @@
"Nutrition": "Nutrition",
"Oldest first": "Oldest first",
"Only the owner can share this list.": "Only the owner can share this list.",
"Show Canonical Recipes": "Include Recipe Variants",
"Hide Variants": "Hide Variants",
"Only with PDF": "Only with PDF",
"Optional description for your list": "Optional description for your list",
"Page Expired": "Page Expired",
Expand Down
2 changes: 1 addition & 1 deletion lang/es.json
Original file line number Diff line number Diff line change
Expand Up @@ -144,7 +144,7 @@
"Not Found": "No encontrado",
"Oldest first": "Más antiguas primero",
"Only the owner can share this list.": "Solo el propietario puede compartir esta lista.",
"Show Canonical Recipes": "Incluir variantes de recetas",
"Hide Variants": "Ocultar variantes",
"Only with PDF": "Solo con PDF",
"Optional description for your list": "Descripción opcional para tu lista",
"Page Expired": "Página expirada",
Expand Down
2 changes: 1 addition & 1 deletion lang/fr.json
Original file line number Diff line number Diff line change
Expand Up @@ -144,7 +144,7 @@
"Not Found": "Non trouvé",
"Oldest first": "Plus anciennes d'abord",
"Only the owner can share this list.": "Seul le propriétaire peut partager cette liste.",
"Show Canonical Recipes": "Inclure les variantes de recettes",
"Hide Variants": "Masquer les variantes",
"Only with PDF": "Uniquement avec PDF",
"Optional description for your list": "Description optionnelle pour votre liste",
"Page Expired": "Page expirée",
Expand Down
2 changes: 1 addition & 1 deletion lang/it.json
Original file line number Diff line number Diff line change
Expand Up @@ -144,7 +144,7 @@
"Not Found": "Non trovato",
"Oldest first": "Più vecchie prima",
"Only the owner can share this list.": "Solo il proprietario può condividere questa lista.",
"Show Canonical Recipes": "Includi varianti delle ricette",
"Hide Variants": "Nascondi varianti",
"Only with PDF": "Solo con PDF",
"Optional description for your list": "Descrizione opzionale per la tua lista",
"Page Expired": "Pagina scaduta",
Expand Down
2 changes: 1 addition & 1 deletion lang/nb.json
Original file line number Diff line number Diff line change
Expand Up @@ -144,7 +144,7 @@
"Not Found": "Ikke funnet",
"Oldest first": "Eldste først",
"Only the owner can share this list.": "Bare eieren kan dele denne listen.",
"Show Canonical Recipes": "Vis også oppskriftsvarianter",
"Hide Variants": "Skjul varianter",
"Only with PDF": "Kun med PDF",
"Optional description for your list": "Valgfri beskrivelse for listen din",
"Page Expired": "Siden har utløpt",
Expand Down
2 changes: 1 addition & 1 deletion lang/nl.json
Original file line number Diff line number Diff line change
Expand Up @@ -144,7 +144,7 @@
"Not Found": "Niet gevonden",
"Oldest first": "Oudste eerst",
"Only the owner can share this list.": "Alleen de eigenaar kan deze lijst delen.",
"Show Canonical Recipes": "Ook receptvarianten tonen",
"Hide Variants": "Varianten verbergen",
"Only with PDF": "Alleen met PDF",
"Optional description for your list": "Optionele beschrijving voor je lijst",
"Page Expired": "Pagina niet meer geldig",
Expand Down
2 changes: 1 addition & 1 deletion lang/sv.json
Original file line number Diff line number Diff line change
Expand Up @@ -144,7 +144,7 @@
"Not Found": "Hittades ej",
"Oldest first": "Äldsta först",
"Only the owner can share this list.": "Endast ägaren kan dela denna lista.",
"Show Canonical Recipes": "Visa även receptvarianter",
"Hide Variants": "Dölj varianter",
"Only with PDF": "Endast med PDF",
"Optional description for your list": "Valfri beskrivning för din lista",
"Page Expired": "Sidan är utgången",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@

<flux:switch wire:model.live="filterHasPdf" :label="__('Only with PDF')" />

<flux:switch wire:model.live="filterShowCanonical" :label="__('Show Canonical Recipes')" />
<flux:switch wire:model.live="filterHideVariants" :label="__('Hide Variants')" />

<flux:field>
<flux:label>{{ __('Difficulty') }}</flux:label>
Expand Down
9 changes: 5 additions & 4 deletions tests/Feature/FilterShareTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
use Livewire\Livewire;
use Override;
use PHPUnit\Framework\Attributes\Test;
use ReflectionClass;
use Tests\TestCase;

final class FilterShareTest extends TestCase
Expand Down Expand Up @@ -133,14 +134,14 @@ public function filter_share_only_includes_active_filters(): void
{
Livewire::test(RecipeIndex::class)
->set('filterHasPdf', true)
->set('filterShowCanonical', false)
->set('filterHideVariants', false)
->set('excludedAllergenIds', [])
->call('generateFilterShareUrl');

$filterShare = FilterShare::latest('created_at')->first();

$this->assertTrue($filterShare->filters['has_pdf']);
$this->assertArrayNotHasKey('show_canonical', $filterShare->filters);
$this->assertArrayNotHasKey('hide_variants', $filterShare->filters);
$this->assertArrayNotHasKey('excluded_allergens', $filterShare->filters);
}

Expand Down Expand Up @@ -171,7 +172,7 @@ public function get_share_page_returns_integer(): void
{
$component = Livewire::test(RecipeIndex::class);

$reflection = new \ReflectionClass($component->instance());
$reflection = new ReflectionClass($component->instance());
$method = $reflection->getMethod('getSharePage');

$result = $method->invoke($component->instance());
Expand All @@ -189,7 +190,7 @@ public function get_share_page_handles_string_page_parameter(): void
$mock->method('getPage')
->willReturn('2');

$reflection = new \ReflectionClass($mock);
$reflection = new ReflectionClass($mock);
$method = $reflection->getMethod('getSharePage');

$result = $method->invoke($mock);
Expand Down
37 changes: 37 additions & 0 deletions tests/Feature/Livewire/Recipes/RecipeIndexTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -445,4 +445,41 @@ public function is_tag_active_returns_false_for_inactive_tag(): void

$this->assertFalse($component->instance()->isTagActive($tag->id));
}

#[Test]
public function it_shows_variants_by_default(): void
{
Recipe::factory()->for($this->country)->create([
'name' => ['en' => 'Main Recipe'],
'variant' => false,
]);

Recipe::factory()->for($this->country)->create([
'name' => ['en' => 'Variant Recipe'],
'variant' => true,
]);

Livewire::test(RecipeIndex::class)
->assertSee('Main Recipe')
->assertSee('Variant Recipe');
}

#[Test]
public function it_can_hide_variants(): void
{
Recipe::factory()->for($this->country)->create([
'name' => ['en' => 'Main Recipe'],
'variant' => false,
]);

Recipe::factory()->for($this->country)->create([
'name' => ['en' => 'Variant Recipe'],
'variant' => true,
]);

Livewire::test(RecipeIndex::class)
->set('filterHideVariants', true)
->assertSee('Main Recipe')
->assertDontSee('Variant Recipe');
}
}
Loading