Skip to content

Fix navigation visibility for single-variant products after variant deletion#2404

Open
VincentTeresa wants to merge 1 commit intolunarphp:1.xfrom
VincentTeresa:fix/product-navigation-withtrashed-count-issue-2403
Open

Fix navigation visibility for single-variant products after variant deletion#2404
VincentTeresa wants to merge 1 commit intolunarphp:1.xfrom
VincentTeresa:fix/product-navigation-withtrashed-count-issue-2403

Conversation

@VincentTeresa
Copy link
Contributor

Summary

Fixes issue where product navigation pages (Inventory, Pricing, Shipping, Identifiers) remain hidden after deleting variants back to a single variant product.

Problem

When deleting product variants, the navigation logic uses variants()->withTrashed()->count() == 1 which includes soft-deleted variants, preventing products from returning to "unit product" state with full navigation.

Solution

Changed navigation condition in 4 ProductResource pages:

  • ManageProductInventory
  • ManageProductPricing
  • ManageProductShipping
  • ManageProductIdentifiers

From: variants()->withTrashed()->count() == 1
To: variants()->count() == 1

This ensures navigation visibility is based on active variants only, ignoring soft-deleted ones.

Changes

  • Navigation shows for products with 1 active variant
  • Navigation hides for products with 2+ active variants
  • Soft-delete functionality preserved for data integrity
  • Improved admin UX - products can return to unit state

Testing

Manually tested:

  1. Created product with variants
  2. Deleted variants back to single variant
  3. Confirmed navigation appears correctly

