npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

@myrmidon/paged-data-browsers

v4.0.1

Published

Generic simple paged data browsers.

Downloads

252

Readme

Paged Data Browsers

This library provides simple components to display filtered and paged data from some service.

There are currently two components, one for displaying a flat list of data, and another to display hierarchically structured data, combining a tree view with paging.

Also, there is a LRU cache service and a compact pager used in the paged tree component.

Paged List

Paged list support is provided by a single utility class, PagedListStore. This templated class provides logic for:

  • a filter object of type F;
  • a list element object of type E.

So you need:

  • a filter class to represent your elements filter (for F).
  • an element item class (for E).
  • a service to fetch data, implementing interface PagedListStoreService<F, E>. In this shell, a local service provides mock data.

Paged Tree

Services

The core of the tree is a PagedTreeStore.

Tree nodes extend interface TreeNode, having:

  • id
  • parentId
  • y and x
  • label
  • tag
  • hasChildren

The corresponding node filter (TreeNodeFilter) has tags and parentId, both optional. Your filters will extend this one, just like your nodes extend TreeNode.

A paged tree node (PagedTreeNode<F> where F is TreeNodeFilter or any extension of it) extends a TreeNode by adding paging (PagingInfo: page number, count and total items), filtering, and expansion state. All the nodes entering the store are enriched with such data, thus becoming paged nodes.

The service which fetches nodes into the store is PagedTreeStoreService<F>. It provides a single method, getNodes(filter, pageNumber, pageSize, hasMockRoot?) to get the specified page of nodes.

The paged tree store (PagedTreeStore<E,F> where E=paged tree node and F=node filter) is the local store for tree nodes. Its ideal hierarchy is:

  • radix: a single, static radix node (Y=0, X=1) including all the other nodes. This is like the ground where one or more trees can be planted. Each tree is identified by a node's tag.
    • roots: the direct children of the radix (Y=1, X=1-N).
      • other descendant nodes, each with a higher Y level.

The essential store data are:

  • flat list of paged nodes (nodes$).
  • list of tree tags (tags$).
  • global filter (filter$). This gets combined with (overridden by) node-specific filters, when specified. You can set it with setFilter. To set the filter for the children of a specific node use setNodeFilter.
  • page size (pageSize), get/set property.

To initialize the store, you call reset, which loads root nodes (via its service's getRootNodes) and their direct children. When getting the children for each root node, an internal cache is used to minimize server fetches (via getPageFromCacheOrServer). The nodes got from the service are enriched with data required as paged tree nodes (paging, filtering, expansion).

Methods related to the cache are clearCache() and hasCachedPage(pageNumber, filter).

Nodes are managed in the tree with:

  • expand(id)
  • expandAll(id)
  • getChildren(id)
  • getNodes()
  • getRootNode()
  • isEmtpy()
  • collapse(id)
  • collapseAll()
  • changePage(parentId, pageNumber)
  • setFilter(filter)
  • setNodeFilter(id, filter)
  • reset()

Component

The component for visualizing each single node of the paged tree is BrowserTreeNodeComponent. This wraps some HTML content providing a toggle button to expand/collapse the node, a paging control for the node's children, and a button to edit the node's filter. You should then provide the HTML content to display the node's data inside this component, e.g.:

 <pdb-browser-tree-node [node]="node">
   <your-node-view [node]="node" />
 <pdb-browser-tree-node>

This component API has:

  • ➡️ node of type PagedTreeNode.
  • ➡️ paging (PagingInfo) with optional data about children nodes paging.
  • ➡️ debug (boolean) flag to toggle debug information in the view.
  • ➡️ hideLabel (boolean) flag to hide the node's loc and label. This is useful if you want to provide your own view for the node, between the expansion toggle and the filter edit button. In this case, in your consumer template provide your own view as the content of this component. If instead you are fine with the default loc and label, and just want to add more data to the view, then you can just add your own content to this component's template, without setting this property to true.
  • ➡️ hidePaging (boolean): true to hide the node's paging control unless hovered.
  • 🔥 toggleExpandedRequest (PagedTreeNode): emitted when the user wants to toggle the expanded state of the node.
  • 🔥 changePageRequest (PageChangeRequest): emitted when the user wants to change the page number of the node's children.
  • 🔥 editNodeFilterRequest (PagedTreeNode): emitted when the user wants to edit the node's filter for its children.

You should provide your components for:

  • the node's filters component. This is used both for global and node-specific filters (in the latter case as a popup).
  • the tree browser component. This combines:
    • a filters component for global filters. This dummy component gets a filter$ and emits filterChange.
    • a tree view.

The tree browser component uses a nested instance of PagedTreeStore<N,F>, typically injected via a middleman service like the sample PagedTreeBrowserService, which provides a new instance of the store to the component. The component orchestrates:

  • filter$ (observable of filters). This simply binds to the global filter of the nested store.
  • nodes$ (observable of paged tree nodes). Each of these nodes is displayed via a BrowserTreeNodeComponent. This simply binds to the nodes from the nested store, so these are all the nodes present in it. They are displayed in a list with various amounts of indentation representing the tree's hierarchy.
  • page change requests
  • filter change requests
  • expand/collapse requests
  • reset requests

All the requests are accomplished by virtue of the nested store.