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

@lefapps/admin-dashboard

v1.2.4

Published

React package dashboard navigation

Downloads

5

Readme

Admin Dashboard

Use this package to automatically create a dashboard with navigation.

Usage

import { BrowserRouter as Router } from 'react-router-dom'
import AdminDashboard, { DashboardLink } from '@lefapps/admin-dashboard'
import { Translate } from '@lefapps/translations'
import { Users, User } from 'users'

const paths = [
  {
    path: '/users',
    component: UsersList,
    label: 'Users',
    views: [
      {
        path: '/new',
        component: User,
        label: 'Create new user'
      },
      {
        path: '/:_id',
        component: User,
        label: 'editing'
      }
    ]
  }
]

const NotFound = () => <h1>404: Path not found</h1>

const branding = {
  color: 'indianred', // color should be dark enough, used as background for white text
  logo: 'https://my.cdn/images/logo.png'
}

const WelcomeBoard = () => (
  <>
    <BoardHead title={'Welcome'} />
    <BoardBody>
      <Translate _id='home_page' md />
    </BoardBody>
  </>
)

const App = () => (
  <Router>
    <Switch>
      <Route path='/admin'>
        <AdminDashboard
          settings={paths}
          label={'Admin'}
          branding={branding}
          notFoundComponent={NotFound}
          darkMode
          allowFullscreen
        >
          <WelcomeBoard />
        </AdminDashboard>
      </Route>
    </Switch>
  </Router>
)

Components

DashboardLink

| prop | required | type | info | | ---------- | --------------- | ------ | --------------------------------------------------------------------------------------------------- | | to | yes1 | String | path to which you would like to linkmax 2 levels2 | | view | yes1 | String | use only when linking to a view (sub level) from it’s root levelonly accepts string without / | | ...props | no | Object | Add additional props like className, title, … |

  1. to or view are required, neither both nor none
  2. prop should match /^(\/?[^\/]+){1,${levels}}$/
import { DashboardLink } from '@lefapps/admin-dashboard'

// ROUTE: /users
const Users = users => (
  <ol>
    {users.map(({ _id, name }, i) => (
      <li key={i}>
        <DashboardLink view={_id}>{name}</id>
      </li>
    ))}
  </ol>
)

// ROUTE: /users/_id
const User = ({ _id, name }) => (
  <>
    <h3>{name}</h3>
    <p>
      This link will create a deeper level which can use the url parameters from its preceding boards
      ROUTE will be "/users/_id/articles" where you can use _id to filter the articles
      <DashboardLink to={'articles'}>view list ››</DashboardLink>
    </p>
    <small>
      This link will not create a deeper level since we already have a 'users' path
      ROUTE will be "/users"
      <DashboardLink to={'users'}>‹‹ back to all users</DashboardLink>
    </small>
  </>
)

BoardHead & BoardBody

| Head | required | type | info | | ---------- | -------- | ------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | title | | StringComponent | Title to show on top of the board | | content | | StringComponent | Text to display below the title | | actions | | Array | Buttons/links/… which are shown on the right. To ensure a nice layout, use icons as content. Use the [title] attribute to populate a tooltip below the action.(Note: apply key props to each element to prevent React warnings) | | children | | StringComponent | Text to display below title and contentsimilar to content |

| Body | required | type | info | | ---------- | -------- | ------------------- | -------------------------------------------------------------------------------------------- | | loading | | Boolean | Shows a spinner while your body content is loading.This prop does not prevent rendering! | | children | | StringComponent | Content to display inside the Board. |

import { DashboardLink, BoardHead, BoardBody } from '@lefapps/admin-dashboard'

const Users = ({loading, users}) => {
  const headProps = {
    title: 'Users',
    content: `${users.length} user(s)`,
    actions: [<button
      className={'btn'}
      onClick={goBack}
      title={'back -- used as tooltip'}
      key={0}>‹</button>,
    <DashboardLink
      className={'btn btn-lg'}
      to={'/users/add'}
      title={'Add a new user'}
      key={1}>+</DashboardLink>
    ]
  }
  return (<>
    <BoardHead {...headProps}>
      <p>Some optional text, which will be shown below "content".</p>
    </BoardHead>
    <BoardBody loading={loading}>
      <ul>
        {loading ? null : users.map(user => <li>{user.name}</li>)}
      </ul>
    </BoardBody>
  </>
)}

