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

@myena/vue-table

v1.1.0

Published

Vue Table components (client/server) used in ENA projects

Downloads

301

Readme

vue-table

CircleCI (all branches) npm (scoped) NpmLicense npm bundle size (minified + gzip) David David

What's this

Components to render a table using client or remote data

Install

npm install @myena/vue-table

Dependencies

  • Vue 2
  • Bootstrap 3
  • FontAwesome 4

Demo

https://myena-vue-table.netlify.app/

Vue Client Table

Vue component for rendering a client side table with pagination, grouping, sorting, filtering, details row. Entire table data should be given to the table and will be paginated client side. Data can come from a Vuex store.

Usage:

<EnaTableClient :columns="columns" :options="options" :data="data" :loading="loading">
  <my-custom-filter-component slot="filter" v-on:search="search"></my-custom-filter-component>
  <span slot="__group_meta" slot-scope="{ data }">
    <strong><span v-html="data.label"></span> (Total in group: {{data.total}})</strong>
  </span>
  <template slot="heading_column1">
    <div>Custom heading of column1</div>
  </template>
  <template slot="column_column1" slot-scope="{ row }" >
    <span><i v-if="row.column2 === 'disable'" class="fa fa-ban"></i> {{row.column1}}</span>
  </template>
  <template slot="details_row" slot-scope="{ row }">
    <div>Div for details (expanded) row</div>
  </template>
</EnaTableClient>

As plugin (or in Browser)

// this will create the global (window) object "EnaTableClient"
import '@myena/vue-table/dist/EnaTableClient';
// or include as script in html : <script type="text/javascript" src="node_modules/@myena/vue-table/dist/EnaTableClient/index.js"></script>
// registers the component globally

// in the view that contains the table
const MyView = new Vue({
  data() {
    // Define properties
    return {
      /**
       * List of objects to present in the table
       *
       * @member
       * @type {Array}
       */
      data: Array,
      /**
       * List of keys to use from each object (table columns)
       *
       * @type {Array}
       */
      columns: Array,
      /**
       * The filter object. If updated will filter the results by the value
       *
       * @type {Object}
       */
      filter: {
        type: Object,
        default: () => ({
          // The search query string. If updated will filter the results by the value
          keyword: '',
        }),
      },
      /**
       * Loading indicator. If true, will display the `loadingMsg` instead of the body
       * @type {Boolean}
       */
      loading: {
        type: Boolean,
        default: false,
      },
      /**
       * Options for the table
       *
       * @inner
       * @type {Object}
       */
      options: {
        /**
         * Classes to use on various elements
         *
         * @inner
         * @type {Object}
         */
        classes: {
          wrapper: 'table-responsive',
          table: 'table',
          formControl: 'form-control',
          sort: {
            none: 'fa fa-sort',
            ascending: 'fa fa-sort-asc',
            descending: 'fa fa-sort-desc',
          },
          pagination: {
            wrapper: 'pagination',
            info: 'info form-inline',
            first: 'fa fa-angle-double-left',
            prev: 'fa fa-angle-left',
            next: 'fa fa-angle-right',
            last: 'fa fa-angle-double-right',
          },
          group: {
            show: 'fa fa-chevron-right',
            hide: 'fa fa-chevron-down',
          },
        },
        /**
         * Key-value pairs with the headings to overwrite (label to display)
         * can also be overwritten with slot: "heading_colname"
         *
         * @inner
         * @type {Object}
         */
        headings: {},
        /**
         * Key-value pairs with templates (components) for the column value
         *
         * @type {Object}
         */
        templates: {},
        /**
         * Key-value pairs with custom search function per column,
         * or false to disable search for that column
         *
         * @type {Object}
         */
        search: {},
        /**
         * Field to group by - key name
         *
         * @default
         * @type {Boolean|String}
         */
        groupBy: false,
        /**
         * Expand/collapse groups
         *
         * @default
         * @type {Boolean}
         */
        toggleGroups: false,
        /**
         * Object of data to use for each group "header" (key is the group value)
         *
         * @type {Object}
         */
        groupMeta: {},
        /**
         * Required, unique identifier
         *
         * @default
         * @type {String}
         */
        uniqueKey: 'id',
        /**
         * show extra row for each row with details
         *
         * @default
         * @type {Boolean}
         */
        detailsRow: false,
        /**
         * Texts
         *
         * @type Object
         */
        text: {
          /**
           * Text to show when row can be expanded
           * @type {String}
           */
          expand: 'Show details',
          /**
           * Text to show when row can be collapsed
           * @type {String}
           */
          collapse: 'Hide details',
          /**
           * Message to show when there is no data
           * @type {String}
           */
          noData: 'No data to show',
          /**
           * Message to show when no results are found for the search
           * @type {String}
           */
          emptyResults: 'No results for this filter',
          /**
           * Message to show when no results are found for the search
           * @type {String}
           */
          loading: 'Loading ...',
          /**
           * Text to show for pagination helper buttons
           * @type {Object}
           */
          pagination: {
            next: '',
            last: '',
            info: {
              showing: 'Showing %s to %s of %s rows.',
              records: 'records per page',
              noRows: 'No rows to display',
            },
          },
        },
        /**
         * empty object to disable sorting for all,
         * or define what columns are sortable; defaults to all sortable
         *
         * @default
         * @type {true|Object}
         */
        sortable: true,
        /**
         * false, to disable pagination - show all; defaults to true
         *
         * @default
         * @type {Boolean}
         */
        pagination: true,
        /**
         * number of items per page
         *
         * @default
         * @type {Number}
         */
        perPage: 10,
        /**
         * How many pages to show in the paginator. Odd number
         *
         * @default
         * @type {Number}
         */
        pageInterval: 7,
        /**
         * values to show in the selector of items per page
         *
         * @default
         * @type {Array}
         */
        perPageValues: [1, 2, 5, 10, 20, 50],
        /**
         * Is the table editable (eg: can select value)
         * @type {Boolean}
         */
        editable: false,
        /**
         * List of columns that should be disabled for click to select/deselect
         * @type {Array}
         */
        nonSelectableColumns: [],
        /**
         * Object (key, order) to sort table by on first load (on created)
         * @type {Object}
         */
        sortBy: {
          column: null,
          order: null,
        },
        /**
         * The collator used for sorting
         * @type {Intl.Collator}
         */
        sortCollator: new Intl.Collator('en', {
          numeric: true,
          sensitivity: 'base',
        }),
      },
    };
  },
  // OR use computed properties instead
  computed: {
    data() {
      return this.$store.state.myListData; // or any other source that has all data
    },
  },
  methods: {
    search(filter) {
      this.searchQuery = filter.keyword;
    },
  },
  watch: {
    data(data) {
      // set the group metas when data changes
      // groupColumn is the same as the one used for 'groupBy' option
      this.options.groupMeta = data.reduce((groupMeta, r) => {
        if (!groupMeta[r.groupColumn]) {
          groupMeta[r.groupColumn] = {
            label: r.groupColumn,
            total: 0,
          };
        }
        groupMeta[r.groupColumn].total += 1;
        return groupMeta;
      }, {});
    },
  },
});

