Skip to content

Conversation

@anondo1969
Copy link
Member

@anondo1969 anondo1969 commented Oct 29, 2024

Description

Source: https://scilifelab.atlassian.net/browse/SS-1176

when we deploy an app it show app-subdomain.serve.scilifelab.se but if user wants the base page to be app-subdomain.serve.scilifelab.se/docs then that should be configurable. There is a field in the database for each app, called url. That’s the field we need to be able to modify with the extra setting.
This should be an advanced setting field for Custom app (similar to how site_dir is an advanced field for specifically Shiny apps now).

Checklist

If you're unsure about any of the items below, don't hesitate to ask. We're here to help!
This is simply a reminder of what we are going to look for before merging your code.

  • This pull request is against develop branch (not applicable for hotfixes)
  • I have included a link to the issue on GitHub or JIRA (if any)
  • I have included migration files (if there are changes to the model classes)
  • I have included, reviewed and executed tests (unit and end2end) to complement my changes
  • I have updated the related documentation (if necessary)
  • I have added a reviewer for this pull request
  • I have added myself as an author for this pull request
  • In the case I have modified settings.py, then I have also updated the studio-settings-configmap.yaml file in serve-charts

Further comments

Anything else you think we should know before merging your code!

@akochari akochari changed the title Ss 1176 ability for users to set a default start url for their apps Users are able to set a custom default start URL for their apps Nov 1, 2024
@akochari akochari changed the title Users are able to set a custom default start URL for their apps SS-1176 Users are able to set a custom default start URL for their apps Nov 1, 2024
@anondo1969 anondo1969 self-assigned this Nov 1, 2024
@anondo1969 anondo1969 marked this pull request as ready for review November 1, 2024 11:38
Copy link
Contributor

Choose a reason for hiding this comment

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

I'm not sure, that this class belongs here, tbh

Like, it's a module for custom types, but this a validator, not a new type if it makes sence

Copy link
Contributor

Choose a reason for hiding this comment

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

And you could use this docs to make it a part of initialization of a CharField on a apps/forms/custom.py:22

Copy link
Member

@alfredeen alfredeen Nov 13, 2024

Choose a reason for hiding this comment

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

I also agree that this is a validator rather than a new type and therefore does not belong in _types. Perhaps there was inspiration from the SubdomainCandidateName class but in that case it is logically a complete class with its own behavior and properties that we may continue to extend in the future.

Copy link
Member Author

Choose a reason for hiding this comment

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

Rewrote it in the apps/forms/custom.py

Comment on lines 14 to 17
__name = None

def __init__(self, name: str):
self.__name = name
Copy link
Contributor

Choose a reason for hiding this comment

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

I don't see a reason to not do it like this:)

Suggested change
__name = None
def __init__(self, name: str):
self.__name = name
def __init__(self, name: str):
self._name = name

Copy link
Member Author

Choose a reason for hiding this comment

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

Removed it.

error_message = (
"Your custom default URL is not valid, please correct it. "
"It must be 1-53 characters long."
" It can contain only Unicode letters, digits, hyphens"
Copy link
Contributor

Choose a reason for hiding this comment

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

So we are allowing unicode characters in the subpath?

Copy link
Member Author

Choose a reason for hiding this comment

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

Yes. We had a discussion and agreed on keeping unicode characters.

Copy link
Contributor

Choose a reason for hiding this comment

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

I have a few question about this file:

  • Why didn't you include the templates/apps/partials/srv_prepend_append_input_group.html?
  • I don't really like the <script> to be placed here. On the other hand, it sort of logical for it to be here, considering all the design choices that we've made. I just don't like two things: that it potentially won't work if it'll be used anywhere else, other than an app with an input for subdomain and second thing is that scripts should be grouped together in the header and not scattered.

Copy link
Member Author

Choose a reason for hiding this comment

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

I think because of the script I created a new file. I placed the script in the header section. Should I try to use the templates/apps/partials/srv_prepend_append_input_group.html for this?

app_orms = (app_model for app_model in APP_REGISTRY.iter_orm_models() if issubclass(app_model, SocialMixin))

for app_orm in app_orms:
logger.info("Processing: %s", app_orm)
Copy link
Contributor

Choose a reason for hiding this comment

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

Is there a reason to remove this?

"port": 8000,
"image": "ghcr.io/scilifelabdatacentre/image:tag",
"tags": ["tag1", "tag2", "tag3"],
"custom_default_url": "valid-custom_default_url/",
Copy link
Contributor

Choose a reason for hiding this comment

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

I'd call it a default_url_subpath, but I'm not insisting. Just that it's not a full URL, that's bothering me a little.

Copy link
Member Author

Choose a reason for hiding this comment

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

Rename this field to default_url_subpath all together.

Copy link
Member

@alfredeen alfredeen left a comment

Choose a reason for hiding this comment

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

I do not see any unit tests of the URL sub path validation.

@hamzaimran08 hamzaimran08 requested a review from Copilot November 18, 2024 15:44
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Copilot reviewed 5 out of 8 changed files in this pull request and generated 1 suggestion.

Files not reviewed (3)
  • templates/apps/partials/srv_prepend_input_group_custom_app.html: Language not supported
  • portal/views.py: Evaluated as low risk
  • apps/tests/test_forms.py: Evaluated as low risk

apps/helpers.py Outdated
URI = URI.strip("/")
if hasattr(instance, "custom_default_url") and instance.custom_default_url != "":
URI = URI + "/" + instance.custom_default_url
logger.info("Modified URI by adding custom default url for the custom app: " + URI)
Copy link

Copilot AI Nov 18, 2024

Choose a reason for hiding this comment

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

String concatenation using the '+' operator is not recommended. Use formatted strings or the logger's formatting capabilities instead.

Suggested change
logger.info("Modified URI by adding custom default url for the custom app: " + URI)
logger.info("Modified URI by adding custom default url for the custom app: %s", URI)

Copilot uses AI. Check for mistakes.
@anondo1969
Copy link
Member Author

I do not see any unit tests of the URL sub path validation.

Wrote two (pass/fail) unit tests for this.

Copy link
Contributor

@churnikov churnikov left a comment

Choose a reason for hiding this comment

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

We are close:)

