Source code for sepal_ui.sepalwidgets.tile
"""Custom Card widget to create Tiles in application.
Gather the customized ``ipyvuetifyWidgets`` used to create Tiles in the application panel framework.
All the content of this modules is included in the parent ``sepal_ui.sepalwidgets`` package. So it can be imported directly from there.
Example:
.. jupyter-execute::
from sepal_ui import sepalwidgets as sw
sw.TileDisclaimer()
"""
from pathlib import Path
from typing import List, Optional, Union
import ipyvuetify as v
from typing_extensions import Self
from sepal_ui.message import ms
from sepal_ui.scripts import utils as su
from sepal_ui.sepalwidgets.sepalwidget import SepalWidget
from sepal_ui.sepalwidgets.widget import Markdown
__all__ = ["Tile", "TileAbout", "TileDisclaimer"]
[docs]
class Tile(v.Layout, SepalWidget):
btn: Optional[v.Btn] = None
"the process btn"
alert: Optional[v.Alert] = None
"the alert to display process information to the end user"
title: Optional[v.Html] = None
"the title of the Tile"
[docs]
def __init__(
self,
id_: str,
title: str,
inputs: list = [""],
btn: Optional[v.Btn] = None,
alert: Optional[v.Alert] = None,
**kwargs,
) -> None:
"""Custom Layout widget for the sepal UI framework.
It is an helper to build a consistent tiling system. Tile objects are indeed compatible with the other classes from sepal_ui.
Args:
id_: the tile id that will be written in its mount_id _metadata attribute
title: the title of the Tile
inputs: the list of widget to display inside the tile
btn: the process btn
alert: the alert to display process information to the end user
kwargs: any parameter from a v.Layout. if set, 'children' and '_metadata' will be overwritten.
"""
self.btn = btn
inputs += [btn] if btn else []
self.alert = alert
inputs += [alert] if alert else []
self.title = v.Html(xs12=True, tag="h2", children=[title])
content = [v.Flex(xs12=True, children=[widget]) for widget in inputs]
card = v.Card(
class_="pa-5", raised=True, xs12=True, children=[self.title] + content
)
# set some default parameters
kwargs["_metadata"] = {"mount_id": id_}
kwargs.setdefault("row", True)
kwargs.setdefault("align_center", True)
kwargs.setdefault("class_", "ma-5 d-inline")
kwargs["children"] = [card]
# call the constructor
super().__init__(**kwargs)
[docs]
def nest(self) -> Self:
"""Prepare the tile to be used as a nested component in a tile.
the elevation will be set to 0 and the title remove from children.
The mount_id will also be changed to nested.
"""
# remove id
self._metadata["mount_id"] = "nested_tile"
# remove elevation
self.children[0].elevation = False
# remove title
self.set_title()
return self
[docs]
def set_content(self, inputs: list) -> Self:
"""Replace the current content of the tile with the provided inputs.
It will keep the output and btn widget if existing.
Args:
the list of widget to display inside the tile
"""
# create the widgets
content = [v.Flex(xs12=True, children=[widget]) for widget in inputs]
# add the output (if existing)
if self.title:
content = [self.title] + content
if self.alert:
content = content + [self.alert]
if self.btn:
content = content + [self.btn]
self.children[0].children = content
return self
[docs]
def set_title(self, title: str = "") -> Self:
"""Replace the current title and activate it.
If no title is provided, the title is removed from the tile content.
Args:
title: the new title of the object
"""
# set the title text
self.title.children = [title]
# add the title if it's deactivated
if title and self.title not in self.children[0].children:
self.children[0].children = [self.title] + self.children[0].children.copy()
# remove it if it's deactivated
elif self.title in self.children[0].children and not title:
# it's the first one
self.children[0].children = self.children[0].children.copy()[1:]
return self
[docs]
def get_title(self) -> str:
"""Return the current title of the tile.
Returns:
the title
"""
return self.title.children[0]
[docs]
def get_id(self) -> str:
"""Get the mount_id value.
Returns:
the moun_id value from _metadata dict
"""
return self._metadata["mount_id"]
[docs]
class TileAbout(Tile):
[docs]
def __init__(self, pathname: Union[str, Path], **kwargs) -> None:
"""Create an about tile using a .md file.
This tile will have the "about_widget" id and "About" title.
Args:
pathname: the path to the .md file
"""
content = Markdown(Path(pathname).read_text())
super().__init__("about_tile", "About", inputs=[content])
[docs]
class TileDisclaimer(Tile):
[docs]
def __init__(self) -> None:
"""Create an about tile.
This tile will have the "about_widget" id and "Disclaimer" title.
"""
# create the tile content on the fly
disclaimer = " \n".join(ms.disclaimer.p)
disclaimer += " \n"
disclaimer += '<div style="inline-block">'
# add the logo (href, src, alt)
logo_list = [
("http://www.openforis.org", "open-foris.png", "openforis_logo"),
("https://sepal.io", "sepal.png", "sepal_logo"),
]
theme = "dark" if v.theme.dark is True else "light"
url = f"https://raw.githubusercontent.com/12rambau/sepal_ui/master/sepal_ui/frontend/images/{theme}"
for href, src, alt in logo_list:
disclaimer += f'<a href="{href}"><img src="{url}/{src}" alt="{alt}" height="100" class="ma-3"/></a>'
# close the file
disclaimer += "</div>"
content = Markdown(disclaimer)
super().__init__("about_tile", "Disclaimer", inputs=[content])