You can add the class admin-board__small-body__hidden to hide certain components in the BoardBody when displayed in the smaller sidebar. Please use sparingly. When this is needed, you are probably not using the dashboard as intended.

<BoardBody>
  <ul>
    {listItems}
  </ul>
  <form className={'admin-board__small-body__hidden'}>
    {formElements}
  </form>
</BoardBody>

BoardList

Use this component to display a minimally styled list (table) in BoardBodys.

import { BoardBody, BoardList, BoardListItem } from '@lefapps/admin-dashboard'

const Board = ({users}) => {
  const actions = _id => [
    {
      type: 'edit',
      view: _id
    }, {
      type: 'remove',
      onClick: () => removeUser(_id)
    }
  ]
  return <BoardBody>
      <BoardList>
        {users.map(({ _id, name, initials, email }, index) =>
          <BoardListItem
            key={index}
            label={initials}
            actions={actions(_id)}
          >
            <strong>{name}</strong>
            <br />
            <small>{email}</small>
          </BoardListItem>
        )}
      </BoardList>
    </BoardBody>
}

| prop | required | type | info | | -------- | -------- | -------- | ----------------------------------------------------------- | | label | | Node | label for the list item, can be a string, number or element | | actions | | [Object] | list of possible actions on item (see below) | | children | kind of | Nodes | Description of list item (e.g.: name or title) |

Actions

| prop | required | type | info | | ------- | -------- | ------ | ------------------------------------------------- | | to | | String | regular link | | view | | String | DashboardLink 'view' | | onClick | | Func | inline action method | | type | | String | predefined action type | | color | | String | bootstrap color name | | icon | | String | FontAwesome Icon | | loading | | Bool | set to true while awaiting inline action response | | error | | String | display message when inline action failed |

Predefined Action props

| Type | Color | Icon | | --------- | ------- | ---------- | | remove | danger | trash-alt | | edit | dark | edit | | view | info | eye | | link | warning | link | | unlink | warning | unlink | | drag | light | sort | | up | light | caret-up | | down | light | caret-down | | duplicate | warning | copy |

AdminTools

Use this component to wrap components to show up on the right-hand side of the breadcrumbs, e.g.: language selection or sign-out button. Correct styling will be provided. Raise an issue or pull request for specific styling issues.

import { AdminTools } from '@lefapps/admin-dashboard'
import { PickLanguage } from 'meteor/lef:translations'
import UserMenu from 'meteor/lef:userui'

const App = props => (
  <Router>
    <Route path={'/admin'}>
      <AdminDashboard {...props} />
      <AdminTools>
        <UserMenu />
        <PickLanguage />
      </AdminTools>
    </Route>
  </Router>
)

API

getLink

Footprint: const targetPath = getLink(path, level, isView)

Usage:

/base is the route where your Dashboard lives, e.g. "/admin"

const Comp = ({ getLink }) => {
  getLink('/path') // /base/path
  getLink('path') // /base/other/levels/path or /base/path
  getLink('id', null, true) // /base/level/id
  getLink(null, 3) // /base/level-1/level-2/level-3
}

withContext(<Comp />)

getUrl

Returns current url, without "/base".

getLevel

Returns current level, which is zero-based.

  • Home view: level = 0
  • Three panels deep: level = 2

Level is also stored in the state of the AdminDashboard component.

Todo

  • Labels can accept: string, function or component

Notes

Icons

The Alert components use the following Fontawesome Icons by default. Please add them to your library to prevent errors.

info: 'info-circle'
danger: 'exclamation-circle'
warning: 'question-circle'
success: 'check-circle'

If you use the allowFullscreen prop, make sure to add the following icons too:

faSignInAlt: 'sign-in-alt'
faSignOutAlt: 'sign-out-alt'