From 49f7b909f8ccfc925dbe4cafb0444edf9ae1ee04 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Anders=20Fredrik=20Ki=C3=A6r?= <31612826+anders-kiaer@users.noreply.github.com> Date: Thu, 3 Oct 2019 14:42:24 +0200 Subject: [PATCH] Add guided tour (#111) --- examples/basic_example.yaml | 4 +++ setup.py | 2 +- tests/test_portable.py | 1 + webviz_config/_container_abc.py | 19 +++++++++++- webviz_config/containers/__init__.py | 2 ++ webviz_config/containers/_example_tour.py | 35 +++++++++++++++++++++++ 6 files changed, 61 insertions(+), 2 deletions(-) create mode 100644 webviz_config/containers/_example_tour.py diff --git a/examples/basic_example.yaml b/examples/basic_example.yaml index 18f92c64..8b26cccc 100644 --- a/examples/basic_example.yaml +++ b/examples/basic_example.yaml @@ -33,6 +33,10 @@ pages: - container: SyntaxHighlighter filename: ./basic_example.yaml + - title: Tour example + content: + - container: ExampleTour + - title: Plot a table content: - container: TablePlotter diff --git a/setup.py b/setup.py index 55071c9e..66c88f69 100644 --- a/setup.py +++ b/setup.py @@ -42,7 +42,7 @@ "pandas~=0.24", "pyarrow~=0.11", "pyyaml~=5.1", - "webviz-core-components>=0.0.8", + "webviz-core-components>=0.0.10", ], tests_require=TESTS_REQUIRES, extras_require={"tests": TESTS_REQUIRES}, diff --git a/tests/test_portable.py b/tests/test_portable.py index e3288b29..a4325399 100644 --- a/tests/test_portable.py +++ b/tests/test_portable.py @@ -29,6 +29,7 @@ def test_portable(dash_duo, tmp_path): "table_example", "pdf_example", "syntax_highlighting_example", + "tour_example", "plot_a_table", "last_page", ]: diff --git a/webviz_config/_container_abc.py b/webviz_config/_container_abc.py index 68ed16a0..6633e357 100644 --- a/webviz_config/_container_abc.py +++ b/webviz_config/_container_abc.py @@ -35,7 +35,13 @@ def layout(self): # E.g. download of zip archive will only appear if the container also # has defined the corresponding callback, and contact person will only # appear if the user configuration file has this information. - TOOLBAR_BUTTONS = ["screenshot", "expand", "download_zip", "contact_person"] + TOOLBAR_BUTTONS = [ + "screenshot", + "expand", + "download_zip", + "contact_person", + "guided_tour", + ] # List of container specific assets which should be copied # over to the ./assets folder in the generated webviz app. @@ -70,6 +76,12 @@ def container_data_output(self): def container_data_requested(self): return Input(self._container_wrapper_id, "data_requested") + @staticmethod + def _reformat_tour_steps(steps): + return [ + {"selector": "#" + step["id"], "content": step["content"]} for step in steps + ] + @staticmethod def container_data_compress(content): byte_io = io.BytesIO() @@ -113,5 +125,10 @@ def container_layout(self, contact_person=None): buttons=buttons, contact_person=contact_person, children=[self.layout], + tour_steps=WebvizContainerABC._reformat_tour_steps( + self.tour_steps # pylint: disable=no-member + ) + if "guided_tour" in buttons and hasattr(self, "tour_steps") + else [], ) return self.layout diff --git a/webviz_config/containers/__init__.py b/webviz_config/containers/__init__.py index 933625b8..f23a9549 100644 --- a/webviz_config/containers/__init__.py +++ b/webviz_config/containers/__init__.py @@ -10,6 +10,7 @@ from ._example_data_download import ExampleDataDownload from ._example_assets import ExampleAssets from ._example_portable import ExamplePortable +from ._example_tour import ExampleTour from ._banner_image import BannerImage from ._data_table import DataTable from ._syntax_highlighter import SyntaxHighlighter @@ -21,6 +22,7 @@ "ExampleContainer", "ExampleAssets", "ExamplePortable", + "ExampleTour", "BannerImage", "DataTable", "SyntaxHighlighter", diff --git a/webviz_config/containers/_example_tour.py b/webviz_config/containers/_example_tour.py new file mode 100644 index 00000000..f11b4958 --- /dev/null +++ b/webviz_config/containers/_example_tour.py @@ -0,0 +1,35 @@ +from uuid import uuid4 + +import dash_html_components as html + +from .. import WebvizContainerABC + + +class ExampleTour(WebvizContainerABC): + def __init__(self): + self.blue_text_id = f"element-{uuid4()}" + self.red_text_id = f"element-{uuid4()}" + + @property + def tour_steps(self): + return [ + {"id": self.blue_text_id, "content": "This is the first step"}, + {"id": self.red_text_id, "content": "This is the second step"}, + ] + + @property + def layout(self): + return html.Div( + children=[ + html.Span( + "Here is some blue text to explain... ", + id=self.blue_text_id, + style={"color": "blue"}, + ), + html.Span( + " ...and here is some red text that also needs an explanation.", + id=self.red_text_id, + style={"color": "red"}, + ), + ] + )