As module/local component

import { Client } from '@myena/vue-table';

// in the view that contains the table
const MyView = new Vue({
  components: {
    ClientTable: Client,
  },
  data() {
    return {
      columns: ['column1', 'column2'],
      options: {
      },
    };
  },
  computed: {
    data() {
      return this.$store.state.myListData; // or any other source that has all data
    },
  },
});

Vue Server Table

Vue component for rendering a table that loads data from the server, with pagination, sorting, filtering, details row. It doesn't support grouping.

Usage:

<EnaTableServer :columns="columns" :options="options" ref="serverTable">
  <div slot="filter">
    <input placeholder="Search by name" v-model="options.filter.name"/>
    <button @click="filter">Find</button>
  </div>
  <template slot="heading_column1">
    <div>Custom heading of column1</div>
  </template>
  <template slot="column_column1" slot-scope="{ row }" >
    <span><i v-if="row.column2 === 'disable'" class="fa fa-ban"></i> {{row.column1}}</span>
  </template>
  <template slot="details_row" slot-scope="{ row }">
    <div>Div for details (expanded) row</div>
  </template>
</EnaTableServer>
import axios from 'axios';
import Qs from 'qs';
import { Server: ServerTable } from '@myena/vue-table';

const myServerTable = {
  extends: ServerTable,
  methods: {
    /**
     * Override the fetch method
     */
    async fetch(params) {
      const { data } = await axios.get(this.url, {
        params: Object.assign({}, params, {
          filter: this.options.filter,
        }),
        paramsSerializer(p) {
          return Qs.stringify(p, { arrayFormat: 'brackets' });
        },
      });
      return data;
    },
    /**
     * Override the parse method to return `data` and `total` fields
     */
    parse({ list, total }) {
      return {
        data: list,
        total,
      };
    },
  },
};

export default {
  name: 'app',
  components: {
    ServerTable: myServerTable,
  },
  data: () => ({
    columns: ['name', 'capital', 'population'],
    url: 'https://us-central1-vue-myena-table.cloudfunctions.net/countries',
    options: {
      perPage: 5,
      uniqueKey: 'alpha3Code',
      // not handled by the component
      // added here for easier access in the overridden fetch function
      filter: {
        name: null,
      },
    },
  }),
  methods: {
    filter() {
      // call component loadData, which sets some params then calls fetch (above)
      this.$refs.serverTable.loadData();
    },
  },
};