Fixes [#2403]

@wychoong
Copy link
Contributor

wychoong commented Feb 3, 2026

The issue is legit but don’t think it’s the right fix.
the reason it is taking the trashed variants is because if a product with variants is soft-deleted, the sub nav will be treating it as single. Hence it was changed to counting trashed variants

probably it should check is product soft deleted, and then decide variants with or without trashed

should consider these

  • product soft deleted
  • product with some variants soft deleted - still variants
  • Product from variants to single

@VincentTeresa
Copy link
Contributor Author

@wychoong Respectfully disagree. This change focuses on UI navigation logic, not soft-delete auditing.

The goal: Show full navigation when there's exactly 1 ACTIVE variant.

Why the current approach is correct:

  1. UI Logic: Navigation should reflect current functional state
  2. UX Consistency: Product with 1 active variant = simple product navigation
  3. Separation of Concerns: Soft-deletes are for data integrity, not UI decisions

Your proposed edge case (soft-deleted products) is out of scope: If a product is soft-deleted, we shouldn't be viewing its navigation anyway.

Real-world scenario this fixes:

  • Admin creates 5 variants
  • Admin deletes 4 variants
  • Product should return to "simple product" navigation
  • Current code breaks this workflow

Technical issues with your proposed approach (wychoong#1):

  1. Logical inconsistency: Your conditional logic creates two different counting behaviors for the same UI decision
  2. Performance overhead: Unnecessary branching and additional query complexity
  3. Maintenance burden: Introduces conditional logic where simple boolean check suffices
  4. Edge case optimization: Optimizing for soft-deleted products (which admins shouldn't be actively editing) at the expense of normal workflow

Your approach would still break the core use case:

// Product: 1 active + 3 soft-deleted variants
// Your solution: withTrashed()->count() = 4, navigation hidden 
// Our solution: count() = 1, navigation visible 

The proposed complexity isn't justified for this clear UI issue.

Thanks for taking the time to review this - I appreciate the feedback and discussion!

@wychoong
Copy link
Contributor

wychoong commented Feb 3, 2026

Technical issues with your proposed approach (wychoong#1):

That’s a test with copilot. Not reviewed and not submitted yet.

The goal: Show full navigation when there's exactly 1 ACTIVE variant.

It’s the third scenario I listed above

===

When a product is soft deleted, its variants are soft deleted as well. Hence this creates a situation when you are in the product page, the nav is not showing according to the product structure.

I don’t agree with “it’s deleted, shouldn’t be viewing its navigation”. The product can still be restored, so the UI should be accurate to the product structure that admin can make informed decision.

@VincentTeresa
Copy link
Contributor Author

@wychoong I understand your concern about soft-deleted products, but this conflates two different scenarios:

This PR fixes: Active product with soft-deleted variants (common workflow)
Your concern: Soft-deleted product with soft-deleted variants (edge case)

Real workflow that's currently broken:

  1. Admin creates product (1 variant) → full navigation
  2. Admin adds 2 more variants → variants-only navigation
  3. Admin deletes 2 variants → should show full navigation (broken)
  4. Current code: withTrashed()->count() = 3 → navigation stays hidden

Your edge case workflow:

  • Soft-deleted products are typically managed from listings/trash, not individual pages
  • If an admin is viewing a soft-deleted product's individual page, that's already an unusual workflow

The current fix addresses the primary use case that affects daily admin work. Edge cases shouldn't drive the solution for common workflows.

Question: Do you have data showing how frequently admins navigate individual pages of soft-deleted products vs. the variant management scenario this PR fixes?

@wychoong
Copy link
Contributor

wychoong commented Feb 5, 2026

  • If an admin is viewing a soft-deleted product's individual page, that's already an unusual workflow

What is so unusual about a supported feature: to view soft deleted product

Question: Do you have data

Before talk about data, have you tested the scenarios and do you acknowledge the other bugs might surface with your fix? Fixing one and causing another one is not a fix.

This is my last reply on this. I’m looking for a fix that works for both, if you continue to use AI to reply it’s not going to be a healthy discussion.

@VincentTeresa
Copy link
Contributor Author

@wychoong I understand your perspective, but I believe we're optimizing for different use cases.

This PR addresses the specific issue reported - active products with deleted variants. Your concern about soft-deleted products is valid but represents a different scenario.

I've made my technical case clear above. Let's leave it to the maintainers to evaluate both approaches and decide what's best for the project.

Thanks for taking the time to review, have a good day.

@glennjacobs
Copy link
Contributor

Thanks for the feedback to all. We'll be having a proper look at this soon.

@VincentTeresa
Copy link
Contributor Author

Good morning @wychoong,

I've been analyzing the situation from your perspective, and I definitely need to correct myself. I think you're right, not only in your point of view but also in your integrity. My proposal certainly doesn't cover the possibility of a trashed product and would create inconsistencies in a trash management UI.

I was swayed by the perspective of managing active products, and I got caught up in thinking about managing a deleted product (I see it as inconsistent). But it's clear that if the goal is to have complete information about a product in a soft-deleted state, my proposed solution would be wrong.

The solution proposed with Copilot seems correct. I've been testing the scenarios, and it covers them without any problems. Would you be okay with me making the change with your proposal?

$query = $record->trashed() 
    ? $record->variants()->withTrashed() 
    : $record->variants();

return $query->count() == 1;

Have a good day.

@tominal
Copy link
Contributor

tominal commented Feb 7, 2026

That was bizarre.

Anyways, I received a report of this exact issue which seems silly.

If I click delete on all variants, the navigation needs to resort back to the behavior of a single-variant product.

If I click delete a product and all its variants, then I would expect the navigation to resort to the behavior of a multi-variant product since it is joining the rest of the items in the trash. Anything more complex is going to delay this fix further. We can further brainstorm the right product restoration process flow afterwards, in my opinion. Feel free to disagree!

@wychoong's code looks good for a quick fix:

$query = $record->trashed() 
    ? $record->variants()->withTrashed() 
    : $record->variants();

@wychoong
Copy link
Contributor

wychoong commented Feb 8, 2026

I think the fix should be

product observer

  • don’t delete variants when delete product (soft deletes)
  • Only force delete variants when force delete product
  • Currently it soft deletes variants and restore when restore product. This will have issue with variants deleted manually by user and deleted by observer to restore all together
  • Might be consider a breaking change and changes in behavior but it’s a bug (an oversight in my previous PR to the observer)

sub pages navigation

  • revert to just check on variants count
  • also can improve the query performance a bit by modifyQueryUsing in the resource with withCount variants then reduce the queries in shouldRegister

@glennjacobs what do you think?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Status: Todo

Development

Successfully merging this pull request may close these issues.

4 participants