Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Conversation

Skuzzle-UK
Copy link
Contributor

Description

Resolves bug where pressing reset in Stepper component pushed StepAction.Activate rather than StepAction.Reset

How Has This Been Tested?

Using the library at work and this bug was causing a lot of grief. Cloned repo, fixed bug and tested in our codebase. Now sending the correct action.

Type of Changes

  • Bug fix (non-breaking change which fixes an issue)

Checklist

  • The PR is submitted to the correct branch (dev).
  • My code follows the code style of this project.
  • I've added relevant tests.

@github-actions github-actions bot added bug Unexpected behavior or functionality not working as intended PR: needs review labels Nov 27, 2024
@Anu6is
Copy link
Contributor

Anu6is commented Nov 27, 2024

While I'm not familiar with this component, based on the comment on the method you updated, setting StepAction.Activate seems to be intended.

comment: Resets the completed status of all steps and set the first step as the active one.

What exactly was the bug you experienced? It may be worth providing more details on what the bug is (possibly with an associated image) and what the end result looks like now with the fix you implemented.

Additionally, there should be tests added to ensure that a similar bug isn't reintroduced (especially as this appears to be intentional)

@ScarletKuro
Copy link
Member

@henon

@Skuzzle-UK
Copy link
Contributor Author

The bug was presenting itself when I used OnPreviewInteraction="OnPreviewInteraction" with ShowResetButton

My method:

    private async Task OnPreviewInteraction(StepperInteractionEventArgs arg)
    {
        if (arg.Action == StepAction.Complete)
        {
            // occurrs when clicking next
            await ControlStepCompletion(arg);
        }
        if (arg.Action == StepAction.Reset)
        {
            Reset();
        }
    }

StepAction.Activate is not useful when reset is pressed. If you press back then it is useful but for reset you expect to be able to trigger a different method to pressing back and actually reset all steps. In my case this was a text field which would retain its value when reset was hit. With StepAction.Reset I am now able to have it clear that text field when reset is clicked, along with all other values in on all pages. This seems much more likely the intended purpose.

@Skuzzle-UK
Copy link
Contributor Author

Before reset clicked:
image

After:
image

Before this change there was no way to tell if it was back or reset that was clicked. Now I can click reset, capture the correct action and perform the reset that I desire and clear down my fields.

@danielchalmers danielchalmers requested a review from henon November 27, 2024 16:58
@henon
Copy link
Collaborator

henon commented Nov 28, 2024

@jgoday I concur. StepAction.Activate means the step is navigated to by the user if I am not mistaken. Thank you for dog-fooding the component and proposing this improvement.

A testcase is strictly necessary though to prevent other PRs from unintentionally breaking this functionality.

@henon
Copy link
Collaborator

henon commented Nov 28, 2024

Reset would activate the first step after it is done, right? So after a StepAction.Reset a StepAction.Activate should probably be sent for the first step?

@henon
Copy link
Collaborator

henon commented Nov 28, 2024

After: image

Before this change there was no way to tell if it was back or reset that was clicked. Now I can click reset, capture the correct action and perform the reset that I desire and clear down my fields.

Hmm, I'd expect that the error states are also resetted on Reset().

@Skuzzle-UK
Copy link
Contributor Author

Skuzzle-UK commented Nov 28, 2024

If everyone is happy with my findings and feels it is now following the correct logic let me know in the comments and I'll find time later to write some unit tests for this. No point writing tests if my idea of the logic is wrong if you get my drift.

@henon
Copy link
Collaborator

henon commented Nov 28, 2024

While I'm not familiar with this component, based on the comment on the method you updated, setting StepAction.Activate seems to be intended.

comment: Resets the completed status of all steps and set the first step as the active one.

This actually confirms everything we discussed. All steps are reset and then the first is activated. You can go ahead and write the test. I am only confused by your screenshot, there shouldn't be any errors after reset IMO. Is this another bug?

@Skuzzle-UK
Copy link
Contributor Author

While I'm not familiar with this component, based on the comment on the method you updated, setting StepAction.Activate seems to be intended.
comment: Resets the completed status of all steps and set the first step as the active one.

This actually confirms everything we discussed. All steps are reset and then the first is activated. You can go ahead and write the test. I am only confused by your screenshot, there shouldn't be any errors after reset IMO. Is this another bug?

I think there is maybe another bug depending on intention as stage 1 and 2 are in error state from a fresh load too so reset is putting everything back as it should, but maybe stage 1 and 2 should not show the error icon until you have tried to continue.

I'll write some tests around my original bug when I get 5 minutes later today and if we get clarification over when then exclamation should be visible I will be happy to write a bug report for that and possibly pick up the work putting that right some day soon.

@henon
Copy link
Collaborator

henon commented Nov 28, 2024