I think after this I'd approve

Comment on lines +1 to +2
import regex as re
from django.core.exceptions import ValidationError
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
import regex as re
from django.core.exceptions import ValidationError
import regex as re
from django.core.exceptions import ValidationError

This should be caught by isort I think

Copy link
Member Author

Choose a reason for hiding this comment

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

Thank you. Addressed it.

Copy link
Contributor

Choose a reason for hiding this comment

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

Following this conversation https://github.com/ScilifelabDataCentre/serve/pull/249/files/3527fd079d58deac18bd5cd9461d242c37dbd8c7..83f995417664557d998e06b577565d4e008756c1#r1837858395

So I'd say, it would be best to also {%include %} the already existing markup for the prepend append group and not copy it.

Copy link
Member Author

Choose a reason for hiding this comment

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

Thank you. Worked on it.

Copy link
Collaborator

@hamzaimran08 hamzaimran08 left a comment

Choose a reason for hiding this comment

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

I would also suggest changing the file templates/apps/partials/srv_prepend_append_input_group.html with the following. The prepend text should be bold in my opinion

- <span class="input-group-text">{{ crispy_prepended_text }}</span>
+ <span class="input-group-text fw-bold">{{ crispy_prepended_text }}</span>

from django import forms
from django.core.exceptions import ValidationError
from django.utils.safestring import mark_safe

Copy link
Collaborator

Choose a reason for hiding this comment

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

Suggested change
from django.urls import reverse

Copy link
Member Author

Choose a reason for hiding this comment

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

Thank you. Addressed it.

image = forms.CharField(max_length=255, required=True)
path = forms.CharField(max_length=255, required=False)

default_url_subpath = forms.CharField(max_length=255, required=False, label="Custom default url subpath")
Copy link
Collaborator

Choose a reason for hiding this comment

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

Suggested change
default_url_subpath = forms.CharField(max_length=255, required=False, label="Custom default url subpath")
default_url_subpath = forms.CharField(max_length=255, required=False, label="Custom URL subpath")

Copy link
Member Author

Choose a reason for hiding this comment

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

Thanks. Changed it.

self.fields["volume"].initial = None

self.fields["default_url_subpath"].widget.attrs.update({"class": "textinput form-control"})
self.fields["default_url_subpath"].help_text = "Specify a non-default start URL if your app requires that."
Copy link
Collaborator

Choose a reason for hiding this comment

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

Suggested change
self.fields["default_url_subpath"].help_text = "Specify a non-default start URL if your app requires that."
self.fields["default_url_subpath"].help_text = "Specify a non-default start URL if your app requires that."
apps_url = reverse('portal:apps')

Copy link
Member Author

Choose a reason for hiding this comment

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

Thanks. Modified it.

Comment on lines 32 to 35
"We will display this URL for your app in our app catalogue."
" Keep in mind that when your app does not have anything on the root URL"
" (<span id='id_custom_default_url_subpath_form_help_text'></span>), if a user manually"
" navigates to the root URL, they will see an empty page there."
Copy link
Collaborator

@hamzaimran08 hamzaimran08 Nov 19, 2024

Choose a reason for hiding this comment

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

Suggested change
"We will display this URL for your app in our app catalogue."
" Keep in mind that when your app does not have anything on the root URL"
" (<span id='id_custom_default_url_subpath_form_help_text'></span>), if a user manually"
" navigates to the root URL, they will see an empty page there."
f"<span class='fw-bold'>Note:</span> This changes the URL connected to the Open button for an app"
f" on the Serve <a href='{apps_url}'>Apps & Models</a> page."

