Skip to content

Conversation

@humitos
Copy link
Member

@humitos humitos commented Jul 2, 2025

This is just a demo of what we can do and/or how to use the last_login_method template variable. This needs more discussion and work, but opening as a draft to have something to talk over.

Email

Screenshot_2025-07-02_17-33-48

GitHub App

Screenshot_2025-07-02_17-34-33

Requires: readthedocs/readthedocs.org#12286
Closes #421

humitos added 2 commits July 2, 2025 17:32
This is just a demo of what we can do and/or how to use the `last_login_method`
template variable.

Closes #421
@agjohnson
Copy link
Contributor

agjohnson commented Jul 9, 2025

One concern I have about using a label and putting the label inside the menu item is that this menu already has space constraints, especially business accessing private versions:

image

With an added label it's going to be very tight and might wrap the menu or menu items.

I was going to use a tooltip for the menu and buttons:

image

<button class="ui  button" type="submit" title="GitLab" data-tooltip="Last used" data-variation="teal visible" data-position="right center">

I think even the menu labeled options could be rethought here though. We should probably just default to the correct tab, no? Do we need a label on this menu?

This is something you'd do at the template level, no JS should be required. We talked in #421 about passing some value to the templates so the templates could render the elements.

@humitos
Copy link
Member Author

humitos commented Jul 10, 2025

I was going to use a tooltip for the menu and buttons:

Tooltips work for me 👍🏼

I think even the menu labeled options could be rethought here though. We should probably just default to the correct tab, no? Do we need a label on this menu?

I'm already doing this in https://github.com/readthedocs/ext-theme/pull/622/files#r2194496182. Do you refer to something different here?

@agjohnson
Copy link
Contributor

Do you refer to something different here?

Yes, specifically "do we need to put a label on the menu"? If we're defaulting is it necessary?

@humitos
Copy link
Member Author

humitos commented Jul 14, 2025

OK, this is moving in a good direction 👍🏼 . I only need to attach the buttons to a specific callback to set the cookie, but all the other login to handle the variables in the template are in place:

VCS - GitHub App

Peek.2025-07-14.14-48.webm

VCS - GitLab

Screenshot_2025-07-14_14-51-38

Email

Screenshot_2025-07-14_14-52-50

SSO

Screenshot_2025-07-14_14-54-05

@humitos
Copy link
Member Author

humitos commented Jul 14, 2025

Yes, specifically "do we need to put a label on the menu"? If we're defaulting is it necessary?

Only for email, since there is no other indicator otherwise.

@humitos humitos marked this pull request as ready for review July 14, 2025 15:21
@humitos humitos requested a review from a team as a code owner July 14, 2025 15:21
@humitos humitos requested a review from agjohnson July 14, 2025 15:21
@humitos
Copy link
Member Author

humitos commented Jul 14, 2025

I had to run the development server at localhost for the cookieStore to work. I used this diff:

