Skip to content

Commit

Permalink
Merge branch 'master' into assign_fix
Browse files Browse the repository at this point in the history
  • Loading branch information
emilhe authored Oct 7, 2023
2 parents f7e57ba + 2531cf4 commit edb24fc
Show file tree
Hide file tree
Showing 8 changed files with 177 additions and 54 deletions.
8 changes: 7 additions & 1 deletion .github/workflows/python-publish.yml
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ jobs:
- uses: actions/setup-node@v3
with:
node-version: 16
registry-url: https://registry.npmjs.org/
- name: Set up Python
uses: actions/setup-python@v4
with:
Expand All @@ -34,9 +35,14 @@ jobs:
- run: poetry --version
- name: Install dependencies
run: poetry install
- name: Build and publish
- name: Build and publish to npm
run: |
poetry run npm install | echo "Ignore npm install error"
poetry run npm run build
poetry run npm publish
env:
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
- name: Build and publish to pypi
run: |
poetry build
poetry publish --username=${{ secrets.PYPI_USERNAME }} --password=${{ secrets.PYPI_PASSWORD }}
10 changes: 8 additions & 2 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,17 @@

All notable changes to this project will be documented in this file.

## [1.0.4] - 31-07-23
## [1.0.4] - 07-10-23

### Added

- Publishing to npm added to CICD pipeline. Fixes [#284](https://github.com/emilhe/dash-extensions/issues/284)

### Changed

- Added `SerializationTransform` and `DataclassTransform`
- Dependencies updated
- Dynamic prefixing is now applied recursively
- Inline JS functions created using `assign` are now re-used if the code is identical

## [1.0.3] - 31-07-23

Expand Down
2 changes: 1 addition & 1 deletion dash_extensions/enrich.py
Original file line number Diff line number Diff line change
Expand Up @@ -927,7 +927,7 @@ def dynamic_prefix(app: Union[DashBlueprint, DashProxy], component: Component):
if len(prefix_transforms) == 0:
return
prefix_transform: PrefixIdTransform = prefix_transforms[0]
prefix_component(prefix_transform.prefix, component, prefix_transform.escape)
prefix_recursively(component, prefix_transform.prefix, prefix_transform.prefix_func, prefix_transform.escape)


# endregion
Expand Down
101 changes: 101 additions & 0 deletions dash_extensions/pages.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
import dash
from collections import OrderedDict
from typing import Optional
from dash import html, Input, Output, clientside_callback
from dash.development.base_component import Component

"""
This module holds utilities related to the [Dash pages](https://dash.plotly.com/urls).
"""

_ID_CONTENT = "_component_content"
_PATH_REGISTRY = OrderedDict()
_CONTAINER_REGISTRY = {}
_COMPONENT_CONTAINER = html.Div(id=_ID_CONTENT, disable_n_clicks=True)

# region Monkey patch page registration function

_original_register_page = dash.register_page


def _register_page(*args, dynamic_components=None, **kwargs):
_original_register_page(*args, **kwargs)
if dynamic_components is None:
return
module = kwargs['module'] if 'module' in kwargs else args[0]
page = dash.page_registry[module]
for component in dynamic_components:
set_visible(component, page['path'])


dash.register_page = _register_page


# endregion

# region Public interface

def assign_container(component: Component, container: Component):
"""
By default, dynamic components are rendered into the '_COMPONENT_CONTAINER' declared above. Call this function to
specify that the component should be rendered in a different container.
:param component: the (dynamic) component in question
:param container: the container into which the component will be rendered
:return: None
"""
if component in _CONTAINER_REGISTRY:
raise ValueError("You can assign a component to one container.")
_CONTAINER_REGISTRY[component] = container


def set_visible(component: Component, path: str):
"""
Register path(s) for which a component should be visible.
:param component: the (dynamic) component in question
:param path: the (url) path for which the component should be visible
:return: None
"""
_PATH_REGISTRY.setdefault(component, []).append(path)


def setup_dynamic_components() -> html.Div:
"""
Initializes the dynamic components and returns the (default) container into which the components are rendered.
:return: the default container, into which dynamic components are rendered. Should be included in the layout,
unless all (dynamic) components are assigned to custom containers (via 'assign_container')
"""
_setup_callbacks()
return _COMPONENT_CONTAINER


# endregion

# region Utils

def _prepare_container(container: Optional[Component] = None):
container = _COMPONENT_CONTAINER if container is None else container
# Make sure children is a list.
if container.children is None:
container.children = []
if not isinstance(container.children, list):
container.children = [container.children]
return container


def _setup_callbacks():
store = dash.dash._ID_STORE
location = dash.dash._ID_LOCATION
components = list(_PATH_REGISTRY.keys())
for component in components:
# Wrap in div to ensure 'hidden' prop exists.
wrapper = html.Div(component, disable_n_clicks=True, hidden=True)
# Add to container.
container = _prepare_container(_CONTAINER_REGISTRY.get(component, _COMPONENT_CONTAINER))
container.children.append(wrapper)
# Setup callback.
f = f"function(y, x){{const paths = {_PATH_REGISTRY[component]}; return !paths.includes(x);}}"
clientside_callback(f, Output(wrapper, "hidden"),
Input(store, "data"),
State(location, "pathname"))

# endregion
42 changes: 26 additions & 16 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "dash-extensions",
"version": "1.0.3",
"version": "1.0.4rc6",
"description": "Extensions for Plotly Dash.",
"main": "build/index.js",
"scripts": {
Expand Down
62 changes: 31 additions & 31 deletions poetry.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 2 additions & 2 deletions pyproject.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[tool.poetry]
name = "dash-extensions"
version = "1.0.3"
version = "1.0.4rc6"
description = "Extensions for Plotly Dash."
authors = ["emher <[email protected]>"]
license = "MIT"
Expand Down Expand Up @@ -45,7 +45,7 @@ requests = "^2.31.0"
certifi = "^2023.07.22"
uvicorn = "^0.20.0"
sse-starlette = "^1.2.1"
urllib3 = "^1.26.9"
urllib3 = "^1.26.17"

[build-system]
requires = ["poetry-core>=1.0.0"]
Expand Down

0 comments on commit edb24fc

Please sign in to comment.