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 jsTree based FileTreeSelector #6837

Open
wants to merge 29 commits into
base: main
Choose a base branch
from
Open

Add jsTree based FileTreeSelector #6837

wants to merge 29 commits into from

Conversation

philippjfr
Copy link
Member

@philippjfr philippjfr commented May 15, 2024

Adapts the panel-jstree components to support selecting both local and remote filesystems.

import s3fs
import panel as pn

from panel.widgets.tree import RemoteFileProvider

fs = s3fs.S3FileSystem(anon=True)
provider = RemoteFileProvider(fs=fs)

pn.widgets.FileTree(directory='s3://datasets.holoviz.org', provider=provider).servable()
Screenshot 2024-05-15 at 23 37 27

Done

  • Clean up RemoteFileProvider
  • Display loading icons while fetching directories

ToDo

  • Add composite component that adds additional controls for navigating different directories
  • Figure out how to efficiently update nodes as you are navigating directories (without losing state)
  • Allow navigating up and down a directory tree while respecting a max_depth parameter setting
  • Consider whether to create file provider internally and simply let the user provide a fsspec FileSystem
  • Add tests
  • Add docs

Nice To Have

  • Allow asynchronously fetching directories
  • Automatically infer the protocol (e.g. s3://) and create a FileSystem
  • Make the generic Tree implementation usable

@madeline-scyphers
Copy link

This is great. It was always my hope that panel-jstree would get put into panel someday. I am gonna put some comments on some parts for the things I was trying to work on when I had time.

The next thing I was trying to do for a side project I help with that was trying to use panel-jstree was create a composite widget, which here https://github.com/madeline-scyphers/panel-jstree/blob/1e364fcf5ff1947912ce8ba2b1f4d9753c4498d8/src/panel_jstree/widgets/jstree.py#L290

    def _set_data_from_directory(self, *event):
        self._data = [{"id": fullpath(self.directory),
                       "text": Path(self.directory).name,
                       "icon": self._folder_icon,
                       "state": {"opened": True},
                       "children": self._get_children_cb(Path(self.directory).name, self.directory,  depth=1)
                       }]

is a FileTree cb triggered on the directory change to swap out the entire data from scratch. I found this worked, but was a bit laggy (lag came from recreate the tree in the browser, not the directory search). Maybe the asynchronous tree will help, but if not, I was trying to play around with the massload plugin to see if that could also help but I never finished it with trying to finish my master's https://www.jstree.com/api/#/?f=$.jstree.defaults.massload

One thing I also wanted to mention was that I was trying really hard to make sure that there was a general tree implementation someone could use that would be independent of a FileTree if they just wanted to explore Tree data. It looks like that is still working properly, but I just want to underscore that I think that is really important, and ideally as many features can be generalized to work for a generalized Tree, not just a FileTree.

I added support for a number of jsTree's plugins, but there are a few more that might be cool to do. drag and drop was one I wanted to do next, which allows the user to just rearrange the Tree, though by default it can move a leaf to another node, so maybe not for the FileTree. Sort also is another one that might be nice. There is a search plugin as well.

That is most of most of what I had left that I wanted to do. I think the remote file provider is super cool, as well as the other features you all are adding. I would love to help with the last things to get this in.

panel/models/jstree.py Outdated Show resolved Hide resolved
f"{config.npm_cdn}/jstree@3.3.16/dist/themes/default/style.min.css",
]

__resources__ = [
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I replaced these icons, let's see if we can get rid of this.

panel/models/jstree.py Outdated Show resolved Hide resolved
Copy link

codecov bot commented May 22, 2024

Codecov Report

Attention: Patch coverage is 57.25191% with 112 lines in your changes are missing coverage. Please review.

Project coverage is 81.39%. Comparing base (97c2918) to head (e9a097c).

Files Patch % Lines
panel/widgets/file_selector.py 49.59% 62 Missing ⚠️
panel/widgets/tree.py 55.44% 45 Missing ⚠️
panel/models/jstree.py 91.17% 3 Missing ⚠️
panel/compiler.py 0.00% 1 Missing ⚠️
panel/util/__init__.py 50.00% 1 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main    #6837      +/-   ##
==========================================
- Coverage   81.52%   81.39%   -0.14%     
==========================================
  Files         318      320       +2     
  Lines       46776    47020     +244     
==========================================
+ Hits        38133    38270     +137     
- Misses       8643     8750     +107     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

@hoxbro
Copy link
Member

hoxbro commented May 28, 2024

Example of max_depth:

image

import s3fs
import panel as pn

fs = s3fs.S3FileSystem(anon=True)
pn.widgets.FileTree(directory="s3://datasets.holoviz.org", fs=fs, max_depth=2).servable()

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

6 participants