cesarve:react-auto-table

v0.1.0Published 8 years ago

This package has not had recent updates. Please investigate it's current state before committing to using it in your project.

install

meteor add cesarve:react-auto-table

Usage

1
2//on server && client
3import createAutoTable from 'meteor/cesarve:react-auto-table'
4import {userSchema as schema} from './Users'
5const Collection = Meteor.users
6const columns = [
7    {
8        Header: 'Email',
9        accessor: 'emails.0.address'
10    },
11    {
12        Header: 'First name',
13        accessor: 'profile.firstName' 
14    },
15    {
16        Header: 'Family name',
17        accessor: 'profile.familyName' 
18    },
19]
20
21export default createAutoTable({Collection, schema, columns})

Props

PropertyTypeRequired/defaultWhereExplanation
CollectionMongoCollectionrequiredBothWhere the data comes from
columnsArrayrequiredBothList of columns to show. see columns prop above
schemaSimpleSchemaundefinedBothSchema. This is used to automatically create filters based on field type
queryObject{}BothMongo query for filter the data
publishFunction()=>trueServerFunction for determine if it is allowed or not publish the data on server side. see publish prop above
defaultTypeFiltersObjectseetype filterBothDefaults cell filterMethod and filter. see defaultTypeFilters prop above
filterKeyUpDelayNumber400ClientNumber of milliseconds for fetch the data after keyup on filters

Columns prop

for complete options see react-table.

There are two special properties

  • filterMethod
  • filter

if you pass schema prop both will be filled by AutoTable according to defaultTypeFilters or if not both will filled with:

1filterMethod = (filter, row) => ({[filter.id]: filter.value}),
2filter = ({filter, onChange}) => <input type="text" onChange={event => onChange(event.target.value)} value={filter.value}/>
3

defaultTypeFilters prop

Based on simple schema there are only ten kind of field types:

  • string
  • number
  • boolean
  • date
  • object
  • stringArray (array of string [ string ])
  • numberArray
  • booleanArray
  • dateArray
  • objectArray

Yu can pass individual filterMethod and filter for each columns and/or you can pass defaultFilter to createAutoTAble function and it assign this properties according to the kind of field.

The default typeFilters is as follow, you need to pass a same shape object

1
2export const typeFilters = {
3    string: {
4        method: (filter, row) => ({[filter.id]: {$regex: filter.value, $options: 'gi'}}),
5        filter: ({filter, onChange}) => <input type="text" onChange={event => onChange(event.target.value)} value={filter.value}/>,
6    },
7    number: {
8        method: defaultFilter.method,
9        filter: ({filter, onChange}) => <input type="numeric" onChange={event => onChange(event.target.value)} value={filter.value}/>,
10    },
11    boolean: {
12        method: (filter, row) => ({[filter.id]: filter.value}),
13        filter: ({filter, onChange}) => <select onChange={event => onChange(event.target.value)} value={filter.value}>
14            <option value={true}>Select</option>
15            <option value={true}>Yes</option>
16            <option value={false}>No</option>
17        </select>,
18    },
19    date: {
20        method: (filter, row) => {
21            const $gte = new Date(filter.value).setHours(0, 0, 0, 0)
22            const $lte = new Date(filter.value).setHours(24, 0, 0, 0)
23            return {[filter.id]: {$gte, $lte}}
24        },
25        filter: ({filter, onChange}) => <input type="date" onChange={event => onChange(event.target.value)} value={filter.value}/>,
26    },
27    object:{
28        method: (filter, row) => ({[filter.id]: filter.value}),
29        filter: ({filter, onChange}) => <input type="text" onChange={event => onChange(event.target.value)} value={filter.value}/>,
30    },
31    stringArray: {
32        method: (filter, row) => ({[filter.id]: filter.value}),
33        filter: ({filter, onChange}) => <input type="text" onChange={event => onChange(event.target.value)} value={filter.value}/>,
34    },
35    numberArray: {
36         method: (filter, row) => ({[filter.id]: filter.value}),
37         filter: ({filter, onChange}) => <input type="text" onChange={event => onChange(event.target.value)} value={filter.value}/>,
38     },
39    booleanArray:  {
40          method: (filter, row) => ({[filter.id]: filter.value}),
41          filter: ({filter, onChange}) => <input type="text" onChange={event => onChange(event.target.value)} value={filter.value}/>,
42    },
43    dateArray: {
44        method: (filter, row) => ({[filter.id]: filter.value}),
45        filter: ({filter, onChange}) => <input type="text" onChange={event => onChange(event.target.value)} value={filter.value}/>,
46    },
47    objectArray: {
48         method: (filter, row) => ({[filter.id]: filter.value}),
49         filter: ({filter, onChange}) => <input type="text" onChange={event => onChange(event.target.value)} value={filter.value}/>,
50     },
51}
52
53

publish prop

This function will receive as unique param a object with {Collection, columns, schema, query} properties and it will have as a context the same context than a publish meteor function (normally you only will need this.userId).

Finally this function need to return:

  • true for automatic publication based on columns prop
  • false for denied publication
  • Any thing else for a custom publication, probably you will need to use this.added('collection_name',_id,{customObject}); this.ready();

Examples:

True or false example

1publish=({Collection, columns, schema, query})=> Roles.userIsInRole(this.userId,'admin')

Custom publish example

1publish=({Collection, columns, schema, query})=> {
2      const handle = Collection.find(query).observeChanges({
3        added: (id,doc) => {
4            doc.joinField=OtherCollection.find({_id: doc.otherCollectionId}).fetch() /*is just a example, don't abuse of this*/
5            this.added(Collection._name, id, doc);
6        },
7        changed: (id) => {
8              /**handle changed**/
9        },
10        removed: (id) => {
11              /**handle removed**/
12         }
13      });
14    
15      this.ready();
16      this.onStop(() => handle.stop());
17      /*
18      note: 
19      I'm returning undefined in this function, 
20      if true is returned automatic publication will be run as well
21      If false is returned, previous publication will be executed but not the automatic
22       */
23}
publish