diff --git a/dockerfiles/nginx/default.conf.template b/dockerfiles/nginx/default.conf.template
new file mode 100644
index 00000000..e69de29b
diff --git a/dockerfiles/nginx/web.conf.template b/dockerfiles/nginx/web.conf.template
index 9badfd39..69659d14 100644
--- a/dockerfiles/nginx/web.conf.template
+++ b/dockerfiles/nginx/web.conf.template
@@ -1,6 +1,6 @@
 server {
-    listen 80;
-    server_name $NGINX_WEB_SERVER_NAME;
+    listen 80 default_server;
+    server_name $NGINX_WEB_SERVER_NAME localhost;
 
     location /static/ {
         proxy_pass http://storage:9000/static/;
@@ -9,10 +9,10 @@ server {
 
     location / {
         proxy_pass http://web:8000/;
-        proxy_set_header Host $http_host;
+        proxy_set_header Host devthedocs.com;
+        proxy_set_header X-Forwarded-Host devthedocs.com;
         proxy_set_header X-Real-IP $remote_addr;
         proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
-        proxy_set_header X-Forwarded-Host $host;
 
         add_header X-Served Django always;
     }
@@ -30,6 +30,4 @@ server {
 
         add_header X-Served Nginx-Proxito-Sendfile always;
     }
-
-
 }
diff --git a/dockerfiles/nginx/wrangler.conf.template b/dockerfiles/nginx/wrangler.conf.template
index b99d1fae..82a6fa12 100644
--- a/dockerfiles/nginx/wrangler.conf.template
+++ b/dockerfiles/nginx/wrangler.conf.template
@@ -1,6 +1,6 @@
 # Proxito
 server {
-    listen 80 default_server;
+    listen 80;
     server_name $NGINX_PROXITO_SERVER_NAME;
 
     # Docker Compose's "logging.driver: none" is not working anymore.

@humitos
Copy link
Member Author

humitos commented Jul 29, 2025

@agjohnson can you take a look at this and do a final review here?

@humitos
Copy link
Member Author

humitos commented Oct 6, 2025

@agjohnson this is ready for review -- can you take a look?

variation.pop("visible");
button.dataset.variation = variation.join(" ");
}
}
Copy link
Contributor

Choose a reason for hiding this comment

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

You should always use KO view code to manipulate the DOM. Using JS queries or jQuery to manipulate the DOM in addition is mixing patterns and should be always avoided.

I'm a bit confused what this is trying to do though. What is the intention here? It also seems like this would affect all modals, which we don't want.

Copy link
Member Author

Choose a reason for hiding this comment

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

This was the way I found to solve this issue:

Peek.2025-11-26.17-58.webm

I'm not sure how to solve it in a better way.

Copy link
Contributor

@agjohnson agjohnson Nov 27, 2025

Choose a reason for hiding this comment

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

Okay yeah, there are better ways to achieve that.

I think part of what is making this complicated is mixing non-Knockout JS patterns, template code, and SUI HTML-only tooltips together. The display issues seem to be from HTML-only tooltips mostly too, so maybe that isn't a good direction. Instead the solution here would be more consistent if it leaned into using Knockout more, and JS driven tooltips/popups are more robust anyways.

@humitos
Copy link
Member Author

humitos commented Nov 26, 2025

@copilot can you help to perform the changes required from the reviewer?

Copy link

Copilot AI commented Nov 26, 2025

@humitos I've opened a new pull request, #670, to work on those changes. Once the pull request is ready, I'll request review from you.

Addresses reviewer feedback to move login-related JS from
`ApplicationView` to a dedicated view class, following the established
pattern for view separation.

### Changes

- **New `LoginView` class** (`src/js/account/index.js`): Dedicated view
for login functionality with `save_login_method` handler
- **Remove from `ApplicationView`**: Deleted `save_login_method` and
removed DOM manipulation in `show_modal` that incorrectly modified all
button tooltips
- **Template updates**: Wrap login content with `data-bind="using:
LoginView()"` context, replace `$root.save_login_method` with
`save_login_method`
- **djlint**: Changed generic `{# djlint: off #}` to specific `{#
djlint: off D018 #}` for template tags in attributes

### Usage

```html
<div data-bind="using: LoginView()">
  <button data-bind="click: save_login_method" data-provider="github">
    Log in using GitHub
  </button>
</div>
```

<!-- START COPILOT CODING AGENT TIPS -->
---

💡 You can make Copilot smarter by setting up custom instructions,
customizing its development environment and configuring Model Context
Protocol (MCP) servers. Learn more [Copilot coding agent
tips](https://gh.io/copilot-coding-agent-tips) in the docs.

---------

Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: humitos <244656+humitos@users.noreply.github.com>
Co-authored-by: Manuel Kaufmann <humitos@gmail.com>
@humitos
Copy link
Member Author

humitos commented Nov 26, 2025

I put AI to work on it and it gave me a really good solution. There is only one comment left that we need to solve, but I'm not sure how to do what I showed in the GIF in a better way.

Copy link
Contributor

@agjohnson agjohnson left a comment

Choose a reason for hiding this comment

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

What the LLM gave back is a mixture of patterns. This can be done in a more consistent way using KO/SUI directly. See #671

Comment on lines +106 to +107
data-bind="click: save_login_method"
data-provider="email"
Copy link
Contributor

@agjohnson agjohnson Nov 26, 2025

Choose a reason for hiding this comment

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

This is still working against KO a bit. We should really not need to do Event or Element manipulation to use data with KO. The two patterns that we already have available are:

data-bind="click: () => { save_login_method('email') }"

Or better if you need to do something like ensure the click event is handled normally (true is returned from the function):

data-bind="click: save_login_method.bind($data, 'email')"

Both from: https://knockoutjs.com/documentation/click-binding.html

Copy link
Member Author

Choose a reason for hiding this comment

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

Oh, I see. I didn't know that using a KO function in data-bind that reads data-* attributes was a mixing of patterns 👍🏼

data-bind="click: save_login_method"
data-provider="sso"
type="submit"
{% if last_login_method == "sso" %} data-tooltip="Last used" data-variation="teal visible" data-position="right center" {% endif %}
Copy link
Contributor

Choose a reason for hiding this comment

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

These all need translated:

Suggested change
{% if last_login_method == "sso" %} data-tooltip="Last used" data-variation="teal visible" data-position="right center" {% endif %}
{% if last_login_method == "sso" %} data-tooltip="{% trans "Last used" %}" data-variation="teal visible" data-position="right center" {% endif %}

*
* <div data-bind="using: LoginView()">
* <form method="post" action="...">
* <button data-bind="click: save_login_method" data-provider="github">
Copy link
Contributor

Choose a reason for hiding this comment

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

Noted above how this should probably use KO patterns instead of mixing element attribute and KO patterns. I don't see where else we're using data-provider


{# djlint: off D018 #}
<button class="ui {{ button_classes }} button"
data-bind="click: save_login_method"
Copy link
Contributor

Choose a reason for hiding this comment

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

This will cause the connected service page to throw exceptions and break. That view will not have this binding, so it can only be added conditionally.

variation.pop("visible");
button.dataset.variation = variation.join(" ");
}
}
Copy link
Contributor

@agjohnson agjohnson Nov 27, 2025

Choose a reason for hiding this comment

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

Okay yeah, there are better ways to achieve that.

I think part of what is making this complicated is mixing non-Knockout JS patterns, template code, and SUI HTML-only tooltips together. The display issues seem to be from HTML-only tooltips mostly too, so maybe that isn't a good direction. Instead the solution here would be more consistent if it leaned into using Knockout more, and JS driven tooltips/popups are more robust anyways.

@humitos
Copy link
Member Author

humitos commented Nov 27, 2025

What the LLM gave back is a mixture of patterns. This can be done in a more consistent way using KO/SUI directly

Ah, from your previous review I didn't understand we wanted to change from HTML-based tooltips to JS. By the way, the LLM did exactly what I would've done by myself.

I will take a look at your PR and see if I can continue from there.

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Login: show "Last used" small icon when showing all the options to login

3 participants