Open SaintPeter opened 2 years ago
This is actually useful. Imagine if I just want to relearn front-end without resetting the progress on the algorithm course 🙄😱
This is something that's pretty commonly requested.
The challenge is with our data structure, unfortunately. An option to reset a specific superblock would need to find all completedChallenges
that are part of that superblock and remove them - and then do the same for progressTimestamps
.
Step 1: Enumerate challenges in the super block.
It's there code that already does this?
Step 2: Build find a filter for the completed timestamps?
I mean, maybe not easy.
I wonder how expensive this would be on the DB?
I wonder how expensive this would be on the DB?
Since it's a rare occasion (max a few per week), I don't think that would be a significant consideration. If it was happening once a minute, I might be concerned.
I wonder how expensive this would be on the DB?
It'll be about the same as the old way of submitting challenges (it recreated the challenge array each time). So, not long. The main thing is, as @SaintPeter said, it'll be rare.
Hey, I definitely want this feature, as mentioned on reddit, thanks a lot @SaintPeter for opening this issue. :+1:
As this is requested by a lot of people, I guess the team could do something. People would use it very scarcely I assume. I started the module, completed a few then got busy. So I would like to reset the progress to keep track of it.
I'm curious @SaintPeter - is the issue that users want to reset their progress? or just that they want to go through the steps in order again? It's probably a combination of both. I don't really see why someone would want to reset their progress on a block if they can just go through the steps in order again - but I guess I don't need to know. If we reset their progress, do we take away their points, too? Points that are just a timestamp and have no reference to any challenge.
I do like the idea of being able to reset a specific block or superblock, so I'm not opposed - but perhaps if we just went to the next lesson instead of the next incomplete lesson, users would be just satisfied enough not to bring it up. Probably a much easier and less complex potential solution, as well.
@moT01 There are two considerations: 1) Being able to progress from challenge to challenge in order 2) Keeping track of where they currently are in the challenges
Imagine that you had "life" happen in the middle of a cert. You go off for a year or so and want to come back to work on the material again, but you don't remember the stuff you did before. You might have several weeks worth of progression in a cert. It wouldn't matter if you could just go through them in order, you also need to keep track of where you left off, day to day. By far, the easiest way to do that is to reset the "superblock" progress.
I don't know anything about how points are used now. Are they even exposed to users anymore? I don't necessarily see a need to clear them out - they arguably earned them. Is it an integer or a list of timestamps?
The points are an array of timestamps, I believe. When you do a challenge you haven't completed before, you get a new timestamp added. I guess we could be fine to just give them another point - as you said, they did do the step again.
That all makes sense. I was looking for easy solution, but I don't think my suggestion would be enough - so I am in favor of adding this. I think we should allow the reset of a block or superblock.
I asked about this feature a few weeks back. (and since then I have fielded 2 similar requests on the forum. One person was okay to reset everything. I was not). I wanted this so I can reset the JS/frontend and on progress because I want to redo these courses. Does the current process of reset also clear the certifications? I'm not sure if people will want that so it is important to specify if clearing means the progress on the challenges only or also the certifications associated with it.
(ps. another reason is I also wanted to do a video showing the steps and explanation of the solutions so I wanted a clear field to record)
I added a help wanted label here if anyone wants to take a crack at it. Not quite sure what all the details of the implementation will look like.
I'll try to spend some time on it when I have some time over the next week or two.
So first I want to say that 90% my time is spent working on the front end so apologies if I say anything dumb lol.
Second, to me it doesn't seem like an issue to iterate over the challenges. For users who have gone through most of the courses we are talking about hundreds of entries, and somewhere in the low thousands once/if we migrate all courses to the new style where there are lots of steps. Realistically most users are not going to complete masa courses anyways so the real circumstances would likely be much slower in most cases. Iterating over let's say 2000 items doesn't seem like a big deal as long as we are talking about O(n) time constraints, which I think we are. My idea would be the following:
completedChallenges
and create the new array by filtering out challenges that have an ID that exists in that set/object. Regarding saving the changes, since we created a new array via filtering we can just save that, which would mean just one write to the database. progressTimestamps
and partiallyCompletedChallenges
How does this sound?
That's pretty close @oriooctopus - but thinking about it a little harder, I think it's going to be a little more complicated...
Resetting a superblock shouldn't have any conditionals - I think it might look something like this:
completedChallenges
, partiallyCompletedChallenges
, and savedChallenges
isCert
to false, e.g. if they reset the RWD superblock, set this isRespWebDesignCert
to falseFor the UI - I think something like SaintPeter's example would work. I've liked all your UI examples @oriooctopus, so I'm sure you can come up with something clean.
isCert
to falseNot sure what the UI would look like here. Maybe add a second dropdown in that example that shows all the blocks in the selected superblock? with an option for all
. Or maybe a button on the map, next to the resume project
button or something?
Note that there's many different UI's for different types of blocks (they don't all have that "resume" button), so adding a reset button here may be a little tricky.
For the progressTimestamps
, I'm not sure if we want to try and remove those or not. It's an array of timestamps - when you complete a challenge or do some other things, you get a point (current timestamp added). Not sure what other things give you points anymore, but we used to have a few ways to get points. The challenges do contain the completedDate
(timestamp), which theoretically, should match a timestamp in the progressTimestamps
- so we could potentially find those and remove them. I feel like I would lean towards just leaving them though, mainly because campers love seeing the "streak" on their profile. Removing timestamps could break a previous streak. Also, we want to implement "batch submissions", which would submit a group of challenges at once to save on api requests and database queries. Those might all share a timestamp. So removing timestamps based on them matching a complete challenge date might remove excess timestamps.
Side notes: The partiallyCompletedChallenges
is only for storing the 5 RDB cert projects, which require two steps to complete. After they finish the first step, it goes into there until they finish the second. The savedChallenges
are only for the new RWD cert projects (at the moment), which are completed in our editor. Users can save their code/progress on those to our database so they can work on them over multiple sessions.
It feels like this just got a lot more complicated, so no worries if you decide not to work on it @oriooctopus - or if you want to try and just do the superblock reset to start or something, that would be cool too. We will be around if you need any help.
Actually, now I'm not sure if we want to reset the certifications when something is reset. I don't think we came to a conclusion on that - I think we would be fine to just reset the challenges for an MVP for this. So we can probably ignore most of what I said there.
In danger zone will it be like individual completed/in-progress curriculum with reset button beside it?
Set the isCert to false, e.g. if they reset the RWD superblock, set this isRespWebDesignCert to false
So the isXCert
property on a user basically represents whether or not they passed the certificate?
Another question: what's the difference between a block and a SuperBlock? Is a SuperBlock an entire course like "Responsive Web Design" and a block one of the many parts of a course like "Learn HTML Forms by Building a Registration Form"?
For the progressTimestamps, I'm not sure if we want to try and remove those or not.
Yeah you're right we shouldn't
what's the difference between a block and a SuperBlock...
You got it 👍 Superblocks = "Responsive Web Design", "Front End Libraries", etc. Blocks = "Learn HTML Forms...", "Basic JavaScript", etc. Usually, a superblock is pretty much directly tied to a certification, but not always. "Coding Interview Prep" doesn't have a cert, for example.
Just to clarify - I don't think we want to reset the certifications when one of these is reset for now, just the challenges. So the isXCert
stuff can stay.
I'm pretty sure we shouldn't be resetting the certs values as campers who have added it to Linkedin will have an invalid link ie. the link will keep redirecting the user back to fCC home page with a flash message
So I've started working on this but as I dig deeper I have a few questions but fetching the data and structuring the changes. @moT01 Do you have a discord where I could ask those questions? I'm also happy to ask on a public channel if that's better
@oriooctopus fCC does have a Discord.
Details and join link here: https://www.freecodecamp.org/news/freecodecamp-discord-chat-room-server/
You can ask for assistance in the #contributors channel. Just post your general question with details and someone will come by.
Regarding whether or not to reset certifications I think we should be consistent with what we do with the 'reset all' functionality. Currently that means resetting the certifications as well, but I personally don't think we should be resetting certifications.
We also maybe want to leave it up to the user. In that case we could add a little check box to the confirmation modal that says "reset certification(s)" which could be unchecked by default.
Another thought I have is that it seems kind of bloated to include all 15 or so of the certificates and properties on the top level of the user. Besides cluttering out the other properties instead of being encapsulated into one property with sub properties, it makes our code more clunky as well. Consider the current reset logic, most of the lines are just dedicated to resetting the certificates and if any new certificates are added it would be easy to forget them here, which would create bugs.
Wouldn't it be cleaner to put them within an object property on the user? I see that the profileUI
property on the user is similar. That would be the ideal in my opinion. If we did that then in this reset function we could just set the value to an empty object which would be much more maintainable.
Another way that this makes things more difficult is the strange naming and the mapping required to work with it. I'm talking about things like api-server/src/server/utils/certTypes.json
. For this task for this task (if we don't do this proposed improvement to simplify things) I might have to create an additional mapping on top of that sense even the keys of that mapping don't match the IDs of the superblocks.
However, If we make the change I'm proposing and had an object property on the user the keys of that object would be the IDs of the super blocks. This would eliminate the need for mappings like the one above.
I made an initial design for this issue, which you can view here. Here’s a screenshot as well:
The goal was to include the functionality that allows campers to reset their progress in a specific course without losing all their progress. The problem I encountered was that by adding that, the section underneath that deletes the account looked like it was something separate from the other two, which could lead people to believe that the initial warning text (Please be careful. Changes in this section are permanent.) only applies to the first part. To solve this, I added labels to each section, to make it clear that the header applies to everything, and the individual label applies to each button. I also made the header bigger and added the word “All” in front of changes.
I have a couple of comments about the design:
The labels above the buttons should look like labels. They currently look like normal body text, like they do in this example I made, but I wanted to check with you before making that change:
The dropdown I created is just a placeholder, I didn’t spend time on it because you probably have a component for dropdowns. If you point it out to me, I’ll replace the placeholder dropdown I created with the one you guys have.
@laportabellita Great work, I like this mockup. I really like breaking out the header with more explanation. I'm thinking that we do need to just focus on the functionality of the buttons rather than say "Need a refresher" - we don't care so much why they are doing it, just what it does.
I was also thinking again that maybe putting the reset for the courses first and then a reset all below it might make more sense - going from a less destructive to more destructive option is more logical. I did a quick mockup of that below.
As an aside: Do we have standard language for describing what is being reset? Is it a "Course" or a "Module"? I don't know what verbiage is used elsewhere on the site, but we should be as consistent as possible about that.
I'd also like to see mockups or the verbiage for the confirmation dialogs which will explain exactly what will be reset. It feels like a bullet point list of items which will be reset would be good.
Finally, we should consider the internationalization/translations for these labels. We need to make sure that the description is clear and consistent across multiple languages.
That makes sense, I can switch the order. As for the changes of copy and verbiage, I wouldn't know about that, but if someone provides it for me I can include it in the design
This is how current UI looks like.
Are we planning modify entire danger zone ? Also is anyone working on this task as I would like to work on this.
@nayabatir1 We are aware of what the current Danger Zone looks like. It seems like putting a related function in the same area is a reasonable thing to do. We're discussing what the updated UI might look like.
I think a few people are working on it, but we generally accept the "first acceptable pull request". We don't really let people "claim" an issue.
You're certainly welcome to participate in the discussion.
@SaintPeter I think a couple of comments of mine got lost amidst the design discussion so I want to re-surface them as they're currently blocking my progress: https://github.com/freeCodeCamp/freeCodeCamp/issues/47464#issuecomment-1364608126 https://github.com/freeCodeCamp/freeCodeCamp/issues/47464#issuecomment-1364609695
@oriooctopus I did see those, but /learn
internals are not my area of expertise. I was focusing on giving UI/UX feedback.
At a high level, though: My initial impression is that you should see how many times/places those named values are used. Are there cases where multiple/all values need to be checked? What would a migration strategy look like, since the entire database (All user records) would need to be updated to take on the new strategy. I'm not maintaining the codebase, so I can't say if there might be other side effects.
Considering the volume of data (and the sensitivity of these specific records), I'd be hesitant to change them without an overall compelling reason. Maybe this is the time to pay down some tech debt in this area, but maybe not?
While it's not as clean as having the superblock IDs/block IDs, having human readable values is possibly more readable/maintainable?
Maybe @moT01 can chime in here?
So I definitely have less full stack experience than I do friend experience, I just wanna precurse my comment with that.
However, I don't think that this would be particularly tricky as long as we have a migration file. The data itself is very simple, it's just some boolean traits. My caveat here is given the scale of FreeCodeCamp there could be complexities I'm not anticipating like perhaps complexities arising from data being stored across multiple databases. However I think we won't have an issue in this case because the user table is self-contained, at least relating to the properties in question.
I'm also curious to see what @moT01 has to say
As I mentioned, I don't think we want to reset the certifications with this at the moment, only the challenges - so I think that is a separate issue @oriooctopus @SaintPeter. I created a new issue where we can discuss it to keep this issue focused on the reset functionality. I will leave my thoughts over there when I get a chance.
This issue was getting a little stale for a bit, so I added the help wanted label a while back in case someone wanted to work on it - but as I'm looking it over again, I have a new idea for the implementation...
I worry that it may not be clear to campers exactly what will be getting reset with the drop down on the settings page in the UI mocks. So I was thinking we could put the reset buttons on the map - maybe something like this:
I think I like this better. It feels like it would really only work for the blocks and not the superblocks - I don't see a good place to put a button like that, on this page, to reset the superblocks. Maybe we could keep the superblock reset in the settings page - or, I'm thinking that we should maybe just add the block reset for now, which I think solves the issue enough.
Then, clicking that button would bring up a model, maybe something like:
What do you all think? Maybe @ahmadabdolsaheb could weigh in if you get a chance. And you may want to hold off just a bit with continuing work on that PR @nayabatir1 - sorry.
@moT01 I think your proposed solution might be a bit easier and would likely serve the same need while being more discoverable. Honestly, I have a hard time finding the "Danger Zone" and I know where it's supposed to be. This has the advantage of being very "in your face".
I might move the "Reset Project" button to be right aligned, just so there is no possibility of a mis-click.
I suspect this will cover 95% of use cases - most people who are asking for a reset have not done all that much work prior to flaming out. The friction of having to open up each block and click the button is not too horrible.
Sorry for not communicating better, this is my first time working on a large open source project. I was working on this and had been figuring out how the backend aspect would work, and then was waiting for the answers to the questions. I may not be able to finish it once I start working 40 hours a week (i'm currently at 25) at my company starting the ninth, but can we hold off on the help wanted label until then?
@nayabatir1 have you started working on this? If so we could split the work
Regarding the design I have a couple thoughts:
@oriooctopus I don't have any objections to having it in both places.
If I understand correctly it would be at a block level in the Curriculum view ("Reset Project"), but at a Superblock level in the Settings page?
I like having the more "super powered" option on the settings page. We could potentially mention it in the Block level confirmation dialog ("To reset multiple projects, go to the Settings Page -> Danger Zone").
We could potentially mention it in the Block level confirmation dialog ("To reset multiple projects, go to the Settings Page - > Danger Zone
I think this is a good idea
I reverted this to just discussing again since we have a new implementation idea.
I'm not against having those things on the settings page, but I think I would vote to maybe just go with just the buttons on the map pages as the MVP for this. It will be easier to create and review. Trying to tackle too much at once will make a pretty big PR.
I would like to hear a few more opinions on these two ideas though first. I prematurely added the help wanted label last time, so I want to try and make sure we want one or both of these things first. cc @freeCodeCamp/dev-team
I agree, a good MVP is just the buttons on the map pages to reset a superblock. It makes possible what is currently not possible in any way (resetting progress), which is the primary complaint. It's also nicely granular.
We can always revisit the issue if there are more requests for a larger scale progress reset.
that would be to reset a block (single project - e.g. Learn Basic HTML by Building a Cat Photo App
), not superblock
I'm confused about block and superblock 😅
Is this superblock ?
Is this block?
That's correct, yes
The only comment I have is from looking at the newest design it seems weird that the reset button is taking up as much space as the continue button. That's almost implying that it's a common action if it's given that much importance. Maybe it should be a bit less prominent, perhaps we can replace it with an icon or move it just a little bit. I'm not sure.
How about this icon with tooltip as text Click here to reset your progress
or Restart from beginning
.
I'm not a fan of icons for destructive actions, personally. We want to be as clear as possible because typically there's no undoing it.
I am assuming we are going to use a modal dialog for verification before we actually do the reset? So that would potentially help clarify what the icon does because we could spell it out in the modal. But I do have the same concerns about this being a destructive behavior and I think that would be an argument against having the reset functionality on the map itself. Probably better to have it in the settings so that the user has to intentionally go there to reset the block instead of accidentally activating it.
Yes, there would definitely be a model before doing something destructive like this @bbsmooth. See my mock above.
We've always been hesitant with icons (avoided them) in our browser layouts for accessibility concerns (I think), so I don't think we want to go that route - we like to just spell it out. There's only one clickable icon on the entire site in the browser layout that I know of, the profile icon in the nav.
@bbsmooth
Probably better to have it in the settings so that the user has to intentionally go there...
I somewhat agree, but I don't think it's the way to go. My argument is that a dropdown or some sort of selector on the settings page isn't clear to campers what is being reset. They will just click Responsive Web Design
or Learn Basic HTML by Building a Cat Photo App
on the settings page and click reset. It isn't clear exactly what their selection will reset - whereas the button on the map will be right next to the thing they are resetting, with the modal to reinforce it.
@oriooctopus
it seems weird that the reset button is taking up as much space as the continue button.
Peter Rex (I knew that) mentioned making the button right aligned, which I think might make this concern a little better. Our buttons have a pretty standard size and I don't particularly like making this one smaller - but I understand the concern and am open to suggestions.
Tom's mock in a previous comment is the best place to do this. It's a clear and concise way of saying what is getting reset, i.e., the block (a.k.a project/challenge-series). There is less chance of a misclick. Did I mention it is the easiest and quickest to implement?
However, We will still need a "superblock" (a.k.a certification) level reset because users want to start over the whole certification, addressing the underlying demand, as Rex noted.
Is your feature request related to a problem? Please describe.
I see a question about once a week from campers who would like to reset their progress on a single module, IE: Responsive Web Design, JavaScript, etc. They have many reasons for wanting to do this - stepped away for a while and want to start over, etc. The current UI makes it quite hard to "progress" through the challenges if you have already completed them, since it goes to the next incomplete challenge.
Describe the solution you'd like
In the "Danger Zone" section of the settings, have a dropdown which lists all currently tracked modules, with a "Reset Progress" button next to it. Have a modal popup with an "Are you super duper sure, type 'RESET' to continue" type warning dialog.
Horrible Mockup
Describe alternatives you've considered
Currently the only options they have are to:
1) Reset ALL their progress via the Danger Zone button 2) Create a new account
I don't think that either are good options. The first means that they will lose ALL their work. If they want to reset their JS or later module, they would lose a huge amount of progress.
Creating a new account is basically the same, and is a negative for us. I presume we want to keep records of users as single entities for various metrics, etc.
Additional context
No response