diff --git a/lumen/tests/views/test_base.py b/lumen/tests/views/test_base.py index be89ec2ae..dd92ae829 100644 --- a/lumen/tests/views/test_base.py +++ b/lumen/tests/views/test_base.py @@ -238,3 +238,32 @@ def test_view_title_download(set_root, view_type): button._on_click() assert button.data.startswith('data:text/plain;charset=UTF-8;base64') + + assert view.download.filename is None + assert view.download.format == 'csv' + + +@pytest.mark.parametrize("view_type", ("table", "hvplot")) +def test_view_title_download_filename(set_root, view_type): + set_root(str(Path(__file__).parent.parent)) + source = FileSource(tables={'test': 'sources/test.csv'}) + view = { + 'type': view_type, + 'table': 'test', + 'title': 'Test title', + 'download': 'example.csv', + } + + view = View.from_spec(view, source) + + title = view.panel[0][0] + assert isinstance(title, pn.pane.HTML) + + button = view.panel[0][1] + assert isinstance(button, DownloadButton) + + button._on_click() + assert button.data.startswith('data:text/plain;charset=UTF-8;base64') + + assert view.download.filename == 'example' + assert view.download.format == 'csv' diff --git a/lumen/views/base.py b/lumen/views/base.py index 6c0c8085f..88cbc8f19 100644 --- a/lumen/views/base.py +++ b/lumen/views/base.py @@ -52,11 +52,10 @@ class Download(Component, Viewer): color = param.Color(default='grey', allow_None=True, doc=""" The color of the download button.""") - filename = param.String(default=None, doc="""filenamefil + filename = param.String(default=None, doc=""" The filename of the downloaded table. File extension is added automatic based on the format. - If filename is not added, it will be based on the name of the view. - """) + If filename is not defined, it will be the name of the orignal table of the view.""") format = param.ObjectSelector(default=None, objects=DOWNLOAD_FORMATS, doc=""" The format to download the data in.""") @@ -109,10 +108,7 @@ def _table_data(self) -> IO: return io def __panel__(self) -> DownloadButton: - if self.filename: - filename = self.filename - else: - filename = slugify(self.view.title or self.view.pipeline.table) + filename = self.filename or slugify(self.view.pipeline.table) filename = f'{filename}.{self.format}' return DownloadButton( callback=self._table_data, filename=filename, color=self.color, @@ -189,7 +185,9 @@ def __init__(self, **params): if pipeline is None: raise ValueError("Views must declare a Pipeline.") if isinstance(params.get("download"), str): - params["download"] = Download(format=params["download"]) + *filenames, ext = params.get("download").split(".") + filename = ".".join(filenames) or None + params["download"] = Download(filename=filename, format=ext) fields = list(pipeline.schema) for fp in self._field_params: if isinstance(self.param[fp], param.Selector): @@ -385,7 +383,9 @@ def from_spec( # Resolve download options download_spec = spec.pop('download', {}) if isinstance(download_spec, str): - download_spec = {'format': download_spec} + *filenames, ext = download_spec.split('.') + filename = '.'.join(filenames) or None + download_spec = {'filename': filename, 'format': ext} resolved_spec['download'] = Download.from_spec(download_spec) view = view_type(refs=refs, **resolved_spec)