Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

💻 autosave feature #5311

Merged
merged 26 commits into from
Apr 10, 2024
Merged

💻 autosave feature #5311

merged 26 commits into from
Apr 10, 2024

Conversation

hasan-sh
Copy link
Contributor

Fixes #4888

Note
The autoSave function that i created can be used generically. So, in case we need it in the future, these are the steps that are needed:

  • make sure that in the HTML you have a form element with a onsubmit event (or htmx!).
    • all the inputs elements (incl. select, textarea etc) are then handled by the function
  • then add a script that invokes the function with the id of that form element, as in https://github.com/hedyorg/hedy/blob/autosave/templates/profile.html#L184-L189.
  • the fuction that you use to make the api request will be invoked once a change has occurred.

Furthermore, sometimes there's an element that we cannot attach an event listener on, like the CKEditor. In this case, you can pass an event as a secon argument to the autoSave function. When you do this, we simply invoke the submit trigger on the form element.

The customize-class page has two differently implemented features. The sortable adventures and the other inputs below. These two have to be syncronized. If we hide all quizzes, for instance, we want the adventure tabs to be updated. Now, instead of changing the whole structure, a third argument could be passed indicating that we should trigger an event on a certain element. See the autosave.ts file on how it's used.

How to test?
check the description of #4888 and test these pages.

Copy link
Member

@Felienne Felienne left a comment

Choose a reason for hiding this comment

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

Nice work @hasan-sh!

A few notes:

The (i) text appears in a weird place:

image

(not sure that is caused by this PR?)

The back button does not work anymore:
image

results in:
image

For the password save, I doubt whether we want an autosave? Somehow that (like making a profile public) feels like a very deliberate action. What do you think?

@hasan-sh
Copy link
Contributor Author

hasan-sh commented Apr 1, 2024

The (i) text appears in a weird place:

Which one exactly?

The back button does not work anymore:

Correct! I think @Annelein was going to fix this issue after adding all go back buttons?

For the password save, I doubt whether we want an autosave? Somehow that (like making a profile public) feels like a very deliberate action. What do you think?

I agree, shall i remove it?

@Annelein
Copy link
Contributor

Annelein commented Apr 1, 2024

Correct! I think @Annelein was going to fix this issue after adding all go back buttons?

See #5263

@hasan-sh
Copy link
Contributor Author

hasan-sh commented Apr 1, 2024

Great, that's now solved by #5349

@Felienne
Copy link
Member

Felienne commented Apr 1, 2024

The (i) text appears in a weird place:

The one I pasted above shows all the way at the bottom:

image

Should be above with the (i) I guess?

Copy link
Member

@jpelay jpelay left a comment

Choose a reason for hiding this comment

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

Hi @hasan-sh! This is a very cool feature, and I love it. I just had a couple of comments about code and functionality. Thanks!

) {
// Debounce function to prevent excessive requests
const formElement = document.getElementById(formId) as HTMLFormElement;
console.log(formId, formElement, customEvent)
Copy link
Member

Choose a reason for hiding this comment

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

Opps, can you delete this debug console log?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Good catch, thanks will do:)

const DEBOUNCE_TIMEOUT = 1000;

let timeoutId: ReturnType<typeof setTimeout> | null = null;
function debounce<F extends (...args: any[]) => any> (func: F, delay: number): (...args: Parameters<F>) => void {
Copy link
Member

Choose a reason for hiding this comment

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

I really like this solution!

@@ -209,4 +210,13 @@ <h3>{{_('adventure_exp_classes')}}</h3>
</div>
</div>
</div>
<script>
document.addEventListener("DOMContentLoaded", () => {
Copy link
Member

Choose a reason for hiding this comment

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

A while ago we were trying to get away from adding scripts to the templates, because we wanted all javascript code to be in a single place. I think you could use initiliaze.ts to initialize these functions in JavaScript.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Why though? I mean we don't really need to initialize anything if the route is not in the wanted page! What I do know is that the main issues with having different scripts is that it could cause a sluggish experience. Was there another (specific) problem we faced? I see that we still use it in some places!!

We could put it in initialize.ts, but it's not as incapsulated as this is! Perhaps it's a matter of docummentation?

Copy link
Member

Choose a reason for hiding this comment

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

I think the reason is that if all code is in one place, it is easy to see what is there. In the past we ran into the issue that similar code was in multiple places and when something was changed, some locations were overlooked. People might not look for js inside an HTML file (it is a sort of separation of concerns)

So I support the idea of having as much in one place as possible!

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I agree about the separation of cencerns concern. Will change it.

Two points. First, so the current scripts that are in html files we still have to clean up? And second there's several downsides of our current approach. The main and crucial one is that gradually more and more TS must be loaded even though it's not in use yet. This affects the overall performance of our app. If you're satisfied with the overall performance, we tackle it when needed. Just good to keep it in mind i think!

Copy link
Member

Choose a reason for hiding this comment

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

Two points. First, so the current scripts that are in html files we still have to clean up?

Yes, I would assume so! There is a lot of places where we still have js/ts in the HTML files, and we like to move that to HTMX or to a typescript file. I don't necessarily think we should do all of that right away, but maybe if you encounter it while working on other things, you can try to clean it up piece by piece. You can also do a bit of cleanup in between other tasks if you think it is a fun palet cleanser!

The main and crucial one is that gradually more and more TS must be loaded even though it's not in use yet.

I don't think that is where the bottle neck of performance is, but yes let's keep it in mind!

Copy link
Member

Choose a reason for hiding this comment

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

Is there a way to prevent this page from reloading every time I click on one of the options? The autosave works great, but that makes this page a little bit annoying to use.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Which options do you mean? I see it only reloads if we change the language or keyword language! These require a reload since the Ui changes accordingly!

@hasan-sh
Copy link
Contributor Author

Should be good to go @jpelay !!

Copy link
Member

@jpelay jpelay left a comment

Choose a reason for hiding this comment

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

Perfect!

@jpelay jpelay dismissed Felienne’s stale review April 10, 2024 13:28

Everything's done!

Copy link
Contributor

mergify bot commented Apr 10, 2024

Thank you for contributing! Your pull request is now going on the merge train (choo choo! Do not click update from main anymore, and be sure to allow changes to be pushed to your fork).

@mergify mergify bot merged commit d3f9d18 into main Apr 10, 2024
12 checks passed
@mergify mergify bot deleted the autosave branch April 10, 2024 13:29
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
Status: Done
Development

Successfully merging this pull request may close these issues.

[UX] Use autosave everywhere
4 participants