I think this text needs to be shorter. We can add a link to documentation and have longer text and examples of how to use this in a separate part of the docs in my opinion. This could be a separate task.

Copy link
Member Author

Choose a reason for hiding this comment

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

Thanks. Edited it.

Comment on lines 64 to 65
"Subdomain/",
template="apps/partials/srv_prepend_input_group_custom_app.html",
Copy link
Collaborator

Choose a reason for hiding this comment

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

Suggested change
"Subdomain/",
template="apps/partials/srv_prepend_input_group_custom_app.html",
mark_safe("<span id='id_custom_default_url_prepend'>Subdomain/</span>"),
template="apps/partials/srv_prepend_append_input_group.html",

I think one way to this this is to not use a separate template but use apps/partials/srv_prepend_input_group_custom_app.html, add an id to the Prepend input group element using span so that it is accessible through the javascript id match that you use. I have also tried to shorten the id, you can ofcourse choose another name.

Then I suggest moving parts of your javascript to the templates/apps/create_base.html file. The changes can be the following:

Load get_setting

{% load get_setting %}

In the script section make the following changes

+ const subdomainInput = document.getElementById("id_subdomain");
+ const customDefaultUrlFormModifiedUrlText = document.getElementById("id_custom_default_url_prepend");

+ function updateUrlWithSubdomain() {
+        const subdomainValue = subdomainInput.value.trim();
+        const displayValue = subdomainValue || "subdomain_name";
+      customDefaultUrlFormModifiedUrlText.innerHTML = `${displayValue}.{% get_setting 'DOMAIN' %}/</b>`;
+    }

    // User is "finished typing," do something
    function doneTyping () {


        let subdomain_input = $("#id_subdomain").val();
        if (subdomain_input.length == 0) {
            //console.log("Empty subdomain input");
            clearSubdomainValidation();
            // Empty text field. Enable the submit button and clear any validation styles.
            $("#submit-id-submit").prop('disabled', false);
        }
        else {
            //console.log(`Checking subdomain validity for: ${subdomain_input}`);
            // Run check if there is text in the input field
            // Convert the input subdomain to lowercase for the validation.
            // OK because the input form and the server does the same.
            checkSubdomainValidity(subdomain_input.toLowerCase());
        }
+        updateUrlWithSubdomain();
    }
........
........
........
 htmx.onLoad(function(content) {
        runScript();
+       updateUrlWithSubdomain();
    })

We already have an eventlistener listening to keystrokes on the subdomain input box. So we can use that one to update the URL for your input prepend text.

Copy link
Member Author

Choose a reason for hiding this comment

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

Thanks a lot for this suggestion. It helped me a lot to understand the existing scripts.

Copy link
Member

@alfredeen alfredeen left a comment

Choose a reason for hiding this comment

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

LGTM. Thanks for adding the unit tests. I will let others review the recent changes as well before approving.

@anondo1969
Copy link
Member Author

LGTM. Thanks for adding the unit tests. I will let others review the recent changes as well before approving.

Thank you so much.

Copy link
Collaborator

@hamzaimran08 hamzaimran08 left a comment

Choose a reason for hiding this comment

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

So, I think just this small change left. We need to catch the console error in case the element does not exist. Otherwise LGTM. Good work.

Comment on lines 130 to 132
const subdomainValue = subdomainInput.value.trim();
const displayValue = subdomainValue || "subdomain_name";
customDefaultUrlFormModifiedUrlText.innerHTML = `${displayValue}.{% get_setting 'DOMAIN' %}/</b>`;
Copy link
Collaborator

Choose a reason for hiding this comment

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

Suggested change
const subdomainValue = subdomainInput.value.trim();
const displayValue = subdomainValue || "subdomain_name";
customDefaultUrlFormModifiedUrlText.innerHTML = `${displayValue}.{% get_setting 'DOMAIN' %}/</b>`;
try {
const subdomainValue = subdomainInput.value.trim();
const displayValue = subdomainValue || "subdomain_name";
customDefaultUrlFormModifiedUrlText.innerHTML = `${displayValue}.{% get_setting 'DOMAIN' %}/</b>`;
} catch (error) {
console.log("No custom url subpath option in this app type.");
}

Copy link
Member Author

Choose a reason for hiding this comment

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

Thanks a lot. With it, it passed all the e2e test cases.

Copy link
Collaborator

@hamzaimran08 hamzaimran08 left a comment

Choose a reason for hiding this comment

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

LGTM. Good work.

@anondo1969
Copy link
Member Author

LGTM. Good work.

Thanks a lot.

@anondo1969 anondo1969 merged commit 8163d0d into develop Nov 21, 2024
3 checks passed
@anondo1969 anondo1969 deleted the SS-1176-Ability-for-users-to-set-a-default-start-URL-for-their-apps branch November 21, 2024 15:02
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.

6 participants