I think there is maybe another bug depending on intention as stage 1 and 2 are in error state from a fresh load too so reset is putting everything back as it should, but maybe stage 1 and 2 should not show the error icon until you have tried to continue.

I'll write some tests around my original bug when I get 5 minutes later today and if we get clarification over when then exclamation should be visible I will be happy to write a bug report for that and possibly pick up the work putting that right some day soon.

Sounds good. I remember something in the back of my head when I worked on the component, thinking that a Touched state would be nice for the steps to manage error display.

@Skuzzle-UK
Copy link
Contributor Author

I've added tests for this bug. I probably could have gotten away with updating the single controlled navigation test but I thought it best to go all in, belts and braces and what not

Copy link

sonarqubecloud bot commented Dec 3, 2024

Copy link

codecov bot commented Dec 3, 2024

Codecov Report

All modified and coverable lines are covered by tests ✅

Project coverage is 91.42%. Comparing base (43fbb95) to head (37de134).
Report is 13 commits behind head on dev.

Additional details and impacted files
@@            Coverage Diff             @@
##              dev   #10341      +/-   ##
==========================================
- Coverage   91.48%   91.42%   -0.07%     
==========================================
  Files         415      418       +3     
  Lines       13053    13226     +173     
  Branches     2473     2538      +65     
==========================================
+ Hits        11942    12092     +150     
- Misses        548      554       +6     
- Partials      563      580      +17     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

@henon henon changed the title ResetAsync now sends correct StepAction arg MudStepper: ResetAsync now sends correct StepAction arg Dec 4, 2024

await UpdateStepAsync(_steps[0], new MouseEventArgs(), StepAction.Activate);
await UpdateStepAsync(_steps[0], new MouseEventArgs(), StepAction.Reset);
}
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry for not looking at the code sooner. I think that the line you changed was actually correct. After all, after the reset we want to activate the first step. I assumed we'd do something like this:

        foreach (var step in _steps)
        {
            //await step.SetCompletedAsync(false, refreshParent: false);
            //if (resetErrors)
            //{
            //    await step.SetHasErrorAsync(false, refreshParent: false);
            //}
            await UpdateStepAsync(steps, new MouseEventArgs(), StepAction.Reset);
        }

        await UpdateStepAsync(_steps[0], new MouseEventArgs(), StepAction.Activate);

and move the commented code into UpdateStepAsync() to be executed only if the step action is Reset.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Have a play with the code I have changed. It works beautifully as expected in my business use case. I can't see any other logical way this should work. In my scenario reset will be caught as a unique action. I can choose to set var values back to original value etc and the stepper goes back to the first action as if I had hit f5 to refresh

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe you are right. It is certainly a working solution, if a bit implicit.

However, my concern was to make it work not only for your use-case but for every possible one. What if we later need to add a way to reset only single steps as opposed to the whole stepper? Then it might be breaking for you if we send a reset for just one step and you would implicitly assume the whole stepper was reset. I know "what if" arguments don't always make sense and are certainly a way to derail every design discussion, just trying to make sure we don't add any roadblocks.

I also get that it would be hard for you to distinguish between a full reset and a partial reset so I guess what I suggested above (sending a reset for every step on Reset()) is also not ideal.

I would do this: Let's rename StepAction.Reset to StepAction.ResetAll. This way it is clear that this is a full reset even if only the first step is sent with it (and we can always add StepAction.Reset later if needed for individual step resets). And I also suggest sending the original StepAction.Activate after sending the reset because it would be just inconsistent not to send it, the step is activated after all.

Does that sound good?

@ScarletKuro
Copy link
Member

@henon what is the status of this?
Do we merge? Reject? Or this needs to be reworked?

@henon
Copy link
Collaborator

henon commented Dec 30, 2024

Waiting on a reply to this: #10341 (comment)
Yes I think this needs a slight change to make sure the reset action is seen as a reset of all steps. Also I think it is not correct to remove the activation event for the first step which was sent after the reset before this change (or it should at least be discussed why it is better not to send it).

@Skuzzle-UK
Copy link
Contributor Author

I'll make some changes. Sorry, Christmas got in the way and now I'm back in to coding. Will get some actual work out of the way and find 5 minutes to make a nice solution.

@Skuzzle-UK
Copy link
Contributor Author

Updated with solution that I think we can all agree on.
Reset action is now sent for each step followed by activate of first step.
In my own use case I can handle this the same by ignoring all reset actions but 1. For other use cases they can react to each step reset even how they like.

Copy link

sonarqubecloud bot commented Jan 3, 2025

@ScarletKuro ScarletKuro requested a review from henon January 3, 2025 17:54
Copy link
Collaborator

@henon henon left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

OK, great. Thanks!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Unexpected behavior or functionality not working as intended
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants