Source code for q2_sdk.ui.forms
import uuid
from typing import Optional, Union, List, TypedDict
from q2_sdk.core.configuration import settings
from q2_sdk.tools import jinja, utils
from . import modals
[docs]
class Q2Form:
def __init__(
self,
header: str,
list_of_rows=None,
custom_template: str = "",
hide_submit_button=False,
submit_label="Submit",
clear_button_label=None,
modal: Union[
modals.SuccessModal, modals.ErrorModal, modals.WarningModal
] = None,
custom_javascript="",
routing_key="",
):
"""
A basic Q2-styled form. Assumes that it is running inside a Q2
environment and that certain styles and JavaScript elements are present.
This already provides the <form id="sdkForm"> element, injecting
your custom code inside of it.
Guaranteed to render correctly and match the Q2 online environment's
look and feel, so is useful for basic forms or as a starting place for
iterating on something more complex.
:param header: If populated, is rendered as an <h1> at the top of the page
:param list_of_rows: (Deprecated. Prefer HTML in custom_template) Rows which in turn contain fields
:param custom_template: HTML to inject inside the provided shell
:param hide_submit_button: If True, this form will not have a submit button
:param submit_label: Text of the submit button
:param clear_button_label: Text of the clear button. If blank, no button will appear
:param modal: If provided, ties into Q2's existing javascript to display a modal over the form
:param custom_javascript: If provided, will be run after the rest of the form renders
:param routing_key: Creates a hidden input named routing_key which can be used by the extension
to determine what step to run next of a multi-step flow.
"""
self.routing_key = routing_key
self.header = header
self.submit_label = submit_label
self.clear_button_label = clear_button_label
self.show_required = False
self.modal = modal
self.rows = list_of_rows
self.base_template = "q2_form.html.jinja2"
self.custom_template = custom_template
self.custom_javascript = custom_javascript
self.hide_submit_button = hide_submit_button
self.template_name = "custom_form.html"
if list_of_rows:
for row in list_of_rows:
for field in row.fields:
if field.required:
self.show_required = True
break
# UUX will not always redraw the form if this is not present
self.guid = str(uuid.uuid4())
[docs]
def serialize(self) -> str:
"""Generates self.template_name with attributes of current instance"""
return jinja.jinja_generate(
self.template_name,
{
"this": self,
"file_upload_js": jinja.jinja_generate("js/file_upload.js"),
"container_image_tag": settings.IMAGE_TAG,
},
)
[docs]
class Q2TectonForm(Q2Form):
def __init__(
self,
header: str,
auth_tokens: List[AuthToken] | str,
tecton_version: str,
base_assets_url: str,
extension_name: str,
form_id: Optional[int] = None,
defer_fetching_stop: bool = False,
head_content: str = "",
foot_content: str = "",
custom_javascript: str = "",
routing_key: str = "",
custom_template: str = "",
hide_submit_button: bool = False,
submit_label: str = "Submit",
clear_button_label: Optional[str] = None,
tecton_beta: bool = False,
page_padding: bool = True,
load_platform_css: bool = True,
load_utilities: bool = True,
load_elements: bool = True,
load_default_theme: bool = True,
modal: Optional[
Union[modals.SuccessModal, modals.ErrorModal, modals.WarningModal]
] = None,
):
"""
Inherits from Q2Form, but adds several options for working with Tecton
enabled environments.
It is possible to use this directly, but typically will be invoked by
calling ``self.get_tecton_form`` from your Tecton Server Side Rendered extension
:param header: If populated, is rendered as an <h1> at the top of the page
:param q2token: SessionId Used to authenticate back through the Q2 system
:param tecton_version: Tecton url which will be dynamically imported in
a <script> tag
:param base_assets_url: Where the Python server is serving up the assets
(typically <root>:<port>/<extension>/assets)
:param extension_name: Used for calling back to the backend
:param form_id: id attribute of the <form> element
:param defer_fetching_stop: By default the loading spinner will go away
once the form is loaded. Setting this to True allows supresses that.
:param head_content: HTML injected into the <head> tag
:param foot_content: HTML injected at the bottom of the <html> tag
:param custom_javascript: If provided, will be run after the rest of the form renders
:param routing_key: Creates a hidden input named routing_key which can
be used by the extension to determine what step to run next of a
multi-step flow.
:param custom_template: HTML to inject inside the provided shell
:param hide_submit_button: If True, this form will not have a submit button
:param submit_label: Text of the submit button
:param clear_button_label: Text of the clear button. If blank, no button will appear
:param modal: If provided, ties into Q2's existing javascript to display a modal over the form
"""
# Backwards compatibility with q2_marketplace
if isinstance(auth_tokens, str):
auth_tokens = [{"key": "q2token", "value": auth_tokens}]
self.extension_name = extension_name
self.template_name = "custom_form.html"
self.custom_template = custom_template
self.routing_key = routing_key
self.header = header
self.submit_label = submit_label
self.clear_button_label = clear_button_label
self.head_content = head_content
self.foot_content = foot_content
self.custom_javascript = custom_javascript
self.hide_submit_button = hide_submit_button
self.base_template = "q2_tecton_form.html.jinja2"
self.tecton_version = tecton_version
self.tecton_beta = tecton_beta
self.page_padding = page_padding
self.load_platform_css = load_platform_css
self.load_utilities = load_utilities
self.load_elements = load_elements
self.load_default_theme = load_default_theme
self.auth_tokens = auth_tokens
self.modal = modal
self.base_assets_url = base_assets_url
if form_id:
form_id = int(form_id)
self.form_id = form_id
self.defer_fetching_stop = defer_fetching_stop
browser_link_url = None
self.browser_link = settings.DEBUG and not settings.DISABLE_BROWSER_LINK
if self.browser_link:
browser_link_url = utils.get_browser_link_url()
self.browser_link_url = browser_link_url
[docs]
class Q2SingleSignOn(Q2Form):
def __init__(
self, header, sso_url: str, use_viewport_height: bool = False, **kwargs
):
"""
(Deprecated. Prefer SSO extension_type since 2.19.0)
For embedding an external site in an iframe within the Q2 Online environment
:param header: Displays on mobile devices
:param sso_url: URL of the content server
:param use_viewport_height: If True, will set the bottom of the iframe to the height of the left nav menu
"""
super().__init__(header, **kwargs)
self.template_name = "q2_sso.html.jinja2"
self.sso_url = sso_url
self.use_viewport_height = use_viewport_height