Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add loading_indicator to global config #4259

Merged
merged 4 commits into from
Jan 11, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions doc/api/config.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,9 @@ The `pn.config` object allows setting various configuration variables, the confi
`exception_handler`
: A custom exception handler can be defined which should accept any exceptions raised while processing events originating from the frontend and onload callbacks.

`loading_indicator`
: Whether a loading indicator is shown by default when panes are updating.

`nthreads`
: If set will start a `ThreadPoolExecutor` to dispatch events to for concurrent execution on separate cores. By default no thread pool is launched, while setting nthreads=0 launches `min(32, os.cpu_count() + 4)` threads.

Expand Down
3 changes: 3 additions & 0 deletions panel/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,9 @@ class _config(_base_config):
load_entry_points = param.Boolean(default=True, doc="""
Load entry points from external packages.""")

loading_indicator = param.Boolean(default=False, doc="""
Whether a loading indicator is shown by default while panes are updating.""")

loading_spinner = param.Selector(default='arc', objects=[
'arc', 'arcs', 'bar', 'dots', 'petal'], doc="""
Loading indicator to use when component loading parameter is set.""")
Expand Down
18 changes: 10 additions & 8 deletions panel/param.py
Original file line number Diff line number Diff line change
Expand Up @@ -764,23 +764,19 @@ class ParamMethod(ReplacementPane):
return any object which itself can be rendered as a Pane.
"""

defer_load = param.Boolean(default=None, doc="""
defer_load = param.Boolean(default=config.defer_load, doc="""
Whether to defer load until after the page is rendered.
Can be set as parameter or by setting panel.config.defer_load.""")

lazy = param.Boolean(default=False, doc="""
Whether to lazily evaluate the contents of the object
only when it is required for rendering.""")

loading_indicator = param.Boolean(default=False, doc="""
Whether to show loading indicator while pane is updating.""")
loading_indicator = param.Boolean(default=config.loading_indicator, doc="""
Whether to show a loading indicator while the pane is updating.
Can be set as parameter or by setting panel.config.loading_indicator.""")

def __init__(self, object=None, **params):
if (
self.param.defer_load.default is None and
'defer_load' not in params and config.defer_load
):
params['defer_load'] = config.defer_load
super().__init__(object, **params)
self._evaled = not (self.lazy or self.defer_load)
self._link_object_params()
Expand Down Expand Up @@ -920,7 +916,13 @@ def _get_model(
def applies(cls, obj: Any) -> float | bool | None:
return inspect.ismethod(obj) and isinstance(get_method_owner(obj), param.Parameterized)

@param.depends(config.param.defer_load, watch=True)
def _update_defer_load_default(default_value):
ParamMethod.param.defer_load.default = default_value

@param.depends(config.param.loading_indicator, watch=True)
def _update_loading_indicator_default(default_value):
ParamMethod.param.loading_indicator.default = default_value

class ParamFunction(ParamMethod):
"""
Expand Down
55 changes: 55 additions & 0 deletions panel/tests/test_param.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
TextInput as BkTextInput, Toggle,
)

from panel import config
from panel.io.state import set_curdoc, state
from panel.layout import Row, Tabs
from panel.pane import (
Expand Down Expand Up @@ -1095,6 +1096,60 @@ def view(a):
assert pane._models == {}
assert inner_pane._models == {}

class ParameterizedMock(param.Parameterized):
run = param.Event()

@param.depends("run")
def click_view(self):
return "click..."

def test_param_function_pane_config_defer_load():
# When
app = ParameterizedMock()
test = ParamMethod(app.click_view)
# Then
assert test.defer_load==config.defer_load

# When
config.defer_load=not config.defer_load
app = ParameterizedMock()
test = ParamMethod(app.click_view)
# Then
assert test.defer_load==config.defer_load

# When
config.defer_load=not config.defer_load
app = ParameterizedMock()
test = ParamMethod(app.click_view)
# Then
assert test.defer_load==config.defer_load

# Clean Up
config.defer_load=config.param.defer_load.default
philippjfr marked this conversation as resolved.
Show resolved Hide resolved

def test_param_function_pane_config_loading_indicator():
# When
app = ParameterizedMock()
test = ParamMethod(app.click_view)
# Then
assert test.loading_indicator==config.loading_indicator

# When
config.loading_indicator=not config.loading_indicator
app = ParameterizedMock()
test = ParamMethod(app.click_view)
# Then
assert test.loading_indicator==config.loading_indicator

# When
config.loading_indicator=not config.loading_indicator
app = ParameterizedMock()
test = ParamMethod(app.click_view)
# Then
assert test.loading_indicator==config.loading_indicator

# Clean Up
config.loading_indicator=config.param.loading_indicator.default

def test_param_function_pane_update(document, comm):
test = View()
Expand Down